1 /*
2 * Copyright (c) 2009, The MilkyTracker Team.
3 * All rights reserved.
4 *
5 * Redistribution and use in source and binary forms, with or without
6 * modification, are permitted provided that the following conditions are met:
7 *
8 * - Redistributions of source code must retain the above copyright notice,
9 * this list of conditions and the following disclaimer.
10 * - Redistributions in binary form must reproduce the above copyright
11 * notice, this list of conditions and the following disclaimer in the
12 * documentation and/or other materials provided with the distribution.
13 * - Neither the name of the <ORGANIZATION> nor the names of its contributors
14 * may be used to endorse or promote products derived from this software
15 * without specific prior written permission.
16 *
17 * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS"
18 * AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
19 * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
20 * ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE
21 * LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
22 * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
23 * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
24 * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
25 * CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
26 * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
27 * POSSIBILITY OF SUCH DAMAGE.
28 */
29
30 /*
31 * ChannelMixer.cpp
32 * MilkyPlay mixer class
33 *
34 *
35 * "- Be prepared! Are you sure you want to know? :-)"
36 *
37 * This class is pretty much emulating a Gravis Ultrasound with a timer set to 250Hz
38 * I.e. the mixer() routine will call a user specified handler 250 times per second
39 * while mixing the audio stream in between.
40 */
41 #include "ChannelMixer.h"
42 #include "ResamplerFactory.h"
43 #include "ResamplerMacros.h"
44 #include "AudioDriverManager.h"
45 #include <math.h>
46
47 // Ramp out will last (THEBEATLENGTH*RAMPDOWNFRACTION)>>8 samples
48 #define RAMPDOWNFRACTION 256
49
myMod(mp_sint32 a,mp_sint32 b)50 static inline mp_sint32 myMod(mp_sint32 a, mp_sint32 b)
51 {
52 mp_sint32 r = a % b;
53 return r < 0 ? b + r : r;
54 }
55
56 /*
57 "I've found out that FT2 uses the square root pan law, which is
58 close to the linear pan law, but it stresses samples that are played
59 on the far left and right. Note that its indices range from 0 to
60 256, while the internal panning ranges from 0 to 255, meaning that
61 there is no true 100% right panning, only 100% left is possible."
62
63 - Saga_Musix @ http://modarchive.org/forums/index.php?topic=3517.0
64 */
65 mp_sint32 ChannelMixer::panLUT[257];
panToVol(ChannelMixer::TMixerChannel * chn,mp_sint32 & volL,mp_sint32 & volR)66 void ChannelMixer::panToVol (ChannelMixer::TMixerChannel *chn, mp_sint32 &volL, mp_sint32 &volR)
67 {
68 mp_sint32 pan = (((chn->pan - 128)*panningSeparation) >> 8) + 128;
69 if (pan < 0) pan = 0;
70 if (pan > 255) pan = 255;
71
72 volL = (chn->vol*panLUT[256-pan]*masterVolume);
73 volR = (chn->vol*panLUT[pan]*masterVolume);
74
75 if (chn->flags&MP_SAMPLE_MUTE)
76 volL = volR = 0;
77 }
78
addChannelsNormal(ChannelMixer * mixer,mp_uint32 numChannels,mp_sint32 * buffer32,mp_sint32 beatNum,mp_sint32 beatlength)79 void ChannelMixer::ResamplerBase::addChannelsNormal(ChannelMixer* mixer, mp_uint32 numChannels, mp_sint32* buffer32,mp_sint32 beatNum, mp_sint32 beatlength)
80 {
81 ChannelMixer::TMixerChannel* channel = mixer->channel;
82 ChannelMixer::TMixerChannel* newChannel = mixer->newChannel;
83
84 for (mp_uint32 c=0;c<numChannels;c++)
85 {
86 ChannelMixer::TMixerChannel* chn = &channel[c];
87 chn->index = c; // For Amiga resampler
88
89 if (!(chn->flags & MP_SAMPLE_PLAY))
90 continue;
91
92 switch (chn->flags&(MP_SAMPLE_FADEOUT|MP_SAMPLE_FADEIN|MP_SAMPLE_FADEOFF))
93 {
94 case MP_SAMPLE_FADEOFF:
95 {
96 chn->flags&=~(MP_SAMPLE_PLAY | MP_SAMPLE_FADEOFF);
97 continue;
98 }
99
100 case MP_SAMPLE_FADEOUT:
101 {
102 chn->sample = newChannel[c].sample;
103 chn->smplen = newChannel[c].smplen;
104 chn->loopstart = newChannel[c].loopstart;
105 chn->loopend = newChannel[c].loopend;
106 chn->smppos = newChannel[c].smppos;
107 chn->smpposfrac = newChannel[c].smpposfrac;
108 chn->flags = newChannel[c].flags;
109 chn->loopendcopy = newChannel[c].loopendcopy;
110 chn->fixedtime = newChannel[c].fixedtimefrac;
111 chn->fixedtimefrac = newChannel[c].fixedtimefrac;
112 // break is missing here intentionally!!!
113 }
114 default:
115 {
116 mixer->panToVol(chn, chn->finalvoll, chn->finalvolr);
117 break;
118 }
119 }
120
121 // mix here
122 addChannel(chn, buffer32, beatlength, beatlength);
123
124 }
125 }
126
addChannelsRamping(ChannelMixer * mixer,mp_uint32 numChannels,mp_sint32 * buffer32,mp_sint32 beatNum,mp_sint32 beatlength)127 void ChannelMixer::ResamplerBase::addChannelsRamping(ChannelMixer* mixer, mp_uint32 numChannels, mp_sint32* buffer32,mp_sint32 beatNum, mp_sint32 beatlength)
128 {
129 ChannelMixer::TMixerChannel* channel = mixer->channel;
130 ChannelMixer::TMixerChannel* newChannel = mixer->newChannel;
131
132 for (mp_uint32 c=0;c<numChannels;c++)
133 {
134 ChannelMixer::TMixerChannel* chn = &channel[c];
135 chn->index = c; // For Amiga resampler
136
137 if (!(chn->flags & MP_SAMPLE_PLAY))
138 continue;
139
140 switch (chn->flags&(MP_SAMPLE_FADEOUT|MP_SAMPLE_FADEIN|MP_SAMPLE_FADEOFF))
141 {
142 case MP_SAMPLE_FADEOFF:
143 {
144 mp_sint32 maxramp = (beatlength*RAMPDOWNFRACTION)>>8;
145 mp_sint32 beatl = (!(chn->flags & 3)) ? (ChannelMixer::fixedmul(chn->loopend,chn->rsmpadd) >> 1) : maxramp;
146
147 if (beatl > maxramp || beatl <= 0)
148 beatl = maxramp;
149
150 chn->rampFromVolStepL = (-chn->finalvoll)/beatl;
151 chn->rampFromVolStepR = (-chn->finalvolr)/beatl;
152
153 if (beatl)
154 addChannel(chn, buffer32, beatl, beatlength);
155 chn->flags&=~(MP_SAMPLE_PLAY | MP_SAMPLE_FADEOFF);
156 continue;
157 }
158
159 case MP_SAMPLE_FADEIN:
160 {
161 chn->flags = (chn->flags&~(MP_SAMPLE_FADEOUT|MP_SAMPLE_FADEIN))/*|MP_SAMPLE_FADEIN*/;
162
163 //mp_sint32 beatl = (beatlength*RAMPDOWNFRACTION)>>8;
164
165 mp_sint32 maxramp = (beatlength*RAMPDOWNFRACTION)>>8;
166 mp_sint32 beatl = (!(chn->flags & 3)) ? (ChannelMixer::fixedmul(chn->loopend,chn->rsmpadd) >> 1) : maxramp;
167
168 if (beatl > maxramp || beatl <= 0)
169 beatl = maxramp;
170
171 mp_sint32 volL, volR;
172 mixer->panToVol(chn, volL, volR);
173
174 chn->rampFromVolStepL = (volL-chn->finalvoll)/beatl;
175 chn->rampFromVolStepR = (volR-chn->finalvolr)/beatl;
176
177 // mix here
178 if (beatl)
179 addChannel(chn, buffer32, beatl, beatlength);
180
181 //chn->finalvoll = volL;
182 //chn->finalvolr = volR;
183
184 chn->rampFromVolStepL = 0;
185 chn->rampFromVolStepR = 0;
186
187 mp_sint32 offset = beatl;
188
189 beatl = beatlength - beatl;
190
191 if (beatl)
192 addChannel(chn, buffer32+offset*MP_NUMCHANNELS, beatl, beatlength);
193 break;
194 }
195
196 case MP_SAMPLE_FADEOUT:
197 {
198 mp_sint32 maxramp = (beatlength*RAMPDOWNFRACTION)>>8;
199 mp_sint32 beatl = (!(chn->flags & 3)) ? (ChannelMixer::fixedmul(chn->loopend,chn->rsmpadd) >> 1) : maxramp;
200
201 if (beatl > maxramp || beatl <= 0)
202 beatl = maxramp;
203
204 chn->rampFromVolStepL = (0-chn->finalvoll)/beatl;
205 chn->rampFromVolStepR = (0-chn->finalvolr)/beatl;
206
207 chn->flags = (chn->flags&~(MP_SAMPLE_FADEOUT|MP_SAMPLE_FADEIN))/*|MP_SAMPLE_FADEIN*/;
208
209 // for the last active sample we need to retrieve the last active sample rate
210 // which is temporarly stored in newChannel[c]
211 // get it, fill it in and restore the original value later
212 mp_sint32 tmpsmpadd = chn->smpadd;
213 mp_sint32 tmprsmpadd = chn->rsmpadd;
214 mp_sint32 tmpcurrsample = chn->currsample;
215 mp_sint32 tmpprevsample = chn->prevsample;
216 mp_sint32 tmpa = chn->a;
217 mp_sint32 tmpb = chn->b;
218 mp_sint32 tmpc = chn->c;
219 chn->smpadd = newChannel[c].smpadd;
220 chn->rsmpadd = newChannel[c].rsmpadd;
221 chn->currsample = newChannel[c].currsample;
222 chn->prevsample = newChannel[c].prevsample;
223 chn->a = newChannel[c].a;
224 chn->b = newChannel[c].b;
225 chn->c = newChannel[c].c;
226 if (beatl)
227 addChannel(chn, buffer32, beatl, beatlength);
228 chn->smpadd = tmpsmpadd;
229 chn->rsmpadd = tmprsmpadd;
230 chn->currsample = tmpcurrsample;
231 chn->prevsample = tmpprevsample;
232 chn->a = tmpa;
233 chn->b = tmpb;
234 chn->c = tmpc;
235
236 // fade in new sample
237 chn->sample = newChannel[c].sample;
238 chn->smplen = newChannel[c].smplen;
239 chn->loopstart = newChannel[c].loopstart;
240 chn->loopend = newChannel[c].loopend;
241 chn->smppos = newChannel[c].smppos;
242 chn->smpposfrac = newChannel[c].smpposfrac;
243 chn->flags = newChannel[c].flags;
244 chn->loopendcopy = newChannel[c].loopendcopy;
245 chn->fixedtime = newChannel[c].fixedtimefrac;
246 chn->fixedtimefrac = newChannel[c].fixedtimefrac;
247
248 beatl = (!(chn->flags & 3)) ? (ChannelMixer::fixedmul(chn->loopend,chn->rsmpadd) >> 1) : maxramp;
249
250 if (beatl > maxramp || beatl <= 0)
251 beatl = maxramp;
252
253 mp_sint32 volL, volR;
254 mixer->panToVol(chn, volL, volR);
255
256 chn->rampFromVolStepL = volL/beatl;
257 chn->rampFromVolStepR = volR/beatl;
258
259 chn->finalvoll = chn->finalvolr = 0;
260
261 if (beatl)
262 addChannel(chn, buffer32, beatl, beatlength);
263
264 chn->rampFromVolStepL = 0;
265 chn->rampFromVolStepR = 0;
266
267 mp_sint32 offset = beatl;
268
269 beatl = beatlength - beatl;
270
271 if (beatl)
272 addChannel(chn, buffer32+offset*MP_NUMCHANNELS, beatl, beatlength);
273
274 continue;
275 }
276 default:
277 {
278 mp_sint32 volL, volR;
279 mixer->panToVol(chn, volL, volR);
280
281 chn->rampFromVolStepL = (volL-chn->finalvoll)/beatlength;
282 chn->rampFromVolStepR = (volR-chn->finalvolr)/beatlength;
283
284 // mix here
285 addChannel(chn, buffer32, beatlength, beatlength);
286
287 //chn->finalvoll = volL;
288 //chn->finalvolr = volR;
289 break;
290 }
291 }
292
293 }
294 }
295
addChannels(ChannelMixer * mixer,mp_uint32 numChannels,mp_sint32 * buffer32,mp_sint32 beatNum,mp_sint32 beatlength)296 void ChannelMixer::ResamplerBase::addChannels(ChannelMixer* mixer, mp_uint32 numChannels, mp_sint32* buffer32,mp_sint32 beatNum, mp_sint32 beatlength)
297 {
298 if (beatNum >= (signed)mixer->getNumBeatPackets())
299 beatNum = mixer->getNumBeatPackets();
300
301 if (isRamping())
302 addChannelsRamping(mixer, numChannels, buffer32, beatNum, beatlength);
303 else
304 addChannelsNormal(mixer, numChannels, buffer32, beatNum, beatlength);
305 }
306
addChannel(TMixerChannel * chn,mp_sint32 * buffer32,const mp_sint32 beatlength,const mp_sint32 beatSize)307 void ChannelMixer::ResamplerBase::addChannel(TMixerChannel* chn, mp_sint32* buffer32, const mp_sint32 beatlength, const mp_sint32 beatSize)
308 {
309 if ((chn->flags&MP_SAMPLE_PLAY))
310 {
311 /* check for computational work */
312 mp_sint32 d = ChannelMixer::fixedmul((chn->loopend - chn->loopstart)<<4,chn->rsmpadd);
313 /* just a threshold value: */
314 /* if distance between loopend and loopstart is very small and sample */
315 /* step is "big" we need to many divisions to compute remaining sample */
316 /* packets so add a full checked channel */
317 if ((d<128 && supportsFullChecking()) || (supportsFullChecking() && !supportsNoChecking()))
318 {
319 addBlockFull((buffer32), chn, (beatlength));
320 }
321 else
322 {
323 mp_sint32* tempBuffer32 = (buffer32);
324 mp_sint32 todo = (beatlength);
325 bool limit = false;
326 while (todo>0)
327 {
328 if (chn->flags&MP_SAMPLE_BACKWARD)
329 {
330 mp_sint32 pos = ((todo*-chn->smpadd - chn->smpposfrac)>>16)+chn->smppos;
331 if (pos>chn->loopstart)
332 {
333 addBlockNoCheck(tempBuffer32,chn,todo);
334 break;
335 }
336 else
337 {
338 mp_sint32 length = MP_FP_CEIL(ChannelMixer::fixedmul((((chn->smppos-chn->loopstart)<<16)+chn->smpposfrac),chn->rsmpadd));
339
340 if (!length) length++;
341 if (length>todo)
342 {
343 // Final mixing length is limited by the remaining buffer size
344 length = todo;
345 // Mark that we're limited
346 limit = true;
347 }
348 /* sample is going to stop => fade out because of ending clicks*/
349 else if ((chn->flags & 3) == 0)
350 {
351 mp_sint32 maxramp = (beatSize*RAMPDOWNFRACTION)>>8;
352 mp_sint32 rampl = ChannelMixer::fixedmul(chn->loopend,chn->rsmpadd) >> 1;
353
354 if (rampl > maxramp || rampl <= 0)
355 rampl = maxramp;
356
357 if (rampl < length)
358 {
359 length = length-rampl;
360 addBlockNoCheck(tempBuffer32,chn,length);
361 tempBuffer32+=length*MP_NUMCHANNELS;
362 length = rampl;
363 }
364
365 chn->rampFromVolStepL = (-chn->finalvoll)/length;
366 chn->rampFromVolStepR = (-chn->finalvolr)/length;
367 }
368 addBlockNoCheck(tempBuffer32, chn, length);
369 // Only stop when we're not limited, otherwise the sample will continue playing
370 if ((chn->flags & 3) == 0 && !limit)
371 {
372 if (chn->flags & MP_SAMPLE_ONESHOT)
373 {
374 chn->flags &= ~MP_SAMPLE_ONESHOT;
375 chn->flags |= 1;
376 chn->loopstart = chn->loopendcopy;
377 chn->smppos = chn->smplen - myMod(chn->smplen - chn->smppos, chn->loopend-chn->loopstart);
378 }
379 else
380 chn->flags&=~MP_SAMPLE_PLAY;
381 break;
382 }
383 else if ((chn->flags & 3) == 1)
384 {
385 // Is this correct looping??
386 chn->smppos = chn->loopend - myMod(chn->loopend - chn->smppos, chn->loopend-chn->loopstart);
387 }
388 // Check if we went out of ping-pong loop bounds
389 else if (chn->smppos < chn->loopstart)
390 {
391 // Invert
392 chn->flags&=~MP_SAMPLE_BACKWARD;
393 BIDIR_REPOSITION(16, chn->smppos, chn->smpposfrac, chn->loopstart, chn->loopend);
394 }
395 tempBuffer32+=length*MP_NUMCHANNELS;
396 todo-=length;
397 }
398 }
399 else
400 {
401 mp_sint32 pos = ((todo*chn->smpadd + chn->smpposfrac)>>16)+chn->smppos;
402 if (pos<chn->loopend)
403 {
404 addBlockNoCheck(tempBuffer32,chn,todo);
405 break;
406 }
407 else
408 {
409 mp_sint32 length = MP_FP_CEIL(ChannelMixer::fixedmul((((chn->loopend-chn->smppos)<<16)-chn->smpposfrac),chn->rsmpadd));
410 if (!length) length++;
411 if (length>todo)
412 {
413 length = todo;
414 limit = true;
415 }
416 /* sample is going to stop => fade out because of ending clicks */
417 else if ((chn->flags & 3) == 0)
418 {
419 mp_sint32 maxramp = (beatSize*RAMPDOWNFRACTION)>>8;
420 mp_sint32 rampl = ChannelMixer::fixedmul(chn->loopend,chn->rsmpadd) >> 1;
421
422 if (rampl > maxramp || rampl <= 0)
423 rampl = maxramp;
424
425 if (rampl < length)
426 {
427 length = length-rampl;
428 addBlockNoCheck(tempBuffer32,chn,length);
429 tempBuffer32+=length*MP_NUMCHANNELS;
430 length = rampl;
431 }
432
433 chn->rampFromVolStepL = (-chn->finalvoll)/length;
434 chn->rampFromVolStepR = (-chn->finalvolr)/length;
435 }
436 addBlockNoCheck(tempBuffer32,chn,length);
437 if ((chn->flags & 3) == 0 && !limit)
438 {
439 if (chn->flags & MP_SAMPLE_ONESHOT)
440 {
441 chn->flags &= ~MP_SAMPLE_ONESHOT;
442 chn->flags |= 1;
443 chn->loopend = chn->loopendcopy;
444 /*ASSERT(chn->loopend-chn->loopstart > 0);*/
445 chn->smppos = ((chn->smppos - chn->smplen)%(chn->loopend-chn->loopstart))+chn->loopstart;
446 }
447 else
448 chn->flags&=~MP_SAMPLE_PLAY;
449 break;
450 }
451 else if ((chn->flags & 3) == 1)
452 {
453 /*ASSERT(chn->loopend-chn->loopstart > 0);*/
454 chn->smppos = ((chn->smppos - chn->loopstart)%(chn->loopend-chn->loopstart))+chn->loopstart;
455 /* correct if pre-calculation was a little bit incorrect*/
456 if (chn->smppos < 0)
457 chn->smppos = 0;
458 }
459 else if (chn->smppos >= chn->loopend)
460 {
461 // Invert
462 chn->flags|=MP_SAMPLE_BACKWARD;
463 BIDIR_REPOSITION(16, chn->smppos, chn->smpposfrac, chn->loopstart, chn->loopend);
464 }
465 tempBuffer32+=length*MP_NUMCHANNELS;
466 todo-=length;
467 }
468 }
469 }
470 }
471 }
472 }
473
muteChannel(mp_sint32 c,bool m)474 void ChannelMixer::muteChannel(mp_sint32 c, bool m)
475 {
476 channel[c].flags&=~MP_SAMPLE_MUTE;
477 if (m) channel[c].flags|=MP_SAMPLE_MUTE;
478 }
479
isChannelMuted(mp_sint32 c)480 bool ChannelMixer::isChannelMuted(mp_sint32 c)
481 {
482 return (channel[c].flags&MP_SAMPLE_MUTE) == MP_SAMPLE_MUTE;
483 }
484
setFrequency(mp_sint32 frequency)485 void ChannelMixer::setFrequency(mp_sint32 frequency)
486 {
487 if (frequency == (signed)mixFrequency)
488 return;
489
490 mixFrequency = frequency;
491 rMixFrequency = 0x7FFFFFFF / frequency;
492
493 beatPacketSize = (MP_BEATLENGTH*frequency)/MP_BASEFREQ;
494
495 if (mixbuffBeatPacket)
496 {
497 delete[] mixbuffBeatPacket;
498 mixbuffBeatPacket = NULL;
499 }
500
501 mixbuffBeatPacket = new mp_sint32[beatPacketSize*MP_NUMCHANNELS];
502
503 // channels contain information based on beatPacketSize so this might
504 // have been changed
505 reallocChannels();
506
507 if (resamplerType != MIXER_INVALID && resamplerTable[resamplerType])
508 resamplerTable[resamplerType]->setFrequency(frequency);
509 }
510
reallocChannels()511 void ChannelMixer::reallocChannels()
512 {
513 // optimization in case we already have the allocated number of channels
514 if (mixerNumAllocatedChannels != mixerLastNumAllocatedChannels)
515 {
516 delete[] channel;
517 channel = new TMixerChannel[mixerNumAllocatedChannels];
518
519 delete[] newChannel;
520 newChannel = new TMixerChannel[mixerNumAllocatedChannels];
521
522 clearChannels();
523 }
524
525 #if defined(MILKYTRACKER) || defined (__MPTIMETRACKING__)
526 for (mp_uint32 i = 0; i < mixerNumAllocatedChannels; i++)
527 channel[i].reallocTimeRecord(getNumBeatPackets()+1);
528 #endif
529
530 mixerLastNumAllocatedChannels = mixerNumAllocatedChannels;
531
532 if (resamplerType != MIXER_INVALID && resamplerTable[resamplerType])
533 resamplerTable[resamplerType]->setNumChannels(mixerNumAllocatedChannels);
534 }
535
clearChannels()536 void ChannelMixer::clearChannels()
537 {
538 for (mp_uint32 i = 0; i < mixerNumAllocatedChannels; i++)
539 {
540 channel[i].clear();
541 newChannel[i].clear();
542 }
543 }
544
ChannelMixer(mp_uint32 numChannels,mp_uint32 frequency)545 ChannelMixer::ChannelMixer(mp_uint32 numChannels,
546 mp_uint32 frequency) :
547 mixerNumAllocatedChannels(numChannels),
548 mixerNumActiveChannels(numChannels),
549 mixerLastNumAllocatedChannels(0),
550 mixFrequency(0),
551 mixbuffBeatPacket(NULL),
552 mixBufferSize(0),
553 channel(NULL),
554 newChannel(NULL),
555 resamplerType(MIXER_INVALID),
556 paused(false),
557 disableMixing(false),
558 allowFilters(false),
559 initialized(false),
560 sampleCounter(0)
561 {
562 memset(resamplerTable, 0, sizeof(resamplerTable));
563
564 setFrequency(frequency);
565
566 // full volume
567 masterVolume = 256;
568 panningSeparation = 256;
569
570 for (mp_sint32 i = 0; i < NUMRESAMPLERTYPES; i++)
571 {
572 setFreqFuncTable[i] = &ChannelMixer::setChannelFrequency;
573 resamplerTable[i] = NULL;
574 }
575
576 setResamplerType(MIXER_NORMAL);
577
578 setBufferSize(BUFFERSIZE_DEFAULT);
579
580 // FT2 panning law
581 if (panLUT[1] == 0)
582 for (int i = 0; i <= 256; i++)
583 panLUT[i] = static_cast<mp_sint32> (8192.0 * sqrt(i/256.0) + 0.5);
584 }
585
~ChannelMixer()586 ChannelMixer::~ChannelMixer()
587 {
588 if (initialized)
589 {
590 closeDevice();
591 }
592
593 if (mixbuffBeatPacket)
594 delete[] mixbuffBeatPacket;
595
596 if (channel)
597 delete[] channel;
598
599 if (newChannel)
600 delete[] newChannel;
601
602 for (mp_uint32 i = 0; i < sizeof(resamplerTable) / sizeof(ResamplerBase*); i++)
603 delete resamplerTable[i];
604 }
605
resetChannelsWithoutMuting()606 void ChannelMixer::resetChannelsWithoutMuting()
607 {
608 mp_ubyte* isMuted = new mp_ubyte[mixerNumAllocatedChannels];
609
610 // save muting
611 mp_uint32 i;
612 for (i = 0; i < mixerNumAllocatedChannels; i++)
613 isMuted[i] = (mp_ubyte)isChannelMuted(i);
614
615 clearChannels();
616
617 for (i = 0; i < mixerNumAllocatedChannels; i++)
618 muteChannel(i, isMuted[i] == 1);
619
620 delete[] isMuted;
621
622 lastBeatRemainder = 0;
623 }
624
resetChannelsFull()625 void ChannelMixer::resetChannelsFull()
626 {
627 clearChannels();
628
629 lastBeatRemainder = 0;
630 }
631
setResamplerType(ResamplerTypes type)632 void ChannelMixer::setResamplerType(ResamplerTypes type)
633 {
634 if (resamplerTable[type] == NULL)
635 resamplerTable[type] = ResamplerFactory::createResampler(type);
636
637 resamplerType = type;
638
639 if (resamplerType != MIXER_INVALID && resamplerTable[resamplerType])
640 {
641 resamplerTable[resamplerType]->setFrequency(mixFrequency);
642 resamplerTable[resamplerType]->setNumChannels(mixerNumAllocatedChannels);
643 }
644 }
645
setNumChannels(mp_uint32 num)646 void ChannelMixer::setNumChannels(mp_uint32 num)
647 {
648 if (num > mixerNumAllocatedChannels)
649 {
650 mixerNumAllocatedChannels = num;
651
652 reallocChannels();
653 resetChannelsFull();
654 }
655 else
656 {
657 mixerNumAllocatedChannels = num;
658 resetChannelsWithoutMuting();
659 }
660
661 mixerNumActiveChannels = num;
662 }
663
setActiveChannels(mp_uint32 num)664 void ChannelMixer::setActiveChannels(mp_uint32 num)
665 {
666 if (num > mixerNumAllocatedChannels)
667 {
668 mixerNumAllocatedChannels = num;
669
670 reallocChannels();
671 resetChannelsFull();
672 }
673
674 mixerNumActiveChannels = num;
675 }
676
677 // Default lo precision calculations
setChannelFrequency(mp_sint32 c,mp_sint32 f)678 void ChannelMixer::setChannelFrequency(mp_sint32 c, mp_sint32 f)
679 {
680 channel[c].smpadd = ((mp_sint32)(((mp_int64)((mp_int64)f*(mp_int64)rMixFrequency))>>15))<<0;
681
682 if (channel[c].smpadd)
683 channel[c].rsmpadd = 0xFFFFFFFF/channel[c].smpadd;
684 else
685 channel[c].rsmpadd = 0;
686 }
687
setFilterAttributes(mp_sint32 chn,mp_sint32 cutoff,mp_sint32 resonance)688 void ChannelMixer::setFilterAttributes(mp_sint32 chn, mp_sint32 cutoff, mp_sint32 resonance)
689 {
690 if (!allowFilters ||
691 (channel[chn].cutoff == cutoff &&
692 channel[chn].resonance == resonance))
693 return;
694
695 channel[chn].cutoff = cutoff;
696 channel[chn].resonance = resonance;
697
698 if (cutoff == MP_INVALID_VALUE || resonance == MP_INVALID_VALUE)
699 return;
700
701 // Thanks to DUMB for the filter coefficient computations
702 const float LOG10 = 2.30258509299f;
703 const mp_sint32 IT_ENVELOPE_SHIFT = 8;
704
705 float a, b, c;
706 {
707 float sampfreq = this->mixFrequency;
708
709 float inv_angle = (float)(sampfreq * pow(0.5, 0.25 + cutoff*(1.0/(24<<IT_ENVELOPE_SHIFT))) * (1.0/(2*3.14159265358979323846*110.0)));
710 float loss = (float)exp(resonance*(-LOG10*1.2/128.0));
711 float d, e;
712 #if 0
713 loss *= 2; // This is the mistake most players seem to make!
714 #endif
715
716 #if 1
717 d = (1.0f - loss) / inv_angle;
718 if (d > 2.0f) d = 2.0f;
719 d = (loss - d) * inv_angle;
720 e = inv_angle * inv_angle;
721 a = 1.0f / (1.0f + d + e);
722 c = -e * a;
723 b = 1.0f - a - c;
724 #else
725 a = 1.0f / (inv_angle*inv_angle + inv_angle*loss + loss);
726 c = -(inv_angle*inv_angle) * a;
727 b = 1.0f - a - c;
728 #endif
729 }
730
731 channel[chn].a = (mp_sint32)(a * (1 << (MP_FILTERPRECISION+16)));
732 channel[chn].b = (mp_sint32)(b * (1 << (MP_FILTERPRECISION+16)));
733 channel[chn].c = (mp_sint32)(c * (1 << (MP_FILTERPRECISION+16)));
734 }
735
playSample(mp_sint32 c,mp_sbyte * smp,mp_sint32 smplen,mp_sint32 smpoffs,mp_sint32 smpoffsfrac,bool smpOffsetWrap,mp_sint32 lstart,mp_sint32 len,mp_sint32 flags,bool ramp)736 void ChannelMixer::playSample(mp_sint32 c, // channel
737 mp_sbyte* smp, // sample buffer
738 mp_sint32 smplen, // sample size
739 mp_sint32 smpoffs, // sample offset
740 mp_sint32 smpoffsfrac,
741 bool smpOffsetWrap,
742 mp_sint32 lstart, // loop start
743 mp_sint32 len, // loop end
744 mp_sint32 flags,
745 bool ramp/* = true*/)
746 {
747 // doesn't play
748 if (smp == NULL)
749 return;
750
751 // disable looping when loopstart = loopend
752 if (lstart == len)
753 {
754 flags &= ~(3+32);
755 lstart = 0;
756 len = smplen;
757 }
758
759 // this is not allowed, assume bidir loop when both forward and biloop settings are made
760 if ((flags & 3) == 3) flags &= ~1;
761
762 // stupid check if artists are to stupid to use a valid sampleoffset
763 // seems to be correct
764 // treat bidir looped samples as normal samples
765 if (((flags & 3) == 2) || !(flags&3))
766 {
767 if (smpoffs >= len)
768 {
769 if (smpOffsetWrap)
770 return;
771 else
772 {
773 stopSample(c);
774 return;
775 }
776 }
777 }
778 // below offset correction code only works for forward played samples
779 // to-do: add offset correction code for bi-dir loops
780 else if ((flags & 3) == 1)
781 {
782 if (smpOffsetWrap)
783 {
784 if (smpoffs > len)
785 {
786 smpoffs = ((smpoffs - lstart)%(len-lstart))+lstart;
787 }
788 else if (smpoffs == len && smpoffsfrac)
789 {
790 smpoffs = lstart;
791 }
792 }
793 else
794 {
795 if (smpoffs >= len)
796 {
797 stopSample(c);
798 return;
799 }
800 }
801 }
802
803 // play sample but don't ramp volume
804 if (!ramp)
805 {
806 channel[c].sample=(mp_sbyte*)smp;
807 channel[c].smplen = smplen;
808 channel[c].loopstart=lstart;
809 channel[c].loopend=len;
810
811 if (flags & MP_SAMPLE_BACKWARD)
812 channel[c].smppos = smplen - smpoffs;
813 else
814 channel[c].smppos = smpoffs;
815
816 channel[c].smpposfrac = smpoffsfrac;
817 channel[c].flags&=~MP_SAMPLE_FADEOFF;
818 channel[c].flags=flags|MP_SAMPLE_PLAY|(channel[c].flags&MP_SAMPLE_MUTE);
819
820 channel[c].currsample = channel[c].prevsample = 0;
821
822 channel[c].fixedtime = 0;
823 channel[c].fixedtimefrac = smpoffsfrac;
824 }
825 // currently no sample playing on that channel
826 else if (!(channel[c].flags&MP_SAMPLE_PLAY))
827 {
828 channel[c].sample=(mp_sbyte*)smp;
829 channel[c].smplen = smplen;
830 channel[c].loopstart=lstart;
831 channel[c].loopend=len;
832
833 if (flags & MP_SAMPLE_BACKWARD)
834 channel[c].smppos = smplen - smpoffs;
835 else
836 channel[c].smppos = smpoffs;
837
838 channel[c].smpposfrac = smpoffsfrac;
839 channel[c].flags&=~MP_SAMPLE_FADEOFF;
840 channel[c].flags=flags|MP_SAMPLE_PLAY|(channel[c].flags&MP_SAMPLE_MUTE)|MP_SAMPLE_FADEIN;
841 // if a new sample is played, its volume is ramped from zero to current volume
842 channel[c].finalvoll = 0;
843 channel[c].finalvolr = 0;
844
845 // one shot looping sample?
846 if (flags & 32)
847 {
848 // Not looping yet
849 channel[c].flags &= ~(3+32);
850 channel[c].flags |= MP_SAMPLE_ONESHOT;
851 if (flags & MP_SAMPLE_BACKWARD)
852 {
853 channel[c].loopendcopy = channel[c].loopstart;
854 channel[c].loopstart = 0;
855 }
856 else
857 {
858 channel[c].loopendcopy = channel[c].loopend;
859 channel[c].loopend = channel[c].smplen;
860 }
861 }
862
863 channel[c].currsample = channel[c].prevsample = 0;
864
865 channel[c].fixedtime = 0;
866 channel[c].fixedtimefrac = smpoffsfrac;
867 }
868 // there is a sample playing on that channel, ramp volume of current sample down
869 // then play new sample and ramp volume up
870 else
871 {
872 newChannel[c].sample=(mp_sbyte*)smp;
873 newChannel[c].smplen = smplen;
874 newChannel[c].loopstart = lstart;
875 newChannel[c].loopend = len;
876
877 if (flags & MP_SAMPLE_BACKWARD)
878 newChannel[c].smppos = smplen - smpoffs;
879 else
880 newChannel[c].smppos = smpoffs;
881
882 newChannel[c].smpposfrac = smpoffsfrac;
883 newChannel[c].flags=flags|MP_SAMPLE_PLAY|(channel[c].flags&MP_SAMPLE_MUTE);
884 // if a new sample is played, its volume is ramped from zero to current volume
885 newChannel[c].finalvoll = newChannel[c].finalvolr = 0;
886 newChannel[c].currsample = newChannel[c].prevsample = 0;
887
888 newChannel[c].fixedtime = 0;
889 newChannel[c].fixedtimefrac = smpoffsfrac;
890
891 // "fade off" current sample
892 channel[c].flags = (channel[c].flags&~(MP_SAMPLE_FADEOUT|MP_SAMPLE_FADEIN|MP_SAMPLE_FADEOFF))|MP_SAMPLE_FADEOUT;
893
894 // one shot looping sample?
895 if (flags & 32)
896 {
897 // Not looping yet
898 newChannel[c].flags &= ~(3+32);
899 newChannel[c].flags |= MP_SAMPLE_ONESHOT;
900
901 if (flags & MP_SAMPLE_BACKWARD)
902 {
903 newChannel[c].loopendcopy = newChannel[c].loopstart;
904 newChannel[c].loopstart = 0;
905 }
906 else
907 {
908 newChannel[c].loopendcopy = newChannel[c].loopend;
909 newChannel[c].loopend = newChannel[c].smplen;
910 }
911 }
912 }
913
914 }
915
storeTimeRecordData(mp_sint32 nb,ChannelMixer::TMixerChannel * chn)916 static inline void storeTimeRecordData(mp_sint32 nb, ChannelMixer::TMixerChannel* chn)
917 {
918 if (!(chn->flags & ChannelMixer::MP_SAMPLE_PLAY))
919 {
920 if (chn->timeRecord)
921 {
922 chn->timeRecord[nb].flags = chn->flags;
923 chn->timeRecord[nb].sample = NULL;
924 chn->timeRecord[nb].volPan = 128 << 16;
925 chn->timeRecord[nb].smppos = -1;
926 }
927 }
928 else
929 {
930 if (chn->timeRecord)
931 {
932 chn->timeRecord[nb].flags = chn->flags;
933 chn->timeRecord[nb].sample = chn->sample;
934 chn->timeRecord[nb].smppos = chn->smppos;
935 chn->timeRecord[nb].volPan = chn->vol + (chn->pan << 16);
936 chn->timeRecord[nb].smpposfrac = chn->smpposfrac;
937 chn->timeRecord[nb].smpadd = chn->smpadd;
938 chn->timeRecord[nb].smplen = chn->smplen;
939 if (chn->flags & ChannelMixer::MP_SAMPLE_ONESHOT)
940 chn->timeRecord[nb].loopend = chn->loopendcopy;
941 else
942 chn->timeRecord[nb].loopend = chn->loopend;
943 chn->timeRecord[nb].loopstart = chn->loopstart;
944 chn->timeRecord[nb].fixedtime = chn->fixedtime;
945 chn->timeRecord[nb].fixedtimefrac = chn->fixedtimefrac;
946 }
947 }
948 }
949
mix(mp_sint32 * mixbuff32,mp_uint32 bufferSize)950 void ChannelMixer::mix(mp_sint32* mixbuff32, mp_uint32 bufferSize)
951 {
952 updateSampleCounter(bufferSize);
953
954 if (!isPlaying())
955 return;
956
957 if (!paused)
958 {
959 mp_sint32* buffer = mixbuff32;
960
961 mp_sint32 beatLength = beatPacketSize;
962 mp_sint32 mixSize = mixBufferSize;
963
964 mp_sint32 done = 0;
965
966 if (lastBeatRemainder)
967 {
968 mp_sint32 todo = lastBeatRemainder;
969 if (lastBeatRemainder > mixBufferSize)
970 {
971 todo = mixBufferSize;
972 mp_uint32 pos = beatLength - lastBeatRemainder;
973 //memcpy(buffer, mixbuffBeatPacket + pos*MP_NUMCHANNELS, todo*MP_NUMCHANNELS*sizeof(mp_sint32));
974 const mp_sint32* src = mixbuffBeatPacket + pos*MP_NUMCHANNELS;
975 mp_sint32* dst = buffer;
976 for (mp_sint32 i = 0; i < todo*MP_NUMCHANNELS; i++, src++, dst++)
977 *dst += *src;
978 done = mixBufferSize;
979 lastBeatRemainder-=done;
980 }
981 else
982 {
983 mp_uint32 pos = beatLength - lastBeatRemainder;
984 //memcpy(buffer, mixbuffBeatPacket + pos*MP_NUMCHANNELS, todo*MP_NUMCHANNELS*sizeof(mp_sint32));
985 const mp_sint32* src = mixbuffBeatPacket + pos*MP_NUMCHANNELS;
986 mp_sint32* dst = buffer;
987 for (mp_sint32 i = 0; i < todo*MP_NUMCHANNELS; i++, src++, dst++)
988 *dst += *src;
989 buffer+=lastBeatRemainder*MP_NUMCHANNELS;
990 mixSize-=lastBeatRemainder;
991 done = lastBeatRemainder;
992 lastBeatRemainder = 0;
993 }
994 }
995
996 if (done < (mp_sint32)mixBufferSize)
997 {
998 const mp_sint32 numbeats = /*numBeatPackets*/mixSize / beatLength;
999
1000 done+=numbeats*beatLength;
1001
1002 mp_sint32 nb;
1003
1004 const bool isRamping = this->isRamping();
1005
1006 for (nb=0;nb<numbeats;nb++)
1007 {
1008 if (isRamping)
1009 {
1010 const TMixerChannel* src = channel;
1011 TMixerChannel* dst = newChannel;
1012 const mp_uint32 mixerNumActiveChannels = this->mixerNumActiveChannels;
1013 if (allowFilters)
1014 {
1015 // this is crucial for volume ramping, store current
1016 // active sample rate (stored in the step values for each channel)
1017 // and also filter coefficients and last samples
1018 for (mp_uint32 c = 0; c < mixerNumActiveChannels; c++, src++, dst++)
1019 {
1020 dst->smpadd = src->smpadd;
1021 dst->rsmpadd = src->rsmpadd;
1022
1023 dst->a = src->a;
1024 dst->b = src->b;
1025 dst->c = src->c;
1026 dst->currsample = src->currsample;
1027 dst->prevsample = src->prevsample;
1028 }
1029 }
1030 else
1031 {
1032 // this is crucial for volume ramping, store current
1033 // active sample rate (stored in the step values for each channel)
1034 // and also filter coefficients and last samples
1035 for (mp_uint32 c = 0; c < mixerNumActiveChannels; c++, src++, dst++)
1036 {
1037 dst->smpadd = src->smpadd;
1038 dst->rsmpadd = src->rsmpadd;
1039 }
1040 }
1041 }
1042
1043 timer(nb);
1044
1045 if (!disableMixing)
1046 {
1047 // do some in between state recording
1048 // to be able to show smooth updates even if the buffer is large
1049 for (mp_uint32 c=0;c<mixerNumActiveChannels;c++)
1050 storeTimeRecordData(nb, &channel[c]);
1051
1052 mixBeatPacket(mixerNumActiveChannels, buffer+nb*beatLength*MP_NUMCHANNELS, nb, beatLength);
1053 }
1054 }
1055
1056 buffer+=numbeats*beatLength*MP_NUMCHANNELS;
1057
1058 if (done < (mp_sint32)mixBufferSize)
1059 {
1060 memset(mixbuffBeatPacket, 0, beatLength*MP_NUMCHANNELS*sizeof(mp_sint32));
1061
1062 if (isRamping)
1063 {
1064 const TMixerChannel* src = channel;
1065 TMixerChannel* dst = newChannel;
1066 const mp_uint32 mixerNumActiveChannels = this->mixerNumActiveChannels;
1067 if (allowFilters)
1068 {
1069 // this is crucial for volume ramping, store current
1070 // active sample rate (stored in the step values for each channel)
1071 // and also filter coefficients and last samples
1072 for (mp_uint32 c = 0; c < mixerNumActiveChannels; c++, src++, dst++)
1073 {
1074 dst->smpadd = src->smpadd;
1075 dst->rsmpadd = src->rsmpadd;
1076
1077 dst->a = src->a;
1078 dst->b = src->b;
1079 dst->c = src->c;
1080 dst->currsample = src->currsample;
1081 dst->prevsample = src->prevsample;
1082 }
1083 }
1084 else
1085 {
1086 // this is crucial for volume ramping, store current
1087 // active sample rate (stored in the step values for each channel)
1088 // and also filter coefficients and last samples
1089 for (mp_uint32 c = 0; c < mixerNumActiveChannels; c++, src++, dst++)
1090 {
1091 dst->smpadd = src->smpadd;
1092 dst->rsmpadd = src->rsmpadd;
1093 }
1094 }
1095 }
1096
1097 timer(numbeats);
1098
1099 if (!disableMixing)
1100 {
1101 // do some in between state recording
1102 // to be able to show smooth updates even if the buffer is large
1103 for (mp_uint32 c=0;c<mixerNumActiveChannels;c++)
1104 storeTimeRecordData(nb, &channel[c]);
1105
1106 mixBeatPacket(mixerNumActiveChannels, mixbuffBeatPacket, numbeats, beatLength);
1107 }
1108
1109 mp_sint32 todo = mixBufferSize - done;
1110
1111 if (todo)
1112 {
1113 //memcpy(buffer, mixbuffBeatPacket, todo*MP_NUMCHANNELS*sizeof(mp_sint32));
1114 const mp_sint32* src = mixbuffBeatPacket;
1115 mp_sint32* dst = buffer;
1116 for (mp_sint32 i = 0; i < todo*MP_NUMCHANNELS; i++, src++, dst++)
1117 *dst += *src;
1118 lastBeatRemainder = beatLength - todo;
1119 }
1120 }
1121 }
1122 }
1123
1124 }
1125
initDevice()1126 mp_sint32 ChannelMixer::initDevice()
1127 {
1128 resetChannelsWithoutMuting();
1129
1130 initialized = true;
1131
1132 return MP_OK;
1133 }
1134
stop()1135 void ChannelMixer::stop()
1136 {
1137 // stop playing
1138 startPlay = false;
1139
1140 paused = false;
1141 }
1142
closeDevice()1143 mp_sint32 ChannelMixer::closeDevice()
1144 {
1145 if (initialized)
1146 {
1147 paused = false;
1148
1149 // finish playing
1150 stop();
1151
1152 resetChannelsWithoutMuting();
1153 initialized = false;
1154 }
1155
1156 return MP_OK;
1157 }
1158
pause()1159 mp_sint32 ChannelMixer::pause()
1160 {
1161 paused = true;
1162 return MP_OK;
1163 }
1164
resume()1165 mp_sint32 ChannelMixer::resume()
1166 {
1167 paused = false;
1168 return MP_OK;
1169 }
1170
adjustFrequency(mp_uint32 frequency)1171 mp_sint32 ChannelMixer::adjustFrequency(mp_uint32 frequency)
1172 {
1173 if (frequency == mixFrequency)
1174 return MP_OK;
1175
1176 mp_sint32 err = MP_OK;
1177 if (initialized)
1178 {
1179 err = closeDevice();
1180 }
1181
1182 // adjust sample counter to keep on the current time
1183 sampleCounter = (mp_sint32)(((double)sampleCounter/(double)mixFrequency)*(double)frequency);
1184
1185 setFrequency(frequency);
1186
1187 return err;
1188 }
1189
beatPacketsToBufferSize(mp_uint32 mixFrequency,mp_uint32 numBeats)1190 mp_sint32 ChannelMixer::beatPacketsToBufferSize(mp_uint32 mixFrequency, mp_uint32 numBeats)
1191 {
1192 mp_uint32 beatPacketSize = (MP_BEATLENGTH*mixFrequency)/MP_BASEFREQ;
1193 return numBeats * beatPacketSize;
1194 }
1195
setBufferSize(mp_uint32 bufferSize)1196 mp_sint32 ChannelMixer::setBufferSize(mp_uint32 bufferSize)
1197 {
1198 if (this->mixBufferSize == bufferSize)
1199 return MP_OK;
1200
1201 this->mixBufferSize = bufferSize;
1202
1203 // channels contain information depending up the buffer size
1204 // update those too
1205 reallocChannels();
1206
1207 return MP_OK;
1208 }
1209
getNumActiveChannels()1210 mp_sint32 ChannelMixer::getNumActiveChannels()
1211 {
1212 mp_sint32 i = 0;
1213
1214 for (mp_uint32 j = 0; j < mixerNumActiveChannels; j++)
1215 if (channel[j].flags & 256)
1216 i++;
1217
1218 return i;
1219 }
1220
getBeatIndexFromSamplePos(mp_uint32 smpPos) const1221 mp_sint32 ChannelMixer::getBeatIndexFromSamplePos(mp_uint32 smpPos) const
1222 {
1223 mp_sint32 maxLen = (mixBufferSize/beatPacketSize)-1;
1224 if (maxLen < 0)
1225 maxLen = 0;
1226
1227 mp_sint32 maxSize = maxLen*(mp_sint32)beatPacketSize - 1;
1228 if (maxSize < 0)
1229 maxSize = 0;
1230
1231 if ((signed)smpPos < 0)
1232 smpPos = 0;
1233
1234 if (smpPos > (unsigned)maxSize)
1235 smpPos = maxSize;
1236
1237 return smpPos / getBeatPacketSize();
1238 }
1239
1240 /*mp_sint32 ChannelMixer::getCurrentSample(mp_sint32 position,mp_sint32 channel)
1241 {
1242 if (position < 0)
1243 {
1244 position = abs(position);
1245 }
1246 if (position > (mp_sint32)mixBufferSize-1)
1247 {
1248 position %= mixBufferSize*2;
1249 position -= mixBufferSize;
1250 position = mixBufferSize-1-position;
1251 }
1252
1253 mp_sint32 val = (mp_sword)mixbuff32[position*MP_NUMCHANNELS+channel];
1254 if (val < -32768)
1255 val = -32768;
1256 if (val > 32767)
1257 val = 32767;
1258
1259 return val;
1260 }
1261
1262 mp_sint32 ChannelMixer::getCurrentSamplePeak(mp_sint32 position,mp_sint32 channel)
1263 {
1264 if (audioDriver->supportsTimeQuery())
1265 {
1266 mp_sword peak = 0;
1267
1268 for (mp_sint32 p = position-mixBufferSize; p <= position; p++)
1269 {
1270 mp_sword s = getCurrentSample(p, channel);
1271 if (s > peak)
1272 peak = s;
1273 if (-s > peak)
1274 peak = -s;
1275 }
1276 return peak;
1277 }
1278 else
1279 {
1280 mp_sword peak = 0;
1281 for (mp_uint32 pos = 0; pos < mixBufferSize; pos++)
1282 {
1283 mp_sint32 s = mixbuff32[pos*MP_NUMCHANNELS+channel];
1284 if (s < -32768)
1285 s = -32768;
1286 if (s > 32767)
1287 s = 32767;
1288 if (s > peak)
1289 peak = s;
1290 if (-s > peak)
1291 peak = -s;
1292 }
1293
1294 return peak;
1295 }
1296 }*/
1297
getSyncSampleCounter()1298 mp_uint32 ChannelMixer::getSyncSampleCounter()
1299 {
1300 /*return audioDriver->getNumPlayedSamples();*/
1301
1302 return 0;
1303 }
1304
1305 #ifdef __MPTIMETRACKING__
1306
1307 #define FULLMIXER_8BIT_NORMAL_TEMP \
1308 if (sample) { \
1309 sd1 = ((mp_sbyte)sample[smppos])<<8; \
1310 sd2 = ((mp_sbyte)sample[smppos+1])<<8; \
1311 sd1 =((sd1<<12)+(smpposfrac>>4)*(sd2-sd1))>>12; \
1312 buffer[i] = (sd1*vol)>>9; \
1313 } \
1314 else buffer[i] = 0; \
1315 i++;
1316
1317 #define FULLMIXER_16BIT_NORMAL_TEMP \
1318 if (sample) { \
1319 sd1 = ((mp_sword*)(sample))[smppos]; \
1320 sd2 = ((mp_sword*)(sample))[smppos+1]; \
1321 sd1 =((sd1<<12)+(smpposfrac>>4)*(sd2-sd1))>>12; \
1322 buffer[i] = (sd1*vol)>>9; \
1323 } \
1324 else buffer[i] = 0; \
1325 i++;
1326
1327 #include "ResamplerMacros.h"
1328
1329 /////////////////////////////////////////////////////////
1330 // SIMPLE MIXER, NO INTERPOLATION, NO RAMPING //
1331 /////////////////////////////////////////////////////////
1332 class ResamplerDummy : public ChannelMixer::ResamplerBase
1333 {
1334 private:
1335 mp_sint32 vol;
1336 public:
ResamplerDummy(mp_sint32 vol)1337 ResamplerDummy(mp_sint32 vol) :
1338 vol(vol)
1339 {
1340 }
1341
isRamping()1342 virtual bool isRamping() { return false; }
supportsFullChecking()1343 virtual bool supportsFullChecking() { return true; }
supportsNoChecking()1344 virtual bool supportsNoChecking() { return false; }
1345
addBlockFull(mp_sint32 * buffer,ChannelMixer::TMixerChannel * chn,mp_uint32 count)1346 virtual void addBlockFull(mp_sint32* buffer, ChannelMixer::TMixerChannel* chn, mp_uint32 count)
1347 {
1348 mp_sint32 vol = this->vol;
1349 mp_sint32 i = 0;
1350 FULLMIXER_TEMPLATE(FULLMIXER_8BIT_NORMAL_TEMP,FULLMIXER_16BIT_NORMAL_TEMP, 16, 0);
1351 }
1352 };
1353
1354
mixData(mp_sint32 c,mp_sint32 * buffer,mp_sint32 count,mp_sint32 sampleShift,mp_sint32 fMul,mp_sint32 bufferIndex,mp_sint32 packetIndex) const1355 void ChannelMixer::mixData(mp_sint32 c,
1356 mp_sint32* buffer,
1357 mp_sint32 count,
1358 mp_sint32 sampleShift,
1359 mp_sint32 fMul/* = 0*/,
1360 mp_sint32 bufferIndex/* = -1*/,
1361 mp_sint32 packetIndex/* = -1*/) const
1362 {
1363 if (fMul == 0)
1364 fMul = count;
1365 if (packetIndex < 0)
1366 packetIndex = 0;
1367
1368 const ChannelMixer::TMixerChannel* tempchn = &channel[c];
1369 ChannelMixer::TMixerChannel channel;
1370
1371 channel.flags = tempchn->timeRecord[packetIndex].flags;
1372 channel.sample = tempchn->timeRecord[packetIndex].sample;
1373 channel.smppos = tempchn->timeRecord[packetIndex].smppos;
1374 channel.smpposfrac = tempchn->timeRecord[packetIndex].smpposfrac;
1375 channel.smpadd = tempchn->timeRecord[packetIndex].smpadd;
1376 channel.smplen = tempchn->timeRecord[packetIndex].smplen;
1377 channel.loopend = channel.loopendcopy = tempchn->timeRecord[packetIndex].loopend;
1378 channel.loopstart = tempchn->timeRecord[packetIndex].loopstart;
1379 channel.vol = tempchn->timeRecord[packetIndex].volPan & 0xFFFF;
1380 channel.pan = tempchn->timeRecord[packetIndex].volPan >> 16;
1381
1382 ChannelMixer::TMixerChannel* chn = &channel;
1383
1384 if (startPlay && (chn->flags & MP_SAMPLE_PLAY))
1385 {
1386 chn->smpadd = (chn->smpadd*fMul) / (count ? count : 1);
1387 mp_sint32 vol = (chn->vol*masterVolume) >> (8 + sampleShift);
1388
1389 ResamplerDummy resampler(vol);
1390 resampler.addBlockFull(buffer, chn, count);
1391 }
1392 else
1393 {
1394 memset(buffer, 0, sizeof(mp_sint32)*count);
1395 }
1396 }
1397
1398 #endif
1399
1400