/[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 1297 - (show annotations) (download)
Thu Aug 16 15:55:21 2007 UTC (16 years, 8 months ago) by iliev
File size: 8692 byte(s)
* bugfix: the active stream/voice count statistic was incorrect

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

  ViewVC Help
Powered by ViewVC