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

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

Parent Directory Parent Directory | Revision Log Revision Log | View Patch Patch

revision 1789 by iliev, Sat Nov 1 19:01:27 2008 UTC revision 2121 by schoenebeck, Tue Sep 14 17:09:08 2010 UTC
# Line 3  Line 3 
3   *   LinuxSampler - modular, streaming capable sampler                     *   *   LinuxSampler - modular, streaming capable sampler                     *
4   *                                                                         *   *                                                                         *
5   *   Copyright (C) 2003, 2004 by Benno Senoner and Christian Schoenebeck   *   *   Copyright (C) 2003, 2004 by Benno Senoner and Christian Schoenebeck   *
6   *   Copyright (C) 2005 - 2007 Christian Schoenebeck                       *   *   Copyright (C) 2005 - 20010 Christian Schoenebeck                      *
7   *                                                                         *   *                                                                         *
8   *   This program is free software; you can redistribute it and/or modify  *   *   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  *   *   it under the terms of the GNU General Public License as published by  *
# Line 28  Line 28 
28  #include "../Sampler.h"  #include "../Sampler.h"
29  #include "../common/global_private.h"  #include "../common/global_private.h"
30  #include "../drivers/midi/MidiInstrumentMapper.h"  #include "../drivers/midi/MidiInstrumentMapper.h"
31    #include "../common/atomic.h"
32    
33  #define NO_MIDI_INSTRUMENT_MAP          -1  #define NO_MIDI_INSTRUMENT_MAP          -1
34  #define DEFAULT_MIDI_INSTRUMENT_MAP     -2  #define DEFAULT_MIDI_INSTRUMENT_MAP     -2
35    
36  namespace LinuxSampler {  namespace LinuxSampler {
37    
38      EngineChannel::EngineChannel() {      struct EngineChannel::private_data_t {
39          iMute = 0;          int     iMute;
40          bSolo = false;          bool    bSolo;
41          uiMidiBankMsb = 0;          uint8_t uiMidiProgram;
42          uiMidiBankLsb = 0;          uint8_t uiMidiBankMsb;
43          uiMidiProgram = 0;          uint8_t uiMidiBankLsb;
44          bProgramChangeReceived = bMidiBankMsbReceived = bMidiBankLsbReceived = false;          uint8_t uiMidiRpnMsb; ///< MIDI Registered Parameter Number (upper 8 bits / coarse)
45          iMidiInstrumentMap = NO_MIDI_INSTRUMENT_MAP;          uint8_t uiMidiRpnLsb; ///< MIDI Registered Parameter Number (lower 8 bits / fine)
46            uint8_t uiMidiNrpnMsb; ///< MIDI Non-Registered Parameter Number (upper 8 bits / coarse)
47            uint8_t uiMidiNrpnLsb; ///< MIDI Non-Registered Parameter Number (lower 8 bits / fine)
48            bool    bMidiBankMsbReceived;
49            bool    bMidiBankLsbReceived;
50            bool    bProgramChangeReceived;
51            bool    bMidiRpnReceived;
52            bool    bMidiNrpnReceived;
53            int     iMidiInstrumentMap;
54            atomic_t voiceCount;
55            atomic_t diskStreamCount;
56            SamplerChannel* pSamplerChannel;
57            ListenerList<FxSendCountListener*> llFxSendCountListeners;
58        };
59    
60        EngineChannel::EngineChannel() : p(new private_data_t) {
61            p->iMute = 0;
62            p->bSolo = false;
63            p->uiMidiBankMsb = 0;
64            p->uiMidiBankLsb = 0;
65            p->uiMidiProgram = 0;
66            p->bProgramChangeReceived =
67            p->bMidiBankMsbReceived =
68            p->bMidiBankLsbReceived = false;
69            p->iMidiInstrumentMap = NO_MIDI_INSTRUMENT_MAP;
70          SetVoiceCount(0);          SetVoiceCount(0);
71          SetDiskStreamCount(0);          SetDiskStreamCount(0);
72          pSamplerChannel = NULL;          p->pSamplerChannel = NULL;
73          ResetMidiRpnController();          ResetMidiRpnController();
74            ResetMidiNrpnController();
75        }
76    
77        EngineChannel::~EngineChannel() {
78            delete p;
79      }      }
80    
81      void EngineChannel::SetMute(int state) throw (Exception) {      void EngineChannel::SetMute(int state) throw (Exception) {
82          if(iMute == state) return;          if (p->iMute == state) return;
83          if(state < -1 || state > 1)          if (state < -1 || state > 1)
84              throw Exception("Invalid Mute state: " + ToString(state));              throw Exception("Invalid Mute state: " + ToString(state));
85    
86          iMute = state;          p->iMute = state;
87    
88          StatusChanged(true);          StatusChanged(true);
89      }      }
90    
91      int EngineChannel::GetMute() {      int EngineChannel::GetMute() {
92          return iMute;          return p->iMute;
93      }      }
94    
95      void EngineChannel::SetSolo(bool solo) {      void EngineChannel::SetSolo(bool solo) {
96          if(bSolo == solo) return;          if (p->bSolo == solo) return;
97          bSolo = solo;          p->bSolo = solo;
98          StatusChanged(true);          StatusChanged(true);
99      }      }
100    
101      bool EngineChannel::GetSolo() {      bool EngineChannel::GetSolo() {
102          return bSolo;          return p->bSolo;
103      }      }
104    
105      /*      /*
# Line 91  namespace LinuxSampler { Line 121  namespace LinuxSampler {
121      */      */
122    
123      uint8_t EngineChannel::GetMidiProgram() {      uint8_t EngineChannel::GetMidiProgram() {
124          return uiMidiProgram; // AFAIK atomic on all systems          return p->uiMidiProgram; // AFAIK atomic on all systems
125      }      }
126    
127      void EngineChannel::SetMidiProgram(uint8_t Program) {      void EngineChannel::SetMidiProgram(uint8_t Program) {
128          bProgramChangeReceived = true;          p->bProgramChangeReceived = true;
129          uiMidiProgram = Program; // AFAIK atomic on all systems          p->uiMidiProgram = Program; // AFAIK atomic on all systems
130      }      }
131    
132      uint8_t EngineChannel::GetMidiBankMsb() {      uint8_t EngineChannel::GetMidiBankMsb() {
133          return (bMidiBankMsbReceived && bMidiBankLsbReceived) ? uiMidiBankMsb : 0;          return (p->bMidiBankMsbReceived && p->bMidiBankLsbReceived)
134                ? p->uiMidiBankMsb : 0;
135      }      }
136    
137      void EngineChannel::SetMidiBankMsb(uint8_t BankMSB) {      void EngineChannel::SetMidiBankMsb(uint8_t BankMSB) {
138          if (bProgramChangeReceived)          if (p->bProgramChangeReceived) {
139              bProgramChangeReceived = bMidiBankLsbReceived = false;              p->bProgramChangeReceived =
140          bMidiBankMsbReceived = true;              p->bMidiBankLsbReceived = false;
141          uiMidiBankMsb = BankMSB; // AFAIK atomic on all systems          }
142            p->bMidiBankMsbReceived = true;
143            p->uiMidiBankMsb = BankMSB; // AFAIK atomic on all systems
144      }      }
145    
146      uint8_t EngineChannel::GetMidiBankLsb() {      uint8_t EngineChannel::GetMidiBankLsb() {
147          return (!bMidiBankMsbReceived && !bMidiBankLsbReceived)          return (!p->bMidiBankMsbReceived && !p->bMidiBankLsbReceived)
148                     ? 0                     ? 0
149                     : (bMidiBankMsbReceived && !bMidiBankLsbReceived)                     : (p->bMidiBankMsbReceived && !p->bMidiBankLsbReceived)
150                           ? uiMidiBankMsb                           ? p->uiMidiBankMsb
151                           : uiMidiBankLsb;                           : p->uiMidiBankLsb;
152      }      }
153    
154      void EngineChannel::SetMidiBankLsb(uint8_t BankLSB) {      void EngineChannel::SetMidiBankLsb(uint8_t BankLSB) {
155          if (bProgramChangeReceived)          if (p->bProgramChangeReceived) {
156              bProgramChangeReceived = bMidiBankMsbReceived = false;              p->bProgramChangeReceived =
157          bMidiBankLsbReceived = true;              p->bMidiBankMsbReceived = false;
158          uiMidiBankLsb = BankLSB; // AFAIK atomic on all systems          }
159            p->bMidiBankLsbReceived = true;
160            p->uiMidiBankLsb = BankLSB; // AFAIK atomic on all systems
161      }      }
162    
163      bool EngineChannel::UsesNoMidiInstrumentMap() {      bool EngineChannel::UsesNoMidiInstrumentMap() {
164          return (iMidiInstrumentMap == NO_MIDI_INSTRUMENT_MAP);          return (p->iMidiInstrumentMap == NO_MIDI_INSTRUMENT_MAP);
165      }      }
166    
167      bool EngineChannel::UsesDefaultMidiInstrumentMap() {      bool EngineChannel::UsesDefaultMidiInstrumentMap() {
168          return (iMidiInstrumentMap == DEFAULT_MIDI_INSTRUMENT_MAP);          return (p->iMidiInstrumentMap == DEFAULT_MIDI_INSTRUMENT_MAP);
169      }      }
170    
171      int EngineChannel::GetMidiInstrumentMap() throw (Exception) {      int EngineChannel::GetMidiInstrumentMap() throw (Exception) {
# Line 140  namespace LinuxSampler { Line 175  namespace LinuxSampler {
175              throw Exception("EngineChannel is using default MIDI instrument map");              throw Exception("EngineChannel is using default MIDI instrument map");
176          // check if the stored map still exists in the MIDI instrument mapper          // check if the stored map still exists in the MIDI instrument mapper
177          std::vector<int> maps = MidiInstrumentMapper::Maps();          std::vector<int> maps = MidiInstrumentMapper::Maps();
178          if (find(maps.begin(), maps.end(), iMidiInstrumentMap) == maps.end()) {          if (find(maps.begin(), maps.end(), p->iMidiInstrumentMap) == maps.end()) {
179              // it doesn't exist anymore, so fall back to NONE and throw an exception              // it doesn't exist anymore, so fall back to NONE and throw an exception
180              iMidiInstrumentMap = NO_MIDI_INSTRUMENT_MAP;              p->iMidiInstrumentMap = NO_MIDI_INSTRUMENT_MAP;
181              throw Exception("Assigned MIDI instrument map doesn't exist anymore, falling back to NONE");              throw Exception("Assigned MIDI instrument map doesn't exist anymore, falling back to NONE");
182          }          }
183          return iMidiInstrumentMap;          return p->iMidiInstrumentMap;
184      }      }
185    
186      void EngineChannel::SetMidiInstrumentMapToNone() {      void EngineChannel::SetMidiInstrumentMapToNone() {
187          if (iMidiInstrumentMap == NO_MIDI_INSTRUMENT_MAP) return;          if (p->iMidiInstrumentMap == NO_MIDI_INSTRUMENT_MAP) return;
188          iMidiInstrumentMap = NO_MIDI_INSTRUMENT_MAP;          p->iMidiInstrumentMap = NO_MIDI_INSTRUMENT_MAP;
189          StatusChanged(true);          StatusChanged(true);
190      }      }
191    
192      void EngineChannel::SetMidiInstrumentMapToDefault() {      void EngineChannel::SetMidiInstrumentMapToDefault() {
193          if (iMidiInstrumentMap == DEFAULT_MIDI_INSTRUMENT_MAP) return;          if (p->iMidiInstrumentMap == DEFAULT_MIDI_INSTRUMENT_MAP) return;
194          iMidiInstrumentMap = DEFAULT_MIDI_INSTRUMENT_MAP;          p->iMidiInstrumentMap = DEFAULT_MIDI_INSTRUMENT_MAP;
195          StatusChanged(true);          StatusChanged(true);
196      }      }
197    
198      void EngineChannel::SetMidiInstrumentMap(int MidiMap) throw (Exception) {      void EngineChannel::SetMidiInstrumentMap(int MidiMap) throw (Exception) {
199          if (iMidiInstrumentMap == MidiMap) return;          if (p->iMidiInstrumentMap == MidiMap) return;
200    
201          // check if given map actually exists in the MIDI instrument mapper          // check if given map actually exists in the MIDI instrument mapper
202          std::vector<int> maps = MidiInstrumentMapper::Maps();          std::vector<int> maps = MidiInstrumentMapper::Maps();
203          if (find(maps.begin(), maps.end(), MidiMap) == maps.end())          if (find(maps.begin(), maps.end(), MidiMap) == maps.end())
204              throw Exception("MIDI instrument map doesn't exist");              throw Exception("MIDI instrument map doesn't exist");
205          iMidiInstrumentMap = MidiMap; // assign the new map ID          p->iMidiInstrumentMap = MidiMap; // assign the new map ID
206          StatusChanged(true);          StatusChanged(true);
207      }      }
208    
209        // RPNs ...
210    
211      void EngineChannel::SetMidiRpnControllerMsb(uint8_t CtrlMSB) {      void EngineChannel::SetMidiRpnControllerMsb(uint8_t CtrlMSB) {
212          uiMidiRpnMsb = CtrlMSB;          p->uiMidiRpnMsb = CtrlMSB;
213          bMidiRpnReceived = true;          p->bMidiRpnReceived = true;
214      }      }
215    
216      void EngineChannel::SetMidiRpnControllerLsb(uint8_t CtrlLSB) {      void EngineChannel::SetMidiRpnControllerLsb(uint8_t CtrlLSB) {
217          uiMidiRpnLsb = CtrlLSB;          p->uiMidiRpnLsb = CtrlLSB;
218          bMidiRpnReceived = true;          p->bMidiRpnReceived = true;
219      }      }
220    
221      void EngineChannel::ResetMidiRpnController() {      void EngineChannel::ResetMidiRpnController() {
222          uiMidiRpnMsb = uiMidiRpnLsb = 0;          p->uiMidiRpnMsb = p->uiMidiRpnLsb = 0;
223          bMidiRpnReceived = false;          p->bMidiRpnReceived = false;
224      }      }
225    
226      int EngineChannel::GetMidiRpnController() {      int EngineChannel::GetMidiRpnController() {
227          return (bMidiRpnReceived) ? (uiMidiRpnMsb << 8) | uiMidiRpnLsb : -1;          return (p->bMidiRpnReceived) ?
228                   (p->uiMidiRpnMsb << 8) | p->uiMidiRpnLsb : -1;
229        }
230    
231        // NRPNs ...
232    
233        void EngineChannel::SetMidiNrpnControllerMsb(uint8_t CtrlMSB) {
234            p->uiMidiNrpnMsb = CtrlMSB;
235            p->bMidiNrpnReceived = true;
236        }
237    
238        void EngineChannel::SetMidiNrpnControllerLsb(uint8_t CtrlLSB) {
239            p->uiMidiNrpnLsb = CtrlLSB;
240            p->bMidiNrpnReceived = true;
241        }
242    
243        void EngineChannel::ResetMidiNrpnController() {
244            p->uiMidiNrpnMsb = p->uiMidiNrpnLsb = 0;
245            p->bMidiNrpnReceived = false;
246        }
247    
248        int EngineChannel::GetMidiNrpnController() {
249            return (p->bMidiNrpnReceived) ?
250                   (p->uiMidiNrpnMsb << 8) | p->uiMidiNrpnLsb : -1;
251      }      }
252    
253      uint EngineChannel::GetVoiceCount() {      uint EngineChannel::GetVoiceCount() {
254          return atomic_read(&voiceCount);          return atomic_read(&p->voiceCount);
255      }      }
256        
257      void EngineChannel::SetVoiceCount(uint Voices) {      void EngineChannel::SetVoiceCount(uint Voices) {
258          atomic_set(&voiceCount, Voices);          atomic_set(&p->voiceCount, Voices);
259      }      }
260    
261      uint EngineChannel::GetDiskStreamCount() {      uint EngineChannel::GetDiskStreamCount() {
262          return atomic_read(&diskStreamCount);          return atomic_read(&p->diskStreamCount);
263      }      }
264        
265      void EngineChannel::SetDiskStreamCount(uint Streams) {      void EngineChannel::SetDiskStreamCount(uint Streams) {
266          atomic_set(&diskStreamCount, Streams);          atomic_set(&p->diskStreamCount, Streams);
267      }      }
268        
269      SamplerChannel* EngineChannel::GetSamplerChannel() {      SamplerChannel* EngineChannel::GetSamplerChannel() {
270          if(pSamplerChannel == NULL) {          if (p->pSamplerChannel == NULL) {
271              std::cerr << "EngineChannel::GetSamplerChannel(): pSamplerChannel is NULL, this is a bug!\n" << std::flush;              std::cerr << "EngineChannel::GetSamplerChannel(): pSamplerChannel is NULL, this is a bug!\n" << std::flush;
272          }          }
273          return pSamplerChannel;          return p->pSamplerChannel;
274      }      }
275    
276      void EngineChannel::SetSamplerChannel(SamplerChannel* pChannel) {      void EngineChannel::SetSamplerChannel(SamplerChannel* pChannel) {
277          pSamplerChannel = pChannel;          p->pSamplerChannel = pChannel;
278      }      }
279    
280      Sampler* EngineChannel::GetSampler() {      Sampler* EngineChannel::GetSampler() {
# Line 223  namespace LinuxSampler { Line 283  namespace LinuxSampler {
283      }      }
284    
285      void EngineChannel::AddFxSendCountListener(FxSendCountListener* l) {      void EngineChannel::AddFxSendCountListener(FxSendCountListener* l) {
286          llFxSendCountListeners.AddListener(l);          p->llFxSendCountListeners.AddListener(l);
287      }      }
288    
289      void EngineChannel::RemoveFxSendCountListener(FxSendCountListener* l) {      void EngineChannel::RemoveFxSendCountListener(FxSendCountListener* l) {
290          llFxSendCountListeners.RemoveListener(l);          p->llFxSendCountListeners.RemoveListener(l);
291      }      }
292    
293      void EngineChannel::RemoveAllFxSendCountListeners() {      void EngineChannel::RemoveAllFxSendCountListeners() {
294          llFxSendCountListeners.RemoveAllListeners();          p->llFxSendCountListeners.RemoveAllListeners();
295      }      }
296    
297      void EngineChannel::fireFxSendCountChanged(int ChannelId, int NewCount) {      void EngineChannel::fireFxSendCountChanged(int ChannelId, int NewCount) {
298          for (int i = 0; i < llFxSendCountListeners.GetListenerCount(); i++) {          for (int i = 0; i < p->llFxSendCountListeners.GetListenerCount(); i++) {
299              llFxSendCountListeners.GetListener(i)->FxSendCountChanged(ChannelId, NewCount);              p->llFxSendCountListeners.GetListener(i)->FxSendCountChanged(ChannelId, NewCount);
300            }
301        }
302    
303        void EngineChannel::ExecuteProgramChange(uint8_t Program) {
304            dmsg(1,("Received MIDI program change (prog=%d)\n",Program));
305            std::vector<int> maps = MidiInstrumentMapper::Maps();
306            if (maps.empty()) return;
307    
308            SetMidiProgram(Program);
309            if (UsesNoMidiInstrumentMap()) return;
310            if (MidiInstrumentMapper::GetMapCount() == 0) return;
311            // retrieve the MIDI instrument map this engine channel is assigned to
312            int iMapID = (UsesDefaultMidiInstrumentMap())
313                ? MidiInstrumentMapper::GetDefaultMap() /*default*/ : GetMidiInstrumentMap();
314            // is there an entry for this MIDI bank&prog pair in that map?
315            midi_prog_index_t midiIndex;
316            midiIndex.midi_bank_msb = GetMidiBankMsb();
317            midiIndex.midi_bank_lsb = GetMidiBankLsb();
318            midiIndex.midi_prog     = GetMidiProgram();
319            optional<MidiInstrumentMapper::entry_t> mapping =
320                MidiInstrumentMapper::GetEntry(iMapID, midiIndex);
321            if (mapping) { // if mapping exists ...
322                InstrumentManager::instrument_id_t id;
323                id.FileName = mapping->InstrumentFile;
324                id.Index    = mapping->InstrumentIndex;
325                //TODO: we should switch the engine type here
326                InstrumentManager::LoadInstrumentInBackground(id, this);
327                Volume(mapping->Volume);
328          }          }
329      }      }
330    

Legend:
Removed from v.1789  
changed lines
  Added in v.2121

  ViewVC Help
Powered by ViewVC