/[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 973 - (show annotations) (download)
Fri Dec 15 21:40:27 2006 UTC (17 years, 4 months ago) by schoenebeck
File size: 6771 byte(s)
* revised and extended MIDI instrument mapping feature to allow managing
  arbitrary amount of maps and assigning each sampler channel individually
  to one map (this commit batch includes LSCP spec document update and
  respective implementation on LS side)

1 /***************************************************************************
2 * *
3 * LinuxSampler - modular, streaming capable sampler *
4 * *
5 * Copyright (C) 2003, 2004 by Benno Senoner and Christian Schoenebeck *
6 * Copyright (C) 2005, 2006 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 }
44
45 void EngineChannel::SetMute(int state) throw (Exception) {
46 if(iMute == state) return;
47 if(state < -1 || state > 1)
48 throw Exception("Invalid Mute state: " + ToString(state));
49
50 iMute = state;
51
52 StatusChanged(true);
53 }
54
55 int EngineChannel::GetMute() {
56 return iMute;
57 }
58
59 void EngineChannel::SetSolo(bool solo) {
60 if(bSolo == solo) return;
61 bSolo = solo;
62 StatusChanged(true);
63 }
64
65 bool EngineChannel::GetSolo() {
66 return bSolo;
67 }
68
69 /*
70 We use a workaround for MIDI devices (i.e. old keyboards) which either
71 only send bank select MSB or only bank select LSB messages. Bank
72 selects will be modified according to the following table:
73
74 MIDI Sequence received: -> GetMidiBankMsb()= | GetMidiBankLsb()=
75 ---------------------------------------------------------------------------
76 program change -> 0 | 0
77 bank LSB, program change -> 0 | LSB value
78 bank MSB, program change -> 0 | MSB value
79 bank LSB, bank MSB, program change -> MSB value | LSB value
80 bank MSB, bank LSB, program change -> MSB value | LSB value
81 ---------------------------------------------------------------------------
82
83 That way we ensure those limited devices always to switch between the
84 following set of MIDI instrument banks: { 0, 1, 2, ..., 127 }
85 */
86
87 uint8_t EngineChannel::GetMidiProgram() {
88 return uiMidiProgram; // AFAIK atomic on all systems
89 }
90
91 void EngineChannel::SetMidiProgram(uint8_t Program) {
92 bProgramChangeReceived = true;
93 uiMidiProgram = Program; // AFAIK atomic on all systems
94 }
95
96 uint8_t EngineChannel::GetMidiBankMsb() {
97 return (bMidiBankMsbReceived && bMidiBankLsbReceived) ? uiMidiBankMsb : 0;
98 }
99
100 void EngineChannel::SetMidiBankMsb(uint8_t BankMSB) {
101 if (bProgramChangeReceived)
102 bProgramChangeReceived = bMidiBankLsbReceived = false;
103 bMidiBankMsbReceived = true;
104 uiMidiBankMsb = BankMSB; // AFAIK atomic on all systems
105 }
106
107 uint8_t EngineChannel::GetMidiBankLsb() {
108 return (!bMidiBankMsbReceived && !bMidiBankLsbReceived)
109 ? 0
110 : (bMidiBankMsbReceived && !bMidiBankLsbReceived)
111 ? uiMidiBankMsb
112 : uiMidiBankLsb;
113 }
114
115 void EngineChannel::SetMidiBankLsb(uint8_t BankLSB) {
116 if (bProgramChangeReceived)
117 bProgramChangeReceived = bMidiBankMsbReceived = false;
118 bMidiBankLsbReceived = true;
119 uiMidiBankLsb = BankLSB; // AFAIK atomic on all systems
120 }
121
122 bool EngineChannel::UsesNoMidiInstrumentMap() {
123 return (iMidiInstrumentMap == NO_MIDI_INSTRUMENT_MAP);
124 }
125
126 bool EngineChannel::UsesDefaultMidiInstrumentMap() {
127 return (iMidiInstrumentMap == DEFAULT_MIDI_INSTRUMENT_MAP);
128 }
129
130 int EngineChannel::GetMidiInstrumentMap() throw (Exception) {
131 if (UsesNoMidiInstrumentMap())
132 throw Exception("EngineChannel is using no MIDI instrument map");
133 if (UsesDefaultMidiInstrumentMap())
134 throw Exception("EngineChannel is using default MIDI instrument map");
135 // check if the stored map still exists in the MIDI instrument mapper
136 std::vector<int> maps = MidiInstrumentMapper::Maps();
137 if (find(maps.begin(), maps.end(), iMidiInstrumentMap) == maps.end()) {
138 // it doesn't exist anymore, so fall back to NONE and throw an exception
139 iMidiInstrumentMap = NO_MIDI_INSTRUMENT_MAP;
140 throw Exception("Assigned MIDI instrument map doesn't exist anymore, falling back to NONE");
141 }
142 return iMidiInstrumentMap;
143 }
144
145 void EngineChannel::SetMidiInstrumentMapToNone() {
146 iMidiInstrumentMap = NO_MIDI_INSTRUMENT_MAP;
147 }
148
149 void EngineChannel::SetMidiInstrumentMapToDefault() {
150 iMidiInstrumentMap = DEFAULT_MIDI_INSTRUMENT_MAP;
151 }
152
153 void EngineChannel::SetMidiInstrumentMap(int MidiMap) throw (Exception) {
154 // check if given map actually exists in the MIDI instrument mapper
155 std::vector<int> maps = MidiInstrumentMapper::Maps();
156 if (find(maps.begin(), maps.end(), MidiMap) == maps.end())
157 throw Exception("MIDI instrument map doesn't exist");
158 iMidiInstrumentMap = MidiMap; // assign the new map ID
159 }
160
161 } // namespace LinuxSampler

  ViewVC Help
Powered by ViewVC