75 |
DiskVoice = cachedsamples < pSample->SamplesTotal; |
DiskVoice = cachedsamples < pSample->SamplesTotal; |
76 |
|
|
77 |
if (DiskVoice) { // voice to be streamed from disk |
if (DiskVoice) { // voice to be streamed from disk |
78 |
MaxRAMPos = cachedsamples - (OutputBufferSize << MAX_PITCH) / pSample->Channels; |
MaxRAMPos = cachedsamples - (MaxSamplesPerCycle << MAX_PITCH) / pSample->Channels; |
79 |
|
|
80 |
// check if there's a loop defined which completely fits into the cached (RAM) part of the sample |
// check if there's a loop defined which completely fits into the cached (RAM) part of the sample |
81 |
if (pSample->Loops && pSample->LoopEnd <= MaxRAMPos) { |
if (pSample->Loops && pSample->LoopEnd <= MaxRAMPos) { |
89 |
Kill(); |
Kill(); |
90 |
return -1; |
return -1; |
91 |
} |
} |
92 |
dmsg(4,("Disk voice launched (cached samples: %d, total Samples: %d, MaxRAMPos: %d, RAMLooping: %s\n", cachedsamples, pSample->SamplesTotal, MaxRAMPos, (RAMLoop) ? "yes" : "no")); |
dmsg(4,("Disk voice launched (cached samples: %d, total Samples: %d, MaxRAMPos: %d, RAMLooping: %s)\n", cachedsamples, pSample->SamplesTotal, MaxRAMPos, (RAMLoop) ? "yes" : "no")); |
93 |
} |
} |
94 |
else { // RAM only voice |
else { // RAM only voice |
95 |
MaxRAMPos = cachedsamples; |
MaxRAMPos = cachedsamples; |
126 |
* will automatically switch to disk playback for the next RenderAudio() |
* will automatically switch to disk playback for the next RenderAudio() |
127 |
* call. |
* call. |
128 |
*/ |
*/ |
129 |
void Voice::RenderAudio() { |
void Voice::Render(uint Samples) { |
130 |
|
|
131 |
// Let all modulators throw their parameter changes for the current audio fragment |
// Let all modulators throw their parameter changes for the current audio fragment |
132 |
ModulationSystem::ResetDestinationParameter(ModulationSystem::destination_vca, this->Volume); |
ModulationSystem::ResetDestinationParameter(ModulationSystem::destination_vca, this->Volume); |
133 |
EG1.ProcessFragment(); |
EG1.Process(Samples); |
134 |
|
|
135 |
|
|
136 |
switch (this->PlaybackState) { |
switch (this->PlaybackState) { |
137 |
|
|
138 |
case playback_state_ram: { |
case playback_state_ram: { |
139 |
if (RAMLoop) InterpolateAndLoop((sample_t*) pSample->GetCache().pStart); |
if (RAMLoop) InterpolateAndLoop(Samples, (sample_t*) pSample->GetCache().pStart); |
140 |
else Interpolate((sample_t*) pSample->GetCache().pStart); |
else Interpolate(Samples, (sample_t*) pSample->GetCache().pStart); |
141 |
if (DiskVoice) { |
if (DiskVoice) { |
142 |
// check if we reached the allowed limit of the sample RAM cache |
// check if we reached the allowed limit of the sample RAM cache |
143 |
if (Pos > MaxRAMPos) { |
if (Pos > MaxRAMPos) { |
165 |
} |
} |
166 |
|
|
167 |
// add silence sample at the end if we reached the end of the stream (for the interpolator) |
// add silence sample at the end if we reached the end of the stream (for the interpolator) |
168 |
if (DiskStreamRef.State == Stream::state_end && DiskStreamRef.pStream->GetReadSpace() < (OutputBufferSize << MAX_PITCH) / pSample->Channels) { |
if (DiskStreamRef.State == Stream::state_end && DiskStreamRef.pStream->GetReadSpace() < (MaxSamplesPerCycle << MAX_PITCH) / pSample->Channels) { |
169 |
DiskStreamRef.pStream->WriteSilence((OutputBufferSize << MAX_PITCH) / pSample->Channels); |
DiskStreamRef.pStream->WriteSilence((MaxSamplesPerCycle << MAX_PITCH) / pSample->Channels); |
170 |
this->PlaybackState = playback_state_end; |
this->PlaybackState = playback_state_end; |
171 |
} |
} |
172 |
|
|
173 |
sample_t* ptr = DiskStreamRef.pStream->GetReadPtr(); // get the current read_ptr within the ringbuffer where we read the samples from |
sample_t* ptr = DiskStreamRef.pStream->GetReadPtr(); // get the current read_ptr within the ringbuffer where we read the samples from |
174 |
Interpolate(ptr); |
Interpolate(Samples, ptr); |
175 |
DiskStreamRef.pStream->IncrementReadPos(double_to_int(Pos) * pSample->Channels); |
DiskStreamRef.pStream->IncrementReadPos(double_to_int(Pos) * pSample->Channels); |
176 |
Pos -= double_to_int(Pos); |
Pos -= double_to_int(Pos); |
177 |
} |
} |
191 |
* |
* |
192 |
* @param pSrc - pointer to input sample data |
* @param pSrc - pointer to input sample data |
193 |
*/ |
*/ |
194 |
void Voice::Interpolate(sample_t* pSrc) { |
void Voice::Interpolate(uint Samples, sample_t* pSrc) { |
195 |
int i = 0; |
int i = 0; |
|
float e = 1.0; |
|
196 |
|
|
197 |
// FIXME: assuming either mono or stereo |
// FIXME: assuming either mono or stereo |
198 |
if (this->pSample->Channels == 2) { // Stereo Sample |
if (this->pSample->Channels == 2) { // Stereo Sample |
199 |
while (i < this->OutputBufferSize) { |
while (i < Samples) { |
200 |
InterpolateOneStep_Stereo(pSrc, i, ModulationSystem::pDestinationParameter[ModulationSystem::destination_vca][i>>1]); |
InterpolateOneStep_Stereo(pSrc, i, ModulationSystem::pDestinationParameter[ModulationSystem::destination_vca][i]); |
201 |
} |
} |
202 |
} |
} |
203 |
else { // Mono Sample |
else { // Mono Sample |
204 |
while (i < this->OutputBufferSize) { |
while (i < Samples) { |
205 |
InterpolateOneStep_Mono(pSrc, i, ModulationSystem::pDestinationParameter[ModulationSystem::destination_vca][i>>1]); |
InterpolateOneStep_Mono(pSrc, i, ModulationSystem::pDestinationParameter[ModulationSystem::destination_vca][i]); |
206 |
} |
} |
207 |
} |
} |
208 |
} |
} |
212 |
* |
* |
213 |
* @param pSrc - pointer to input sample data |
* @param pSrc - pointer to input sample data |
214 |
*/ |
*/ |
215 |
void Voice::InterpolateAndLoop(sample_t* pSrc) { |
void Voice::InterpolateAndLoop(uint Samples, sample_t* pSrc) { |
216 |
int i = 0; |
int i = 0; |
217 |
|
|
218 |
// FIXME: assuming either mono or stereo |
// FIXME: assuming either mono or stereo |
219 |
if (pSample->Channels == 2) { // Stereo Sample |
if (pSample->Channels == 2) { // Stereo Sample |
220 |
if (pSample->LoopPlayCount) { |
if (pSample->LoopPlayCount) { |
221 |
// render loop (loop count limited) |
// render loop (loop count limited) |
222 |
while (i < OutputBufferSize && LoopCyclesLeft) { |
while (i < Samples && LoopCyclesLeft) { |
223 |
InterpolateOneStep_Stereo(pSrc, i, ModulationSystem::pDestinationParameter[ModulationSystem::destination_vca][i>>1]); |
InterpolateOneStep_Stereo(pSrc, i, ModulationSystem::pDestinationParameter[ModulationSystem::destination_vca][i]); |
224 |
if (Pos > pSample->LoopEnd) { |
if (Pos > pSample->LoopEnd) { |
225 |
Pos = pSample->LoopStart + fmod(Pos - pSample->LoopEnd, pSample->LoopSize);; |
Pos = pSample->LoopStart + fmod(Pos - pSample->LoopEnd, pSample->LoopSize);; |
226 |
LoopCyclesLeft--; |
LoopCyclesLeft--; |
227 |
} |
} |
228 |
} |
} |
229 |
// render on without loop |
// render on without loop |
230 |
while (i < OutputBufferSize) { |
while (i < Samples) { |
231 |
InterpolateOneStep_Stereo(pSrc, i, ModulationSystem::pDestinationParameter[ModulationSystem::destination_vca][i>>1]); |
InterpolateOneStep_Stereo(pSrc, i, ModulationSystem::pDestinationParameter[ModulationSystem::destination_vca][i]); |
232 |
} |
} |
233 |
} |
} |
234 |
else { // render loop (endless loop) |
else { // render loop (endless loop) |
235 |
while (i < OutputBufferSize) { |
while (i < Samples) { |
236 |
InterpolateOneStep_Stereo(pSrc, i, ModulationSystem::pDestinationParameter[ModulationSystem::destination_vca][i>>1]); |
InterpolateOneStep_Stereo(pSrc, i, ModulationSystem::pDestinationParameter[ModulationSystem::destination_vca][i]); |
237 |
if (Pos > pSample->LoopEnd) { |
if (Pos > pSample->LoopEnd) { |
238 |
Pos = pSample->LoopStart + fmod(Pos - pSample->LoopEnd, pSample->LoopSize); |
Pos = pSample->LoopStart + fmod(Pos - pSample->LoopEnd, pSample->LoopSize); |
239 |
} |
} |
243 |
else { // Mono Sample |
else { // Mono Sample |
244 |
if (pSample->LoopPlayCount) { |
if (pSample->LoopPlayCount) { |
245 |
// render loop (loop count limited) |
// render loop (loop count limited) |
246 |
while (i < OutputBufferSize && LoopCyclesLeft) { |
while (i < Samples && LoopCyclesLeft) { |
247 |
InterpolateOneStep_Mono(pSrc, i, ModulationSystem::pDestinationParameter[ModulationSystem::destination_vca][i>>1]); |
InterpolateOneStep_Mono(pSrc, i, ModulationSystem::pDestinationParameter[ModulationSystem::destination_vca][i]); |
248 |
if (Pos > pSample->LoopEnd) { |
if (Pos > pSample->LoopEnd) { |
249 |
Pos = pSample->LoopStart + fmod(Pos - pSample->LoopEnd, pSample->LoopSize);; |
Pos = pSample->LoopStart + fmod(Pos - pSample->LoopEnd, pSample->LoopSize);; |
250 |
LoopCyclesLeft--; |
LoopCyclesLeft--; |
251 |
} |
} |
252 |
} |
} |
253 |
// render on without loop |
// render on without loop |
254 |
while (i < OutputBufferSize) { |
while (i < Samples) { |
255 |
InterpolateOneStep_Mono(pSrc, i, ModulationSystem::pDestinationParameter[ModulationSystem::destination_vca][i>>1]); |
InterpolateOneStep_Mono(pSrc, i, ModulationSystem::pDestinationParameter[ModulationSystem::destination_vca][i]); |
256 |
} |
} |
257 |
} |
} |
258 |
else { // render loop (endless loop) |
else { // render loop (endless loop) |
259 |
while (i < OutputBufferSize) { |
while (i < Samples) { |
260 |
InterpolateOneStep_Mono(pSrc, i, ModulationSystem::pDestinationParameter[ModulationSystem::destination_vca][i>>1]); |
InterpolateOneStep_Mono(pSrc, i, ModulationSystem::pDestinationParameter[ModulationSystem::destination_vca][i]); |
261 |
if (Pos > pSample->LoopEnd) { |
if (Pos > pSample->LoopEnd) { |
262 |
Pos = pSample->LoopStart + fmod(Pos - pSample->LoopEnd, pSample->LoopSize);; |
Pos = pSample->LoopStart + fmod(Pos - pSample->LoopEnd, pSample->LoopSize);; |
263 |
} |
} |