5 |
* Copyright (C) 2003,2004 by Benno Senoner and Christian Schoenebeck * |
* Copyright (C) 2003,2004 by Benno Senoner and Christian Schoenebeck * |
6 |
* Copyright (C) 2005-2008 Christian Schoenebeck * |
* Copyright (C) 2005-2008 Christian Schoenebeck * |
7 |
* Copyright (C) 2009-2012 Christian Schoenebeck and Grigor Iliev * |
* Copyright (C) 2009-2012 Christian Schoenebeck and Grigor Iliev * |
8 |
* Copyright (C) 2012-2016 Christian Schoenebeck and Andreas Persson * |
* Copyright (C) 2012-2017 Christian Schoenebeck and Andreas Persson * |
9 |
* * |
* * |
10 |
* This program is free software; you can redistribute it and/or modify * |
* This program is free software; you can redistribute it and/or modify * |
11 |
* it under the terms of the GNU General Public License as published by * |
* it under the terms of the GNU General Public License as published by * |
52 |
template<class V> |
template<class V> |
53 |
class NotePool { |
class NotePool { |
54 |
public: |
public: |
55 |
|
/** |
56 |
|
* Pool from where Voice objects are allocated from (and freed back to). |
57 |
|
*/ |
58 |
virtual Pool<V>* GetVoicePool() = 0; |
virtual Pool<V>* GetVoicePool() = 0; |
59 |
|
|
60 |
|
/** |
61 |
|
* Pool from where new Note objects are allocated from (and freed back to). |
62 |
|
*/ |
63 |
virtual Pool< Note<V> >* GetNotePool() = 0; |
virtual Pool< Note<V> >* GetNotePool() = 0; |
64 |
virtual Pool<note_id_t>* GetNodeIDPool() = 0; |
|
65 |
|
/** |
66 |
|
* Pool for saving already existing Note object IDs somewhere. |
67 |
|
* |
68 |
|
* @b IMPORTANT: This pool is @b NOT used for generating any IDs for |
69 |
|
* Note objects! The respective Note objective IDs are emitted by |
70 |
|
* the Note object pool (see GetNotePool() above). |
71 |
|
*/ |
72 |
|
virtual Pool<note_id_t>* GetNoteIDPool() = 0; |
73 |
}; |
}; |
74 |
|
|
75 |
template <class V /* Voice */, class R /* Region */, class I /* Instrument */> |
template <class V /* Voice */, class R /* Region */, class I /* Instrument */> |
142 |
} |
} |
143 |
} |
} |
144 |
|
|
145 |
virtual void Connect(AudioOutputDevice* pAudioOut) { |
virtual void Connect(AudioOutputDevice* pAudioOut) OVERRIDE { |
146 |
if (pEngine) { |
if (pEngine) { |
147 |
if (pEngine->pAudioOutputDevice == pAudioOut) return; |
if (pEngine->pAudioOutputDevice == pAudioOut) return; |
148 |
DisconnectAudioOutputDevice(); |
DisconnectAudioOutputDevice(); |
204 |
MidiInputPort::AddSysexListener(pEngine); |
MidiInputPort::AddSysexListener(pEngine); |
205 |
} |
} |
206 |
|
|
207 |
virtual void DisconnectAudioOutputDevice() { |
virtual void DisconnectAudioOutputDevice() OVERRIDE { |
208 |
if (pEngine) { // if clause to prevent disconnect loops |
if (pEngine) { // if clause to prevent disconnect loops |
209 |
|
|
210 |
ResetInternal(false/*don't reset engine*/); // 'false' is error prone here, but the danger of recursion with 'true' would be worse, there could be a better solution though |
ResetInternal(false/*don't reset engine*/); // 'false' is error prone here, but the danger of recursion with 'true' would be worse, there could be a better solution though |
393 |
pEvents->free(itEvent); |
pEvents->free(itEvent); |
394 |
} |
} |
395 |
|
|
396 |
|
/** |
397 |
|
* Copies the note IDs of all currently active notes on this engine |
398 |
|
* channel to the note ID buffer @a dstBuf, and returns the amount |
399 |
|
* of note IDs that have been copied to the destination buffer. |
400 |
|
* |
401 |
|
* @param dstBuf - destination buffer for note IDs |
402 |
|
* @param bufSize - size of destination buffer (as amount of max. |
403 |
|
* note IDs, not as amount of bytes) |
404 |
|
* @returns amount of note IDs that have been copied to buffer |
405 |
|
*/ |
406 |
|
uint AllNoteIDs(note_id_t* dstBuf, uint bufSize) OVERRIDE { |
407 |
|
uint n = 0; |
408 |
|
|
409 |
|
Pool< Note<V> >* pNotePool = |
410 |
|
dynamic_cast<NotePool<V>*>(pEngine)->GetNotePool(); |
411 |
|
|
412 |
|
RTList<uint>::Iterator iuiKey = this->pActiveKeys->first(); |
413 |
|
RTList<uint>::Iterator end = this->pActiveKeys->end(); |
414 |
|
for(; iuiKey != end; ++iuiKey) { |
415 |
|
MidiKey* pKey = &this->pMIDIKeyInfo[*iuiKey]; |
416 |
|
NoteIterator itNote = pKey->pActiveNotes->first(); |
417 |
|
for (; itNote; ++itNote) { |
418 |
|
if (n >= bufSize) goto done; |
419 |
|
dstBuf[n++] = pNotePool->getID(itNote); |
420 |
|
} |
421 |
|
} |
422 |
|
done: |
423 |
|
return n; |
424 |
|
} |
425 |
|
|
426 |
RTList<R*>* pRegionsInUse; ///< temporary pointer into the instrument change command, used by the audio thread |
RTList<R*>* pRegionsInUse; ///< temporary pointer into the instrument change command, used by the audio thread |
427 |
I* pInstrument; |
I* pInstrument; |
428 |
|
|
483 |
EngineChannelBase<V, R, I>* pChannel; |
EngineChannelBase<V, R, I>* pChannel; |
484 |
|
|
485 |
RenderVoicesHandler(EngineChannelBase<V, R, I>* channel, uint samples) : |
RenderVoicesHandler(EngineChannelBase<V, R, I>* channel, uint samples) : |
486 |
pChannel(channel), Samples(samples), VoiceCount(0), StreamCount(0) { } |
Samples(samples), VoiceCount(0), StreamCount(0), pChannel(channel) { } |
487 |
|
|
488 |
virtual void Process(RTListVoiceIterator& itVoice) { |
virtual void Process(RTListVoiceIterator& itVoice) { |
489 |
// now render current voice |
// now render current voice |
516 |
MidiKeyboardManager<V>::Reset(); |
MidiKeyboardManager<V>::Reset(); |
517 |
} |
} |
518 |
|
|
519 |
virtual void ResetControllers() { |
virtual void ResetControllers() OVERRIDE { |
520 |
AbstractEngineChannel::ResetControllers(); |
AbstractEngineChannel::ResetControllers(); |
521 |
|
|
522 |
MidiKeyboardManager<V>::SustainPedal = false; |
MidiKeyboardManager<V>::SustainPedal = false; |