示例#1
0
        static void Main(string[] args)
        {
            var songs = new List <Song>();

            songs.AddRange(DeserializeSongs.LoadSongs(args));
            songs.AddRange(DeserializeSongs.LoadSongs(DefaultSongAddress));
            DetectSongs.Initialize(songs);

            var sb = new StringBuilder();

            songs.Select(item => sb.Append($"{item.name}, ")).ToArray();
            Console.WriteLine($"{songs.Count} songs loaded: {sb.ToString()}");

            var deviceCount = WaveInEvent.DeviceCount;

            if (deviceCount == 0)
            {
                Console.WriteLine("No microphone device found.");
                return;
            }

            for (int i = 0; i < deviceCount; i++)
            {
                var deviceInfo = WaveInEvent.GetCapabilities(i);
                Console.WriteLine("Device {0}: {1}, {2} channels",
                                  i, deviceInfo.ProductName, deviceInfo.Channels);
            }

            Console.WriteLine($"Select device from {0} to {deviceCount - 1}");

            int index;

            while (!int.TryParse(Console.ReadLine(), out index))
            {
                Console.WriteLine($"Select device from {0} to {deviceCount - 1}");
            }

            Console.WriteLine("Press escape to finish process.");

            Freq2Note.Init();
            var waveIn = new WaveInEvent()
            {
                DeviceNumber = index
            };

            waveIn.DataAvailable     += AudioDataAvailable;
            waveIn.WaveFormat         = new WaveFormat(SamplingRate, 1);
            waveIn.BufferMilliseconds = (int)((double)BufferSize / (double)SamplingRate * 1000.0);

            bwp = new BufferedWaveProvider(waveIn.WaveFormat)
            {
                BufferLength = BufferSize * 2, DiscardOnBufferOverflow = true
            };

            try
            {
                waveIn.StartRecording();
            }
            catch
            {
                string msg = "Could not record from audio device!\n\n";
                msg += "Is your microphone plugged in?\n";
                msg += "Is it set as your default recording device?";
                Console.WriteLine(msg, "ERROR");
            }

            ThreadPool.QueueUserWorkItem(EscapeLoad, null);
            while (true)
            {
                lock (lockObj)
                {
                    if (keyPressed)
                    {
                        break;
                    }
                }

                var note = Process();
                if (note != null)
                {
                    DetectSongs.NoteStreamLoader(note.Value);
                }

                var song = DetectSongs.FindSong();
                if (song != null)
                {
                    Console.WriteLine($"------------------------------------\nSong detect: {song.Value.name}\n------------------------------------");
                }
            }

            waveIn.StopRecording();
            waveIn.Dispose();
        }
示例#2
0
        private static NoteOctave?Process()
        {
            // check the incoming microphone audio
            int frameSize  = BufferSize;
            var audioBytes = new byte[frameSize];

            bwp.Read(audioBytes, 0, frameSize);

            // return if there's nothing new to plot
            if (audioBytes.Length == 0)
            {
                return(null);
            }
            if (audioBytes[frameSize - 2] == 0)
            {
                return(null);
            }

            // incoming data is 16-bit (2 bytes per audio point)
            int BYTES_PER_POINT = 2;

            // create a (32-bit) int array ready to fill with the 16-bit data
            int graphPointCount = audioBytes.Length / BYTES_PER_POINT;

            // create double arrays to hold the data we will graph
            double[] pcm     = new double[graphPointCount];
            double[] fft     = new double[graphPointCount];
            double[] fftReal = new double[graphPointCount / 2];

            // populate Xs and Ys with double data
            for (int i = 0; i < graphPointCount; i++)
            {
                // read the int16 from the two bytes
                Int16 val = BitConverter.ToInt16(audioBytes, i * 2);

                // store the value in Ys as a percent (+/- 100% = 200%)
                pcm[i] = (double)(val) / Math.Pow(2, 16) * 200.0;
            }

            // calculate the full FFT
            fft = FourierProcess.FFT(pcm);

            // determine horizontal axis units for graphs
            double fftMaxFreq        = SamplingRate / 2;
            double fftPointSpacingHz = fftMaxFreq / graphPointCount;

            // just keep the real half (the other half imaginary)
            Array.Copy(fft, fftReal, fftReal.Length);

            /*var sb = new StringBuilder();
             * fftReal.Select(item => sb.Append($"{item.ToString("F2")}, ")).ToArray();
             * Console.WriteLine(sb.ToString());*/

            var peekFrequency = FourierProcess.FindMaxPeekIndex(fftReal) * fftPointSpacingHz;
            var noteAccuracy  = Freq2Note.GetNote(peekFrequency);

            if (noteAccuracy.accuracy > 0.5)
            {
                Console.WriteLine($"Frequency: {peekFrequency:F2}Hz, Note: {noteAccuracy.note}{noteAccuracy.octave}, Accuracy: {noteAccuracy.accuracy * 100:F0}%");
                return(new NoteOctave()
                {
                    note = noteAccuracy.note, octave = noteAccuracy.octave
                });
            }

            return(null);
        }