Beispiel #1
0
        /* Attempts to start playing the sound samples from
         * where it last left off, returns true if playing is successful,
         * false otherwise (can only play one at a time) */
        public bool Play(ProcessFrequencies pf)
        {
            PlayMutex.WaitOne();
            bool isPlaying = IsPlaying;

            if (!isPlaying)
            {
                IsPlaying = true;
            }
            PlayMutex.ReleaseMutex();

            if (!isPlaying)
            {
                PlayTask = Task.Run(() => Playing(pf, LastSampleProcessed));
            }

            return(!isPlaying);
        }
Beispiel #2
0
        /* Plays the loaded media file until it's finished or another thread
         * tells us to stop */
        private void Playing(ProcessFrequencies process, long totalSamplesProcessed)
        {
            long      currentSamplesProcessed = 0; // Keep track of what samples currently need to be processed
            Stopwatch stopWatch     = new Stopwatch();
            bool      isMono        = NChannels == NumChannels.Mono;
            int       processLength = isMono ? BufferSize : BufferSize * 2; //Need to process Left + Right channels for Stereo

            stopWatch.Start();

            // While music is playing and all samples haven't been played
            while (totalSamplesProcessed < SampleData.Count())
            {
                bool isPlaying;
                PlayMutex.WaitOne();
                isPlaying = IsPlaying;
                PlayMutex.ReleaseMutex();

                if (!isPlaying)
                {
                    return;
                }

                // Sleep for some time as we don't need to continually send data all the time
                Task.Delay(100).Wait();
                long elapsed = stopWatch.ElapsedMilliseconds;
                stopWatch.Restart();

                // Check how many samples we need to send based on the time elapsed since we last sent samples
                long nextSamplesProcessed = (SampleRate * elapsed) / 1000;
                currentSamplesProcessed += nextSamplesProcessed;

                // Time Elapsed enough to process an entire buffer
                if (totalSamplesProcessed + processLength < SampleData.Count())
                {
                    double[] buffer;
                    if (isMono)
                    {
                        buffer =
                            FFT.Magnitude(FFT.PerformFFT(
                                              SampleData.Skip((int)totalSamplesProcessed)
                                              .Take(processLength)
                                              .Select(sample => new Complex(sample, 0))
                                              .ToArray()));
                        // Stereo
                    }
                    else
                    {
                        Complex[] fftBuff = new Complex[BufferSize];
                        int       idx     = 0;
                        for (int i = (int)totalSamplesProcessed; i < (int)totalSamplesProcessed + processLength; i += 2)
                        {
                            fftBuff[idx++] = (SampleData[i] + SampleData[i + 1]) / 2; // Average left and right channels
                        }
                        buffer = FFT.Magnitude(FFT.PerformFFT(fftBuff));
                    }

                    process(buffer);
                    currentSamplesProcessed -= processLength;
                    totalSamplesProcessed   += processLength;


                    // Reached the end
                }
                else if (currentSamplesProcessed + totalSamplesProcessed >= SampleData.Count())
                {
                    int      toTake = SampleData.Count() - (int)totalSamplesProcessed;
                    double[] buffer;
                    if (isMono)
                    {
                        buffer =
                            FFT.Magnitude(FFT.PerformFFT(
                                              SampleData.Skip((int)totalSamplesProcessed)
                                              .Take(toTake)
                                              .Select(sample => new Complex(sample, 0))
                                              .Concat(Enumerable.Repeat(new Complex(0, 0), BufferSize - toTake))
                                              .ToArray()));
                        // Stereo
                    }
                    else
                    {
                        Complex[] fftBuff = new Complex[BufferSize];
                        int       idx     = 0;
                        for (int i = (int)totalSamplesProcessed; i < (int)totalSamplesProcessed + toTake; i += 2)
                        {
                            fftBuff[idx++] = (SampleData[i] + SampleData[i + 1]) / 2; // Average left and right channels
                        }
                        // Pad ending with 0s
                        for (int i = toTake; i < BufferSize; i++)
                        {
                            fftBuff[i] = 0;
                        }
                        Debug.WriteLine(fftBuff.Length);
                        buffer = FFT.Magnitude(FFT.PerformFFT(fftBuff));
                    }

                    process(buffer);
                    totalSamplesProcessed = SampleData.Count();
                }
            }

            LastSampleProcessed = totalSamplesProcessed;
        }