Advertisement
Guest User

Samsung test task - Simple vinyl reader in C#

a guest
Apr 6th, 2013
589
0
Never
Not a member of Pastebin yet? Sign Up, it unlocks many cool features!
C# 3.82 KB | None | 0 0
  1. using System;
  2. using System.Collections.Generic;
  3. using System.Drawing;
  4. using System.Drawing.Imaging;
  5. using NAudio.Wave;
  6.  
  7. namespace Funbit.VinylDecoder
  8. {
  9.     class Program
  10.     {
  11.         static byte[,] ReadGrayscaleVinylBitmapData(string imageFileName)
  12.         {
  13.             using (var image = Image.FromFile(imageFileName))
  14.             using (var bitmap = new Bitmap(image))
  15.             {
  16.                 var bitmapData = bitmap.LockBits(new Rectangle(0, 0, bitmap.Width, bitmap.Height),
  17.                                                  ImageLockMode.ReadWrite, bitmap.PixelFormat);
  18.                 IntPtr ptr = bitmapData.Scan0;
  19.                 int totalBytes = bitmapData.Stride * bitmap.Height;
  20.                 byte[,] grayValues = new byte[bitmap.Width, bitmap.Height];
  21.                 byte[] rgbValues = new byte[totalBytes];
  22.                 System.Runtime.InteropServices.Marshal.Copy(ptr, rgbValues, 0, totalBytes);
  23.                 bitmap.UnlockBits(bitmapData);
  24.                 int channels = bitmapData.Stride / bitmap.Width;
  25.                 for (int y = 0; y < bitmapData.Height; y++)
  26.                 {
  27.                     for (int x = 0; x < bitmapData.Width; x++)
  28.                     {
  29.                         // since image is in grayscale RGB we can use any channel (1st is ok)
  30.                         grayValues[x, y] = rgbValues[y * bitmapData.Stride + x * channels];
  31.                     }
  32.                 }
  33.                 return grayValues;
  34.             }
  35.         }
  36.        
  37.         static void ProcessVinylImage(string imageFileName, Point outerStartPoint,
  38.             int roads, int vinylInnerRadius, int vinylOuterRadius, string outputWaveFileName)
  39.         {
  40.             var imageData = ReadGrayscaleVinylBitmapData(imageFileName);
  41.             using (var logImage = Image.FromFile(imageFileName))
  42.             using (var logBitmap = new Bitmap(logImage))
  43.             {
  44.                 const int sampleBaselineShift = 70 / 4; // 70 - grayscale value
  45.                 const int rpm = 120;
  46.  
  47.                 int rate = (int)(2 * Math.PI * vinylOuterRadius * (rpm / 60));
  48.                 int centerX = outerStartPoint.X;
  49.                 int centerY = outerStartPoint.Y + vinylOuterRadius;
  50.                 List<byte> waveData = new List<byte>(roads * rate);
  51.                 double r = vinylOuterRadius,
  52.                     phi = 0,
  53.                     dr = ((double)vinylOuterRadius - vinylInnerRadius) / roads;
  54.  
  55.                 do
  56.                 {
  57.                     double x = Math.Cos((-Math.PI / 2) - phi) * r + centerX;
  58.                     double y = Math.Sin((-Math.PI / 2) - phi) * r + centerY;
  59.  
  60.                     logBitmap.SetPixel((int)x, (int)y, Color.Red);
  61.  
  62.                     byte sample = (byte)(imageData[(int)x, (int)y] - sampleBaselineShift);
  63.                     waveData.Add(sample);
  64.                     phi += 1.0d / vinylOuterRadius;
  65.                     r = vinylOuterRadius - ((phi / (Math.PI * 2)) * dr);
  66.                 } while (r > vinylInnerRadius);
  67.                
  68.                 WaveFormat format = new WaveFormat(rate, 8, 1);
  69.                 using (var writer = new WaveFileWriter(outputWaveFileName, format))
  70.                 {
  71.                     writer.Write(waveData.ToArray(), 0, waveData.Count);
  72.                 }
  73.  
  74.                 logBitmap.Save("play-log.png");
  75.             }
  76.         }
  77.  
  78.         static void Main(string[] args)
  79.         {
  80.             Console.WriteLine("Processing...");
  81.  
  82.             ProcessVinylImage("../../../../04.png", // input vinyl image
  83.                 new Point(996, 72), // needle start position in px
  84.                 39,  // total numbers of roads
  85.                 472, // radius of inner road
  86.                 935, // radius of outer road
  87.                 "play.wav"); // output wave file
  88.  
  89.             Console.WriteLine("Done.");
  90.         }
  91.     }
  92. }
Advertisement
Add Comment
Please, Sign In to add comment
Advertisement