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

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

Parent Directory Parent Directory | Revision Log Revision Log


Revision 1254 - (hide annotations) (download)
Sun Jun 24 20:02:56 2007 UTC (16 years, 9 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 schoenebeck 888 /***************************************************************************
2     * *
3     * LinuxSampler - modular, streaming capable sampler *
4     * *
5     * Copyright (C) 2003, 2004 by Benno Senoner and Christian Schoenebeck *
6 schoenebeck 1041 * Copyright (C) 2005 - 2007 Christian Schoenebeck *
7 schoenebeck 888 * *
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 schoenebeck 973 #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 schoenebeck 888 namespace LinuxSampler {
34    
35     EngineChannel::EngineChannel() {
36     iMute = 0;
37     bSolo = false;
38 schoenebeck 947 uiMidiBankMsb = 0;
39     uiMidiBankLsb = 0;
40     uiMidiProgram = 0;
41 schoenebeck 973 bProgramChangeReceived = bMidiBankMsbReceived = bMidiBankLsbReceived = false;
42     iMidiInstrumentMap = NO_MIDI_INSTRUMENT_MAP;
43 schoenebeck 1044 ResetMidiRpnController();
44 schoenebeck 888 }
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 schoenebeck 973 /*
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 schoenebeck 947 uint8_t EngineChannel::GetMidiProgram() {
89     return uiMidiProgram; // AFAIK atomic on all systems
90     }
91    
92     void EngineChannel::SetMidiProgram(uint8_t Program) {
93 schoenebeck 973 bProgramChangeReceived = true;
94 schoenebeck 947 uiMidiProgram = Program; // AFAIK atomic on all systems
95     }
96    
97     uint8_t EngineChannel::GetMidiBankMsb() {
98 schoenebeck 973 return (bMidiBankMsbReceived && bMidiBankLsbReceived) ? uiMidiBankMsb : 0;
99 schoenebeck 947 }
100    
101     void EngineChannel::SetMidiBankMsb(uint8_t BankMSB) {
102 schoenebeck 973 if (bProgramChangeReceived)
103     bProgramChangeReceived = bMidiBankLsbReceived = false;
104     bMidiBankMsbReceived = true;
105 schoenebeck 947 uiMidiBankMsb = BankMSB; // AFAIK atomic on all systems
106     }
107    
108     uint8_t EngineChannel::GetMidiBankLsb() {
109 schoenebeck 973 return (!bMidiBankMsbReceived && !bMidiBankLsbReceived)
110     ? 0
111     : (bMidiBankMsbReceived && !bMidiBankLsbReceived)
112     ? uiMidiBankMsb
113     : uiMidiBankLsb;
114 schoenebeck 947 }
115    
116     void EngineChannel::SetMidiBankLsb(uint8_t BankLSB) {
117 schoenebeck 973 if (bProgramChangeReceived)
118     bProgramChangeReceived = bMidiBankMsbReceived = false;
119     bMidiBankLsbReceived = true;
120 schoenebeck 947 uiMidiBankLsb = BankLSB; // AFAIK atomic on all systems
121     }
122    
123 schoenebeck 973 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 iliev 1254 if (iMidiInstrumentMap == NO_MIDI_INSTRUMENT_MAP) return;
148 schoenebeck 973 iMidiInstrumentMap = NO_MIDI_INSTRUMENT_MAP;
149 iliev 1254 StatusChanged(true);
150 schoenebeck 973 }
151    
152     void EngineChannel::SetMidiInstrumentMapToDefault() {
153 iliev 1254 if (iMidiInstrumentMap == DEFAULT_MIDI_INSTRUMENT_MAP) return;
154 schoenebeck 973 iMidiInstrumentMap = DEFAULT_MIDI_INSTRUMENT_MAP;
155 iliev 1254 StatusChanged(true);
156 schoenebeck 973 }
157    
158     void EngineChannel::SetMidiInstrumentMap(int MidiMap) throw (Exception) {
159 iliev 1254 if (iMidiInstrumentMap == MidiMap) return;
160    
161 schoenebeck 973 // 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 iliev 1254 StatusChanged(true);
167 schoenebeck 973 }
168    
169 schoenebeck 1041 void EngineChannel::SetMidiRpnControllerMsb(uint8_t CtrlMSB) {
170     uiMidiRpnMsb = CtrlMSB;
171 schoenebeck 1044 bMidiRpnReceived = true;
172 schoenebeck 1041 }
173    
174     void EngineChannel::SetMidiRpnControllerLsb(uint8_t CtrlLSB) {
175     uiMidiRpnLsb = CtrlLSB;
176 schoenebeck 1044 bMidiRpnReceived = true;
177 schoenebeck 1041 }
178    
179 schoenebeck 1044 void EngineChannel::ResetMidiRpnController() {
180     uiMidiRpnMsb = uiMidiRpnLsb = 0;
181     bMidiRpnReceived = false;
182     }
183    
184 schoenebeck 1041 int EngineChannel::GetMidiRpnController() {
185 schoenebeck 1044 return (bMidiRpnReceived) ? (uiMidiRpnMsb << 8) | uiMidiRpnLsb : -1;
186 schoenebeck 1041 }
187    
188 iliev 1130 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 schoenebeck 888 } // namespace LinuxSampler

  ViewVC Help
Powered by ViewVC