58 |
pLFO2 = NULL; |
pLFO2 = NULL; |
59 |
pLFO3 = NULL; |
pLFO3 = NULL; |
60 |
KeyGroup = 0; |
KeyGroup = 0; |
61 |
|
SynthesisMode = 0; //Set all mode bits to 0 first |
62 |
|
|
63 |
// select synthesis implementation (currently either pure C++ or MMX+SSE(1)) |
// select synthesis implementation (currently either pure C++ or MMX+SSE(1)) |
64 |
SYNTHESIS_MODE_SET_IMPLEMENTATION(SynthesisMode, Features::supportsMMX() && Features::supportsSSE()); |
SYNTHESIS_MODE_SET_IMPLEMENTATION(SynthesisMode, Features::supportsMMX() && Features::supportsSSE()); |
146 |
|
|
147 |
// get current dimension values to select the right dimension region |
// get current dimension values to select the right dimension region |
148 |
//FIXME: controller values for selecting the dimension region here are currently not sample accurate |
//FIXME: controller values for selecting the dimension region here are currently not sample accurate |
149 |
uint DimValues[5] = {0,0,0,0,0}; |
uint DimValues[8] = { 0 }; |
150 |
for (int i = pRegion->Dimensions - 1; i >= 0; i--) { |
for (int i = pRegion->Dimensions - 1; i >= 0; i--) { |
151 |
switch (pRegion->pDimensionDefinitions[i].dimension) { |
switch (pRegion->pDimensionDefinitions[i].dimension) { |
152 |
case ::gig::dimension_samplechannel: |
case ::gig::dimension_samplechannel: |
248 |
std::cerr << "gig::Voice::Trigger() Error: Unknown dimension\n" << std::flush; |
std::cerr << "gig::Voice::Trigger() Error: Unknown dimension\n" << std::flush; |
249 |
} |
} |
250 |
} |
} |
251 |
pDimRgn = pRegion->GetDimensionRegionByValue(DimValues[4],DimValues[3],DimValues[2],DimValues[1],DimValues[0]); |
pDimRgn = pRegion->GetDimensionRegionByValue(DimValues); |
252 |
|
|
253 |
pSample = pDimRgn->pSample; // sample won't change until the voice is finished |
pSample = pDimRgn->pSample; // sample won't change until the voice is finished |
254 |
|
|
310 |
|
|
311 |
// calculate initial pitch value |
// calculate initial pitch value |
312 |
{ |
{ |
313 |
double pitchbasecents = pDimRgn->FineTune * 10 + (int) pEngine->ScaleTuning[MIDIKey % 12]; |
double pitchbasecents = pDimRgn->FineTune + (int) pEngine->ScaleTuning[MIDIKey % 12]; |
314 |
if (pDimRgn->PitchTrack) pitchbasecents += (MIDIKey - (int) pDimRgn->UnityNote) * 100; |
if (pDimRgn->PitchTrack) pitchbasecents += (MIDIKey - (int) pDimRgn->UnityNote) * 100; |
315 |
this->PitchBase = RTMath::CentsToFreqRatio(pitchbasecents) * (double(pSample->SamplesPerSecond) / double(pEngine->pAudioOutputDevice->SampleRate())); |
this->PitchBase = RTMath::CentsToFreqRatio(pitchbasecents) * (double(pSample->SamplesPerSecond) / double(pEngine->pAudioOutputDevice->SampleRate())); |
316 |
this->PitchBend = RTMath::CentsToFreqRatio(((double) PitchBend / 8192.0) * 200.0); // pitchbend wheel +-2 semitones = 200 cents |
this->PitchBend = RTMath::CentsToFreqRatio(((double) PitchBend / 8192.0) * 200.0); // pitchbend wheel +-2 semitones = 200 cents |
695 |
} |
} |
696 |
DiskStreamRef.pStream->IncrementReadPos(pSample->Channels * (int(Pos) - MaxRAMPos)); |
DiskStreamRef.pStream->IncrementReadPos(pSample->Channels * (int(Pos) - MaxRAMPos)); |
697 |
Pos -= int(Pos); |
Pos -= int(Pos); |
698 |
|
RealSampleWordsLeftToRead = -1; // -1 means no silence has been added yet |
699 |
} |
} |
700 |
|
|
701 |
const int sampleWordsLeftToRead = DiskStreamRef.pStream->GetReadSpace(); |
const int sampleWordsLeftToRead = DiskStreamRef.pStream->GetReadSpace(); |
704 |
if (DiskStreamRef.State == Stream::state_end) { |
if (DiskStreamRef.State == Stream::state_end) { |
705 |
const int maxSampleWordsPerCycle = (pEngine->MaxSamplesPerCycle << MAX_PITCH) * pSample->Channels + 6; // +6 for the interpolator algorithm |
const int maxSampleWordsPerCycle = (pEngine->MaxSamplesPerCycle << MAX_PITCH) * pSample->Channels + 6; // +6 for the interpolator algorithm |
706 |
if (sampleWordsLeftToRead <= maxSampleWordsPerCycle) { |
if (sampleWordsLeftToRead <= maxSampleWordsPerCycle) { |
707 |
|
// remember how many sample words there are before any silence has been added |
708 |
|
if (RealSampleWordsLeftToRead < 0) RealSampleWordsLeftToRead = sampleWordsLeftToRead; |
709 |
DiskStreamRef.pStream->WriteSilence(maxSampleWordsPerCycle - sampleWordsLeftToRead); |
DiskStreamRef.pStream->WriteSilence(maxSampleWordsPerCycle - sampleWordsLeftToRead); |
710 |
} |
} |
711 |
} |
} |
721 |
Pos -= iPos; // just keep fractional part of Pos |
Pos -= iPos; // just keep fractional part of Pos |
722 |
|
|
723 |
// change state of voice to 'end' if we really reached the end of the sample data |
// change state of voice to 'end' if we really reached the end of the sample data |
724 |
if (DiskStreamRef.State == Stream::state_end && readSampleWords >= sampleWordsLeftToRead) this->PlaybackState = playback_state_end; |
if (RealSampleWordsLeftToRead >= 0) { |
725 |
|
RealSampleWordsLeftToRead -= readSampleWords; |
726 |
|
if (RealSampleWordsLeftToRead <= 0) this->PlaybackState = playback_state_end; |
727 |
|
} |
728 |
} |
} |
729 |
break; |
break; |
730 |
|
|