示例#1
0
        public VariableSpeedSampleProvider(ISampleProvider sourceProvider, int readDurationMilliseconds,
                                           SoundTouchProfile soundTouchProfile)
        {
            _soundTouch = new SoundTouch.SoundTouch();
            // explore what the default values are before we change them:
            //Debug.WriteLine(String.Format("SoundTouch Version {0}", soundTouch.VersionString));
            //Debug.WriteLine("Use QuickSeek: {0}", soundTouch.GetUseQuickSeek());
            //Debug.WriteLine("Use AntiAliasing: {0}", soundTouch.GetUseAntiAliasing());

            SetSoundTouchProfile(soundTouchProfile);
            _sourceProvider = sourceProvider;
            _soundTouch.SetSampleRate(WaveFormat.SampleRate);
            _channelCount = WaveFormat.Channels;
            _soundTouch.SetChannels(_channelCount);
            _sourceReadBuffer     = new float[(WaveFormat.SampleRate * _channelCount * (long)readDurationMilliseconds) / 1000];
            _soundTouchReadBuffer = new float[_sourceReadBuffer.Length * 10]; // support down to 0.1 speed
        }
示例#2
0
        private int VocodeAudioChunk(Chunk chunk, AudioFileReader audioFileReader, WaveFileWriter audioFileWriter)
        {
            ///TODO Create the soundtouch outside this loop, and just reset it!!!!!!
            var speed       = (chunk.GetSpeed(ref options) - 1) * 100;
            var samplesLeft = false;

            soundTouch = new SoundTouch.SoundTouch <float, double>();

            //Init soundtouch
            soundTouch.SetRate(1.0f);
            soundTouch.SetPitchOctaves(0f);
            soundTouch.SetTempo(0);

            //Set soundtouch rates
            soundTouch.SetSampleRate((int)(audioFileReader.WaveFormat.SampleRate));
            soundTouch.SetChannels(audioFileReader.WaveFormat.Channels);


            soundTouch.SetTempoChange(speed);

            //Sample count of chunk
            var chunkSamplesLength = ((chunk.endFrame * options.samplesPerFrame) - (chunk.startFrame * options.samplesPerFrame));


            int totalSamplesRead = 0;

            //Set buffer size to 6750 or chunkSamplesLength if its less
            int bufferSize = reAlignBuffer(chunkSamplesLength < 6750 ? chunkSamplesLength : 6750, audioFileReader.WaveFormat.BlockAlign);


            //Init buffers
            float[] inputBuffer  = new float[bufferSize];
            float[] outputBuffer = new float[bufferSize];

            var samplesRead = 0;


            var readAll = false;
            int nSamples;

            while (!readAll || samplesLeft)
            {
                if (!readAll)
                {
                    utils.ReportStatus(WRITE_AUDIO_MESSAGE, chunk.startFrame + (totalSamplesRead / options.samplesPerFrame), options.frame_count, 2);

                    //Shorten buffer if needed
                    if (bufferSize > chunkSamplesLength - totalSamplesRead)
                    {
                        bufferSize = reAlignBuffer(chunkSamplesLength - totalSamplesRead, audioFileReader.WaveFormat.BlockAlign);
                    }

                    //Read next block of samples
                    samplesRead = audioFileReader.Read(inputBuffer, 0, bufferSize);

                    //End of stream or chunk finished
                    if (samplesRead == 0 || totalSamplesRead >= chunkSamplesLength)
                    {
                        //Stop reading more and flush the soundtouch buffer
                        readAll = true;
                        if (samplesRead > 0)
                        {
                            //Read the next block and and input them into soundtouch
                            nSamples = samplesRead / audioFileReader.WaveFormat.Channels;
                            soundTouch.PutSamples(inputBuffer, nSamples);
                        }
                        soundTouch.Flush();
                    }
                    else
                    {
                        //Read the next block and and input them into soundtouch
                        nSamples = samplesRead / audioFileReader.WaveFormat.Channels;
                        soundTouch.PutSamples(inputBuffer, nSamples);
                    }
                }

                do
                {
                    //Get samples from soundtouch
                    nSamples = soundTouch.ReceiveSamples(outputBuffer, outputBuffer.Length / audioFileReader.WaveFormat.Channels);

                    //Write samples to file
                    audioFileWriter.WriteSamples(outputBuffer, 0, nSamples * audioFileReader.WaveFormat.Channels);
                } while (nSamples != 0);


                totalSamplesRead += samplesRead;
                samplesLeft       = soundTouch?.AvailableSamples > 0;
            }

            soundTouch.Clear();

            return(totalSamplesRead);
        }