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.h 32 * MilkyPlay 33 * 34 * Created by Peter Barth on Tue Oct 19 2004. 35 * 36 * This class is pretty much emulating a Gravis Ultrasound with a timer set to 250Hz 37 * i.e. mixerHandler() will call a timer routine 250 times per second while mixing 38 * the audio stream in between. 39 */ 40 #ifndef __CHANNELMIXER_H__ 41 #define __CHANNELMIXER_H__ 42 43 #include "MilkyPlayCommon.h" 44 #include "AudioDriverBase.h" 45 #include "Mixable.h" 46 47 #define MP_FP_CEIL(x) (((x)+65535)>>16) 48 #define MP_FP_MUL(a, b) ((mp_sint32)(((mp_int64)(a)*(mp_int64)(b))>>16)) 49 50 #define MP_INCREASESMPPOS(intpart, fracpart, fp, fractbits) \ 51 intpart+=((fp)>>(fractbits)); \ 52 fracpart+=((fp)&(1<<(fractbits))-1); \ 53 if (((fracpart)>>(fractbits))==1) \ 54 { \ 55 intpart++; \ 56 fracpart&=(1<<(fractbits))-1; \ 57 } 58 59 class ChannelMixer; 60 typedef void (ChannelMixer::*TSetFreq)(mp_sint32 c, mp_sint32 f); 61 62 class MixerSettings 63 { 64 protected: 65 enum 66 { 67 NUMRESAMPLERTYPES = 21, 68 }; 69 70 public: 71 // These are arranged in a way, so that the ramping flag toggles with the 72 // LSB (bit 0) if you count through them 73 enum ResamplerTypes 74 { 75 MIXER_NORMAL, 76 MIXER_NORMAL_RAMPING, 77 78 MIXER_LERPING, 79 MIXER_LERPING_RAMPING, 80 81 MIXER_LAGRANGE, 82 MIXER_LAGRANGE_RAMPING, 83 84 MIXER_SPLINE, 85 MIXER_SPLINE_RAMPING, 86 87 MIXER_SINCTABLE, 88 MIXER_SINCTABLE_RAMPING, 89 90 MIXER_SINC, 91 MIXER_SINC_RAMPING, 92 93 MIXER_AMIGA500, 94 MIXER_AMIGA500_RAMPING, 95 96 MIXER_AMIGA500LED, 97 MIXER_AMIGA500LED_RAMPING, 98 99 MIXER_AMIGA1200, 100 MIXER_AMIGA1200_RAMPING, 101 102 MIXER_AMIGA1200LED, 103 MIXER_AMIGA1200LED_RAMPING, 104 105 MIXER_DUMMY, 106 107 MIXER_INVALID 108 }; 109 110 enum 111 { 112 // pretty large buffer for most systems 113 BUFFERSIZE_DEFAULT = 8192 114 }; 115 }; 116 117 class ChannelMixer : public MixerSettings, public Mixable 118 { 119 public: 120 enum 121 { 122 // This is the basis for timing & mixing 123 // 250hz timer 124 MP_TIMERFREQ = 250, 125 MP_BASEFREQ = 48000, // is chosen because (48000 % 250) == 0 126 // period in samples for MP_TIMERFREQ 127 MP_BEATLENGTH = (MP_BASEFREQ/MP_TIMERFREQ), 128 // mixer state flags 129 MP_SAMPLE_FILTERLP = 65536, 130 MP_SAMPLE_MUTE = 32768, 131 MP_SAMPLE_ONESHOT = 8192, 132 MP_SAMPLE_FADEOFF = 4096, 133 MP_SAMPLE_FADEOUT = 2048, 134 MP_SAMPLE_FADEIN = 1024, 135 MP_SAMPLE_PLAY = 256, 136 MP_SAMPLE_BACKWARD = 128, 137 138 MP_INVALID_VALUE = 0x7FFFFFFF, 139 MP_FILTERPRECISION = 8 140 }; 141 fixedmul(mp_sint32 a,mp_sint32 b)142 static inline mp_sint32 fixedmul(mp_sint32 a,mp_sint32 b) { return MP_FP_MUL(a,b); } fixeddiv(mp_sint32 a,mp_sint32 b)143 static inline mp_sint32 fixeddiv(mp_sint32 a,mp_sint32 b) { return ((mp_sint32)(((mp_int64)(a)*65536/(mp_int64)(b)))); } 144 145 // this is a subset of the channel state which is stored along 146 // with the time progress, so you can do a look up of the state 147 // even with large buffer sizes 148 struct TTimeRecord 149 { 150 mp_uint32 flags; // bit 8 = sample played 151 // bit 9 = sample direction (0 = forward, 1 = backward) 152 // bit 10-11 = sample ticker used to represent ramping states 153 // bit 12 = scheduled to stop 154 // bit 13 = one shot looping 155 // bit 15 = mute channel 156 const mp_sbyte* sample; // pointer to sample 157 mp_sint32 smppos; // 32 bit integer part of sample position 158 mp_sint32 volPan; // 32 bits, upper 16 bits = pan, lower 16 bits = vol 159 mp_sint32 smplen; 160 mp_sint32 smpposfrac; // 16 bit fractional part of sample position 161 mp_sint32 smpadd; // 16:16 fixedpoint increment 162 mp_sint32 loopend; 163 mp_sint32 loopstart; 164 mp_sint32 fixedtime; // for amiga resampler (running time) 165 mp_sint32 fixedtimefrac; // for sinc/amiga resamplers (running time fraction) 166 TTimeRecordTTimeRecord167 TTimeRecord() : 168 flags(0), 169 sample(NULL), 170 smppos(0), 171 volPan(0), 172 smplen(0), 173 smpposfrac(0), 174 smpadd(0), 175 loopend(0), 176 loopstart(0), 177 fixedtime(0), 178 fixedtimefrac(0) 179 { 180 } 181 }; 182 183 struct TMixerChannel 184 { 185 mp_uint32 flags; // bit 8 = sample played 186 // bit 9 = sample direction (0 = forward, 1 = backward) 187 // bit 10-11 = sample ticker used to represent ramping states 188 // bit 12 = scheduled to stop 189 // bit 13 = one shot looping 190 // bit 15 = mute channel 191 const mp_sbyte* sample; // pointer to sample 192 mp_sint32 smplen; 193 mp_sint32 smppos; // 32 bit integer part of sample position 194 mp_sint32 smpposfrac; // 16 bit fractional part of sample position 195 mp_sint32 smpadd; // 16:16 fixed point increment 196 mp_sint32 rsmpadd; // fixed point reciprocal of the increment 197 mp_sint32 loopend; // loop end 198 mp_sint32 loopendcopy; // Temporary placeholder for one-shot looping 199 mp_sint32 loopstart; // loop start 200 201 mp_sint32 finalvolr; 202 mp_sint32 finalvoll; 203 204 mp_sint32 vol; 205 mp_sint32 pan; 206 207 mp_sint32 rampFromVolStepR; 208 mp_sint32 rampFromVolStepL; 209 210 mp_sint32 a,b,c; // Filter coefficients 211 mp_sint32 currsample; // sample history for filtering 212 mp_sint32 prevsample; // see above 213 214 mp_sint32 cutoff; 215 mp_sint32 resonance; 216 217 mp_sint32 fixedtime; // for amiga resampler (running time) 218 mp_sint32 fixedtimefrac; // for sinc/amiga resamplers (running time fraction) 219 220 mp_uint32 timeRecordSize; 221 TTimeRecord* timeRecord; 222 mp_sint32 index; // For Amiga resampler 223 TMixerChannelTMixerChannel224 TMixerChannel() : 225 timeRecordSize(0), 226 timeRecord(NULL) 227 { 228 clear(); 229 } 230 TMixerChannelTMixerChannel231 TMixerChannel(bool fastContruction) : 232 timeRecordSize(0), 233 timeRecord(NULL) 234 { 235 } 236 ~TMixerChannelTMixerChannel237 ~TMixerChannel() 238 { 239 if (timeRecord) 240 delete[] timeRecord; 241 } 242 clearTMixerChannel243 void clear() 244 { 245 flags = 0; 246 sample = NULL; 247 smplen = 0; 248 smppos = 0; 249 smpposfrac = 0; 250 smpadd = 0; 251 rsmpadd = 0; 252 loopend = 0; 253 loopendcopy = 0; 254 loopstart = 0; 255 256 finalvolr = 0; 257 finalvoll = 0; 258 259 vol = 0; 260 pan = 128; 261 262 rampFromVolStepR = 0; 263 rampFromVolStepL = 0; 264 265 a = b = c = 0; 266 currsample = 0; 267 prevsample = 0; 268 269 cutoff = MP_INVALID_VALUE; 270 resonance = MP_INVALID_VALUE; 271 272 fixedtime = 0; 273 fixedtimefrac = 0; 274 index = -1; // is filled during runtime 275 276 if (timeRecord) 277 memset(timeRecord, 0, sizeof(TTimeRecord) * timeRecordSize); 278 } 279 reallocTimeRecordTMixerChannel280 void reallocTimeRecord(mp_uint32 size) 281 { 282 delete[] timeRecord; 283 timeRecordSize = size; 284 timeRecord = new TTimeRecord[size]; 285 } 286 }; 287 288 class ResamplerBase 289 { 290 private: 291 // add channels without volume ramping 292 void addChannelsNormal(ChannelMixer* mixer, mp_uint32 numChannels, mp_sint32* buffer32,mp_sint32 beatNum, mp_sint32 beatlength); 293 // add channels with volume ramping 294 void addChannelsRamping(ChannelMixer* mixer, mp_uint32 numChannels, mp_sint32* buffer32,mp_sint32 beatNum, mp_sint32 beatlength); 295 296 public: ~ResamplerBase()297 virtual ~ResamplerBase() 298 { 299 } 300 301 void addChannels(ChannelMixer* mixer, mp_uint32 numChannels, mp_sint32* buffer32,mp_sint32 beatNum, mp_sint32 beatlength); 302 void addChannel(TMixerChannel* chn, mp_sint32* buffer32, const mp_sint32 beatlength, const mp_sint32 beatSize); 303 304 // walk along the sample 305 // intpart is the 32 bit integer part of the position 306 // fracpart is the fractional part of the position 307 // fp is the amount of samples to advance 308 // is the resolution of the fractional part in bits (default is 16) 309 static inline void advanceSamplePosition(mp_sint32& intpart, 310 mp_sint32& fracpart, 311 const mp_sint32 fp, 312 const mp_sint32 fracbits = 16) 313 { 314 MP_INCREASESMPPOS(intpart, fracpart, fp, fracbits); 315 } 316 317 // if this resampler is doing ramping 318 virtual bool isRamping() = 0; 319 // this resampler can perform a normal block add to the mixing buffer 320 virtual bool supportsNoChecking() = 0; 321 // optional: if this resampler is able to perform a full checked walk along the sample 322 virtual bool supportsFullChecking() = 0; 323 324 // see above, you will need to implement at least one of the following addBlockNoCheck(mp_sint32 * buffer,TMixerChannel * chn,mp_uint32 count)325 virtual void addBlockNoCheck(mp_sint32* buffer, TMixerChannel* chn, mp_uint32 count) 326 { 327 // if this is called your own derived resampler is not properly working 328 ASSERT(false); 329 } 330 331 // see above for comments addBlockFull(mp_sint32 * buffer,TMixerChannel * chn,mp_uint32 count)332 virtual void addBlockFull(mp_sint32* buffer, TMixerChannel* chn, mp_uint32 count) 333 { 334 ASSERT(false); 335 } 336 337 // in case the resampler needs to get hold of the current mixing frequency setFrequency(mp_sint32 frequency)338 virtual void setFrequency(mp_sint32 frequency) { } 339 340 // in case the resampler needs to get hold of the current number of channels setNumChannels(mp_sint32 num)341 virtual void setNumChannels(mp_sint32 num) { } 342 }; 343 344 friend class ChannelMixer::ResamplerBase; 345 346 private: 347 mp_uint32 mixerNumAllocatedChannels; // Number of channels to be allocated by mixer 348 mp_uint32 mixerNumActiveChannels; // Number of channels to be mixed 349 mp_uint32 mixerLastNumAllocatedChannels; 350 351 mp_uint32 mixFrequency; // Mixing frequency 352 mp_uint32 rMixFrequency; // 0x7FFFFFFF/mixFrequency 353 354 mp_sint32* mixbuffBeatPacket; 355 mp_uint32 mixBufferSize; // this is the resulting buffer size in 16 bit words 356 357 mp_uint32 beatPacketSize; // size of 1/250 of a second in samples 358 mp_uint32 numBeatPackets; // how many of these fit in our buffer size 359 mp_uint32 lastBeatRemainder; // used while filling the buffer, if the buffer is not an exact multiple of beatPacketSize 360 361 TMixerChannel* channel; 362 TMixerChannel* newChannel; 363 364 mp_sint32 masterVolume; // mixer master volume 365 mp_sint32 panningSeparation; // panning separation from 0 (mono) to 256 (full stereo) 366 367 ResamplerTypes resamplerType; 368 TSetFreq setFreqFuncTable[NUMRESAMPLERTYPES]; // If different precisions are used, use other frequency calculation procedures 369 ResamplerBase* resamplerTable[NUMRESAMPLERTYPES]; 370 371 bool paused; 372 bool disableMixing; 373 bool allowFilters; 374 375 void setFrequency(mp_sint32 frequency); 376 mixBeatPacket(mp_uint32 numChannels,mp_sint32 * buffer32,mp_sint32 beatPacketIndex,mp_sint32 beatPacketSize)377 void mixBeatPacket(mp_uint32 numChannels, 378 mp_sint32* buffer32, 379 mp_sint32 beatPacketIndex, 380 mp_sint32 beatPacketSize) 381 { 382 resamplerTable[resamplerType]->addChannels(this, numChannels, buffer32, beatPacketIndex, beatPacketSize); 383 } 384 timer(mp_uint32 beatIndex)385 inline void timer(mp_uint32 beatIndex) 386 { 387 timerHandler(beatIndex <= getNumBeatPackets() ? beatIndex : getNumBeatPackets()); 388 } 389 390 void reallocChannels(); 391 void clearChannels(); 392 393 public: 394 ChannelMixer(mp_uint32 numChannels, 395 mp_uint32 frequency); 396 397 virtual ~ChannelMixer(); 398 getMixBufferSize()399 mp_uint32 getMixBufferSize() const { return mixBufferSize; } 400 void mix(mp_sint32* buffer, mp_uint32 numSamples); updateSampleCounter(mp_sint32 numSamples)401 void updateSampleCounter(mp_sint32 numSamples) { sampleCounter+=numSamples; } resetSampleCounter()402 void resetSampleCounter() { sampleCounter=0; } 403 404 mp_sint32 initDevice(); 405 mp_sint32 closeDevice(); 406 407 void stop(); 408 mp_sint32 pause(); 409 mp_sint32 resume(); 410 setDisableMixing(bool disableMixing)411 void setDisableMixing(bool disableMixing) { this->disableMixing = disableMixing; } setAllowFilters(bool allowFilters)412 void setAllowFilters(bool allowFilters) { this->allowFilters = allowFilters; } getAllowFilters()413 bool getAllowFilters() const { return allowFilters; } 414 415 void resetChannelsFull(); 416 void resetChannelsWithoutMuting(); 417 418 void setResamplerType(ResamplerTypes type); getResamplerType()419 ResamplerTypes getResamplerType() const { return resamplerType; } isRamping()420 bool isRamping() const { return resamplerTable[resamplerType]->isRamping(); } 421 422 virtual mp_sint32 adjustFrequency(mp_uint32 frequency); getMixFrequency()423 mp_sint32 getMixFrequency() { return mixFrequency; } 424 425 static mp_sint32 beatPacketsToBufferSize(mp_uint32 mixFrequency, mp_uint32 numBeats); 426 virtual mp_sint32 setBufferSize(mp_uint32 bufferSize); 427 getBeatPacketSize()428 mp_uint32 getBeatPacketSize() const { return beatPacketSize; } getNumBeatPackets()429 mp_uint32 getNumBeatPackets() const { return mixBufferSize / beatPacketSize; } 430 431 // volume control setMasterVolume(mp_sint32 vol)432 void setMasterVolume(mp_sint32 vol) { masterVolume = vol; } getMasterVolume()433 mp_sint32 getMasterVolume() const { return masterVolume; } 434 // panning control setPanningSeparation(mp_sint32 separation)435 void setPanningSeparation(mp_sint32 separation) { panningSeparation = separation; } getPanningSeparation()436 mp_sint32 getPanningSeparation() const { return panningSeparation; } 437 isInitialized()438 bool isInitialized() const { return initialized; } isPlaying()439 bool isPlaying() const { return startPlay; } 440 441 mp_sint32 getNumActiveChannels(); getNumAllocatedChannels()442 mp_sint32 getNumAllocatedChannels() const { return mixerNumActiveChannels; } 443 getSampleCounter()444 mp_int64 getSampleCounter() const { return sampleCounter; } 445 446 mp_sint32 getBeatIndexFromSamplePos(mp_uint32 smpPos) const; 447 getCurrentResampler()448 ResamplerBase* getCurrentResampler() const { return resamplerTable[resamplerType]; } 449 450 protected: 451 bool initialized; 452 bool startPlay; 453 454 mp_int64 sampleCounter; // number of samples played (per song) 455 startMixer()456 void startMixer() 457 { 458 lastBeatRemainder = 0; 459 } 460 461 void setNumChannels(mp_uint32 num); 462 463 void setActiveChannels(mp_uint32 num); 464 465 public: setVol(mp_sint32 c,mp_sint32 v)466 void setVol(mp_sint32 c,mp_sint32 v) { channel[c].vol = v; } getVol(mp_sint32 c)467 mp_sint32 getVol(mp_sint32 c) { return channel[c].vol; } 468 setPan(mp_sint32 c,mp_sint32 p)469 void setPan(mp_sint32 c,mp_sint32 p) { channel[c].pan = p; } 470 setFreq(mp_sint32 c,mp_sint32 f)471 void setFreq(mp_sint32 c,mp_sint32 f) 472 { 473 (this->*setFreqFuncTable[resamplerType])(c,f); 474 } 475 476 // Default low precision calculations 477 void setChannelFrequency(mp_sint32 c, mp_sint32 f); 478 479 void setFilterAttributes(mp_sint32 c, mp_sint32 cutoff, mp_sint32 resonance); 480 481 void playSample(mp_sint32 c, // channel 482 mp_sbyte* smp, // sample buffer 483 mp_sint32 smplen, // sample size 484 mp_sint32 smpoffs, // sample offset 485 mp_sint32 smpoffsfrac, 486 bool smpOffsetWrap, 487 mp_sint32 lstart, // loop start 488 mp_sint32 len, // loop end 489 mp_sint32 flags, 490 bool ramp = true); 491 isChannelPlaying(mp_sint32 c)492 bool isChannelPlaying(mp_sint32 c) { return (channel[c].flags&MP_SAMPLE_PLAY) != 0; } 493 stopSample(mp_sint32 c)494 void stopSample(mp_sint32 c) { channel[c].flags&=~(MP_SAMPLE_FADEIN|MP_SAMPLE_FADEOUT); channel[c].flags|=MP_SAMPLE_FADEOFF; } 495 breakLoop(mp_sint32 c)496 void breakLoop(mp_sint32 c) { channel[c].flags&=~3; channel[c].loopend = channel[c].smplen; } 497 498 // handle with care setSamplePos(mp_sint32 c,mp_sint32 pos)499 void setSamplePos(mp_sint32 c, mp_sint32 pos) { channel[c].smppos = pos; channel[c].smpposfrac = 0; } 500 getSamplePos(mp_sint32 c)501 mp_sint32 getSamplePos(mp_sint32 c) { return channel[c].smppos; } getSamplePosFrac(mp_sint32 c)502 mp_sint32 getSamplePosFrac(mp_sint32 c) { return channel[c].smpposfrac; } 503 setBackward(mp_sint32 c)504 void setBackward(mp_sint32 c) 505 { 506 if (channel[c].flags & MP_SAMPLE_PLAY) 507 { 508 channel[c].flags |= MP_SAMPLE_BACKWARD; 509 if (channel[c].smppos < channel[c].loopstart) 510 { 511 channel[c].smppos = channel[c].loopend; 512 } 513 } 514 } 515 setForward(mp_sint32 c)516 void setForward(mp_sint32 c) 517 { 518 if (channel[c].flags & MP_SAMPLE_PLAY) 519 { 520 channel[c].flags &= ~MP_SAMPLE_BACKWARD; 521 if (channel[c].smppos > channel[c].loopend) 522 { 523 channel[c].smppos = channel[c].loopstart; 524 } 525 } 526 } 527 528 void muteChannel(mp_sint32 c, bool m); 529 530 bool isChannelMuted(mp_sint32 c); 531 532 mp_uint32 getSyncSampleCounter(); 533 534 protected: 535 // timer procedure for mixing 536 virtual void timerHandler(mp_sint32 currentBeatPacket) = 0; 537 void panToVol(ChannelMixer::TMixerChannel *chn, mp_sint32 &left, mp_sint32 &right); 538 static mp_sint32 panLUT[257]; 539 540 #ifdef MILKYTRACKER 541 friend class PlayerController; 542 #endif 543 544 #ifdef __MPTIMETRACKING__ 545 public: 546 void mixData(mp_sint32 c, 547 mp_sint32* buffer, 548 mp_sint32 count, 549 mp_sint32 sampleShift, 550 mp_sint32 fMul = 0, 551 mp_sint32 bufferIndex = -1, 552 mp_sint32 packetIndex = -1) const; 553 #endif 554 }; 555 556 #endif 557