1 /*
2 File: CAAUMIDIMapManager.cpp
3 Abstract: CAAUMIDIMapManager.h
4 Version: 1.1
5
6 Disclaimer: IMPORTANT: This Apple software is supplied to you by Apple
7 Inc. ("Apple") in consideration of your agreement to the following
8 terms, and your use, installation, modification or redistribution of
9 this Apple software constitutes acceptance of these terms. If you do
10 not agree with these terms, please do not use, install, modify or
11 redistribute this Apple software.
12
13 In consideration of your agreement to abide by the following terms, and
14 subject to these terms, Apple grants you a personal, non-exclusive
15 license, under Apple's copyrights in this original Apple software (the
16 "Apple Software"), to use, reproduce, modify and redistribute the Apple
17 Software, with or without modifications, in source and/or binary forms;
18 provided that if you redistribute the Apple Software in its entirety and
19 without modifications, you must retain this notice and the following
20 text and disclaimers in all such redistributions of the Apple Software.
21 Neither the name, trademarks, service marks or logos of Apple Inc. may
22 be used to endorse or promote products derived from the Apple Software
23 without specific prior written permission from Apple. Except as
24 expressly stated in this notice, no other rights or licenses, express or
25 implied, are granted by Apple herein, including but not limited to any
26 patent rights that may be infringed by your derivative works or by other
27 works in which the Apple Software may be incorporated.
28
29 The Apple Software is provided by Apple on an "AS IS" basis. APPLE
30 MAKES NO WARRANTIES, EXPRESS OR IMPLIED, INCLUDING WITHOUT LIMITATION
31 THE IMPLIED WARRANTIES OF NON-INFRINGEMENT, MERCHANTABILITY AND FITNESS
32 FOR A PARTICULAR PURPOSE, REGARDING THE APPLE SOFTWARE OR ITS USE AND
33 OPERATION ALONE OR IN COMBINATION WITH YOUR PRODUCTS.
34
35 IN NO EVENT SHALL APPLE BE LIABLE FOR ANY SPECIAL, INDIRECT, INCIDENTAL
36 OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
37 SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
38 INTERRUPTION) ARISING IN ANY WAY OUT OF THE USE, REPRODUCTION,
39 MODIFICATION AND/OR DISTRIBUTION OF THE APPLE SOFTWARE, HOWEVER CAUSED
40 AND WHETHER UNDER THEORY OF CONTRACT, TORT (INCLUDING NEGLIGENCE),
41 STRICT LIABILITY OR OTHERWISE, EVEN IF APPLE HAS BEEN ADVISED OF THE
42 POSSIBILITY OF SUCH DAMAGE.
43
44 Copyright (C) 2014 Apple Inc. All Rights Reserved.
45
46 */
47 #include "CAAUMIDIMapManager.h"
48 #include <AudioToolbox/AudioUnitUtilities.h>
49
CAAUMIDIMapManager()50 CAAUMIDIMapManager::CAAUMIDIMapManager()
51 {
52 hotMapping = false;
53 }
54
FillInMap(CAAUMIDIMap & map,AUBase & That)55 static void FillInMap (CAAUMIDIMap &map, AUBase &That)
56 {
57 AudioUnitParameterInfo info;
58 That.GetParameterInfo (map.mScope, map.mParameterID, info);
59
60 if (map.IsSubRange()) {
61 map.mMinValue = map.mSubRangeMin;
62 map.mMaxValue = map.mSubRangeMax;
63 } else {
64 map.mMinValue = info.minValue;
65 map.mMaxValue = info.maxValue;
66 }
67
68 map.mTransType = CAAUMIDIMap::GetTransformer(info.flags);
69 }
70
SortedInsertToParamaterMaps(AUParameterMIDIMapping * maps,UInt32 inNumMaps,AUBase & That)71 OSStatus CAAUMIDIMapManager::SortedInsertToParamaterMaps (AUParameterMIDIMapping *maps, UInt32 inNumMaps, AUBase &That)
72 {
73 for (unsigned int i = 0; i < inNumMaps; ++i)
74 {
75 CAAUMIDIMap map(maps[i]);
76
77 FillInMap (map, That);
78
79 int idx = FindParameterIndex (maps[i]);
80 if (idx > -1)
81 mParameterMaps.erase(mParameterMaps.begin() + idx);
82
83 // least disruptive place to put this is at the end
84 mParameterMaps.push_back(map);
85 }
86
87 std::sort(mParameterMaps.begin(), mParameterMaps.end(), CompareMIDIMap());
88
89 return noErr;
90 }
91
GetHotParameterMap(AUParameterMIDIMapping & outMap)92 void CAAUMIDIMapManager::GetHotParameterMap(AUParameterMIDIMapping &outMap )
93 {
94 outMap = mHotMap;
95 }
96
SortedRemoveFromParameterMaps(AUParameterMIDIMapping * maps,UInt32 inNumMaps,bool & outMapDidChange)97 void CAAUMIDIMapManager::SortedRemoveFromParameterMaps(AUParameterMIDIMapping *maps, UInt32 inNumMaps, bool &outMapDidChange)
98 {
99 if (hotMapping) {
100 hotMapping = false;
101 }
102
103 outMapDidChange = false;
104 for (unsigned int i = 0; i < inNumMaps; ++i) {
105 int idx = FindParameterIndex (maps[i]);
106 if (idx > -1) {
107 //mParameterMaps[idx].Print();
108 mParameterMaps.erase(mParameterMaps.begin() + idx);
109 outMapDidChange = true;
110 }
111 }
112 }
113
ReplaceAllMaps(AUParameterMIDIMapping * inMappings,UInt32 inNumMaps,AUBase & That)114 void CAAUMIDIMapManager::ReplaceAllMaps (AUParameterMIDIMapping* inMappings, UInt32 inNumMaps, AUBase &That)
115 {
116 mParameterMaps.clear();
117
118 for (unsigned int i = 0; i < inNumMaps; ++i) {
119 CAAUMIDIMap mapping(inMappings[i]);
120
121 FillInMap (mapping, That);
122 mParameterMaps.push_back (mapping);
123 }
124
125 std::sort(mParameterMaps.begin(),mParameterMaps.end(), CompareMIDIMap());
126 }
127
HandleHotMapping(UInt8 inStatus,UInt8 inChannel,UInt8 inData1,AUBase & That)128 bool CAAUMIDIMapManager::HandleHotMapping(UInt8 inStatus,
129 UInt8 inChannel,
130 UInt8 inData1,
131 AUBase &That)
132 { //used to set the hot map info
133
134 if (inStatus == 0xf0) return false;
135
136 if (!hotMapping) return false;
137 hotMapping = false;
138
139 mHotMap.mStatus = inStatus | inChannel;
140 mHotMap.mData1 = inData1;
141
142 SortedInsertToParamaterMaps (&mHotMap, 1, That);
143 return true;
144 }
145
146 #if DEBUG
147
Print()148 void CAAUMIDIMapManager::Print()
149 {
150 for ( ParameterMaps::iterator i = mParameterMaps.begin(); i < mParameterMaps.end(); ++i) {
151 CAAUMIDIMap* listmap = &(*i);
152 listmap->Print();
153 }
154 }
155
156 #endif // DEBUG
157
GetMaps(AUParameterMIDIMapping * maps)158 void CAAUMIDIMapManager::GetMaps(AUParameterMIDIMapping* maps)
159 {
160 int i = 0;
161 for ( ParameterMaps::iterator iter = mParameterMaps.begin(); iter < mParameterMaps.end(); ++iter, ++i) {
162 AUParameterMIDIMapping &listmap = (*iter);
163 maps[i] = listmap;
164 }
165 }
166
FindParameterIndex(AUParameterMIDIMapping & inMap)167 int CAAUMIDIMapManager::FindParameterIndex (AUParameterMIDIMapping &inMap)
168 {
169 //used to get back hot mapping and one at a time maps, for ui
170
171 int idx = 0;
172 for ( ParameterMaps::iterator i = mParameterMaps.begin(); i < mParameterMaps.end(); ++i) {
173 CAAUMIDIMap & listmap = (*i);
174 if ( (listmap.mParameterID == inMap.mParameterID) &&
175 (listmap.mScope == inMap.mScope) &&
176 (listmap.mElement == inMap.mElement) )
177 {
178 return idx;
179 }
180 idx++;
181 }
182 return -1;
183 }
184
FindParameterMapEventMatch(UInt8 inStatus,UInt8 inChannel,UInt8 inData1,UInt8 inData2,UInt32 inBufferOffset,AUBase & inAUBase)185 bool CAAUMIDIMapManager::FindParameterMapEventMatch( UInt8 inStatus,
186 UInt8 inChannel,
187 UInt8 inData1,
188 UInt8 inData2,
189 UInt32 inBufferOffset,
190 AUBase& inAUBase)
191 {
192 bool ret_value = false;
193
194 if (inStatus == 0x90 && !inData2)
195 inStatus = 0x80 | inChannel;
196
197 //used to test for midi matches once map is made
198 CAAUMIDIMap tempMap;
199 tempMap.mStatus = inStatus | inChannel;
200 tempMap.mData1 = inData1;
201
202 CompareMIDIMap compareObj;
203
204 AudioUnitEvent event;
205 event.mEventType = kAudioUnitEvent_ParameterValueChange;
206 event.mArgument.mParameter.mAudioUnit = inAUBase.GetComponentInstance();
207
208 ParameterMaps::iterator lower_iter =
209 std::lower_bound(mParameterMaps.begin(), mParameterMaps.end(), tempMap, compareObj);
210
211 while (lower_iter < mParameterMaps.end())
212 {
213 CAAUMIDIMap & map = (*lower_iter);
214 if (compareObj.Finish(map, tempMap))
215 break;
216
217 Float32 value;
218 if (map.MIDI_Matches(inChannel, inData1, inData2, value))
219 {
220 inAUBase.SetParameter ( map.mParameterID, map.mScope, map.mElement,
221 map.ParamValueFromMIDILinear(value), inBufferOffset);
222
223 event.mArgument.mParameter.mParameterID = map.mParameterID;
224 event.mArgument.mParameter.mScope = map.mScope;
225 event.mArgument.mParameter.mElement = map.mElement;
226
227 AUEventListenerNotify(NULL, NULL, &event);
228 ret_value = true;
229 }
230 ++lower_iter;
231 }
232 return ret_value;
233 }
234