/[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 973 - (hide 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 schoenebeck 888 /***************************************************************************
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 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 888 }
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 schoenebeck 973 /*
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 schoenebeck 947 uint8_t EngineChannel::GetMidiProgram() {
88     return uiMidiProgram; // AFAIK atomic on all systems
89     }
90    
91     void EngineChannel::SetMidiProgram(uint8_t Program) {
92 schoenebeck 973 bProgramChangeReceived = true;
93 schoenebeck 947 uiMidiProgram = Program; // AFAIK atomic on all systems
94     }
95    
96     uint8_t EngineChannel::GetMidiBankMsb() {
97 schoenebeck 973 return (bMidiBankMsbReceived && bMidiBankLsbReceived) ? uiMidiBankMsb : 0;
98 schoenebeck 947 }
99    
100     void EngineChannel::SetMidiBankMsb(uint8_t BankMSB) {
101 schoenebeck 973 if (bProgramChangeReceived)
102     bProgramChangeReceived = bMidiBankLsbReceived = false;
103     bMidiBankMsbReceived = true;
104 schoenebeck 947 uiMidiBankMsb = BankMSB; // AFAIK atomic on all systems
105     }
106    
107     uint8_t EngineChannel::GetMidiBankLsb() {
108 schoenebeck 973 return (!bMidiBankMsbReceived && !bMidiBankLsbReceived)
109     ? 0
110     : (bMidiBankMsbReceived && !bMidiBankLsbReceived)
111     ? uiMidiBankMsb
112     : uiMidiBankLsb;
113 schoenebeck 947 }
114    
115     void EngineChannel::SetMidiBankLsb(uint8_t BankLSB) {
116 schoenebeck 973 if (bProgramChangeReceived)
117     bProgramChangeReceived = bMidiBankMsbReceived = false;
118     bMidiBankLsbReceived = true;
119 schoenebeck 947 uiMidiBankLsb = BankLSB; // AFAIK atomic on all systems
120     }
121    
122 schoenebeck 973 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 schoenebeck 888 } // namespace LinuxSampler

  ViewVC Help
Powered by ViewVC