34 |
Voice::~Voice() { |
Voice::~Voice() { |
35 |
} |
} |
36 |
|
|
37 |
void Voice::Trigger(int MIDIKey, uint8_t Velocity, gig::Instrument* Instrument) { |
/** |
38 |
|
* Initializes and triggers the voice, a disk stream will be launched if |
39 |
|
* needed. |
40 |
|
* |
41 |
|
* @returns 0 on success, a value < 0 if something failed |
42 |
|
*/ |
43 |
|
int Voice::Trigger(int MIDIKey, uint8_t Velocity, gig::Instrument* Instrument) { |
44 |
Active = true; |
Active = true; |
45 |
this->MIDIKey = MIDIKey; |
this->MIDIKey = MIDIKey; |
46 |
pRegion = Instrument->GetRegion(MIDIKey); |
pRegion = Instrument->GetRegion(MIDIKey); |
50 |
|
|
51 |
if (!pRegion) { |
if (!pRegion) { |
52 |
std::cerr << "Audio Thread: No Region defined for MIDI key " << MIDIKey << std::endl << std::flush; |
std::cerr << "Audio Thread: No Region defined for MIDI key " << MIDIKey << std::endl << std::flush; |
53 |
Active = false; |
Kill(); |
54 |
return; |
return -1; |
55 |
} |
} |
56 |
|
|
57 |
//TODO: current MIDI controller values are not taken into account yet |
//TODO: current MIDI controller values are not taken into account yet |
76 |
|
|
77 |
if (DiskVoice) { |
if (DiskVoice) { |
78 |
MaxRAMPos = cachedsamples - (OutputBufferSize << MAX_PITCH) / pSample->Channels; |
MaxRAMPos = cachedsamples - (OutputBufferSize << MAX_PITCH) / pSample->Channels; |
79 |
pDiskThread->OrderNewStream(&DiskStreamRef, pSample, MaxRAMPos); |
if (pDiskThread->OrderNewStream(&DiskStreamRef, pSample, MaxRAMPos) < 0) { |
80 |
|
dmsg(1,("Disk stream order failed!\n")); |
81 |
|
Kill(); |
82 |
|
return -1; |
83 |
|
} |
84 |
dmsg(5,("Disk voice launched (cached samples: %d, total Samples: %d, MaxRAMPos: %d\n", cachedsamples, pSample->SamplesTotal, MaxRAMPos)); |
dmsg(5,("Disk voice launched (cached samples: %d, total Samples: %d, MaxRAMPos: %d\n", cachedsamples, pSample->SamplesTotal, MaxRAMPos)); |
85 |
} |
} |
86 |
else { |
else { |
94 |
// ************************************************ |
// ************************************************ |
95 |
// TODO: ARTICULATION DATA HANDLING IS MISSING HERE |
// TODO: ARTICULATION DATA HANDLING IS MISSING HERE |
96 |
// ************************************************ |
// ************************************************ |
97 |
|
|
98 |
|
return 0; // success |
99 |
} |
} |
100 |
|
|
101 |
void Voice::RenderAudio() { |
void Voice::RenderAudio() { |
123 |
DiskStreamRef.pStream = pDiskThread->AskForCreatedStream(DiskStreamRef.OrderID); |
DiskStreamRef.pStream = pDiskThread->AskForCreatedStream(DiskStreamRef.OrderID); |
124 |
if (!DiskStreamRef.pStream) { |
if (!DiskStreamRef.pStream) { |
125 |
std::cout << stderr << "Disk stream not available in time!" << std::endl << std::flush; |
std::cout << stderr << "Disk stream not available in time!" << std::endl << std::flush; |
126 |
pDiskThread->OrderDeletionOfStream(&DiskStreamRef); |
Kill(); |
|
this->Active = false; |
|
127 |
return; |
return; |
128 |
} |
} |
129 |
DiskStreamRef.pStream->IncrementReadPos(pSample->Channels * (double_to_int(Pos) - MaxRAMPos)); |
DiskStreamRef.pStream->IncrementReadPos(pSample->Channels * (double_to_int(Pos) - MaxRAMPos)); |
160 |
// FIXME: assuming either mono or stereo |
// FIXME: assuming either mono or stereo |
161 |
if (this->pSample->Channels == 2) { // Stereo Sample |
if (this->pSample->Channels == 2) { // Stereo Sample |
162 |
while (i < this->OutputBufferSize) { |
while (i < this->OutputBufferSize) { |
163 |
#ifdef USE_LINEAR_INTERPOLATION |
int pos_int = double_to_int(this->Pos); // integer position |
164 |
int pos_int = double_to_int(this->Pos); // integer position |
float pos_fract = this->Pos - pos_int; // fractional part of position |
165 |
float pos_fract = this->Pos - pos_int; // fractional part of position |
pos_int <<= 1; |
166 |
pos_int <<= 1; |
|
167 |
|
#if USE_LINEAR_INTERPOLATION |
168 |
// left channel |
// left channel |
169 |
this->pOutput[i++] += effective_volume * (pSrc[pos_int] + pos_fract * (pSrc[pos_int+2] - pSrc[pos_int])); |
this->pOutput[i++] += effective_volume * (pSrc[pos_int] + pos_fract * (pSrc[pos_int+2] - pSrc[pos_int])); |
170 |
// right channel |
// right channel |
171 |
this->pOutput[i++] += effective_volume * (pSrc[pos_int+1] + pos_fract * (pSrc[pos_int+3] - pSrc[pos_int+1])); |
this->pOutput[i++] += effective_volume * (pSrc[pos_int+1] + pos_fract * (pSrc[pos_int+3] - pSrc[pos_int+1])); |
172 |
#else // polynomial interpolation |
#else // polynomial interpolation |
173 |
//FIXME: !!!THIS WON'T WORK!!! needs to be adjusted for stereo, use linear interpolation meanwhile |
// calculate left channel |
174 |
xm1 = pSrc[pos_int]; |
float xm1 = pSrc[pos_int]; |
175 |
x0 = pSrc[pos_int+1]; |
float x0 = pSrc[pos_int+2]; |
176 |
x1 = pSrc[pos_int+2]; |
float x1 = pSrc[pos_int+4]; |
177 |
x2 = pSrc[pos_int+3]; |
float x2 = pSrc[pos_int+6]; |
178 |
a = (3 * (x0-x1) - xm1 + x2) / 2; |
float a = (3 * (x0 - x1) - xm1 + x2) / 2; |
179 |
|
float b = 2 * x1 + xm1 - (5 * x0 + x2) / 2; |
180 |
|
float c = (x1 - xm1) / 2; |
181 |
|
this->pOutput[i++] += effective_volume * ((((a * pos_fract) + b) * pos_fract + c) * pos_fract + x0); |
182 |
|
|
183 |
|
//calculate right channel |
184 |
|
xm1 = pSrc[pos_int+1]; |
185 |
|
x0 = pSrc[pos_int+3]; |
186 |
|
x1 = pSrc[pos_int+5]; |
187 |
|
x2 = pSrc[pos_int+7]; |
188 |
|
a = (3 * (x0 - x1) - xm1 + x2) / 2; |
189 |
b = 2 * x1 + xm1 - (5 * x0 + x2) / 2; |
b = 2 * x1 + xm1 - (5 * x0 + x2) / 2; |
190 |
c = (x1 - xm1) / 2; |
c = (x1 - xm1) / 2; |
191 |
this->pOutput[u] += effective_volume*((((a * pos_fract) + b) * pos_fract + c) * pos_fract + x0); |
this->pOutput[i++] += effective_volume * ((((a * pos_fract) + b) * pos_fract + c) * pos_fract + x0); |
192 |
#endif // USE_LINEAR_INTERPOLATION |
#endif // USE_LINEAR_INTERPOLATION |
193 |
|
|
194 |
this->Pos += this->CurrentPitch; |
this->Pos += this->CurrentPitch; |
196 |
} |
} |
197 |
else { // Mono Sample |
else { // Mono Sample |
198 |
while (i < this->OutputBufferSize) { |
while (i < this->OutputBufferSize) { |
199 |
#ifdef USE_LINEAR_INTERPOLATION |
int pos_int = double_to_int(this->Pos); // integer position |
200 |
int pos_int = double_to_int(this->Pos); // integer position |
float pos_fract = this->Pos - pos_int; // fractional part of position |
201 |
float pos_fract = this->Pos - pos_int; // fractional part of position |
|
202 |
|
#if USE_LINEAR_INTERPOLATION |
203 |
float sample_point = effective_volume * (pSrc[pos_int] + pos_fract * (pSrc[pos_int+1] - pSrc[pos_int])); |
float sample_point = effective_volume * (pSrc[pos_int] + pos_fract * (pSrc[pos_int+1] - pSrc[pos_int])); |
|
this->pOutput[i] += sample_point; |
|
|
this->pOutput[i+1] += sample_point; |
|
|
i += 2; |
|
204 |
#else // polynomial interpolation |
#else // polynomial interpolation |
205 |
//FIXME: !!!THIS WON'T WORK!!! needs to be adjusted for stereo, use linear interpolation meanwhile |
float xm1 = pSrc[pos_int]; |
206 |
xm1 = pSrc[pos_int]; |
float x0 = pSrc[pos_int+1]; |
207 |
x0 = pSrc[pos_int+1]; |
float x1 = pSrc[pos_int+2]; |
208 |
x1 = pSrc[pos_int+2]; |
float x2 = pSrc[pos_int+3]; |
209 |
x2 = pSrc[pos_int+3]; |
float a = (3 * (x0 - x1) - xm1 + x2) / 2; |
210 |
a = (3 * (x0-x1) - xm1 + x2) / 2; |
float b = 2 * x1 + xm1 - (5 * x0 + x2) / 2; |
211 |
b = 2 * x1 + xm1 - (5 * x0 + x2) / 2; |
float c = (x1 - xm1) / 2; |
212 |
c = (x1 - xm1) / 2; |
float sample_point = effective_volume * ((((a * pos_fract) + b) * pos_fract + c) * pos_fract + x0); |
213 |
this->pOutput[u] += effective_volume*((((a * pos_fract) + b) * pos_fract + c) * pos_fract + x0); |
#endif // USE_LINEAR_INTERPOLATION |
214 |
#endif |
|
215 |
|
this->pOutput[i++] += sample_point; |
216 |
|
this->pOutput[i++] += sample_point; |
217 |
|
|
218 |
this->Pos += this->CurrentPitch; |
this->Pos += this->CurrentPitch; |
219 |
} |
} |
224 |
if (DiskVoice && DiskStreamRef.State != Stream::state_unused) { |
if (DiskVoice && DiskStreamRef.State != Stream::state_unused) { |
225 |
pDiskThread->OrderDeletionOfStream(&DiskStreamRef); |
pDiskThread->OrderDeletionOfStream(&DiskStreamRef); |
226 |
} |
} |
227 |
|
DiskStreamRef.pStream = NULL; |
228 |
|
DiskStreamRef.hStream = 0; |
229 |
|
DiskStreamRef.State = Stream::state_unused; |
230 |
|
DiskStreamRef.OrderID = 0; |
231 |
Active = false; |
Active = false; |
232 |
} |
} |