35 |
|
|
36 |
namespace LinuxSampler { |
namespace LinuxSampler { |
37 |
|
|
38 |
struct _private_data_t { |
struct EngineChannel::private_data_t { |
39 |
int iMute; |
int iMute; |
40 |
bool bSolo; |
bool bSolo; |
41 |
uint8_t uiMidiProgram; |
uint8_t uiMidiProgram; |
54 |
ListenerList<FxSendCountListener*> llFxSendCountListeners; |
ListenerList<FxSendCountListener*> llFxSendCountListeners; |
55 |
}; |
}; |
56 |
|
|
57 |
#define PTHIS ((_private_data_t*)pPrivateData) |
EngineChannel::EngineChannel() : p(new private_data_t) { |
58 |
|
p->iMute = 0; |
59 |
EngineChannel::EngineChannel() : pPrivateData(new _private_data_t) { |
p->bSolo = false; |
60 |
PTHIS->iMute = 0; |
p->uiMidiBankMsb = 0; |
61 |
PTHIS->bSolo = false; |
p->uiMidiBankLsb = 0; |
62 |
PTHIS->uiMidiBankMsb = 0; |
p->uiMidiProgram = 0; |
63 |
PTHIS->uiMidiBankLsb = 0; |
p->bProgramChangeReceived = |
64 |
PTHIS->uiMidiProgram = 0; |
p->bMidiBankMsbReceived = |
65 |
PTHIS->bProgramChangeReceived = |
p->bMidiBankLsbReceived = false; |
66 |
PTHIS->bMidiBankMsbReceived = |
p->iMidiInstrumentMap = NO_MIDI_INSTRUMENT_MAP; |
|
PTHIS->bMidiBankLsbReceived = false; |
|
|
PTHIS->iMidiInstrumentMap = NO_MIDI_INSTRUMENT_MAP; |
|
67 |
SetVoiceCount(0); |
SetVoiceCount(0); |
68 |
SetDiskStreamCount(0); |
SetDiskStreamCount(0); |
69 |
PTHIS->pSamplerChannel = NULL; |
p->pSamplerChannel = NULL; |
70 |
ResetMidiRpnController(); |
ResetMidiRpnController(); |
71 |
} |
} |
72 |
|
|
73 |
EngineChannel::~EngineChannel() { |
EngineChannel::~EngineChannel() { |
74 |
if (PTHIS) delete PTHIS; |
delete p; |
75 |
} |
} |
76 |
|
|
77 |
void EngineChannel::SetMute(int state) throw (Exception) { |
void EngineChannel::SetMute(int state) throw (Exception) { |
78 |
if (PTHIS->iMute == state) return; |
if (p->iMute == state) return; |
79 |
if (state < -1 || state > 1) |
if (state < -1 || state > 1) |
80 |
throw Exception("Invalid Mute state: " + ToString(state)); |
throw Exception("Invalid Mute state: " + ToString(state)); |
81 |
|
|
82 |
PTHIS->iMute = state; |
p->iMute = state; |
83 |
|
|
84 |
StatusChanged(true); |
StatusChanged(true); |
85 |
} |
} |
86 |
|
|
87 |
int EngineChannel::GetMute() { |
int EngineChannel::GetMute() { |
88 |
return PTHIS->iMute; |
return p->iMute; |
89 |
} |
} |
90 |
|
|
91 |
void EngineChannel::SetSolo(bool solo) { |
void EngineChannel::SetSolo(bool solo) { |
92 |
if (PTHIS->bSolo == solo) return; |
if (p->bSolo == solo) return; |
93 |
PTHIS->bSolo = solo; |
p->bSolo = solo; |
94 |
StatusChanged(true); |
StatusChanged(true); |
95 |
} |
} |
96 |
|
|
97 |
bool EngineChannel::GetSolo() { |
bool EngineChannel::GetSolo() { |
98 |
return PTHIS->bSolo; |
return p->bSolo; |
99 |
} |
} |
100 |
|
|
101 |
/* |
/* |
117 |
*/ |
*/ |
118 |
|
|
119 |
uint8_t EngineChannel::GetMidiProgram() { |
uint8_t EngineChannel::GetMidiProgram() { |
120 |
return PTHIS->uiMidiProgram; // AFAIK atomic on all systems |
return p->uiMidiProgram; // AFAIK atomic on all systems |
121 |
} |
} |
122 |
|
|
123 |
void EngineChannel::SetMidiProgram(uint8_t Program) { |
void EngineChannel::SetMidiProgram(uint8_t Program) { |
124 |
PTHIS->bProgramChangeReceived = true; |
p->bProgramChangeReceived = true; |
125 |
PTHIS->uiMidiProgram = Program; // AFAIK atomic on all systems |
p->uiMidiProgram = Program; // AFAIK atomic on all systems |
126 |
} |
} |
127 |
|
|
128 |
uint8_t EngineChannel::GetMidiBankMsb() { |
uint8_t EngineChannel::GetMidiBankMsb() { |
129 |
return (PTHIS->bMidiBankMsbReceived && PTHIS->bMidiBankLsbReceived) |
return (p->bMidiBankMsbReceived && p->bMidiBankLsbReceived) |
130 |
? PTHIS->uiMidiBankMsb : 0; |
? p->uiMidiBankMsb : 0; |
131 |
} |
} |
132 |
|
|
133 |
void EngineChannel::SetMidiBankMsb(uint8_t BankMSB) { |
void EngineChannel::SetMidiBankMsb(uint8_t BankMSB) { |
134 |
if (PTHIS->bProgramChangeReceived) { |
if (p->bProgramChangeReceived) { |
135 |
PTHIS->bProgramChangeReceived = |
p->bProgramChangeReceived = |
136 |
PTHIS->bMidiBankLsbReceived = false; |
p->bMidiBankLsbReceived = false; |
137 |
} |
} |
138 |
PTHIS->bMidiBankMsbReceived = true; |
p->bMidiBankMsbReceived = true; |
139 |
PTHIS->uiMidiBankMsb = BankMSB; // AFAIK atomic on all systems |
p->uiMidiBankMsb = BankMSB; // AFAIK atomic on all systems |
140 |
} |
} |
141 |
|
|
142 |
uint8_t EngineChannel::GetMidiBankLsb() { |
uint8_t EngineChannel::GetMidiBankLsb() { |
143 |
return (!PTHIS->bMidiBankMsbReceived && !PTHIS->bMidiBankLsbReceived) |
return (!p->bMidiBankMsbReceived && !p->bMidiBankLsbReceived) |
144 |
? 0 |
? 0 |
145 |
: (PTHIS->bMidiBankMsbReceived && !PTHIS->bMidiBankLsbReceived) |
: (p->bMidiBankMsbReceived && !p->bMidiBankLsbReceived) |
146 |
? PTHIS->uiMidiBankMsb |
? p->uiMidiBankMsb |
147 |
: PTHIS->uiMidiBankLsb; |
: p->uiMidiBankLsb; |
148 |
} |
} |
149 |
|
|
150 |
void EngineChannel::SetMidiBankLsb(uint8_t BankLSB) { |
void EngineChannel::SetMidiBankLsb(uint8_t BankLSB) { |
151 |
if (PTHIS->bProgramChangeReceived) { |
if (p->bProgramChangeReceived) { |
152 |
PTHIS->bProgramChangeReceived = |
p->bProgramChangeReceived = |
153 |
PTHIS->bMidiBankMsbReceived = false; |
p->bMidiBankMsbReceived = false; |
154 |
} |
} |
155 |
PTHIS->bMidiBankLsbReceived = true; |
p->bMidiBankLsbReceived = true; |
156 |
PTHIS->uiMidiBankLsb = BankLSB; // AFAIK atomic on all systems |
p->uiMidiBankLsb = BankLSB; // AFAIK atomic on all systems |
157 |
} |
} |
158 |
|
|
159 |
bool EngineChannel::UsesNoMidiInstrumentMap() { |
bool EngineChannel::UsesNoMidiInstrumentMap() { |
160 |
return (PTHIS->iMidiInstrumentMap == NO_MIDI_INSTRUMENT_MAP); |
return (p->iMidiInstrumentMap == NO_MIDI_INSTRUMENT_MAP); |
161 |
} |
} |
162 |
|
|
163 |
bool EngineChannel::UsesDefaultMidiInstrumentMap() { |
bool EngineChannel::UsesDefaultMidiInstrumentMap() { |
164 |
return (PTHIS->iMidiInstrumentMap == DEFAULT_MIDI_INSTRUMENT_MAP); |
return (p->iMidiInstrumentMap == DEFAULT_MIDI_INSTRUMENT_MAP); |
165 |
} |
} |
166 |
|
|
167 |
int EngineChannel::GetMidiInstrumentMap() throw (Exception) { |
int EngineChannel::GetMidiInstrumentMap() throw (Exception) { |
171 |
throw Exception("EngineChannel is using default MIDI instrument map"); |
throw Exception("EngineChannel is using default MIDI instrument map"); |
172 |
// check if the stored map still exists in the MIDI instrument mapper |
// check if the stored map still exists in the MIDI instrument mapper |
173 |
std::vector<int> maps = MidiInstrumentMapper::Maps(); |
std::vector<int> maps = MidiInstrumentMapper::Maps(); |
174 |
if (find(maps.begin(), maps.end(), PTHIS->iMidiInstrumentMap) == maps.end()) { |
if (find(maps.begin(), maps.end(), p->iMidiInstrumentMap) == maps.end()) { |
175 |
// it doesn't exist anymore, so fall back to NONE and throw an exception |
// it doesn't exist anymore, so fall back to NONE and throw an exception |
176 |
PTHIS->iMidiInstrumentMap = NO_MIDI_INSTRUMENT_MAP; |
p->iMidiInstrumentMap = NO_MIDI_INSTRUMENT_MAP; |
177 |
throw Exception("Assigned MIDI instrument map doesn't exist anymore, falling back to NONE"); |
throw Exception("Assigned MIDI instrument map doesn't exist anymore, falling back to NONE"); |
178 |
} |
} |
179 |
return PTHIS->iMidiInstrumentMap; |
return p->iMidiInstrumentMap; |
180 |
} |
} |
181 |
|
|
182 |
void EngineChannel::SetMidiInstrumentMapToNone() { |
void EngineChannel::SetMidiInstrumentMapToNone() { |
183 |
if (PTHIS->iMidiInstrumentMap == NO_MIDI_INSTRUMENT_MAP) return; |
if (p->iMidiInstrumentMap == NO_MIDI_INSTRUMENT_MAP) return; |
184 |
PTHIS->iMidiInstrumentMap = NO_MIDI_INSTRUMENT_MAP; |
p->iMidiInstrumentMap = NO_MIDI_INSTRUMENT_MAP; |
185 |
StatusChanged(true); |
StatusChanged(true); |
186 |
} |
} |
187 |
|
|
188 |
void EngineChannel::SetMidiInstrumentMapToDefault() { |
void EngineChannel::SetMidiInstrumentMapToDefault() { |
189 |
if (PTHIS->iMidiInstrumentMap == DEFAULT_MIDI_INSTRUMENT_MAP) return; |
if (p->iMidiInstrumentMap == DEFAULT_MIDI_INSTRUMENT_MAP) return; |
190 |
PTHIS->iMidiInstrumentMap = DEFAULT_MIDI_INSTRUMENT_MAP; |
p->iMidiInstrumentMap = DEFAULT_MIDI_INSTRUMENT_MAP; |
191 |
StatusChanged(true); |
StatusChanged(true); |
192 |
} |
} |
193 |
|
|
194 |
void EngineChannel::SetMidiInstrumentMap(int MidiMap) throw (Exception) { |
void EngineChannel::SetMidiInstrumentMap(int MidiMap) throw (Exception) { |
195 |
if (PTHIS->iMidiInstrumentMap == MidiMap) return; |
if (p->iMidiInstrumentMap == MidiMap) return; |
196 |
|
|
197 |
// check if given map actually exists in the MIDI instrument mapper |
// check if given map actually exists in the MIDI instrument mapper |
198 |
std::vector<int> maps = MidiInstrumentMapper::Maps(); |
std::vector<int> maps = MidiInstrumentMapper::Maps(); |
199 |
if (find(maps.begin(), maps.end(), MidiMap) == maps.end()) |
if (find(maps.begin(), maps.end(), MidiMap) == maps.end()) |
200 |
throw Exception("MIDI instrument map doesn't exist"); |
throw Exception("MIDI instrument map doesn't exist"); |
201 |
PTHIS->iMidiInstrumentMap = MidiMap; // assign the new map ID |
p->iMidiInstrumentMap = MidiMap; // assign the new map ID |
202 |
StatusChanged(true); |
StatusChanged(true); |
203 |
} |
} |
204 |
|
|
205 |
void EngineChannel::SetMidiRpnControllerMsb(uint8_t CtrlMSB) { |
void EngineChannel::SetMidiRpnControllerMsb(uint8_t CtrlMSB) { |
206 |
PTHIS->uiMidiRpnMsb = CtrlMSB; |
p->uiMidiRpnMsb = CtrlMSB; |
207 |
PTHIS->bMidiRpnReceived = true; |
p->bMidiRpnReceived = true; |
208 |
} |
} |
209 |
|
|
210 |
void EngineChannel::SetMidiRpnControllerLsb(uint8_t CtrlLSB) { |
void EngineChannel::SetMidiRpnControllerLsb(uint8_t CtrlLSB) { |
211 |
PTHIS->uiMidiRpnLsb = CtrlLSB; |
p->uiMidiRpnLsb = CtrlLSB; |
212 |
PTHIS->bMidiRpnReceived = true; |
p->bMidiRpnReceived = true; |
213 |
} |
} |
214 |
|
|
215 |
void EngineChannel::ResetMidiRpnController() { |
void EngineChannel::ResetMidiRpnController() { |
216 |
PTHIS->uiMidiRpnMsb = PTHIS->uiMidiRpnLsb = 0; |
p->uiMidiRpnMsb = p->uiMidiRpnLsb = 0; |
217 |
PTHIS->bMidiRpnReceived = false; |
p->bMidiRpnReceived = false; |
218 |
} |
} |
219 |
|
|
220 |
int EngineChannel::GetMidiRpnController() { |
int EngineChannel::GetMidiRpnController() { |
221 |
return (PTHIS->bMidiRpnReceived) ? |
return (p->bMidiRpnReceived) ? |
222 |
(PTHIS->uiMidiRpnMsb << 8) | PTHIS->uiMidiRpnLsb : -1; |
(p->uiMidiRpnMsb << 8) | p->uiMidiRpnLsb : -1; |
223 |
} |
} |
224 |
|
|
225 |
uint EngineChannel::GetVoiceCount() { |
uint EngineChannel::GetVoiceCount() { |
226 |
return atomic_read(&PTHIS->voiceCount); |
return atomic_read(&p->voiceCount); |
227 |
} |
} |
228 |
|
|
229 |
void EngineChannel::SetVoiceCount(uint Voices) { |
void EngineChannel::SetVoiceCount(uint Voices) { |
230 |
atomic_set(&PTHIS->voiceCount, Voices); |
atomic_set(&p->voiceCount, Voices); |
231 |
} |
} |
232 |
|
|
233 |
uint EngineChannel::GetDiskStreamCount() { |
uint EngineChannel::GetDiskStreamCount() { |
234 |
return atomic_read(&PTHIS->diskStreamCount); |
return atomic_read(&p->diskStreamCount); |
235 |
} |
} |
236 |
|
|
237 |
void EngineChannel::SetDiskStreamCount(uint Streams) { |
void EngineChannel::SetDiskStreamCount(uint Streams) { |
238 |
atomic_set(&PTHIS->diskStreamCount, Streams); |
atomic_set(&p->diskStreamCount, Streams); |
239 |
} |
} |
240 |
|
|
241 |
SamplerChannel* EngineChannel::GetSamplerChannel() { |
SamplerChannel* EngineChannel::GetSamplerChannel() { |
242 |
if (PTHIS->pSamplerChannel == NULL) { |
if (p->pSamplerChannel == NULL) { |
243 |
std::cerr << "EngineChannel::GetSamplerChannel(): pSamplerChannel is NULL, this is a bug!\n" << std::flush; |
std::cerr << "EngineChannel::GetSamplerChannel(): pSamplerChannel is NULL, this is a bug!\n" << std::flush; |
244 |
} |
} |
245 |
return PTHIS->pSamplerChannel; |
return p->pSamplerChannel; |
246 |
} |
} |
247 |
|
|
248 |
void EngineChannel::SetSamplerChannel(SamplerChannel* pChannel) { |
void EngineChannel::SetSamplerChannel(SamplerChannel* pChannel) { |
249 |
PTHIS->pSamplerChannel = pChannel; |
p->pSamplerChannel = pChannel; |
250 |
} |
} |
251 |
|
|
252 |
Sampler* EngineChannel::GetSampler() { |
Sampler* EngineChannel::GetSampler() { |
255 |
} |
} |
256 |
|
|
257 |
void EngineChannel::AddFxSendCountListener(FxSendCountListener* l) { |
void EngineChannel::AddFxSendCountListener(FxSendCountListener* l) { |
258 |
PTHIS->llFxSendCountListeners.AddListener(l); |
p->llFxSendCountListeners.AddListener(l); |
259 |
} |
} |
260 |
|
|
261 |
void EngineChannel::RemoveFxSendCountListener(FxSendCountListener* l) { |
void EngineChannel::RemoveFxSendCountListener(FxSendCountListener* l) { |
262 |
PTHIS->llFxSendCountListeners.RemoveListener(l); |
p->llFxSendCountListeners.RemoveListener(l); |
263 |
} |
} |
264 |
|
|
265 |
void EngineChannel::RemoveAllFxSendCountListeners() { |
void EngineChannel::RemoveAllFxSendCountListeners() { |
266 |
PTHIS->llFxSendCountListeners.RemoveAllListeners(); |
p->llFxSendCountListeners.RemoveAllListeners(); |
267 |
} |
} |
268 |
|
|
269 |
void EngineChannel::fireFxSendCountChanged(int ChannelId, int NewCount) { |
void EngineChannel::fireFxSendCountChanged(int ChannelId, int NewCount) { |
270 |
for (int i = 0; i < PTHIS->llFxSendCountListeners.GetListenerCount(); i++) { |
for (int i = 0; i < p->llFxSendCountListeners.GetListenerCount(); i++) { |
271 |
PTHIS->llFxSendCountListeners.GetListener(i)->FxSendCountChanged(ChannelId, NewCount); |
p->llFxSendCountListeners.GetListener(i)->FxSendCountChanged(ChannelId, NewCount); |
272 |
} |
} |
273 |
} |
} |
274 |
|
|