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 * PlayerGeneric.h 32 * MilkyPlay 33 * 34 * This class is meant to be a wrapper class that handles all 35 * different sorts of players for different Module types. 36 * 37 * Created by Peter Barth on 21.01.05. 38 * 39 */ 40 41 #ifndef __PLAYERGENERIC_H__ 42 #define __PLAYERGENERIC_H__ 43 44 #include "MilkyPlayTypes.h" 45 #include "XMFile.h" 46 #include "ChannelMixer.h" 47 #include "PlayerBase.h" 48 49 class XModule; 50 class AudioDriverInterface; 51 52 class PlayerGeneric : public MixerSettings, public PlayModeSettings 53 { 54 private: 55 class MasterMixer* mixer; 56 class MixerNotificationListener* listener; 57 58 // the current PlayerBase instance 59 PlayerBase* player; 60 61 // ---------------------------------------------------------- 62 // Since we are destroying and creating PlayerBase instances 63 // within this class there is no way to keep the settings 64 // we set for this special instance, so we need to store them 65 // not only in the instance but also in this class: 66 // ---------------------------------------------------------- 67 // remember mixer type 68 ChannelMixer::ResamplerTypes resamplerType; 69 // remember mixing frequency 70 mp_uint32 frequency; 71 // overwrite default audiodriver 72 AudioDriverInterface* audioDriver; 73 // remember buffersize 74 mp_uint32 bufferSize; 75 // remember sample shift 76 mp_uint32 sampleShift; 77 // this flag indicates if audiodriver tries to compensate for 2^n buffer sizes 78 bool compensateBufferFlag; 79 // This contains the string of the selected audio driver 80 char* audioDriverName; 81 82 // remember paused state 83 bool paused; 84 // remember if mixing has been disabled 85 bool disableMixing; 86 // remember if filters are allowed 87 bool allowFilters; 88 // remember idle state 89 bool idle; 90 // remember to play only one row 91 bool playOneRowOnly; 92 // remember to repeat the song 93 bool repeat; 94 // remember to reset on stop 95 bool resetOnStopFlag; 96 // remember to reset main volume on start 97 bool resetMainVolumeOnStartPlayFlag; 98 // remember to auto adjust the peak 99 bool autoAdjustPeak; 100 // remember our mixer mastervolume 101 mp_sint32 masterVolume; 102 // remember our mixer panning separation 103 mp_sint32 panningSeparation; 104 // remember maximum amount of virtual channels 105 mp_sint32 numMaxVirChannels; 106 107 void adjustSettings(); 108 109 /** 110 * Determine the best player type for a given module 111 * @param module the module which should be played 112 * @return an enum with identifies the player type 113 */ 114 static PlayerBase::PlayerTypes getPreferredPlayerType(XModule* module); 115 116 /** 117 * Return an actual player instance for a given module 118 * This instance MUST be deleted after usage 119 * @param module the module which should be played 120 * @param audioDriver you can specify your own audioDriver instance, if this is NULL the default driver will be selected 121 * @return a PlayerBase instance is returned 122 */ 123 PlayerBase* getPreferredPlayer(XModule* module) const; 124 125 public: 126 /** 127 * Construct a PlayerGeneric object for a given output frequency 128 * @param frequency output frequency for the mixer 129 */ 130 PlayerGeneric(mp_sint32 frequency, 131 AudioDriverInterface* audioDriver = NULL); 132 /** 133 * Destructor 134 */ 135 ~PlayerGeneric(); 136 137 /////////////////////////////////////////////////////////////////////////////////////////// 138 // -------------------------- wrapping mixer specific stuff ------------------------------- 139 /////////////////////////////////////////////////////////////////////////////////////////// 140 /** 141 * Specify mixer type. This basically selects the output quality 142 * @param type mixer type 143 * @see MixerSettings 144 */ 145 void setResamplerType(ResamplerTypes type); 146 147 /** 148 * Specify mixer type with two flags indicating whether to interpolate or to do volume ramping. 149 * @param type mixer type 150 * @see MixerSettings 151 */ 152 void setResamplerType(bool interpolation, bool ramping); 153 154 /** 155 * Get the mixer type 156 * @return mixer type 157 * @see setResamplerType 158 */ 159 ChannelMixer::ResamplerTypes getResamplerType() const; 160 161 /** 162 * Specify the amount of which the sample data is right-shifted before sent to the sound driver 163 * This is an amplify in the opposite direction (shift value of 2 means 25% of the original volume) 164 * @param shift sample data shift amount 165 */ 166 void setSampleShift(mp_sint32 shift); 167 168 /** 169 * Get the shift amount 170 * @return shift amount 171 * @see setSampleShift 172 */ 173 mp_sint32 getSampleShift() const; 174 175 /** 176 * Doesn't work. Don't call. 177 * @param b true or false 178 */ 179 void setPeakAutoAdjust(bool b); 180 181 /** 182 * Set the desired output frequency 183 * It's up the the driver if the wanted frequency is possible or not 184 * Note that there is no fallback, if the driver can't handle the frequency 185 * your song will probably sound to fast or to slow 186 * @param frequency output frequency for the mixer 187 */ 188 mp_sint32 adjustFrequency(mp_uint32 frequency); 189 190 /** 191 * Get the current mixer output frequency 192 * @return output frequency 193 * @see adjustFrequency 194 */ 195 mp_sint32 getMixFrequency() const; 196 197 /** 198 * Convert number of beat backets to buffer size: 199 * The ChannelMixer class uses a fixed 250Hz timer so the mixer size is 200 * always a multiple of CurrentOutputFrequency / 250 201 * E.g. if you're mixing at 44100Hz the buffer size is always a multiple 202 * of 176 samples. 203 * Thus specifying a value of 10 will result in a buffer of 1760 samples size. 204 * Important: Some sound device drivers don't allow buffer sizes which are 205 * not multiple of 2^n that's why on some systems setting up the sound 206 * device with such a buffer size might not work. Use adjustBufferSize with 207 * a 2^n buffer size or call setPowerOfTwoCompensationFlag(true). 208 * 209 * @param numBeats The number of beat "packets" 210 */ 211 mp_sint32 beatPacketsToBufferSize(mp_uint32 numBeats); 212 213 /** 214 * Here for legacy reasons, sets the buffer size according to the number 215 * of beat packets (see function above) 216 */ 217 mp_sint32 adjustBufferSize(mp_uint32 numBeats); 218 219 /** 220 * Set the desired buffer size 221 * Important: Some sound device drivers don't allow buffer sizes which are 222 * not multiple of 2^n that's why on some systems you might call 223 * setPowerOfTwoCompensationFlag(true) to always round to the next 2^n buffer size 224 * 225 * @param bufferSize buffer size description 226 */ 227 mp_sint32 setBufferSize(mp_uint32 bufferSize); 228 229 /** 230 * Tell the sound driver to force forcing 2^n buffer blocks if possible 231 * @param b true or false 232 * @see getPowerOfTwoCompensationFlag, audioDriverSupportsPowerOfTwoCompensation 233 */ 234 mp_sint32 setPowerOfTwoCompensationFlag(bool b); 235 236 /** 237 * Query if the sound driver is currently forcing 2^n buffer blocks 238 * @return true or false 239 * @see setPowerOfTwoCompensationFlag, audioDriverSupportsPowerOfTwoCompensation 240 */ 241 bool getPowerOfTwoCompensationFlag() const; 242 243 /** 244 * Query the the sound drivers name 245 * @return Name of the audio driver. Do NOT save this value. It's only temporary and may change. 246 */ 247 const char* getCurrentAudioDriverName() const; 248 249 /** 250 * Select an audio driver from the available list of audio drivers 251 * specified by the given name 252 * If the return value is false the select has failed but 253 * the default driver has been selected instead so playback 254 * is still possible 255 * @param name Full qualified name of the audio driver 256 * @return true or false indicating if the selection has succeeded 257 */ 258 bool setCurrentAudioDriverByName(const char* name); 259 260 /** 261 * Get state information about the mixer: Check if the mixer has been initialized 262 * @return true or false 263 */ 264 bool isInitialized() const; 265 266 /** 267 * Get state information about the player: Check if we're playing a song 268 * @return true or false 269 */ 270 bool isPlaying() const; 271 272 /** 273 * Get how many samples have been played since the player has started playing 274 * this is only 32 bit and might overflow quickly depending on your output frequency 275 * @return number of samples played 276 */ 277 mp_int64 getSampleCounter() const; 278 279 /** 280 * Reset the sample counter 281 * @see getSampleCounter 282 */ 283 void resetSampleCounter(); 284 285 /** 286 * For hi latency audio drivers this might return 287 * a pointer to the sample which is currently played 288 * in the mixing BUFFER!!! Don't depend on this function 289 * it might not work on your system 290 * @return the position of the driver within the sample buffer 291 */ 292 mp_sint32 getCurrentSamplePosition() const; 293 294 mp_sint32 getCurrentBeatIndex(); 295 296 /** 297 * Get a sample from the current mixing buffer 298 * a pointer to the sample which is currently played 299 * in the mixing BUFFER!!! Don't depend on this function 300 * it might not work on your system 301 * @param position position within the mixing buffer 302 * @param channel the channel (0 = left, 1 = right [mixing is always stereo]) 303 * @return a sample between -32768 and 32768 304 */ 305 mp_sint32 getCurrentSample(mp_sint32 position, mp_sint32 channel); 306 307 /** 308 * Get some peaks around the position "pos" in the current mixing buffer 309 * Just looks good when displayed, is not a perfect peak detector 310 * @param position in the buffer, needs to be within the valid range 311 * @param channel the channel (0 = left, 1 = right [mixing is always stereo]) 312 */ 313 mp_sint32 getCurrentSamplePeak(mp_sint32 position, mp_sint32 channel); 314 315 /** 316 * Reset channels. All channels will immediately stop playing after this has been called. 317 */ 318 void resetChannels(); 319 320 /** 321 * How many active channels do we have? 322 * @return return the number of channels which are active in the mixing process 323 */ 324 mp_sint32 getNumActiveChannels() const; 325 326 /** 327 * How many channels have been allocated for playback? 328 * @return return the number of channels allocated for playback 329 */ 330 mp_sint32 getNumAllocatedChannels() const; 331 332 /////////////////////////////////////////////////////////////////////////////////////////// 333 // -------------------------- wrapping player specific stuff ------------------------------ 334 /////////////////////////////////////////////////////////////////////////////////////////// 335 /** 336 * Set a specified play mode 337 * @param mode play mode 338 * @see PlayModeSettings 339 */ 340 void setPlayMode(PlayModes mode); 341 342 /** 343 * Get current selected play mode 344 * @return current play mode 345 * @see setPlayMode 346 */ 347 PlayModes getPlayMode() const; 348 349 /** 350 * Switch special playmode flags, only applies to players 351 * which are able to play the kind of modules of interest 352 * @param option option to enable or disable 353 * @param b enable or disable option 354 */ 355 void enable(PlayModeOptions option, bool b); 356 357 /** 358 * See if a special flags is enabled for the current player 359 * @param option option to enable or disable 360 * @return true if option is enabled, false otherwise 361 */ 362 bool isEnabled(PlayModeOptions option) const; 363 364 /** 365 * Restart playback 366 * @param startPosition start position within the song 367 * @param startRow start position within the pattern 368 * @param resetMixer whether or not to reset the mixer 369 * @param customPanningTable When specifying a custom panning table the panning default from the module is ignored 370 * @param playOneRowOnly stop after playing exactly ONE row 371 */ 372 void restart(mp_uint32 startPosition = 0, mp_uint32 startRow = 0, bool resetMixer = true, const mp_ubyte* customPanningTable = NULL, bool playOneRowOnly = false); 373 374 /** 375 * Reset everything. Includes audio device if there is one. 376 */ 377 void reset(); 378 379 /** 380 * Reset speed settings to the default. 381 */ 382 void resetAllSpeed(); 383 384 /** 385 * Start playback 386 * @param module module to play 387 * @param repeat repeat song? 388 * @param startPosition start position within the song 389 * @param startRow start position within the pattern 390 * @param numChannels number of channels to be allocated for playback, supply -1 for auto adjust 391 * @param customPanningTable When specifying a custom panning table the panning default from the module is ignored 392 * @param idle whether or not to start in idle mode 393 * @param patternIndex this specifies to play a given pattern only, supply -1 to play entire song instead of just one pattern 394 */ 395 mp_sint32 startPlaying(XModule* module, 396 bool repeat = false, 397 mp_uint32 startPosition = 0, 398 mp_uint32 startRow = 0, 399 mp_sint32 numChannels = -1, 400 const mp_ubyte* customPanningTable = NULL, 401 bool idle = false, 402 mp_sint32 patternIndex = -1, 403 bool playOneRowOnly = false); 404 405 /** 406 * Specify a pattern to be played instead of playing the entire song 407 * @param patternIndex this specifies to play a given pattern only, supply -1 to play entire song instead of just one pattern 408 */ 409 void setPatternToPlay(mp_sint32 patternIndex); 410 411 /** 412 * Stop playing, also stops audio device (easy, huh?) 413 * @return error code (0 = everything is fine) 414 */ 415 mp_sint32 stopPlaying(); 416 417 /** 418 * Check if song has been stopped (either the song did something stupid or it played once and repeat is false) 419 * NOTE: This will not mean that audio streaming has stopped, it only tells you that the song hit a position 420 * that was already played and if it's not in repeat mode it will halt. 421 * If the player is in repeat mode this will most probably always return false and even if it is true you need 422 * to still call stopPlaying() if you want to play another song. 423 * @return true or false 424 */ 425 bool hasSongHalted() const; 426 427 /** 428 * This is probably only used by MilkyTracker 429 * You can tell the core not to play any song, but the mixer is still active 430 * So if you play samples on the channels manually they will still be mixed 431 * @param idle true = go into idle mode stop song but mixer stays active, false = start playing the song again 432 */ 433 void setIdle(bool idle); 434 435 /** 436 * Check if player is in idle state 437 * @return true or false 438 * @see setIdle 439 */ 440 bool isIdle() const; 441 442 /** 443 * Tell the player to enable/disable repeating 444 * @param repeat true or false 445 */ 446 void setRepeat(bool repeat); 447 448 /** 449 * Check if player is repeating 450 * @return true or false 451 * @see setRepeat 452 */ 453 bool isRepeating() const; 454 455 /** 456 * Pause the player 457 */ 458 mp_sint32 pausePlaying(); 459 460 /** 461 * Resume from paused state 462 * @see pausePlaying 463 */ 464 mp_sint32 resumePlaying(); 465 466 /** 467 * Check if player is in paused state 468 * @return true or false 469 * @see pausePlaying 470 */ 471 bool isPaused() const; 472 473 /** 474 * Turn mixer off, but song is still played 475 * This is used for calculating the song length: 476 * Song is played internally but the entire mixer 477 * is disabled so playing will be really fast 478 * @param b true or false 479 */ 480 void setDisableMixing(bool b); 481 482 /** 483 * Allow DSP filters. 484 * IT uses a low pass resonanance IIR filter 485 * which can be disabled to save CPU power. 486 * @param b true or false 487 */ 488 void setAllowFilters(bool b); 489 490 /** 491 * Tell if filters are allowed. 492 * @return true if filters are enabled. 493 * @see setAllowFilters 494 */ 495 bool getAllowFilters() const; 496 497 /** 498 * Set master volume for the mixer 499 * @param vol Master volume between 0 and 256 500 */ 501 void setMasterVolume(mp_sint32 vol); 502 503 /** 504 * Return the master volume for the mixer 505 * @return master volume (usually a volume between 0 and 256) 506 * @see setMasterVolume 507 */ 508 mp_sint32 getMasterVolume() const; 509 510 /** 511 * Set panning separation for the mixer 512 * @param separation Panning separation between 0 (none) and 256 (full) 513 */ 514 void setPanningSeparation(mp_sint32 separation); 515 516 /** 517 * Return the panning separation for the mixer 518 * @return Panning separation between 0 (none) and 256 (full) 519 * @see setPanningSeparation 520 */ 521 mp_sint32 getPanningSeparation() const; 522 523 /** 524 * Return the main volume of the currently played song, this is NOT the mixer master volume 525 * @return main volume between 0 and 255 526 */ 527 mp_sint32 getSongMainVolume() const; 528 529 /** 530 * Which row in the current pattern is the player at? 531 * @return current row in current pattern 532 */ 533 mp_sint32 getRow() const; 534 535 /** 536 * Which order position is the player at? 537 * @return order position from 0 to 255 (might return bigger values in future) 538 */ 539 mp_sint32 getOrder() const; 540 541 /** 542 * Return both, order and row at the same time, 543 * might be needed for sync reasons (MilkyTracker) 544 * Retrieving the row requires very low latency output, so it might 545 * not be as precise as you want to have it 546 * @param order reference to an 32 bit integer to hold the order 547 * @param row reference to an 32 bit integer to hold the row 548 */ 549 void getPosition(mp_sint32& order, mp_sint32& row) const; 550 551 mp_sint32 getLastUnvisitedPosition() const; 552 553 /** 554 * Return order, row and ticker at the same time, 555 * might be needed for sync reasons (MilkyTracker) 556 * Retrieving the ticker/row requires very low latency output, so it might 557 * not be as precise as you want to have it 558 * @param order reference to an 32 bit integer to hold the order 559 * @param row reference to an 32 bit integer to hold the row 560 * @param ticker reference to an 32 bit integer to hold the ticker 561 */ 562 void getPosition(mp_sint32& order, mp_sint32& row, mp_sint32& ticker) const; 563 564 /** 565 * Return the number of rows played since the player has started 566 * Might become handy for sync reasons. 567 * @return number of rows played since start 568 */ 569 mp_int64 getSyncCount() const; 570 571 /** 572 * Return number of samples played but this time the 573 * audio driver will return this value. 574 * This is also used for VERY accurate synching especially 575 * using MMSYSTEM. The value will be resettet on calling stopPlaying() 576 * @return number of samples the audiodriver has played since start 577 */ 578 mp_uint32 getSyncSampleCounter() const; 579 580 /** 581 * Jump to next pattern 582 */ 583 void nextPattern(); 584 585 /** 586 * Jump to previous pattern 587 */ 588 void lastPattern(); 589 590 /** 591 * Select a new position within the song 592 * @param pos new order position 593 * @param row new row 594 * @param resetChannels reset channels, yes or no 595 */ 596 void setPatternPos(mp_uint32 pos, mp_uint32 row = 0, bool resetChannels = true, bool resetFXMemory = true); 597 598 /** 599 * Return the tempo of the song at the current position (in BPM) 600 * When there is no song playing the last active tempo will be returned 601 * @return current tempo in BPM 602 */ 603 mp_sint32 getTempo() const; 604 605 /** 606 * Return the speed of the current position in ticks 607 * When there is no song playing the last active tick speed will be returned 608 * @return current speed in ticks 609 */ 610 mp_sint32 getSpeed() const; 611 612 /** 613 * Tell the player to reset the channels when the song stops (= is played once) 614 * When the player is in repeat mode the channels will never be resettet, not 615 * even when the song loops 616 * @param b reset on stop, yes or no 617 */ 618 void resetOnStop(bool b); 619 620 /** 621 * Tell the player to reset the main volume of the player (not the mixer master volume) 622 * when the song is restarted (MilkyTracker does not want the volume to be reset) 623 * @param b reset volume on start, yes or no 624 */ 625 void resetMainVolumeOnStartPlay(bool b); 626 627 /** 628 * Export the song as WAV file 629 * @param fileName the path and the filename to export to 630 * @param module the module to export 631 * @param startOrder the start position within the order list of the song 632 * @param endOrder the last order to be played 633 * @param mutingArray optional: an array telling which channels to mute 634 * @param mutingNumChannels optional: many channels does the muting array contain? 635 * @param customPanningTable When specifying a custom panning table the panning default from the module is ignored 636 * @param preferredDriver optional: specify another output audio driver here (NULL = WAV driver) 637 * @param timingLUT optional: specify a pointer to a buffer which will hold the 638 * number of samples played up to this position in the orderlist 639 * the buffer needs at least module->header.ordnum entries 640 */ 641 mp_sint32 exportToWAV(const SYSCHAR* fileName, 642 XModule* module, 643 mp_sint32 startOrder = 0, mp_sint32 endOrder = -1, 644 const mp_ubyte* mutingArray = NULL, mp_uint32 mutingNumChannels = 0, 645 const mp_ubyte* customPanningTable = NULL, 646 AudioDriverBase* preferredDriver = NULL, 647 mp_sint32* timingLUT = NULL); 648 649 /** 650 * Grab current channel data from a module channel 651 * @param chn the channel index to grab the data from 652 * @param channelInfo reference to a channelInfo structure to be filled 653 */ 654 bool grabChannelInfo(mp_sint32 chn, TPlayerChannelInfo& channelInfo) const; 655 656 /** 657 * Set the maximum number of virtual channels to be allocated while playing. 658 * This might reduce CPU consumption a lot but only if the current player is using 659 * virtual channels (like PlayerIT for example). If the current player doesn't 660 * support virtual channels, this function has no effect. 661 * 662 * IMPORTANT: call this only before startPlaying, otherwise it will have no effect. 663 * 664 * @param max maximum amount of virtual channels (default is 256) 665 */ 666 void setNumMaxVirChannels(mp_sint32 max); 667 668 /** 669 * Return the maximum number of virtual channels to be allocated while playing. 670 * @return maximum amount of virtual channels (default is 256) 671 */ 672 mp_sint32 getNumMaxVirChannels() const; 673 674 // ---------------------------- milkytracker ---------------------------- 675 /** 676 * Change panning of a current playing channel 677 * @param chn the channel 678 * @param pan new panning value Left(0..255)Right 679 */ 680 void setPanning(mp_ubyte chn, mp_ubyte pan); 681 682 /** 683 * Return the currently used player instance (handle with care) 684 * @return a PlayerBase instance is returned or NULL if there is none right now 685 */ getPlayerInstance()686 PlayerBase* getPlayerInstance() { return player; } 687 688 friend class MixerNotificationListener; 689 }; 690 691 #endif 692 693