Advertisement
Not a member of Pastebin yet?
Sign Up,
it unlocks many cool features!
- using System;
- using System.Collections.Generic;
- using System.Drawing;
- using System.Drawing.Imaging;
- using NAudio.Wave;
- namespace Funbit.VinylDecoder
- {
- class Program
- {
- static byte[,] ReadGrayscaleVinylBitmapData(string imageFileName)
- {
- using (var image = Image.FromFile(imageFileName))
- using (var bitmap = new Bitmap(image))
- {
- var bitmapData = bitmap.LockBits(new Rectangle(0, 0, bitmap.Width, bitmap.Height),
- ImageLockMode.ReadWrite, bitmap.PixelFormat);
- IntPtr ptr = bitmapData.Scan0;
- int totalBytes = bitmapData.Stride * bitmap.Height;
- byte[,] grayValues = new byte[bitmap.Width, bitmap.Height];
- byte[] rgbValues = new byte[totalBytes];
- System.Runtime.InteropServices.Marshal.Copy(ptr, rgbValues, 0, totalBytes);
- bitmap.UnlockBits(bitmapData);
- int channels = bitmapData.Stride / bitmap.Width;
- for (int y = 0; y < bitmapData.Height; y++)
- {
- for (int x = 0; x < bitmapData.Width; x++)
- {
- // since image is in grayscale RGB we can use any channel (1st is ok)
- grayValues[x, y] = rgbValues[y * bitmapData.Stride + x * channels];
- }
- }
- return grayValues;
- }
- }
- static void ProcessVinylImage(string imageFileName, Point outerStartPoint,
- int roads, int vinylInnerRadius, int vinylOuterRadius, string outputWaveFileName)
- {
- var imageData = ReadGrayscaleVinylBitmapData(imageFileName);
- using (var logImage = Image.FromFile(imageFileName))
- using (var logBitmap = new Bitmap(logImage))
- {
- const int sampleBaselineShift = 70 / 4; // 70 - grayscale value
- const int rpm = 120;
- int rate = (int)(2 * Math.PI * vinylOuterRadius * (rpm / 60));
- int centerX = outerStartPoint.X;
- int centerY = outerStartPoint.Y + vinylOuterRadius;
- List<byte> waveData = new List<byte>(roads * rate);
- double r = vinylOuterRadius,
- phi = 0,
- dr = ((double)vinylOuterRadius - vinylInnerRadius) / roads;
- do
- {
- double x = Math.Cos((-Math.PI / 2) - phi) * r + centerX;
- double y = Math.Sin((-Math.PI / 2) - phi) * r + centerY;
- logBitmap.SetPixel((int)x, (int)y, Color.Red);
- byte sample = (byte)(imageData[(int)x, (int)y] - sampleBaselineShift);
- waveData.Add(sample);
- phi += 1.0d / vinylOuterRadius;
- r = vinylOuterRadius - ((phi / (Math.PI * 2)) * dr);
- } while (r > vinylInnerRadius);
- WaveFormat format = new WaveFormat(rate, 8, 1);
- using (var writer = new WaveFileWriter(outputWaveFileName, format))
- {
- writer.Write(waveData.ToArray(), 0, waveData.Count);
- }
- logBitmap.Save("play-log.png");
- }
- }
- static void Main(string[] args)
- {
- Console.WriteLine("Processing...");
- ProcessVinylImage("../../../../04.png", // input vinyl image
- new Point(996, 72), // needle start position in px
- 39, // total numbers of roads
- 472, // radius of inner road
- 935, // radius of outer road
- "play.wav"); // output wave file
- Console.WriteLine("Done.");
- }
- }
- }
Advertisement
Add Comment
Please, Sign In to add comment
Advertisement