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