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