/[svn]/linuxsampler/trunk/src/engines/EngineChannel.cpp
ViewVC logotype

Contents of /linuxsampler/trunk/src/engines/EngineChannel.cpp

Parent Directory Parent Directory | Revision Log Revision Log


Revision 1761 - (show annotations) (download)
Fri Aug 29 15:42:06 2008 UTC (15 years, 7 months ago) by iliev
File size: 9321 byte(s)
* fixed a crash which occurs when removing a sampler channel waiting
  to start instrument loading after another channel

1 /***************************************************************************
2 * *
3 * LinuxSampler - modular, streaming capable sampler *
4 * *
5 * Copyright (C) 2003, 2004 by Benno Senoner and Christian Schoenebeck *
6 * Copyright (C) 2005 - 2007 Christian Schoenebeck *
7 * *
8 * This program 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 2 of the License, or *
11 * (at your option) any later version. *
12 * *
13 * This program 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 this program; if not, write to the Free Software *
20 * Foundation, Inc., 59 Temple Place, Suite 330, Boston, *
21 * MA 02111-1307 USA *
22 ***************************************************************************/
23
24 #include "EngineChannel.h"
25
26 #include <algorithm>
27
28 #include "../Sampler.h"
29 #include "../common/global_private.h"
30 #include "../drivers/midi/MidiInstrumentMapper.h"
31
32 #define NO_MIDI_INSTRUMENT_MAP -1
33 #define DEFAULT_MIDI_INSTRUMENT_MAP -2
34
35 namespace LinuxSampler {
36
37 EngineChannel::EngineChannel() {
38 iMute = 0;
39 bSolo = false;
40 uiMidiBankMsb = 0;
41 uiMidiBankLsb = 0;
42 uiMidiProgram = 0;
43 bProgramChangeReceived = bMidiBankMsbReceived = bMidiBankLsbReceived = false;
44 iMidiInstrumentMap = NO_MIDI_INSTRUMENT_MAP;
45 uiVoiceCount = 0;
46 uiDiskStreamCount = 0;
47 pSamplerChannel = NULL;
48 ResetMidiRpnController();
49 }
50
51 void EngineChannel::SetMute(int state) throw (Exception) {
52 if(iMute == state) return;
53 if(state < -1 || state > 1)
54 throw Exception("Invalid Mute state: " + ToString(state));
55
56 iMute = state;
57
58 StatusChanged(true);
59 }
60
61 int EngineChannel::GetMute() {
62 return iMute;
63 }
64
65 void EngineChannel::SetSolo(bool solo) {
66 if(bSolo == solo) return;
67 bSolo = solo;
68 StatusChanged(true);
69 }
70
71 bool EngineChannel::GetSolo() {
72 return bSolo;
73 }
74
75 /*
76 We use a workaround for MIDI devices (i.e. old keyboards) which either
77 only send bank select MSB or only bank select LSB messages. Bank
78 selects will be modified according to the following table:
79
80 MIDI Sequence received: -> GetMidiBankMsb()= | GetMidiBankLsb()=
81 ---------------------------------------------------------------------------
82 program change -> 0 | 0
83 bank LSB, program change -> 0 | LSB value
84 bank MSB, program change -> 0 | MSB value
85 bank LSB, bank MSB, program change -> MSB value | LSB value
86 bank MSB, bank LSB, program change -> MSB value | LSB value
87 ---------------------------------------------------------------------------
88
89 That way we ensure those limited devices always to switch between the
90 following set of MIDI instrument banks: { 0, 1, 2, ..., 127 }
91 */
92
93 uint8_t EngineChannel::GetMidiProgram() {
94 return uiMidiProgram; // AFAIK atomic on all systems
95 }
96
97 void EngineChannel::SetMidiProgram(uint8_t Program) {
98 bProgramChangeReceived = true;
99 uiMidiProgram = Program; // AFAIK atomic on all systems
100 }
101
102 uint8_t EngineChannel::GetMidiBankMsb() {
103 return (bMidiBankMsbReceived && bMidiBankLsbReceived) ? uiMidiBankMsb : 0;
104 }
105
106 void EngineChannel::SetMidiBankMsb(uint8_t BankMSB) {
107 if (bProgramChangeReceived)
108 bProgramChangeReceived = bMidiBankLsbReceived = false;
109 bMidiBankMsbReceived = true;
110 uiMidiBankMsb = BankMSB; // AFAIK atomic on all systems
111 }
112
113 uint8_t EngineChannel::GetMidiBankLsb() {
114 return (!bMidiBankMsbReceived && !bMidiBankLsbReceived)
115 ? 0
116 : (bMidiBankMsbReceived && !bMidiBankLsbReceived)
117 ? uiMidiBankMsb
118 : uiMidiBankLsb;
119 }
120
121 void EngineChannel::SetMidiBankLsb(uint8_t BankLSB) {
122 if (bProgramChangeReceived)
123 bProgramChangeReceived = bMidiBankMsbReceived = false;
124 bMidiBankLsbReceived = true;
125 uiMidiBankLsb = BankLSB; // AFAIK atomic on all systems
126 }
127
128 bool EngineChannel::UsesNoMidiInstrumentMap() {
129 return (iMidiInstrumentMap == NO_MIDI_INSTRUMENT_MAP);
130 }
131
132 bool EngineChannel::UsesDefaultMidiInstrumentMap() {
133 return (iMidiInstrumentMap == DEFAULT_MIDI_INSTRUMENT_MAP);
134 }
135
136 int EngineChannel::GetMidiInstrumentMap() throw (Exception) {
137 if (UsesNoMidiInstrumentMap())
138 throw Exception("EngineChannel is using no MIDI instrument map");
139 if (UsesDefaultMidiInstrumentMap())
140 throw Exception("EngineChannel is using default MIDI instrument map");
141 // check if the stored map still exists in the MIDI instrument mapper
142 std::vector<int> maps = MidiInstrumentMapper::Maps();
143 if (find(maps.begin(), maps.end(), iMidiInstrumentMap) == maps.end()) {
144 // it doesn't exist anymore, so fall back to NONE and throw an exception
145 iMidiInstrumentMap = NO_MIDI_INSTRUMENT_MAP;
146 throw Exception("Assigned MIDI instrument map doesn't exist anymore, falling back to NONE");
147 }
148 return iMidiInstrumentMap;
149 }
150
151 void EngineChannel::SetMidiInstrumentMapToNone() {
152 if (iMidiInstrumentMap == NO_MIDI_INSTRUMENT_MAP) return;
153 iMidiInstrumentMap = NO_MIDI_INSTRUMENT_MAP;
154 StatusChanged(true);
155 }
156
157 void EngineChannel::SetMidiInstrumentMapToDefault() {
158 if (iMidiInstrumentMap == DEFAULT_MIDI_INSTRUMENT_MAP) return;
159 iMidiInstrumentMap = DEFAULT_MIDI_INSTRUMENT_MAP;
160 StatusChanged(true);
161 }
162
163 void EngineChannel::SetMidiInstrumentMap(int MidiMap) throw (Exception) {
164 if (iMidiInstrumentMap == MidiMap) return;
165
166 // check if given map actually exists in the MIDI instrument mapper
167 std::vector<int> maps = MidiInstrumentMapper::Maps();
168 if (find(maps.begin(), maps.end(), MidiMap) == maps.end())
169 throw Exception("MIDI instrument map doesn't exist");
170 iMidiInstrumentMap = MidiMap; // assign the new map ID
171 StatusChanged(true);
172 }
173
174 void EngineChannel::SetMidiRpnControllerMsb(uint8_t CtrlMSB) {
175 uiMidiRpnMsb = CtrlMSB;
176 bMidiRpnReceived = true;
177 }
178
179 void EngineChannel::SetMidiRpnControllerLsb(uint8_t CtrlLSB) {
180 uiMidiRpnLsb = CtrlLSB;
181 bMidiRpnReceived = true;
182 }
183
184 void EngineChannel::ResetMidiRpnController() {
185 uiMidiRpnMsb = uiMidiRpnLsb = 0;
186 bMidiRpnReceived = false;
187 }
188
189 int EngineChannel::GetMidiRpnController() {
190 return (bMidiRpnReceived) ? (uiMidiRpnMsb << 8) | uiMidiRpnLsb : -1;
191 }
192
193 uint EngineChannel::GetVoiceCount() {
194 return uiVoiceCount;
195 }
196
197 void EngineChannel::SetVoiceCount(uint Voices) {
198 uiVoiceCount = Voices;
199 }
200
201 uint EngineChannel::GetDiskStreamCount() {
202 return uiDiskStreamCount;
203 }
204
205 void EngineChannel::SetDiskStreamCount(uint Streams) {
206 uiDiskStreamCount = Streams;
207 }
208
209 SamplerChannel* EngineChannel::GetSamplerChannel() {
210 if(pSamplerChannel == NULL) {
211 std::cerr << "EngineChannel::GetSamplerChannel(): pSamplerChannel is NULL, this is a bug!\n" << std::flush;
212 }
213 return pSamplerChannel;
214 }
215
216 void EngineChannel::SetSamplerChannel(SamplerChannel* pChannel) {
217 pSamplerChannel = pChannel;
218 }
219
220 Sampler* EngineChannel::GetSampler() {
221 if (GetSamplerChannel() == NULL) return NULL;
222 return GetSamplerChannel()->GetSampler();
223 }
224
225 void EngineChannel::AddFxSendCountListener(FxSendCountListener* l) {
226 llFxSendCountListeners.AddListener(l);
227 }
228
229 void EngineChannel::RemoveFxSendCountListener(FxSendCountListener* l) {
230 llFxSendCountListeners.RemoveListener(l);
231 }
232
233 void EngineChannel::RemoveAllFxSendCountListeners() {
234 llFxSendCountListeners.RemoveAllListeners();
235 }
236
237 void EngineChannel::fireFxSendCountChanged(int ChannelId, int NewCount) {
238 for (int i = 0; i < llFxSendCountListeners.GetListenerCount(); i++) {
239 llFxSendCountListeners.GetListener(i)->FxSendCountChanged(ChannelId, NewCount);
240 }
241 }
242
243 } // namespace LinuxSampler

  ViewVC Help
Powered by ViewVC