/[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 973 by schoenebeck, Fri Dec 15 21:40:27 2006 UTC revision 1879 by schoenebeck, Sun Mar 29 18:43:40 2009 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, 2006 Christian Schoenebeck                        *   *   Copyright (C) 2005 - 2009 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 25  Line 25 
25    
26  #include <algorithm>  #include <algorithm>
27    
28    #include "../Sampler.h"
29    #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 _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            bool    bMidiBankMsbReceived;
47            bool    bMidiBankLsbReceived;
48            bool    bProgramChangeReceived;
49            bool    bMidiRpnReceived;
50            int     iMidiInstrumentMap;
51            atomic_t voiceCount;
52            atomic_t diskStreamCount;
53            SamplerChannel* pSamplerChannel;
54            ListenerList<FxSendCountListener*> llFxSendCountListeners;
55        };
56    
57        #define PTHIS ((_private_data_t*)pPrivateData)
58    
59        EngineChannel::EngineChannel() : pPrivateData(new _private_data_t) {
60            PTHIS->iMute = 0;
61            PTHIS->bSolo = false;
62            PTHIS->uiMidiBankMsb = 0;
63            PTHIS->uiMidiBankLsb = 0;
64            PTHIS->uiMidiProgram = 0;
65            PTHIS->bProgramChangeReceived =
66            PTHIS->bMidiBankMsbReceived =
67            PTHIS->bMidiBankLsbReceived = false;
68            PTHIS->iMidiInstrumentMap = NO_MIDI_INSTRUMENT_MAP;
69            SetVoiceCount(0);
70            SetDiskStreamCount(0);
71            PTHIS->pSamplerChannel = NULL;
72            ResetMidiRpnController();
73        }
74    
75        EngineChannel::~EngineChannel() {
76            if (PTHIS) delete PTHIS;
77      }      }
78    
79      void EngineChannel::SetMute(int state) throw (Exception) {      void EngineChannel::SetMute(int state) throw (Exception) {
80          if(iMute == state) return;          if (PTHIS->iMute == state) return;
81          if(state < -1 || state > 1)          if (state < -1 || state > 1)
82              throw Exception("Invalid Mute state: " + ToString(state));              throw Exception("Invalid Mute state: " + ToString(state));
83    
84          iMute = state;          PTHIS->iMute = state;
85    
86          StatusChanged(true);          StatusChanged(true);
87      }      }
88    
89      int EngineChannel::GetMute() {      int EngineChannel::GetMute() {
90          return iMute;          return PTHIS->iMute;
91      }      }
92    
93      void EngineChannel::SetSolo(bool solo) {      void EngineChannel::SetSolo(bool solo) {
94          if(bSolo == solo) return;          if (PTHIS->bSolo == solo) return;
95          bSolo = solo;          PTHIS->bSolo = solo;
96          StatusChanged(true);          StatusChanged(true);
97      }      }
98    
99      bool EngineChannel::GetSolo() {      bool EngineChannel::GetSolo() {
100          return bSolo;          return PTHIS->bSolo;
101      }      }
102    
103      /*      /*
# Line 85  namespace LinuxSampler { Line 119  namespace LinuxSampler {
119      */      */
120    
121      uint8_t EngineChannel::GetMidiProgram() {      uint8_t EngineChannel::GetMidiProgram() {
122          return uiMidiProgram; // AFAIK atomic on all systems          return PTHIS->uiMidiProgram; // AFAIK atomic on all systems
123      }      }
124    
125      void EngineChannel::SetMidiProgram(uint8_t Program) {      void EngineChannel::SetMidiProgram(uint8_t Program) {
126          bProgramChangeReceived = true;          PTHIS->bProgramChangeReceived = true;
127          uiMidiProgram = Program; // AFAIK atomic on all systems          PTHIS->uiMidiProgram = Program; // AFAIK atomic on all systems
128      }      }
129    
130      uint8_t EngineChannel::GetMidiBankMsb() {      uint8_t EngineChannel::GetMidiBankMsb() {
131          return (bMidiBankMsbReceived && bMidiBankLsbReceived) ? uiMidiBankMsb : 0;          return (PTHIS->bMidiBankMsbReceived && PTHIS->bMidiBankLsbReceived)
132                ? PTHIS->uiMidiBankMsb : 0;
133      }      }
134    
135      void EngineChannel::SetMidiBankMsb(uint8_t BankMSB) {      void EngineChannel::SetMidiBankMsb(uint8_t BankMSB) {
136          if (bProgramChangeReceived)          if (PTHIS->bProgramChangeReceived) {
137              bProgramChangeReceived = bMidiBankLsbReceived = false;              PTHIS->bProgramChangeReceived =
138          bMidiBankMsbReceived = true;              PTHIS->bMidiBankLsbReceived = false;
139          uiMidiBankMsb = BankMSB; // AFAIK atomic on all systems          }
140            PTHIS->bMidiBankMsbReceived = true;
141            PTHIS->uiMidiBankMsb = BankMSB; // AFAIK atomic on all systems
142      }      }
143    
144      uint8_t EngineChannel::GetMidiBankLsb() {      uint8_t EngineChannel::GetMidiBankLsb() {
145          return (!bMidiBankMsbReceived && !bMidiBankLsbReceived)          return (!PTHIS->bMidiBankMsbReceived && !PTHIS->bMidiBankLsbReceived)
146                     ? 0                     ? 0
147                     : (bMidiBankMsbReceived && !bMidiBankLsbReceived)                     : (PTHIS->bMidiBankMsbReceived && !PTHIS->bMidiBankLsbReceived)
148                           ? uiMidiBankMsb                           ? PTHIS->uiMidiBankMsb
149                           : uiMidiBankLsb;                           : PTHIS->uiMidiBankLsb;
150      }      }
151    
152      void EngineChannel::SetMidiBankLsb(uint8_t BankLSB) {      void EngineChannel::SetMidiBankLsb(uint8_t BankLSB) {
153          if (bProgramChangeReceived)          if (PTHIS->bProgramChangeReceived) {
154              bProgramChangeReceived = bMidiBankMsbReceived = false;              PTHIS->bProgramChangeReceived =
155          bMidiBankLsbReceived = true;              PTHIS->bMidiBankMsbReceived = false;
156          uiMidiBankLsb = BankLSB; // AFAIK atomic on all systems          }
157            PTHIS->bMidiBankLsbReceived = true;
158            PTHIS->uiMidiBankLsb = BankLSB; // AFAIK atomic on all systems
159      }      }
160    
161      bool EngineChannel::UsesNoMidiInstrumentMap() {      bool EngineChannel::UsesNoMidiInstrumentMap() {
162          return (iMidiInstrumentMap == NO_MIDI_INSTRUMENT_MAP);          return (PTHIS->iMidiInstrumentMap == NO_MIDI_INSTRUMENT_MAP);
163      }      }
164    
165      bool EngineChannel::UsesDefaultMidiInstrumentMap() {      bool EngineChannel::UsesDefaultMidiInstrumentMap() {
166          return (iMidiInstrumentMap == DEFAULT_MIDI_INSTRUMENT_MAP);          return (PTHIS->iMidiInstrumentMap == DEFAULT_MIDI_INSTRUMENT_MAP);
167      }      }
168    
169      int EngineChannel::GetMidiInstrumentMap() throw (Exception) {      int EngineChannel::GetMidiInstrumentMap() throw (Exception) {
# Line 134  namespace LinuxSampler { Line 173  namespace LinuxSampler {
173              throw Exception("EngineChannel is using default MIDI instrument map");              throw Exception("EngineChannel is using default MIDI instrument map");
174          // check if the stored map still exists in the MIDI instrument mapper          // check if the stored map still exists in the MIDI instrument mapper
175          std::vector<int> maps = MidiInstrumentMapper::Maps();          std::vector<int> maps = MidiInstrumentMapper::Maps();
176          if (find(maps.begin(), maps.end(), iMidiInstrumentMap) == maps.end()) {          if (find(maps.begin(), maps.end(), PTHIS->iMidiInstrumentMap) == maps.end()) {
177              // 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
178              iMidiInstrumentMap = NO_MIDI_INSTRUMENT_MAP;              PTHIS->iMidiInstrumentMap = NO_MIDI_INSTRUMENT_MAP;
179              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");
180          }          }
181          return iMidiInstrumentMap;          return PTHIS->iMidiInstrumentMap;
182      }      }
183    
184      void EngineChannel::SetMidiInstrumentMapToNone() {      void EngineChannel::SetMidiInstrumentMapToNone() {
185          iMidiInstrumentMap = NO_MIDI_INSTRUMENT_MAP;          if (PTHIS->iMidiInstrumentMap == NO_MIDI_INSTRUMENT_MAP) return;
186            PTHIS->iMidiInstrumentMap = NO_MIDI_INSTRUMENT_MAP;
187            StatusChanged(true);
188      }      }
189    
190      void EngineChannel::SetMidiInstrumentMapToDefault() {      void EngineChannel::SetMidiInstrumentMapToDefault() {
191          iMidiInstrumentMap = DEFAULT_MIDI_INSTRUMENT_MAP;          if (PTHIS->iMidiInstrumentMap == DEFAULT_MIDI_INSTRUMENT_MAP) return;
192            PTHIS->iMidiInstrumentMap = DEFAULT_MIDI_INSTRUMENT_MAP;
193            StatusChanged(true);
194      }      }
195    
196      void EngineChannel::SetMidiInstrumentMap(int MidiMap) throw (Exception) {      void EngineChannel::SetMidiInstrumentMap(int MidiMap) throw (Exception) {
197            if (PTHIS->iMidiInstrumentMap == MidiMap) return;
198    
199          // check if given map actually exists in the MIDI instrument mapper          // check if given map actually exists in the MIDI instrument mapper
200          std::vector<int> maps = MidiInstrumentMapper::Maps();          std::vector<int> maps = MidiInstrumentMapper::Maps();
201          if (find(maps.begin(), maps.end(), MidiMap) == maps.end())          if (find(maps.begin(), maps.end(), MidiMap) == maps.end())
202              throw Exception("MIDI instrument map doesn't exist");              throw Exception("MIDI instrument map doesn't exist");
203          iMidiInstrumentMap = MidiMap; // assign the new map ID          PTHIS->iMidiInstrumentMap = MidiMap; // assign the new map ID
204            StatusChanged(true);
205        }
206    
207        void EngineChannel::SetMidiRpnControllerMsb(uint8_t CtrlMSB) {
208            PTHIS->uiMidiRpnMsb = CtrlMSB;
209            PTHIS->bMidiRpnReceived = true;
210        }
211    
212        void EngineChannel::SetMidiRpnControllerLsb(uint8_t CtrlLSB) {
213            PTHIS->uiMidiRpnLsb = CtrlLSB;
214            PTHIS->bMidiRpnReceived = true;
215        }
216    
217        void EngineChannel::ResetMidiRpnController() {
218            PTHIS->uiMidiRpnMsb = PTHIS->uiMidiRpnLsb = 0;
219            PTHIS->bMidiRpnReceived = false;
220        }
221    
222        int EngineChannel::GetMidiRpnController() {
223            return (PTHIS->bMidiRpnReceived) ?
224                   (PTHIS->uiMidiRpnMsb << 8) | PTHIS->uiMidiRpnLsb : -1;
225        }
226    
227        uint EngineChannel::GetVoiceCount() {
228            return atomic_read(&PTHIS->voiceCount);
229        }
230    
231        void EngineChannel::SetVoiceCount(uint Voices) {
232            atomic_set(&PTHIS->voiceCount, Voices);
233        }
234    
235        uint EngineChannel::GetDiskStreamCount() {
236            return atomic_read(&PTHIS->diskStreamCount);
237        }
238    
239        void EngineChannel::SetDiskStreamCount(uint Streams) {
240            atomic_set(&PTHIS->diskStreamCount, Streams);
241        }
242    
243        SamplerChannel* EngineChannel::GetSamplerChannel() {
244            if (PTHIS->pSamplerChannel == NULL) {
245                std::cerr << "EngineChannel::GetSamplerChannel(): pSamplerChannel is NULL, this is a bug!\n" << std::flush;
246            }
247            return PTHIS->pSamplerChannel;
248        }
249    
250        void EngineChannel::SetSamplerChannel(SamplerChannel* pChannel) {
251            PTHIS->pSamplerChannel = pChannel;
252        }
253    
254        Sampler* EngineChannel::GetSampler() {
255            if (GetSamplerChannel() == NULL) return NULL;
256            return GetSamplerChannel()->GetSampler();
257        }
258    
259        void EngineChannel::AddFxSendCountListener(FxSendCountListener* l) {
260            PTHIS->llFxSendCountListeners.AddListener(l);
261        }
262    
263        void EngineChannel::RemoveFxSendCountListener(FxSendCountListener* l) {
264            PTHIS->llFxSendCountListeners.RemoveListener(l);
265        }
266    
267        void EngineChannel::RemoveAllFxSendCountListeners() {
268            PTHIS->llFxSendCountListeners.RemoveAllListeners();
269        }
270    
271        void EngineChannel::fireFxSendCountChanged(int ChannelId, int NewCount) {
272            for (int i = 0; i < PTHIS->llFxSendCountListeners.GetListenerCount(); i++) {
273                PTHIS->llFxSendCountListeners.GetListener(i)->FxSendCountChanged(ChannelId, NewCount);
274            }
275      }      }
276    
277  } // namespace LinuxSampler  } // namespace LinuxSampler

Legend:
Removed from v.973  
changed lines
  Added in v.1879

  ViewVC Help
Powered by ViewVC