41 #ifndef __CAAUMIDIMap_h_
42 #define __CAAUMIDIMap_h_
44 #include <AudioUnit/AudioUnitProperties.h>
193 struct MIDIValueTransformer {
194 virtual double tolinear(
double) = 0;
195 virtual double fromlinear(
double) = 0;
198 virtual ~MIDIValueTransformer() { }
202 struct MIDILinearTransformer :
public MIDIValueTransformer {
203 virtual double tolinear(
double x) {
return x; }
204 virtual double fromlinear(
double x) {
return x; }
207 struct MIDILogTransformer :
public MIDIValueTransformer {
208 virtual double tolinear(
double x) {
return log(std::max(x, .00001)); }
209 virtual double fromlinear(
double x) {
return exp(x); }
212 struct MIDIExpTransformer :
public MIDIValueTransformer {
213 virtual double tolinear(
double x) {
return exp(x); }
214 virtual double fromlinear(
double x) {
return log(std::max(x, .00001)); }
217 struct MIDISqrtTransformer :
public MIDIValueTransformer {
218 virtual double tolinear(
double x) {
return x < 0. ? -(sqrt(-x)) : sqrt(x); }
219 virtual double fromlinear(
double x) {
return x < 0. ? -(x * x) : x * x; }
222 struct MIDISquareTransformer :
public MIDIValueTransformer {
223 virtual double tolinear(
double x) {
return x < 0. ? -(x * x) : x * x; }
224 virtual double fromlinear(
double x) {
return x < 0. ? -(sqrt(-x)) : sqrt(x); }
227 struct MIDICubeRtTransformer :
public MIDIValueTransformer {
228 virtual double tolinear(
double x) {
return x < 0. ? -(pow(-x, 1./3.)) : pow(x, 1./3.); }
229 virtual double fromlinear(
double x) {
return x * x * x; }
232 struct MIDICubeTransformer :
public MIDIValueTransformer {
233 virtual double tolinear(
double x) {
return x * x * x; }
234 virtual double fromlinear(
double x) {
return x < 0. ? -(pow(-x, 1./3.)) : pow(x, 1./3.); }
238 class CAAUMIDIMap :
public AUParameterMIDIMapping {
244 MIDIValueTransformer *mTransType;
247 static MIDIValueTransformer *GetTransformer (UInt32 inFlags);
249 CAAUMIDIMap() { memset(
this, 0,
sizeof(CAAUMIDIMap)); }
250 CAAUMIDIMap (
const AUParameterMIDIMapping& inMap)
252 memset(
this, 0,
sizeof(CAAUMIDIMap));
253 memcpy (
this, &inMap,
sizeof(inMap));
255 CAAUMIDIMap (AudioUnitScope inScope, AudioUnitElement inElement, AudioUnitParameterID inParam)
257 memset(
this, 0,
sizeof(CAAUMIDIMap));
259 mElement = inElement;
260 mParameterID = inParam;
264 bool IsValid ()
const {
return mStatus != 0; }
267 SInt32 Channel ()
const {
return IsAnyChannel() ? -1 : (mStatus & 0xF); }
268 bool IsAnyChannel ()
const {
269 return mFlags & kAUParameterMIDIMapping_AnyChannelFlag;
273 void SetAnyChannel (
bool inFlag)
276 mFlags |= kAUParameterMIDIMapping_AnyChannelFlag;
278 mFlags &= ~kAUParameterMIDIMapping_AnyChannelFlag;
281 bool IsAnyNote ()
const {
282 return (mFlags & kAUParameterMIDIMapping_AnyNoteFlag) != 0;
286 void SetAnyNote (
bool inFlag)
289 mFlags |= kAUParameterMIDIMapping_AnyNoteFlag;
291 mFlags &= ~kAUParameterMIDIMapping_AnyNoteFlag;
294 bool IsToggle()
const {
return (mFlags & kAUParameterMIDIMapping_Toggle) != 0; }
295 void SetToggle (
bool inFlag)
298 mFlags |= kAUParameterMIDIMapping_Toggle;
300 mFlags &= ~kAUParameterMIDIMapping_Toggle;
303 bool IsBipolar()
const {
return (mFlags & kAUParameterMIDIMapping_Bipolar) != 0; }
305 void SetBipolar (
bool inFlag,
bool inUseOnValue =
false)
308 mFlags |= kAUParameterMIDIMapping_Bipolar;
310 mFlags |= kAUParameterMIDIMapping_Bipolar_On;
312 mFlags &= ~kAUParameterMIDIMapping_Bipolar_On;
314 mFlags &= ~kAUParameterMIDIMapping_Bipolar;
315 mFlags &= ~kAUParameterMIDIMapping_Bipolar_On;
318 bool IsBipolar_OnValue ()
const {
return (mFlags & kAUParameterMIDIMapping_Bipolar_On) != 0; }
320 bool IsSubRange ()
const {
return (mFlags & kAUParameterMIDIMapping_SubRange) != 0; }
321 void SetSubRange (Float32 inStartValue, Float32 inStopValue)
323 mFlags |= kAUParameterMIDIMapping_SubRange;
325 mSubRangeMin = inStartValue;
326 mSubRangeMax = inStopValue;
329 void SetParamRange(Float32 minValue, Float32 maxValue)
331 mMinValue = minValue;
332 mMaxValue = maxValue;
336 void SetSubRange (
bool inFlag)
339 mFlags |= kAUParameterMIDIMapping_SubRange;
341 mFlags &= ~kAUParameterMIDIMapping_SubRange;
344 bool IsAnyValue()
const{
return !IsBipolar();}
345 bool IsOnValue()
const{
return IsBipolar_OnValue();}
346 bool IsOffValue()
const{
return IsBipolar();}
348 bool IsNoteOff ()
const {
return ((mStatus & 0xF0) == 0x80); }
349 bool IsNoteOn ()
const {
return ((mStatus & 0xF0) == 0x90); }
351 bool IsKeyPressure ()
const {
return ((mStatus & 0xF0) == 0xA0); }
353 bool IsKeyEvent ()
const {
return (mStatus > 0x7F) && (mStatus < 0xB0); }
355 bool IsPatchChange ()
const {
return ((mStatus & 0xF0) == 0xC0); }
356 bool IsChannelPressure ()
const {
return ((mStatus & 0xF0) == 0xD0); }
357 bool IsPitchBend ()
const {
return ((mStatus & 0xF0) == 0xE0); }
358 bool IsControlChange ()
const {
return ((mStatus & 0xF0) == 0xB0); }
361 void SetControllerOnValue(){SetBipolar(
true,
true);}
362 void SetControllerOffValue(){SetBipolar(
true,
false);}
363 void SetControllerAnyValue(){SetBipolar(
false,
false);}
367 void SetNoteOff (UInt8 key, SInt8 channel,
bool anyChannel =
false)
369 mStatus = 0x80 | (channel & 0xF);
371 mFlags = (anyChannel ? kAUParameterMIDIMapping_AnyChannelFlag : 0);
375 void SetNoteOn (UInt8 key, SInt8 channel,
bool anyChannel =
false)
377 mStatus = 0x90 | (channel & 0xF);
379 mFlags = (anyChannel ? kAUParameterMIDIMapping_AnyChannelFlag : 0);
382 void SetPolyKey (UInt8 key, SInt8 channel,
bool anyChannel =
false)
384 mStatus = 0xA0 | (channel & 0xF);
386 mFlags = (anyChannel ? kAUParameterMIDIMapping_AnyChannelFlag : 0);
389 void SetControlChange (UInt8 controllerID, SInt8 channel,
bool anyChannel =
false)
391 mStatus = 0xB0 | (channel & 0xF);
392 mData1 = controllerID;
393 mFlags = (anyChannel ? kAUParameterMIDIMapping_AnyChannelFlag : 0);
396 void SetPatchChange (UInt8 patchChange, SInt8 channel,
bool anyChannel =
false)
398 mStatus = 0xC0 | (channel & 0xF);
399 mData1 = patchChange;
400 mFlags = (anyChannel ? kAUParameterMIDIMapping_AnyChannelFlag : 0);
403 void SetChannelPressure (SInt8 channel,
bool anyChannel =
false)
405 mStatus = 0xD0 | (channel & 0xF);
407 mFlags = (anyChannel ? kAUParameterMIDIMapping_AnyChannelFlag : 0);
410 void SetPitchBend (SInt8 channel,
bool anyChannel =
false)
412 mStatus = 0xE0 | (channel & 0xF);
414 mFlags = (anyChannel ? kAUParameterMIDIMapping_AnyChannelFlag : 0);
418 Float32 ParamValueFromMIDILinear (Float32 inLinearValue)
const
432 return mTransType->fromlinear((inLinearValue * (high - low)) + low);
437 bool MIDI_Matches (UInt8 inChannel, UInt8 inData1, UInt8 inData2, Float32 &outLinear)
const;
441 void Save (CFPropertyListRef &outData)
const;
442 void Restore (CFDictionaryRef inData);
444 static void SaveAsMapPList (AudioUnit inUnit,
445 const AUParameterMIDIMapping * inMappings,
446 UInt32 inNumMappings,
447 CFPropertyListRef &outData,
448 CFStringRef inName = NULL);
451 static void RestoreFromMapPList (
const CFDictionaryRef inData,
452 AUParameterMIDIMapping * outMappings,
453 UInt32 inNumMappings);
455 static UInt32 NumberOfMaps (
const CFDictionaryRef inData);
460 inline bool operator== (
const CAAUMIDIMap &a,
const CAAUMIDIMap &b)
463 return (((a.mStatus & 0xF0) == (b.mStatus & 0xF0))
464 && (a.mData1 == b.mData1)
465 && ((a.mStatus & 0xF) == (b.mStatus & 0xf))
466 && (a.mParameterID == b.mParameterID)
467 && (a.mElement == b.mElement)
468 && (a.mScope == b.mScope));
473 inline bool operator< (
const CAAUMIDIMap &a,
const CAAUMIDIMap &b)
475 if ((a.mStatus & 0xF0) != (b.mStatus & 0xF0))
476 return ((a.mStatus & 0xF0) < (b.mStatus & 0xF0));
478 if (a.mData1 != b.mData1)
479 return (a.mData1 < b.mData1);
481 if ((a.mStatus & 0xF) != (b.mStatus & 0xf))
482 return ((a.mStatus & 0xF) < (b.mStatus & 0xf));
487 return ((a.mParameterID < b.mParameterID)
488 && (a.mElement < b.mElement)
489 && (a.mScope < b.mScope));
494 class CompareMIDIMap {
495 int compare (
const CAAUMIDIMap &a,
const CAAUMIDIMap &b)
497 if ((a.mStatus & 0xF0) < (b.mStatus & 0xF0))
499 if ((a.mStatus & 0xF0) > (b.mStatus & 0xF0))
503 if (a.mStatus < 0xB0 || a.mStatus >= 0xD0)
505 if (a.mData1 > b.mData1)
return 1;
506 if (a.mData1 < b.mData1)
return -1;
511 bool operator() (
const CAAUMIDIMap &a,
const CAAUMIDIMap &b) {
512 return compare (a, b) < 0;
514 bool Finish (
const CAAUMIDIMap &a,
const CAAUMIDIMap &b) {
515 return compare (a, b) != 0;
bool TTFOUNDATION_EXPORT operator==(const TTObject &anObject, const TTObject &anotherObject)
Compare two objects for equality.