/[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 1041 - (show annotations) (download)
Wed Feb 7 17:45:19 2007 UTC (17 years, 2 months ago) by schoenebeck
File size: 7130 byte(s)
* handle MIDI coarse tuning messages (MIDI RPN #0 MSB, #2 LSB),
  currently lazy implementation, transpose value is simply added on the
  note on/off values instead only at the mandatory places, thus when
  altering transpose while playing, voices can unintendedly survive

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 uiMidiRpnMsb = uiMidiRpnLsb = 0;
42 bProgramChangeReceived = bMidiBankMsbReceived = bMidiBankLsbReceived = false;
43 iMidiInstrumentMap = NO_MIDI_INSTRUMENT_MAP;
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 }
165
166 void EngineChannel::SetMidiRpnControllerLsb(uint8_t CtrlLSB) {
167 uiMidiRpnLsb = CtrlLSB;
168 }
169
170 int EngineChannel::GetMidiRpnController() {
171 return (uiMidiRpnMsb << 8) | uiMidiRpnLsb;
172 }
173
174 } // namespace LinuxSampler

  ViewVC Help
Powered by ViewVC