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

  ViewVC Help
Powered by ViewVC