--- linuxsampler/trunk/src/engines/gig/Voice.cpp 2004/12/13 00:46:42 319 +++ linuxsampler/trunk/src/engines/gig/Voice.cpp 2004/12/29 01:14:15 330 @@ -61,6 +61,7 @@ // select synthesis implementation (currently either pure C++ or MMX+SSE(1)) SYNTHESIS_MODE_SET_IMPLEMENTATION(SynthesisMode, Features::supportsMMX() && Features::supportsSSE()); + SYNTHESIS_MODE_SET_PROFILING(SynthesisMode, true); } Voice::~Voice() { @@ -693,12 +694,19 @@ } DiskStreamRef.pStream->IncrementReadPos(pSample->Channels * (int(Pos) - MaxRAMPos)); Pos -= int(Pos); + RealSampleWordsLeftToRead = -1; // -1 means no silence has been added yet } + const int sampleWordsLeftToRead = DiskStreamRef.pStream->GetReadSpace(); + // add silence sample at the end if we reached the end of the stream (for the interpolator) - if (DiskStreamRef.State == Stream::state_end && DiskStreamRef.pStream->GetReadSpace() < (pEngine->MaxSamplesPerCycle << MAX_PITCH) / pSample->Channels) { - DiskStreamRef.pStream->WriteSilence((pEngine->MaxSamplesPerCycle << MAX_PITCH) / pSample->Channels); - this->PlaybackState = playback_state_end; + if (DiskStreamRef.State == Stream::state_end) { + const int maxSampleWordsPerCycle = (pEngine->MaxSamplesPerCycle << MAX_PITCH) * pSample->Channels + 6; // +6 for the interpolator algorithm + if (sampleWordsLeftToRead <= maxSampleWordsPerCycle) { + // remember how many sample words there are before any silence has been added + if (RealSampleWordsLeftToRead < 0) RealSampleWordsLeftToRead = sampleWordsLeftToRead; + DiskStreamRef.pStream->WriteSilence(maxSampleWordsPerCycle - sampleWordsLeftToRead); + } } sample_t* ptr = DiskStreamRef.pStream->GetReadPtr(); // get the current read_ptr within the ringbuffer where we read the samples from @@ -706,8 +714,16 @@ // render current audio fragment Synthesize(Samples, ptr, Delay); - DiskStreamRef.pStream->IncrementReadPos(int(Pos) * pSample->Channels); - Pos -= int(Pos); + const int iPos = (int) Pos; + const int readSampleWords = iPos * pSample->Channels; // amount of sample words actually been read + DiskStreamRef.pStream->IncrementReadPos(readSampleWords); + Pos -= iPos; // just keep fractional part of Pos + + // change state of voice to 'end' if we really reached the end of the sample data + if (RealSampleWordsLeftToRead >= 0) { + RealSampleWordsLeftToRead -= readSampleWords; + if (RealSampleWordsLeftToRead <= 0) this->PlaybackState = playback_state_end; + } } break; @@ -926,6 +942,7 @@ float prev_cutoff = pEngine->pSynthesisParameters[Event::destination_vcfc][0]; float prev_res = pEngine->pSynthesisParameters[Event::destination_vcfr][0]; FilterLeft.SetParameters(&bqbase, &bqmain, prev_cutoff, prev_res, pEngine->SampleRate); + FilterRight.SetParameters(&bqbase, &bqmain, prev_cutoff, prev_res, pEngine->SampleRate); pEngine->pBasicFilterParameters[0] = bqbase; pEngine->pMainFilterParameters[0] = bqmain; @@ -939,24 +956,25 @@ prev_cutoff = pEngine->pSynthesisParameters[Event::destination_vcfc][i]; prev_res = pEngine->pSynthesisParameters[Event::destination_vcfr][i]; FilterLeft.SetParameters(&bqbase, &bqmain, prev_cutoff, prev_res, pEngine->SampleRate); + FilterRight.SetParameters(&bqbase, &bqmain, prev_cutoff, prev_res, pEngine->SampleRate); } } //same as 'pEngine->pBasicFilterParameters[i] = bqbase;' bq = (float*) &pEngine->pBasicFilterParameters[i]; - bq[0] = bqbase.a1; - bq[1] = bqbase.a2; - bq[2] = bqbase.b0; - bq[3] = bqbase.b1; - bq[4] = bqbase.b2; + bq[0] = bqbase.b0; + bq[1] = bqbase.b1; + bq[2] = bqbase.b2; + bq[3] = bqbase.a1; + bq[4] = bqbase.a2; // same as 'pEngine->pMainFilterParameters[i] = bqmain;' bq = (float*) &pEngine->pMainFilterParameters[i]; - bq[0] = bqmain.a1; - bq[1] = bqmain.a2; - bq[2] = bqmain.b0; - bq[3] = bqmain.b1; - bq[4] = bqmain.b2; + bq[0] = bqmain.b0; + bq[1] = bqmain.b1; + bq[2] = bqmain.b2; + bq[3] = bqmain.a1; + bq[4] = bqmain.a2; } } @@ -968,18 +986,8 @@ * @param pSrc - pointer to input sample data * @param Skip - number of sample points to skip in output buffer */ - void Voice::Synthesize(uint Samples, sample_t* pSrc, int Skip) { - UpdateSynthesisMode(); - SynthesizeFragment_Fn* f = (SynthesizeFragment_Fn*) SynthesizeFragmentFnPtr; - f(*this, Samples, pSrc, Skip); - } - - /** - * Determine the respective synthesis function for the given synthesis - * mode. - */ - void Voice::UpdateSynthesisMode() { - SynthesizeFragmentFnPtr = GetSynthesisFunction(SynthesisMode); + void Voice::Synthesize(uint Samples, sample_t* pSrc, uint Skip) { + RunSynthesisFunction(SynthesisMode, *this, Samples, pSrc, Skip); } /**