1 /*
2  *  tracker/PlayerController.cpp
3  *
4  *  Copyright 2009 Peter Barth
5  *
6  *  This file is part of Milkytracker.
7  *
8  *  Milkytracker is free software: you can redistribute it and/or modify
9  *  it under the terms of the GNU General Public License as published by
10  *  the Free Software Foundation, either version 3 of the License, or
11  *  (at your option) any later version.
12  *
13  *  Milkytracker is distributed in the hope that it will be useful,
14  *  but WITHOUT ANY WARRANTY; without even the implied warranty of
15  *  MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
16  *  GNU General Public License for more details.
17  *
18  *  You should have received a copy of the GNU General Public License
19  *  along with Milkytracker.  If not, see <http://www.gnu.org/licenses/>.
20  *
21  */
22 
23 /*
24  *  PlayerController.cpp
25  *  MilkyTracker
26  *
27  *  Created by Peter Barth on Tue Mar 15 2005.
28  *
29  */
30 
31 #include "PlayerController.h"
32 #include "PlayerMaster.h"
33 #include "MilkyPlay.h"
34 #include "ResamplerMacros.h"
35 #include "PPSystem.h"
36 #include "PlayerCriticalSection.h"
37 #include "ModuleEditor.h"
38 
39 class PlayerStatusTracker : public PlayerSTD::StatusEventListener
40 {
41 public:
PlayerStatusTracker(PlayerController & playerController)42 	PlayerStatusTracker(PlayerController& playerController) :
43 		playerController(playerController)
44 	{
45 		clearUpdateCommandBuff();
46 	}
47 
48 	// this is being called from the player callback in a serialized fashion
playerTickStarted(PlayerSTD & player,XModule & module)49 	virtual void playerTickStarted(PlayerSTD& player, XModule& module)
50 	{
51 		while (rbReadIndex < rbWriteIndex)
52 		{
53 			mp_sint32 idx = rbReadIndex & (UPDATEBUFFSIZE-1);
54 
55 			// handle notes that are played from external source
56 			// i.e. keyboard playback
57 			switch (updateCommandBuff[idx].code)
58 			{
59 				case UpdateCommandCodeNote:
60 				{
61 					UpdateCommandNote* command = reinterpret_cast<UpdateCommandNote*>(&updateCommandBuff[idx]);
62 					mp_sint32 note = command->note;
63 					if (note)
64 					{
65 						player.playNote(command->channel, note,
66 										command->ins,
67 										command->volume);
68 						command->note = 0;
69 					}
70 					break;
71 				}
72 
73 				case UpdateCommandCodeSample:
74 				{
75 					UpdateCommandSample* command = reinterpret_cast<UpdateCommandSample*>(&updateCommandBuff[idx]);
76 					const TXMSample* smp = command->smp;
77 					if (smp)
78 					{
79 						playSampleInternal(player, command->channel, smp, command->currentSamplePlayNote,
80 										   command->rangeStart,  command->rangeEnd);
81 						command->smp = NULL;
82 					}
83 
84 					break;
85 				}
86 
87 			}
88 			rbReadIndex++;
89 		}
90 	}
91 
patternEndReached(PlayerSTD & player,XModule & module,mp_sint32 & newOrderIndex)92 	virtual void patternEndReached(PlayerSTD& player, XModule& module, mp_sint32& newOrderIndex)
93 	{
94 		handleQueuedPositions(player, newOrderIndex);
95 	}
96 
playNote(mp_ubyte chn,mp_sint32 note,mp_sint32 ins,mp_sint32 vol)97 	void playNote(mp_ubyte chn, mp_sint32 note, mp_sint32 ins, mp_sint32 vol/* = -1*/)
98 	{
99 		// fill ring buffer with note entries
100 		// the callback will query these notes and play them
101 		mp_sint32 idx = rbWriteIndex & (UPDATEBUFFSIZE-1);
102 		UpdateCommandNote* command = reinterpret_cast<UpdateCommandNote*>(&updateCommandBuff[idx]);
103 		command->channel = chn;
104 		command->ins = ins;
105 		command->volume = vol;
106 		command->note = note;
107 		// code needs to be filled in last
108 		command->code = UpdateCommandCodeNote;
109 		rbWriteIndex++;
110 	}
111 
playSample(mp_ubyte chn,const TXMSample & smp,mp_sint32 currentSamplePlayNote,mp_sint32 rangeStart,mp_sint32 rangeEnd)112 	void playSample(mp_ubyte chn, const TXMSample& smp, mp_sint32 currentSamplePlayNote, mp_sint32 rangeStart, mp_sint32 rangeEnd)
113 	{
114 		// fill ring buffer with sample playback entries
115 		mp_sint32 idx = rbWriteIndex & (UPDATEBUFFSIZE-1);
116 		UpdateCommandSample* command = reinterpret_cast<UpdateCommandSample*>(&updateCommandBuff[idx]);
117 		command->channel = chn;
118 		command->currentSamplePlayNote = currentSamplePlayNote;
119 		command->rangeStart = rangeStart;
120 		command->rangeEnd = rangeEnd;
121 		command->smp = &smp;
122 		command->code = UpdateCommandCodeSample;
123 		rbWriteIndex++;
124 	}
125 
126 private:
127 	PlayerController& playerController;
128 
handleQueuedPositions(PlayerSTD & player,mp_sint32 & poscnt)129 	void handleQueuedPositions(PlayerSTD& player, mp_sint32& poscnt)
130 	{
131 		// there is a queued position
132 		if (playerController.nextOrderIndexToPlay != -1)
133 		{
134 			// the new order the queued one
135 			poscnt = playerController.nextOrderIndexToPlay;
136 			// the queued one becomes invalid
137 			playerController.nextOrderIndexToPlay = -1;
138 			// we're no longer in pattern play mode...
139 			playerController.patternPlay = false;
140 			// ... that's why we're going to set the pattern index to -1
141 			playerController.patternIndex = -1;
142 			player.setPatternToPlay(-1);
143 		}
144 		// there is a queued pattern
145 		else if (playerController.nextPatternIndexToPlay != -1)
146 		{
147 			// the new pattern index
148 			player.setPatternToPlay(playerController.nextPatternIndexToPlay);
149 			// we're no in pattern play mode
150 			playerController.patternPlay = true;
151 			// that's our new pattern
152 			playerController.patternIndex = playerController.nextPatternIndexToPlay;
153 			// the queued one becomes invalid
154 			playerController.nextPatternIndexToPlay = -1;
155 		}
156 	}
157 
playSampleInternal(PlayerSTD & player,mp_ubyte chn,const TXMSample * smp,mp_sint32 currentSamplePlayNote,mp_sint32 rangeStart,mp_sint32 rangeEnd)158 	void playSampleInternal(PlayerSTD& player, mp_ubyte chn, const TXMSample* smp, mp_sint32 currentSamplePlayNote,
159 							mp_sint32 rangeStart, mp_sint32 rangeEnd)
160 	{
161 		pp_int32 period = player.getlogperiod(currentSamplePlayNote+1, smp->relnote, smp->finetune) << 8;
162 		pp_int32 freq = player.getlogfreq(period);
163 
164 		player.setFreq(chn,freq);
165 		player.setVol(chn, (smp->vol*512)/255);
166 		player.setPan(chn, 128);
167 
168 		player.chninfo[chn].flags |= 0x100; // CHANNEL_FLAGS_UPDATE_IGNORE
169 
170 		pp_int32 flags = (smp->type >> 2) & 4;
171 
172 		if (rangeStart == -1 && rangeEnd == -1)
173 		{
174 			flags |= smp->type & 3;
175 
176 			if (flags & 3)
177 				player.playSample(chn, smp->sample, smp->samplen, 0, 0, false, smp->loopstart, smp->loopstart+smp->looplen, flags);
178 			else
179 				player.playSample(chn, smp->sample, smp->samplen, 0, 0, false, 0, smp->samplen, flags);
180 		}
181 		else
182 		{
183 			if (rangeStart == -1 || rangeEnd == -1)
184 				return;
185 
186 			if (rangeEnd > (signed)smp->samplen)
187 				rangeEnd = smp->samplen;
188 
189 			player.playSample(chn, smp->sample, smp->samplen, rangeStart, 0, false, 0, rangeEnd, flags);
190 		}
191 	}
192 
clearUpdateCommandBuff()193 	void clearUpdateCommandBuff()
194 	{
195 		memset(updateCommandBuff, 0, sizeof(updateCommandBuff));
196 		rbReadIndex = rbWriteIndex = 0;
197 	}
198 
199 	enum
200 	{
201 		// must be 2^n
202 		UPDATEBUFFSIZE = 128
203 	};
204 
205 	enum UpdateCommandCodes
206 	{
207 		UpdateCommandCodeInvalid = 0,
208 		UpdateCommandCodeNote,
209 		UpdateCommandCodeSample,
210 	};
211 
212 	struct UpdateCommand
213 	{
214 		mp_ubyte code;
215 		mp_uint32 data[8];
216 		void* pdata[8];
217 	};
218 
219 	struct UpdateCommandNote
220 	{
221 		mp_ubyte code;
222 		mp_sint32 note;
223 		mp_sint32 channel;
224 		mp_sint32 ins;
225 		mp_sint32 volume;
226 		mp_uint32 data[4];
227 		void* pdata[8];
228 	};
229 
230 	struct UpdateCommandSample
231 	{
232 		mp_ubyte code;
233 		mp_uint32 currentSamplePlayNote;
234 		mp_uint32 rangeStart;
235 		mp_uint32 rangeEnd;
236 		mp_sint32 channel;
237 		mp_uint32 data[4];
238 		const TXMSample* smp;
239 		void* pdata[7];
240 	};
241 
242 	UpdateCommand updateCommandBuff[UPDATEBUFFSIZE];
243 
244 	mp_sint32 rbReadIndex;
245 	mp_sint32 rbWriteIndex;
246 };
247 
assureNotSuspended()248 void PlayerController::assureNotSuspended()
249 {
250 	if (mixer->isDevicePaused(player))
251 	{
252 		mixer->resumeDevice(player);
253 		if (suspended)
254 			suspended = false;
255 	}
256 }
257 
reset()258 void PlayerController::reset()
259 {
260 	if (!player)
261 		return;
262 
263 	// reset internal player variables (effect memory) and looping information
264 	player->BPMCounter = 0;
265 	player->reset();
266 	// reset mixer channels (stop playing channels)
267 	player->resetChannelsFull();
268 }
269 
detachDevice()270 bool PlayerController::detachDevice()
271 {
272 	if (!mixer->isDeviceRemoved(player))
273 	{
274 		return mixer->removeDevice(player);
275 	}
276 	return false;
277 }
278 
PlayerController(MasterMixer * mixer,bool fakeScopes)279 PlayerController::PlayerController(MasterMixer* mixer, bool fakeScopes) :
280 	mixer(mixer),
281 	player(NULL),
282 	module(NULL),
283 	criticalSection(NULL),
284 	playerStatusTracker(new PlayerStatusTracker(*this)),
285 	patternPlay(false), playRowOnly(false),
286 	patternIndex(-1),
287 	nextOrderIndexToPlay(-1),
288 	nextPatternIndexToPlay(-1),
289 	lastPosition(-1), lastRow(-1),
290 	suspended(false),
291 	firstRecordChannelCall(true),
292 	numPlayerChannels(TrackerConfig::numPlayerChannels),
293 	numVirtualChannels(TrackerConfig::numVirtualChannels),
294 	totalPlayerChannels(numPlayerChannels + numVirtualChannels + 2),
295 	useVirtualChannels(TrackerConfig::useVirtualChannels),
296 	multiChannelKeyJazz(true),
297 	multiChannelRecord(true),
298 	mixerDataCacheSize(fakeScopes ? 0 : 512*2),
299 	mixerDataCache(fakeScopes ? NULL : new mp_sint32[mixerDataCacheSize])
300 {
301 	criticalSection = new PlayerCriticalSection(*this);
302 
303 	player = new PlayerSTD(mixer->getSampleRate(), playerStatusTracker);
304 	player->setPlayMode(PlayerBase::PlayMode_FastTracker2);
305 	player->resetMainVolumeOnStartPlay(false);
306 	player->setBufferSize(mixer->getBufferSize());
307 
308 	currentPlayingChannel = useVirtualChannels ? numPlayerChannels : 0;
309 
310 	pp_uint32 i;
311 
312 	for (i = 0; i < sizeof(muteChannels) / sizeof(bool); i++)
313 		muteChannels[i] = false;
314 
315 	for (i = 0; i < sizeof(recordChannels) / sizeof(bool); i++)
316 		recordChannels[i] = false;
317 
318 	for (i = 0; i < sizeof(panning) / sizeof(mp_ubyte); i++)
319 	{
320 		switch (i & 3)
321 		{
322 			case 0:
323 				panning[i] = 0;
324 				break;
325 			case 1:
326 				panning[i] = 255;
327 				break;
328 			case 2:
329 				panning[i] = 255;
330 				break;
331 			case 3:
332 				panning[i] = 0;
333 				break;
334 		}
335 	}
336 }
337 
~PlayerController()338 PlayerController::~PlayerController()
339 {
340 	delete[] mixerDataCache;
341 
342 	if (player)
343 	{
344 		detachDevice();
345 		delete player;
346 	}
347 
348 	delete playerStatusTracker;
349 
350 	delete criticalSection;
351 }
352 
attachModuleEditor(ModuleEditor * moduleEditor)353 void PlayerController::attachModuleEditor(ModuleEditor* moduleEditor)
354 {
355 	this->moduleEditor = moduleEditor;
356 	this->module = moduleEditor->getModule();
357 
358 	if (!player)
359 		return;
360 
361 	if (!mixer->isDeviceRemoved(player))
362 		mixer->removeDevice(player);
363 
364 	ASSERT(sizeof(muteChannels)/sizeof(bool) >= (unsigned)totalPlayerChannels);
365 
366 	player->startPlaying(module, true, 0, 0, totalPlayerChannels, panning, true);
367 
368 	// restore muting
369 	for (mp_sint32 i = 0; i < numPlayerChannels; i++)
370 		player->muteChannel(i, muteChannels[i]);
371 
372 	mixer->addDevice(player);
373 }
374 
playSong(mp_sint32 startIndex,mp_sint32 rowPosition,bool * muteChannels)375 void PlayerController::playSong(mp_sint32 startIndex, mp_sint32 rowPosition, bool* muteChannels)
376 {
377 	if (!player)
378 		return;
379 
380 	if (!module)
381 		return;
382 
383 	if (!module->isModuleLoaded())
384 		return;
385 
386 	assureNotSuspended();
387 
388 	if (!suspended)
389 		criticalSection->enter(false);
390 
391 	readjustSpeed();
392 
393 	reset();
394 
395 	player->setPatternToPlay(-1);
396 	setNextOrderToPlay(-1);
397 	setNextPatternToPlay(-1);
398 
399 	// muting has been reset, restore it
400 	for (mp_sint32 i = 0; i < numPlayerChannels; i++)
401 	{
402 		player->muteChannel(i, muteChannels[i]);
403 		this->muteChannels[i] = muteChannels[i];
404 	}
405 	player->restart(startIndex, rowPosition, false, panning);
406 	player->setIdle(false);
407 	//resetPlayTimeCounter();
408 
409 	patternPlay = false;
410 	playRowOnly = false;
411 	patternIndex = 0;
412 
413 	criticalSection->leave(false);
414 }
415 
playPattern(mp_sint32 index,mp_sint32 songPosition,mp_sint32 rowPosition,bool * muteChannels,bool playRowOnly)416 void PlayerController::playPattern(mp_sint32 index, mp_sint32 songPosition, mp_sint32 rowPosition, bool* muteChannels, bool playRowOnly/* = false*/)
417 {
418 	if (!player)
419 		return;
420 
421 	if (!module)
422 		return;
423 
424 	if (!module->isModuleLoaded())
425 		return;
426 
427 	assureNotSuspended();
428 
429 	if (!suspended)
430 		criticalSection->enter(false);
431 
432 	readjustSpeed();
433 
434 	reset();
435 
436 	setCurrentPatternIndex(index);
437 	setNextOrderToPlay(-1);
438 	setNextPatternToPlay(-1);
439 
440 	// muting has been reset, restore it
441 	for (mp_sint32 i = 0; i < numPlayerChannels; i++)
442 	{
443 		player->muteChannel(i, muteChannels[i]);
444 		this->muteChannels[i] = muteChannels[i];
445 	}
446 
447 	if (rowPosition == -1)
448 	{
449 		rowPosition = player->getRow();
450 		if (rowPosition >= module->phead[index].rows)
451 			rowPosition = 0;
452 	}
453 
454 	player->restart(songPosition, rowPosition, false, panning, playRowOnly);
455 	player->setIdle(false);
456 	//resetPlayTimeCounter();
457 
458 	patternPlay = true;
459 	this->playRowOnly = playRowOnly;
460 	patternIndex = index;
461 
462 	criticalSection->leave(false);
463 }
464 
setCurrentPatternIndex(mp_sint32 index)465 void PlayerController::setCurrentPatternIndex(mp_sint32 index)
466 {
467 	if (player)
468 		player->setPatternToPlay(index);
469 }
470 
stop(bool bResetMainVolume)471 void PlayerController::stop(bool bResetMainVolume/* = true*/)
472 {
473 	if (!player)
474 		return;
475 
476 	if (!module)
477 		return;
478 
479 	if (!suspended)
480 		criticalSection->enter(false);
481 
482 	if (isPlaying() && !playRowOnly)
483 	{
484 		lastPosition = player->getOrder();
485 		lastRow = player->getRow();
486 		wasPlayingPattern = isPlayingPattern();
487 	}
488 	else
489 	{
490 		lastPosition = -1;
491 		lastRow = -1;
492 		wasPlayingPattern = false;
493 	}
494 
495 	patternPlay = false;
496 	playRowOnly = false;
497 
498 	readjustSpeed();
499 
500 	player->setIdle(true);
501 	reset();
502 	player->restart(0, 0, true, panning);
503 
504 	// muting has been reset, restore it
505 	for (mp_sint32 i = 0; i < numPlayerChannels; i++)
506 	{
507 		player->muteChannel(i, muteChannels[i]);
508 		this->muteChannels[i] = muteChannels[i];
509 	}
510 
511 	// reset internal variables
512 	if (bResetMainVolume)
513 		resetMainVolume();
514 
515 	setNextOrderToPlay(-1);
516 	setNextPatternToPlay(-1);
517 
518 	criticalSection->leave(false);
519 }
520 
continuePlaying()521 void PlayerController::continuePlaying()
522 {
523 	continuePlaying(true);
524 }
525 
continuePlaying(bool assureNotSuspended)526 void PlayerController::continuePlaying(bool assureNotSuspended)
527 {
528 	if (lastPosition == -1 || lastRow == -1)
529 		return;
530 
531 	if (!player)
532 		return;
533 
534 	if (!module)
535 		return;
536 
537 	if (!module->isModuleLoaded())
538 		return;
539 
540 	if (assureNotSuspended)
541 		this->assureNotSuspended();
542 
543 	if (!suspended)
544 		criticalSection->enter(false);
545 
546 	readjustSpeed();
547 
548 	if (wasPlayingPattern)
549 		player->setPatternToPlay(patternIndex);
550 	else
551 		player->setPatternToPlay(-1);
552 
553 	for (mp_sint32 i = 0; i < numPlayerChannels; i++)
554 		player->muteChannel(i, muteChannels[i]);
555 
556 	player->restart(lastPosition, lastRow, false, panning);
557 	player->setIdle(false);
558 
559 	patternPlay = wasPlayingPattern;
560 	playRowOnly = false;
561 
562 	criticalSection->leave(false);
563 }
564 
restartPlaying()565 void PlayerController::restartPlaying()
566 {
567 	if (!player)
568 		return;
569 
570 	if (!module)
571 		return;
572 
573 	if (!module->isModuleLoaded())
574 		return;
575 
576 	lastPosition = lastRow = 0;
577 }
578 
isPlaying() const579 bool PlayerController::isPlaying() const
580 {
581 	if (!player)
582 		return false;
583 
584 	if (!module)
585 		return false;
586 
587 	return player->isPlaying() && (!player->isIdle()) && !player->hasSongHalted();
588 }
589 
isPlayingRowOnly() const590 bool PlayerController::isPlayingRowOnly() const
591 {
592 	if (!player)
593 		return false;
594 
595 	if (!module)
596 		return false;
597 
598 	return playRowOnly;
599 }
600 
isActive() const601 bool PlayerController::isActive() const
602 {
603 	if (!player)
604 		return false;
605 
606 	if (!module)
607 		return false;
608 
609 	return player->isPlaying() && (!player->isIdle());
610 }
611 
isPlayingPattern(mp_sint32 index) const612 bool PlayerController::isPlayingPattern(mp_sint32 index) const
613 {
614 	if (!player)
615 		return false;
616 
617 	if (index < 0)
618 		return false;
619 
620 	if (player->getPatternToPlay() < 0)
621 		return false;
622 
623 	return isPlayingPattern() && (player->getPatternToPlay() == index);
624 }
625 
setNextOrderToPlay(mp_sint32 orderIndex)626 void PlayerController::setNextOrderToPlay(mp_sint32 orderIndex)
627 {
628 	nextOrderIndexToPlay = orderIndex;
629 	if (orderIndex != -1)
630 		nextPatternIndexToPlay = -1;
631 }
632 
getNextOrderToPlay() const633 mp_sint32 PlayerController::getNextOrderToPlay() const
634 {
635 	return nextOrderIndexToPlay;
636 }
637 
setNextPatternToPlay(mp_sint32 patternIndex)638 void PlayerController::setNextPatternToPlay(mp_sint32 patternIndex)
639 {
640 	nextPatternIndexToPlay = patternIndex;
641 	if (patternIndex != -1)
642 		nextOrderIndexToPlay = -1;
643 }
644 
getNextPatternToPlay() const645 mp_sint32 PlayerController::getNextPatternToPlay() const
646 {
647 	return nextPatternIndexToPlay;
648 }
649 
pause()650 void PlayerController::pause()
651 {
652 	if (player)
653 		player->pausePlaying();
654 }
655 
unpause()656 void PlayerController::unpause()
657 {
658 	if (player)
659 		player->resumePlaying();
660 }
661 
isPaused() const662 bool PlayerController::isPaused() const
663 {
664 	if (player)
665 		return player->isPaused();
666 
667 	return false;
668 }
669 
getSpeed(mp_sint32 & BPM,mp_sint32 & speed)670 void PlayerController::getSpeed(mp_sint32& BPM, mp_sint32& speed)
671 {
672 	if (player && player->isPlaying())
673 	{
674 		BPM = player->getTempo();
675 		speed = player->getSpeed();
676 	}
677 	else if (module)
678 	{
679 		BPM = module->header.speed;
680 		speed = module->header.tempo;
681 	}
682 	else
683 	{
684 		BPM = 125;
685 		speed = 6;
686 	}
687 }
688 
setSpeed(mp_sint32 BPM,mp_sint32 speed,bool adjustModuleHeader)689 void PlayerController::setSpeed(mp_sint32 BPM, mp_sint32 speed, bool adjustModuleHeader/* = true*/)
690 {
691 	if (!player)
692 		return;
693 
694 	if (BPM < 32)
695 		BPM = 32;
696 	if (BPM > 255)
697 		BPM = 255;
698 
699 	if (speed < 1)
700 		speed = 1;
701 	if (speed > 31)
702 		speed = 31;
703 
704 	if (player->isPlaying())
705 	{
706 		player->setTempo(BPM);
707 		player->setSpeed(speed);
708 		// this is a MUST!!!
709 		pp_uint32 bpmRate = player->getbpmrate(BPM);
710 		player->adder = bpmRate;
711 	}
712 
713 	if (module && adjustModuleHeader)
714 	{
715 		module->header.speed = BPM;
716 		module->header.tempo = speed;
717 	}
718 }
719 
readjustSpeed(bool adjustModuleHeader)720 void PlayerController::readjustSpeed(bool adjustModuleHeader/* = true*/)
721 {
722 	mp_sint32 speed, bpm;
723 	getSpeed(bpm, speed);
724 	setSpeed(bpm, speed, adjustModuleHeader);
725 }
726 
playSample(const TXMSample & smp,mp_sint32 currentSamplePlayNote,mp_sint32 rangeStart,mp_sint32 rangeEnd)727 void PlayerController::playSample(const TXMSample& smp, mp_sint32 currentSamplePlayNote, mp_sint32 rangeStart/* = -1*/, mp_sint32 rangeEnd/* = -1*/)
728 {
729 	if (!player)
730 		return;
731 
732 	assureNotSuspended();
733 
734 	if (player->isPlaying())
735 	{
736 		pp_int32 i = numPlayerChannels + numVirtualChannels + 1;
737 
738 		playerStatusTracker->playSample(i, smp, currentSamplePlayNote, rangeStart, rangeEnd);
739 	}
740 
741 }
742 
stopSample()743 void PlayerController::stopSample()
744 {
745 	if (!player)
746 		return;
747 
748 	if (player->isPlaying())
749 	{
750 		// doesn't seem to be a critical race condition
751 		pp_int32 i = numPlayerChannels + numVirtualChannels + 1;
752 
753 		player->stopSample(i);
754 
755 		player->chninfo[i].flags &= ~0x100; // CHANNEL_FLAGS_UPDATE_IGNORE
756 	}
757 
758 }
759 
stopInstrument(mp_sint32 insIndex)760 void PlayerController::stopInstrument(mp_sint32 insIndex)
761 {
762 	if (!player)
763 		return;
764 
765 	if (player->isPlaying())
766 	{
767 		// doesn't seem to be a critical race condition
768 		for (pp_int32 i = 0; i < numPlayerChannels + numVirtualChannels; i++)
769 		{
770 			if (player->chninfo[i].ins == insIndex)
771 			{
772 				player->stopSample(i);
773 				player->chninfo[i].flags &= ~0x100; // CHANNEL_FLAGS_UPDATE_IGNORE
774 			}
775 		}
776 	}
777 }
778 
playNote(mp_ubyte chn,mp_sint32 note,mp_sint32 i,mp_sint32 vol)779 void PlayerController::playNote(mp_ubyte chn, mp_sint32 note, mp_sint32 i, mp_sint32 vol/* = -1*/)
780 {
781 	if (!player)
782 		return;
783 
784 	assureNotSuspended();
785 
786 	// note playing goes synchronized in the playback callback
787 	playerStatusTracker->playNote(chn, note, i, vol);
788 }
789 
suspendPlayer(bool bResetMainVolume,bool stopPlaying)790 void PlayerController::suspendPlayer(bool bResetMainVolume/* = true*/, bool stopPlaying/* = true*/)
791 {
792 	if (!player || suspended || mixer->isDeviceRemoved(player))
793 		return;
794 
795 	mixer->pauseDevice(player);
796 	suspended = true;
797 
798 	if (stopPlaying)
799 	{
800 		stopSample();
801 		stop(bResetMainVolume);
802 	}
803 }
804 
resumePlayer(bool continuePlaying)805 void PlayerController::resumePlayer(bool continuePlaying)
806 {
807 	if (!player)
808 		return;
809 
810 	if (continuePlaying)
811 		this->continuePlaying(!suspended);
812 
813 	if (suspended)
814 	{
815 		mixer->resumeDevice(player);
816 		suspended = false;
817 	}
818 }
819 
muteChannel(mp_sint32 c,bool m)820 void PlayerController::muteChannel(mp_sint32 c, bool m)
821 {
822 	muteChannels[c] = m;
823 
824 	if (player)
825 		player->muteChannel(c, m);
826 }
827 
isChannelMuted(mp_sint32 c)828 bool PlayerController::isChannelMuted(mp_sint32 c)
829 {
830 	return muteChannels[c];
831 	// do not poll the state from the player it will be resetted when the
832 	// player stops playing of a song
833 	/*if (player)
834 	{
835 		if (!player->getPlayerInstance())
836 			return false;
837 
838 		return static_cast<PlayerSTD*>(player->getPlayerInstance())->isChannelMuted(c);
839 	}
840 
841 	return false;*/
842 }
843 
recordChannel(mp_sint32 c,bool m)844 void PlayerController::recordChannel(mp_sint32 c, bool m)
845 {
846 	recordChannels[c] = m;
847 }
848 
isChannelRecording(mp_sint32 c)849 bool PlayerController::isChannelRecording(mp_sint32 c)
850 {
851 	return recordChannels[c];
852 }
853 
reallocateChannels(mp_sint32 moduleChannels,mp_sint32 virtualChannels)854 void PlayerController::reallocateChannels(mp_sint32 moduleChannels/* = 32*/, mp_sint32 virtualChannels/* = 0*/)
855 {
856 
857     // channels might be changed, we need to make sure playing is stopped firstly
858     bool paused = false;
859     if (player && module) {
860         paused = player->isPaused();
861         stop(false);
862     }
863 
864 	numPlayerChannels = moduleChannels;
865 	numVirtualChannels = virtualChannels;
866     totalPlayerChannels = numPlayerChannels + (numVirtualChannels >= 0 ? numVirtualChannels : 0) + 2;
867 
868     if (player && module) {
869         // reattaching will cause the desired channels to be allocated
870         attachModuleEditor(moduleEditor);
871         if (paused)
872             player->pausePlaying();
873         continuePlaying();
874     }
875 }
876 
setUseVirtualChannels(bool bUseVirtualChannels)877 void PlayerController::setUseVirtualChannels(bool bUseVirtualChannels)
878 {
879 	useVirtualChannels = bUseVirtualChannels;
880 
881 	currentPlayingChannel = useVirtualChannels ? numPlayerChannels : 0;
882 }
883 
resetFirstPlayingChannel()884 void PlayerController::resetFirstPlayingChannel()
885 {
886 	for (pp_int32 i = 0; i < module->header.channum; i++)
887 	{
888 		if (recordChannels[i])
889 		{
890 			currentPlayingChannel = i;
891 			break;
892 		}
893 	}
894 }
895 
getNextPlayingChannel(mp_sint32 currentChannel)896 mp_sint32 PlayerController::getNextPlayingChannel(mp_sint32 currentChannel)
897 {
898 	// if we're using virtual channels for instrument playback
899 	// the virtual channels are located in the range
900 	// [numPlayerChannels .. numPlayerChannels + numVirtualChannels]
901 	if (useVirtualChannels)
902 	{
903 		if (currentPlayingChannel < numPlayerChannels)
904 			currentPlayingChannel = numPlayerChannels-1;
905 
906 		mp_sint32 res = currentPlayingChannel++;
907 
908 		if (currentPlayingChannel >= numPlayerChannels + numVirtualChannels)
909 			currentPlayingChannel = numPlayerChannels;
910 
911 		return res;
912 	}
913 	// if we're not using virtual channels for instrument playback
914 	// just use the module channels and cut notes which are playing
915 	else if (multiChannelKeyJazz)
916 	{
917 		mp_sint32 res = currentPlayingChannel/*++*/;
918 		//if (currentPlayingChannel >= module->header.channum)
919 		//	currentPlayingChannel = 0;
920 
921 		bool found = false;
922 		for (pp_int32 i = currentPlayingChannel+1; i < currentPlayingChannel + 1 + module->header.channum; i++)
923 		{
924 			pp_int32 c = i % module->header.channum;
925 			if (recordChannels[c])
926 			{
927 				currentPlayingChannel = c;
928 				found = true;
929 				break;
930 			}
931 		}
932 
933 		return found ? res : currentChannel;
934 	}
935 
936 	return currentChannel;
937 }
938 
initRecording()939 void PlayerController::initRecording()
940 {
941 	firstRecordChannelCall = true;
942 }
943 
getNextRecordingChannel(mp_sint32 currentChannel)944 mp_sint32 PlayerController::getNextRecordingChannel(mp_sint32 currentChannel)
945 {
946 	if (currentChannel < 0 || currentChannel >= TrackerConfig::MAXCHANNELS)
947 		return -1;
948 
949 	if (firstRecordChannelCall && recordChannels[currentChannel])
950 	{
951 		firstRecordChannelCall = false;
952 		return currentChannel;
953 	}
954 	else
955 	{
956 		for (pp_int32 i = currentChannel+1; i < currentChannel + 1 + module->header.channum; i++)
957 		{
958 			pp_int32 c = i % module->header.channum;
959 			if (recordChannels[c])
960 				return c;
961 		}
962 		//return (currentChannel+1)%module->header.channum;
963 	}
964 	return currentChannel;
965 }
966 
getSongMainVolume()967 mp_sint32 PlayerController::getSongMainVolume()
968 {
969 	if (!player || !module)
970 		return 255;
971 
972 	return player->getSongMainVolume();
973 }
974 
resetMainVolume()975 void PlayerController::resetMainVolume()
976 {
977 	if (!player || !module)
978 		return;
979 
980 	player->setSongMainVolume((mp_ubyte)module->header.mainvol);
981 }
982 
getPlayTime()983 mp_int64 PlayerController::getPlayTime()
984 {
985 	if (!player)
986 		return 0;
987 
988 	float freq = (float)player->getMixFrequency();
989 
990 	return (mp_int64)(player->getSampleCounter()/freq);
991 }
992 
resetPlayTimeCounter()993 void PlayerController::resetPlayTimeCounter()
994 {
995 	if (!player)
996 		return;
997 
998 	player->resetSampleCounter();
999 }
1000 
setPanning(mp_ubyte chn,mp_ubyte pan)1001 void PlayerController::setPanning(mp_ubyte chn, mp_ubyte pan)
1002 {
1003 	if (!player)
1004 		return;
1005 
1006 	panning[chn] = pan;
1007 
1008 	if (player && player->isPlaying())
1009 	{
1010 		for (mp_sint32 i = 0; i < TrackerConfig::numPlayerChannels; i++)
1011 			player->setPanning((mp_ubyte)i, panning[i]);
1012 	}
1013 }
1014 
getPosition(mp_sint32 & pos,mp_sint32 & row)1015 void PlayerController::getPosition(mp_sint32& pos, mp_sint32& row)
1016 {
1017 	mp_uint32 index = player->getBeatIndexFromSamplePos(getCurrentSamplePosition());
1018 	player->getPosition(pos, row, index);
1019 }
1020 
getPosition(mp_sint32 & order,mp_sint32 & row,mp_sint32 & ticker)1021 void PlayerController::getPosition(mp_sint32& order, mp_sint32& row, mp_sint32& ticker)
1022 {
1023 	mp_uint32 index = player->getBeatIndexFromSamplePos(getCurrentSamplePosition());
1024 	player->getPosition(order, row, ticker, index);
1025 }
1026 
setPatternPos(mp_sint32 pos,mp_sint32 row)1027 void PlayerController::setPatternPos(mp_sint32 pos, mp_sint32 row)
1028 {
1029 	player->setPatternPos(pos, row, false, false);
1030 }
1031 
switchPlayMode(PlayModes playMode,bool exactSwitch)1032 void PlayerController::switchPlayMode(PlayModes playMode, bool exactSwitch/* = true*/)
1033 {
1034 	if (!player)
1035 		return;
1036 
1037 	switch (playMode)
1038 	{
1039 		case PlayMode_ProTracker2:
1040 			if (exactSwitch)
1041 			{
1042 				player->enable(PlayerSTD::PlayModeOptionPanningE8x, false);
1043 				player->enable(PlayerSTD::PlayModeOptionPanning8xx, false);
1044 				player->enable(PlayerSTD::PlayModeOptionForcePTPitchLimit, true);
1045 			}
1046 			player->setPlayMode(PlayerBase::PlayMode_ProTracker2);
1047 			break;
1048 		case PlayMode_ProTracker3:
1049 			if (exactSwitch)
1050 			{
1051 				player->enable(PlayerSTD::PlayModeOptionPanningE8x, false);
1052 				player->enable(PlayerSTD::PlayModeOptionPanning8xx, false);
1053 				player->enable(PlayerSTD::PlayModeOptionForcePTPitchLimit, true);
1054 			}
1055 			player->setPlayMode(PlayerBase::PlayMode_ProTracker3);
1056 			break;
1057 		case PlayMode_FastTracker2:
1058 			if (exactSwitch)
1059 			{
1060 				player->enable(PlayerSTD::PlayModeOptionPanningE8x, false);
1061 				player->enable(PlayerSTD::PlayModeOptionPanning8xx, true);
1062 				player->enable(PlayerSTD::PlayModeOptionForcePTPitchLimit, false);
1063 			}
1064 			player->setPlayMode(PlayerBase::PlayMode_FastTracker2);
1065 			break;
1066 
1067 		default:
1068 			ASSERT(false);
1069 	}
1070 
1071 	//stop();
1072 	//continuePlaying();
1073 }
1074 
getPlayMode()1075 PlayerController::PlayModes PlayerController::getPlayMode()
1076 {
1077 	if (!player)
1078 		return PlayMode_Auto;
1079 
1080 	switch (player->getPlayMode())
1081 	{
1082 		case PlayerBase::PlayMode_ProTracker2:
1083 			return PlayMode_ProTracker2;
1084 		case PlayerBase::PlayMode_ProTracker3:
1085 			return PlayMode_ProTracker3;
1086 		case PlayerBase::PlayMode_FastTracker2:
1087 			return PlayMode_FastTracker2;
1088 		default:
1089 			ASSERT(false);
1090 	}
1091 
1092 	return PlayMode_Auto;
1093 }
1094 
enablePlayModeOption(PlayModeOptions option,bool b)1095 void PlayerController::enablePlayModeOption(PlayModeOptions option, bool b)
1096 {
1097 	switch (option)
1098 	{
1099 		case PlayModeOptionPanning8xx:
1100 			player->enable(PlayerSTD::PlayModeOptionPanning8xx, b);
1101 			break;
1102 		case PlayModeOptionPanningE8x:
1103 			player->enable(PlayerSTD::PlayModeOptionPanningE8x, b);
1104 			break;
1105 		case PlayModeOptionForcePTPitchLimit:
1106 			player->enable(PlayerSTD::PlayModeOptionForcePTPitchLimit, b);
1107 			break;
1108 		default:
1109 			ASSERT(false);
1110 	}
1111 }
1112 
isPlayModeOptionEnabled(PlayModeOptions option)1113 bool PlayerController::isPlayModeOptionEnabled(PlayModeOptions option)
1114 {
1115 	if (!player)
1116 		return false;
1117 
1118 	switch (option)
1119 	{
1120 		case PlayModeOptionPanning8xx:
1121 			return player->isEnabled(PlayerSTD::PlayModeOptionPanning8xx);
1122 		case PlayModeOptionPanningE8x:
1123 			return player->isEnabled(PlayerSTD::PlayModeOptionPanningE8x);
1124 		case PlayModeOptionForcePTPitchLimit:
1125 			return player->isEnabled(PlayerSTD::PlayModeOptionForcePTPitchLimit);
1126 		default:
1127 			ASSERT(false);
1128 			return false;
1129 	}
1130 }
1131 
getAllNumPlayingChannels()1132 mp_sint32 PlayerController::getAllNumPlayingChannels()
1133 {
1134 	if (!player)
1135 		return 0;
1136 
1137 	return player->mixerNumAllocatedChannels;
1138 }
1139 
getPlayerNumPlayingChannels()1140 mp_sint32 PlayerController::getPlayerNumPlayingChannels()
1141 {
1142 	if (!player)
1143 		return 0;
1144 
1145 	return player->initialNumChannels;
1146 }
1147 
getCurrentSamplePosition()1148 mp_sint32 PlayerController::getCurrentSamplePosition()
1149 {
1150 	if (mixer && mixer->getAudioDriver())
1151 		return mixer->getAudioDriver()->getBufferPos();
1152 
1153 	return 0;
1154 }
1155 
getCurrentBeatIndex()1156 mp_sint32 PlayerController::getCurrentBeatIndex()
1157 {
1158 	if (player)
1159 		return player->getBeatIndexFromSamplePos(getCurrentSamplePosition());
1160 
1161 	return 0;
1162 }
1163 
isSamplePlaying(const TXMSample & smp,mp_sint32 channel,mp_sint32 & pos,mp_sint32 & vol,mp_sint32 & pan)1164 bool PlayerController::isSamplePlaying(const TXMSample& smp, mp_sint32 channel, mp_sint32& pos, mp_sint32& vol, mp_sint32& pan)
1165 {
1166 	if (!player)
1167 		return false;
1168 
1169 	ChannelMixer* mixer = player;
1170 
1171 	// this rather critical
1172 	// maybe someday this entire decision should go into the
1173 	// player or mixer class itself, so I don't need to access it here
1174 	pp_int32 j = getCurrentBeatIndex();
1175 	pos = mixer->channel[channel].timeRecord[j].smppos;
1176 
1177 	// compare sample from sample editor against sample from current mixer channel
1178 	if (pos >= 0 &&
1179 		(void*)mixer->channel[channel].timeRecord[j].sample == (void*)smp.sample)
1180 	{
1181 		vol = (mixer->channel[channel].timeRecord[j].volPan & 0xFFFF) >> 1;
1182 		pan = (mixer->channel[channel].timeRecord[j].volPan) >> 16;
1183 		return true;
1184 	}
1185 
1186 	return false;
1187 }
1188 
isEnvelopePlaying(const TEnvelope & envelope,mp_sint32 envelopeType,mp_sint32 channel,mp_sint32 & pos)1189 bool PlayerController::isEnvelopePlaying(const TEnvelope& envelope, mp_sint32 envelopeType, mp_sint32 channel, mp_sint32& pos)
1190 {
1191 	if (!player)
1192 		return false;
1193 
1194 	ChannelMixer* mixer = player;
1195 
1196 	const PlayerSTD::TPrEnv* env = NULL;
1197 
1198 	switch (envelopeType)
1199 	{
1200 		case 0:
1201 			env = &player->chninfo[channel].venv;
1202 			break;
1203 		case 1:
1204 			env = &player->chninfo[channel].penv;
1205 			break;
1206 	}
1207 
1208 	pp_int32 j = getCurrentBeatIndex();
1209 	pos = env->timeRecord[j].pos;
1210 
1211 	if (env && env->timeRecord[j].envstruc && env->timeRecord[j].envstruc == &envelope)
1212 	{
1213 
1214 		if ((env->timeRecord[j].envstruc->num &&
1215 			 !(env->timeRecord[j].envstruc->type & 4) &&
1216 			 pos >= env->timeRecord[j].envstruc->env[env->timeRecord[j].envstruc->num-1][0]) ||
1217 			!(mixer->channel[channel].timeRecord[j].volPan & 0xFFFF))
1218 		{
1219 			pos = -1;
1220 		}
1221 
1222 		return true;
1223 	}
1224 
1225 	return false;
1226 }
1227 
isNotePlaying(mp_sint32 ins,mp_sint32 channel,mp_sint32 & note,bool & muted)1228 bool PlayerController::isNotePlaying(mp_sint32 ins, mp_sint32 channel, mp_sint32& note, bool& muted)
1229 {
1230 	if (!player)
1231 		return false;
1232 
1233 	const PlayerSTD::TModuleChannel* chnInf = &player->chninfo[channel];
1234 
1235 	if (player->channel[channel].flags&ChannelMixer::MP_SAMPLE_PLAY)
1236 	{
1237 		if (chnInf->ins == ins && chnInf->keyon && chnInf->note)
1238 		{
1239 			muted = (player->channel[channel].flags & ChannelMixer::MP_SAMPLE_MUTE) != 0;
1240 			note = chnInf->note;
1241 			return true;
1242 		}
1243 	}
1244 
1245 	return false;
1246 }
1247 
1248 #define FULLMIXER_8BIT_NORMAL_TEMP \
1249 	if (sample) { \
1250 		sd1 = ((mp_sbyte)sample[smppos])<<8; \
1251 		sd2 = ((mp_sbyte)sample[smppos+1])<<8; \
1252 		sd1 =((sd1<<12)+(smpposfrac>>4)*(sd2-sd1))>>12; \
1253 		y = (sd1*vol)>>9; \
1254 	} \
1255 	else { \
1256 		y = 0; \
1257  	} \
1258 	fetcher.fetchSampleData(y);
1259 
1260 #define FULLMIXER_16BIT_NORMAL_TEMP \
1261 	if (sample) { \
1262 		sd1 = ((mp_sword*)(sample))[smppos]; \
1263 		sd2 = ((mp_sword*)(sample))[smppos+1]; \
1264 		sd1 =((sd1<<12)+(smpposfrac>>4)*(sd2-sd1))>>12; \
1265 		y = (sd1*vol)>>9; \
1266 	} \
1267 	else { \
1268 		y = 0; \
1269  	} \
1270 	fetcher.fetchSampleData(y);
1271 
grabSampleData(mp_uint32 chnIndex,mp_sint32 count,mp_sint32 fMul,SampleDataFetcher & fetcher)1272 void PlayerController::grabSampleData(mp_uint32 chnIndex, mp_sint32 count, mp_sint32 fMul, SampleDataFetcher& fetcher)
1273 {
1274 	if (!player)
1275 		return;
1276 
1277 	if (mixerDataCache && (count * 2 > mixerDataCacheSize))
1278 	{
1279 		delete[] mixerDataCache;
1280 		mixerDataCacheSize = count * 2 * 2;
1281 		mixerDataCache = new mp_sint32[mixerDataCacheSize];
1282 	}
1283 
1284 	ChannelMixer* mixer = player;
1285 
1286 	ChannelMixer::TMixerChannel* chn = &mixer->channel[chnIndex];
1287 
1288 	pp_int32 j = getCurrentBeatIndex();
1289 
1290 	if (chn->flags & ChannelMixer::MP_SAMPLE_PLAY)
1291 	{
1292 		// this is critical
1293 		// it might be that the audio thread modifies the data as we are
1294 		// accessing it... So in the worst case we're getting a sample
1295 		// but the channel state data does belong to another sample already
1296 		// in that case we're displaying garbage...
1297 		// BUT it's important that we only access sample data
1298 		// within the range of the current sample we have
1299 		ChannelMixer::TMixerChannel channel;
1300 		channel.sample = chn->timeRecord[j].sample;
1301 
1302 		if (channel.sample == NULL)
1303 			goto resort;
1304 
1305 		channel.smplen = TXMSample::getSampleSizeInSamples((mp_ubyte*)channel.sample);
1306 		channel.flags = chn->timeRecord[j].flags;
1307 		channel.smppos = chn->timeRecord[j].smppos % channel.smplen;
1308 		channel.smpposfrac = chn->timeRecord[j].smpposfrac;
1309 		channel.smpadd = chn->timeRecord[j].smpadd;
1310 		channel.loopend = channel.loopendcopy = chn->timeRecord[j].loopend % (channel.smplen+1);
1311 		channel.loopstart = chn->timeRecord[j].loopstart % (channel.smplen+1);
1312 		if (channel.loopstart >= channel.loopend)
1313 			channel.flags &= ~3;
1314 		channel.vol = chn->timeRecord[j].volPan & 0xFFFF;
1315 		channel.pan = chn->timeRecord[j].volPan >> 16;
1316 		channel.fixedtimefrac = chn->timeRecord[j].fixedtimefrac;
1317 		channel.cutoff = ChannelMixer::MP_INVALID_VALUE;
1318 		channel.resonance = ChannelMixer::MP_INVALID_VALUE;
1319 //		channel.index = chnIndex; Uncomment this if you like crackly audio
1320 		// The scopes (which I assume is what this function is for) are currently
1321 		// using channel 33, to avoid interfering with playback
1322 
1323 		channel.smpadd = (channel.smpadd*fMul) / (!count ? 1 : count);
1324 		chn = &channel;
1325 
1326 		if (mixerDataCache && channel.smpadd <= 65536)
1327 		{
1328 			memset(mixerDataCache, 0, count*2*sizeof(mp_sint32));
1329 
1330 			channel.rsmpadd = (mp_sint32)((1.0 / channel.smpadd) * 65536.0);
1331 
1332 			// we only need the left channel as no panning is involved
1333 			channel.finalvoll = (channel.vol*128*256)<<6;
1334 			channel.finalvolr = 0;
1335 			channel.rampFromVolStepL = channel.rampFromVolStepR = 0;
1336 
1337 			player->getCurrentResampler()->addChannel(chn, mixerDataCache, count, count);
1338 
1339 			for (mp_sint32 i = 0; i < count; i++)
1340 				fetcher.fetchSampleData(mixerDataCache[i*2]);
1341 		}
1342 		else
1343 		{
1344 			pp_int32 vol = chn->vol;
1345 			mp_sint32 y;
1346 			FULLMIXER_TEMPLATE(FULLMIXER_8BIT_NORMAL_TEMP, FULLMIXER_16BIT_NORMAL_TEMP, 16, 0);
1347 		}
1348 	}
1349 	else
1350 	{
1351 resort:
1352 		for (mp_sint32 i = 0; i < count; i++)
1353 			fetcher.fetchSampleData(0);
1354 	}
1355 }
1356 
hasSampleData(mp_uint32 chnIndex)1357 bool PlayerController::hasSampleData(mp_uint32 chnIndex)
1358 {
1359 	if (!player)
1360 		return false;
1361 
1362 	ChannelMixer* mixer = player;
1363 
1364 	ChannelMixer::TMixerChannel* chn = &mixer->channel[chnIndex];
1365 
1366 	pp_int32 j = getCurrentBeatIndex();
1367 
1368 	return ((chn->timeRecord[j].flags & ChannelMixer::MP_SAMPLE_PLAY) && (chn->timeRecord[j].volPan & 0xFFFF));
1369 }
1370