/[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 1130 - (show annotations) (download)
Sun Mar 25 18:59:14 2007 UTC (17 years, 1 month ago) by iliev
File size: 7991 byte(s)
* Implemented new, improved notification system

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 iMidiInstrumentMap = NO_MIDI_INSTRUMENT_MAP;
148 }
149
150 void EngineChannel::SetMidiInstrumentMapToDefault() {
151 iMidiInstrumentMap = DEFAULT_MIDI_INSTRUMENT_MAP;
152 }
153
154 void EngineChannel::SetMidiInstrumentMap(int MidiMap) throw (Exception) {
155 // check if given map actually exists in the MIDI instrument mapper
156 std::vector<int> maps = MidiInstrumentMapper::Maps();
157 if (find(maps.begin(), maps.end(), MidiMap) == maps.end())
158 throw Exception("MIDI instrument map doesn't exist");
159 iMidiInstrumentMap = MidiMap; // assign the new map ID
160 }
161
162 void EngineChannel::SetMidiRpnControllerMsb(uint8_t CtrlMSB) {
163 uiMidiRpnMsb = CtrlMSB;
164 bMidiRpnReceived = true;
165 }
166
167 void EngineChannel::SetMidiRpnControllerLsb(uint8_t CtrlLSB) {
168 uiMidiRpnLsb = CtrlLSB;
169 bMidiRpnReceived = true;
170 }
171
172 void EngineChannel::ResetMidiRpnController() {
173 uiMidiRpnMsb = uiMidiRpnLsb = 0;
174 bMidiRpnReceived = false;
175 }
176
177 int EngineChannel::GetMidiRpnController() {
178 return (bMidiRpnReceived) ? (uiMidiRpnMsb << 8) | uiMidiRpnLsb : -1;
179 }
180
181 void EngineChannel::AddFxSendCountListener(FxSendCountListener* l) {
182 llFxSendCountListeners.AddListener(l);
183 }
184
185 void EngineChannel::RemoveFxSendCountListener(FxSendCountListener* l) {
186 llFxSendCountListeners.RemoveListener(l);
187 }
188
189 void EngineChannel::RemoveAllFxSendCountListeners() {
190 llFxSendCountListeners.RemoveAllListeners();
191 }
192
193 void EngineChannel::fireFxSendCountChanged(int ChannelId, int NewCount) {
194 for (int i = 0; i < llFxSendCountListeners.GetListenerCount(); i++) {
195 llFxSendCountListeners.GetListener(i)->FxSendCountChanged(ChannelId, NewCount);
196 }
197 }
198
199 } // namespace LinuxSampler

  ViewVC Help
Powered by ViewVC