2015-10-17 20:46:58 -04:00
|
|
|
/*
|
|
|
|
File: CAPersistence.cpp
|
|
|
|
Abstract: CAPersistence.h
|
|
|
|
Version: 1.1
|
2015-10-26 14:35:06 -04:00
|
|
|
|
2015-10-17 20:46:58 -04:00
|
|
|
Disclaimer: IMPORTANT: This Apple software is supplied to you by Apple
|
|
|
|
Inc. ("Apple") in consideration of your agreement to the following
|
|
|
|
terms, and your use, installation, modification or redistribution of
|
|
|
|
this Apple software constitutes acceptance of these terms. If you do
|
|
|
|
not agree with these terms, please do not use, install, modify or
|
|
|
|
redistribute this Apple software.
|
2015-10-26 14:35:06 -04:00
|
|
|
|
2015-10-17 20:46:58 -04:00
|
|
|
In consideration of your agreement to abide by the following terms, and
|
|
|
|
subject to these terms, Apple grants you a personal, non-exclusive
|
|
|
|
license, under Apple's copyrights in this original Apple software (the
|
|
|
|
"Apple Software"), to use, reproduce, modify and redistribute the Apple
|
|
|
|
Software, with or without modifications, in source and/or binary forms;
|
|
|
|
provided that if you redistribute the Apple Software in its entirety and
|
|
|
|
without modifications, you must retain this notice and the following
|
|
|
|
text and disclaimers in all such redistributions of the Apple Software.
|
|
|
|
Neither the name, trademarks, service marks or logos of Apple Inc. may
|
|
|
|
be used to endorse or promote products derived from the Apple Software
|
|
|
|
without specific prior written permission from Apple. Except as
|
|
|
|
expressly stated in this notice, no other rights or licenses, express or
|
|
|
|
implied, are granted by Apple herein, including but not limited to any
|
|
|
|
patent rights that may be infringed by your derivative works or by other
|
|
|
|
works in which the Apple Software may be incorporated.
|
2015-10-26 14:35:06 -04:00
|
|
|
|
2015-10-17 20:46:58 -04:00
|
|
|
The Apple Software is provided by Apple on an "AS IS" basis. APPLE
|
|
|
|
MAKES NO WARRANTIES, EXPRESS OR IMPLIED, INCLUDING WITHOUT LIMITATION
|
|
|
|
THE IMPLIED WARRANTIES OF NON-INFRINGEMENT, MERCHANTABILITY AND FITNESS
|
|
|
|
FOR A PARTICULAR PURPOSE, REGARDING THE APPLE SOFTWARE OR ITS USE AND
|
|
|
|
OPERATION ALONE OR IN COMBINATION WITH YOUR PRODUCTS.
|
2015-10-26 14:35:06 -04:00
|
|
|
|
2015-10-17 20:46:58 -04:00
|
|
|
IN NO EVENT SHALL APPLE BE LIABLE FOR ANY SPECIAL, INDIRECT, INCIDENTAL
|
|
|
|
OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
|
|
|
|
SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
|
|
|
|
INTERRUPTION) ARISING IN ANY WAY OUT OF THE USE, REPRODUCTION,
|
|
|
|
MODIFICATION AND/OR DISTRIBUTION OF THE APPLE SOFTWARE, HOWEVER CAUSED
|
|
|
|
AND WHETHER UNDER THEORY OF CONTRACT, TORT (INCLUDING NEGLIGENCE),
|
|
|
|
STRICT LIABILITY OR OTHERWISE, EVEN IF APPLE HAS BEEN ADVISED OF THE
|
|
|
|
POSSIBILITY OF SUCH DAMAGE.
|
2015-10-26 14:35:06 -04:00
|
|
|
|
2015-10-17 20:46:58 -04:00
|
|
|
Copyright (C) 2014 Apple Inc. All Rights Reserved.
|
2015-10-26 14:35:06 -04:00
|
|
|
|
2015-10-17 20:46:58 -04:00
|
|
|
*/
|
|
|
|
#include "CACFArray.h"
|
|
|
|
#include "CACFDictionary.h"
|
|
|
|
|
|
|
|
#include "CAAudioUnit.h"
|
|
|
|
#include "CACFString.h"
|
|
|
|
#include "CAAudioChannelLayout.h"
|
|
|
|
#include "CAAUParameter.h"
|
|
|
|
#include "CAAUMIDIMap.h"
|
|
|
|
|
|
|
|
#include <CoreServices/../Frameworks/CarbonCore.framework/Headers/MacErrors.h>
|
|
|
|
|
|
|
|
#pragma mark __CAStreamBasicDescription
|
|
|
|
|
|
|
|
static const CFStringRef kSampleRate = CFSTR("sample rate");
|
|
|
|
static const CFStringRef kFormat = CFSTR("format");
|
|
|
|
static const CFStringRef kFormatFlags = CFSTR("format flags");
|
|
|
|
static const CFStringRef kPacketBytes = CFSTR("packet bytes");
|
|
|
|
static const CFStringRef kFramePackets = CFSTR("frame packets");
|
|
|
|
static const CFStringRef kFrameBytes = CFSTR("frame bytes");
|
|
|
|
static const CFStringRef kFrameChannels = CFSTR("frame channels");
|
|
|
|
static const CFStringRef kChannelBits = CFSTR("channel bits");
|
|
|
|
|
|
|
|
// This will return a value that should be used as the key for this struct
|
|
|
|
// and a CFData object that contains the current state of this object
|
|
|
|
OSStatus CAStreamBasicDescription::Save (CFPropertyListRef *outData) const
|
|
|
|
{
|
|
|
|
CACFDictionary dict(false);
|
|
|
|
|
|
|
|
if (!dict.AddFloat64 (kSampleRate, mSampleRate)) goto error;
|
|
|
|
if (!dict.AddUInt32 (kFormat, mFormatID)) goto error;
|
|
|
|
if (!dict.AddUInt32 (kFormatFlags, mFormatFlags)) goto error;
|
|
|
|
if (!dict.AddUInt32 (kPacketBytes, mBytesPerPacket)) goto error;
|
|
|
|
if (!dict.AddUInt32 (kFramePackets, mFramesPerPacket)) goto error;
|
|
|
|
if (!dict.AddUInt32 (kFrameBytes, mBytesPerFrame)) goto error;
|
|
|
|
if (!dict.AddUInt32 (kFrameChannels, mChannelsPerFrame)) goto error;
|
|
|
|
if (!dict.AddUInt32 (kChannelBits, mBitsPerChannel)) goto error;
|
2015-10-26 14:35:06 -04:00
|
|
|
|
2015-10-17 20:46:58 -04:00
|
|
|
*outData = dict.GetDict();
|
|
|
|
|
|
|
|
return noErr;
|
|
|
|
|
|
|
|
error:
|
|
|
|
dict.ShouldRelease (true);
|
|
|
|
return paramErr;
|
|
|
|
}
|
|
|
|
|
2015-10-26 14:35:06 -04:00
|
|
|
|
2015-10-17 20:46:58 -04:00
|
|
|
// Given a CFData object generated by the save command, this will re-establish
|
|
|
|
// the CAStreamBasicDescription
|
|
|
|
OSStatus CAStreamBasicDescription::Restore (CFPropertyListRef& inData)
|
|
|
|
{
|
|
|
|
if (CFGetTypeID (inData) != CFDictionaryGetTypeID()) return paramErr;
|
|
|
|
CACFDictionary dict(static_cast<CFDictionaryRef>(inData), false);
|
2015-10-26 14:35:06 -04:00
|
|
|
|
2015-10-17 20:46:58 -04:00
|
|
|
if (!dict.GetFloat64 (kSampleRate, mSampleRate)) return paramErr;
|
|
|
|
if (!dict.GetUInt32 (kFormat, mFormatID)) return paramErr;
|
|
|
|
if (!dict.GetUInt32 (kFormatFlags, mFormatFlags)) return paramErr;
|
|
|
|
if (!dict.GetUInt32 (kPacketBytes, mBytesPerPacket)) return paramErr;
|
|
|
|
if (!dict.GetUInt32 (kFramePackets, mFramesPerPacket)) return paramErr;
|
|
|
|
if (!dict.GetUInt32 (kFrameBytes, mBytesPerFrame)) return paramErr;
|
|
|
|
if (!dict.GetUInt32 (kFrameChannels, mChannelsPerFrame)) return paramErr;
|
|
|
|
if (!dict.GetUInt32 (kChannelBits, mBitsPerChannel)) return paramErr;
|
|
|
|
|
|
|
|
return noErr;
|
|
|
|
}
|
|
|
|
|
|
|
|
#pragma mark __CAComponentDescription
|
|
|
|
|
|
|
|
static const CFStringRef kType = CFSTR("type");
|
|
|
|
static const CFStringRef kSubType = CFSTR("subtype");
|
|
|
|
static const CFStringRef kManu = CFSTR("manufacturer");
|
|
|
|
|
|
|
|
OSStatus CAComponentDescription::Save (CFPropertyListRef *outData) const
|
|
|
|
{
|
|
|
|
CACFDictionary dict(false);
|
|
|
|
if (!dict.AddUInt32 (kType, componentType)) goto error;
|
|
|
|
if (!dict.AddUInt32 (kSubType, componentSubType)) goto error;
|
|
|
|
if (!dict.AddUInt32 (kManu, componentManufacturer)) goto error;
|
2015-10-26 14:35:06 -04:00
|
|
|
|
2015-10-17 20:46:58 -04:00
|
|
|
*outData = dict.GetDict();
|
2015-10-26 14:35:06 -04:00
|
|
|
|
2015-10-17 20:46:58 -04:00
|
|
|
return 0;
|
|
|
|
error:
|
|
|
|
dict.ShouldRelease (true);
|
|
|
|
return paramErr;
|
|
|
|
}
|
|
|
|
|
|
|
|
OSStatus CAComponentDescription::Restore (CFPropertyListRef &inData)
|
|
|
|
{
|
|
|
|
if (CFGetTypeID (inData) != CFDictionaryGetTypeID()) return paramErr;
|
|
|
|
CACFDictionary dict(static_cast<CFDictionaryRef>(inData), false);
|
2015-10-26 14:35:06 -04:00
|
|
|
|
2015-10-17 20:46:58 -04:00
|
|
|
if (!dict.GetUInt32 (kType, componentType)) return paramErr;
|
|
|
|
if (!dict.GetUInt32 (kSubType, componentSubType)) return paramErr;
|
|
|
|
if (!dict.GetUInt32 (kManu, componentManufacturer)) return paramErr;
|
|
|
|
|
|
|
|
componentFlags = 0;
|
|
|
|
componentFlagsMask = 0;
|
2015-10-26 14:35:06 -04:00
|
|
|
|
2015-10-17 20:46:58 -04:00
|
|
|
return 0;
|
|
|
|
}
|
|
|
|
|
|
|
|
#pragma mark __CAComponent
|
|
|
|
|
|
|
|
OSStatus CAComponent::Save (CFPropertyListRef *outData) const
|
|
|
|
{
|
|
|
|
OSStatus result = mDesc.Save (outData);
|
|
|
|
if (result) return result;
|
2015-10-26 14:35:06 -04:00
|
|
|
|
2015-10-17 20:46:58 -04:00
|
|
|
//add the name string of the component for a human readable name...
|
|
|
|
// this name string is *not* restored when restoring the component
|
|
|
|
CFStringRef name = GetCompName ();
|
|
|
|
if (name && *outData)
|
|
|
|
CFDictionarySetValue ((CFMutableDictionaryRef)(*outData), CFSTR("name"), name);
|
2015-10-26 14:35:06 -04:00
|
|
|
|
2015-10-17 20:46:58 -04:00
|
|
|
return noErr;
|
|
|
|
}
|
|
|
|
|
|
|
|
OSStatus CAComponent::Restore (CFPropertyListRef &inData)
|
|
|
|
{
|
|
|
|
if (mDesc.Restore (inData)) return paramErr;
|
|
|
|
|
|
|
|
Clear();
|
|
|
|
|
|
|
|
mComp = AudioComponentFindNext (NULL, &mDesc);
|
|
|
|
// this will restore the current flags...
|
|
|
|
if (mComp)
|
|
|
|
AudioComponentGetDescription (Comp(), &mDesc);
|
|
|
|
|
|
|
|
return noErr;
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
#pragma mark __CAAudioChannelLayout
|
|
|
|
|
|
|
|
static const CFStringRef kACLTagKey = CFSTR("acl tag");
|
|
|
|
static const CFStringRef kACLBitmapKey = CFSTR("chan bitmap");
|
|
|
|
static const CFStringRef kACLLabelKey = CFSTR("label");
|
|
|
|
static const CFStringRef kACLFlagsKey = CFSTR("flags");
|
|
|
|
static const CFStringRef kACLCoords0Key = CFSTR("coords 0");
|
|
|
|
static const CFStringRef kACLCoords1Key = CFSTR("coords 1");
|
|
|
|
static const CFStringRef kACLCoords2Key = CFSTR("coords 2");
|
|
|
|
static const CFStringRef kACLDescsKey = CFSTR("descriptions");
|
2015-10-26 14:35:06 -04:00
|
|
|
|
|
|
|
OSStatus CAAudioChannelLayout::Save (CFPropertyListRef *outData) const
|
2015-10-17 20:46:58 -04:00
|
|
|
{
|
|
|
|
const AudioChannelLayout& layout = Layout();
|
|
|
|
|
|
|
|
CACFDictionary dict (false);
|
|
|
|
if (!dict.AddUInt32 (kACLTagKey, layout.mChannelLayoutTag))
|
|
|
|
goto badadd;
|
|
|
|
if (layout.mChannelBitmap && !dict.AddUInt32 (kACLBitmapKey, layout.mChannelBitmap))
|
|
|
|
goto badadd;
|
2015-10-26 14:35:06 -04:00
|
|
|
|
2015-10-17 20:46:58 -04:00
|
|
|
if (layout.mNumberChannelDescriptions)
|
2015-10-26 14:35:06 -04:00
|
|
|
{
|
2015-10-17 20:46:58 -04:00
|
|
|
CFMutableArrayRef descs = CFArrayCreateMutable (NULL, layout.mNumberChannelDescriptions, &kCFTypeArrayCallBacks);
|
2015-10-26 14:35:06 -04:00
|
|
|
|
2015-10-17 20:46:58 -04:00
|
|
|
const AudioChannelDescription *desc = layout.mChannelDescriptions;
|
2015-10-26 14:35:06 -04:00
|
|
|
for (unsigned int i = 0; i < layout.mNumberChannelDescriptions; ++i, ++desc)
|
2015-10-17 20:46:58 -04:00
|
|
|
{
|
|
|
|
CACFDictionary descDict (true);
|
|
|
|
if (!descDict.AddUInt32 (kACLLabelKey, desc->mChannelLabel))
|
|
|
|
{ CFRelease (descs); goto badadd; }
|
|
|
|
if (!descDict.AddUInt32 (kACLFlagsKey, desc->mChannelFlags))
|
|
|
|
{ CFRelease (descs); goto badadd; }
|
|
|
|
if (!descDict.AddFloat32 (kACLCoords0Key, desc->mCoordinates[0]))
|
|
|
|
{ CFRelease (descs); goto badadd; }
|
|
|
|
if (!descDict.AddFloat32 (kACLCoords1Key, desc->mCoordinates[1]))
|
|
|
|
{ CFRelease (descs); goto badadd; }
|
|
|
|
if (!descDict.AddFloat32 (kACLCoords2Key, desc->mCoordinates[2]))
|
|
|
|
{ CFRelease (descs); goto badadd; }
|
2015-10-26 14:35:06 -04:00
|
|
|
|
2015-10-17 20:46:58 -04:00
|
|
|
CFArrayAppendValue (descs, descDict.AsPropertyList());
|
|
|
|
}
|
|
|
|
dict.AddArray (kACLDescsKey, descs);
|
2015-10-26 14:35:06 -04:00
|
|
|
|
2015-10-17 20:46:58 -04:00
|
|
|
CFRelease (descs);
|
|
|
|
}
|
2015-10-26 14:35:06 -04:00
|
|
|
|
|
|
|
*outData = dict.GetDict();
|
|
|
|
|
2015-10-17 20:46:58 -04:00
|
|
|
return noErr;
|
2015-10-26 14:35:06 -04:00
|
|
|
|
2015-10-17 20:46:58 -04:00
|
|
|
badadd:
|
|
|
|
dict.ShouldRelease(true);
|
|
|
|
return paramErr;
|
|
|
|
}
|
|
|
|
|
2015-10-26 14:35:06 -04:00
|
|
|
OSStatus CAAudioChannelLayout::Restore (CFPropertyListRef &inData)
|
2015-10-17 20:46:58 -04:00
|
|
|
{
|
|
|
|
if (CFGetTypeID (inData) != CFDictionaryGetTypeID()) return paramErr;
|
|
|
|
CACFDictionary dict(static_cast<CFDictionaryRef>(inData), false);
|
|
|
|
|
|
|
|
RefCountedLayout *temp = NULL;
|
|
|
|
AudioChannelLayout* layout;
|
2015-10-26 14:35:06 -04:00
|
|
|
|
2015-10-17 20:46:58 -04:00
|
|
|
CFArrayRef descs = NULL;
|
|
|
|
UInt32 numDescs = 0;
|
|
|
|
|
|
|
|
if (dict.GetArray (kACLDescsKey, descs)) {
|
|
|
|
numDescs = static_cast<OSStatus>(CFArrayGetCount (descs));
|
|
|
|
}
|
2015-10-26 14:35:06 -04:00
|
|
|
|
2015-10-17 20:46:58 -04:00
|
|
|
temp = RefCountedLayout::CreateWithNumberChannelDescriptions(numDescs);
|
|
|
|
layout = temp->GetLayout();
|
2015-10-26 14:35:06 -04:00
|
|
|
|
2015-10-17 20:46:58 -04:00
|
|
|
if (!dict.GetUInt32 (kACLTagKey, layout->mChannelLayoutTag))
|
|
|
|
goto badget;
|
|
|
|
if (dict.HasKey (kACLBitmapKey)) {
|
|
|
|
if (!dict.GetUInt32 (kACLBitmapKey, layout->mChannelBitmap))
|
|
|
|
goto badget;
|
|
|
|
} else
|
|
|
|
layout->mChannelBitmap = 0;
|
2015-10-26 14:35:06 -04:00
|
|
|
|
2015-10-17 20:46:58 -04:00
|
|
|
layout->mNumberChannelDescriptions = numDescs;
|
2015-10-26 14:35:06 -04:00
|
|
|
|
2015-10-17 20:46:58 -04:00
|
|
|
if (numDescs)
|
|
|
|
{
|
|
|
|
AudioChannelDescription *desc = layout->mChannelDescriptions;
|
|
|
|
for (unsigned int i = 0; i < numDescs; ++i, ++desc)
|
|
|
|
{
|
2015-10-26 14:35:06 -04:00
|
|
|
CFDictionaryRef descDict = (CFDictionaryRef)CFArrayGetValueAtIndex (descs, i);
|
2015-10-17 20:46:58 -04:00
|
|
|
CACFDictionary theDesc (descDict, false);
|
2015-10-26 14:35:06 -04:00
|
|
|
|
2015-10-17 20:46:58 -04:00
|
|
|
if (!theDesc.GetUInt32 (kACLLabelKey, desc->mChannelLabel))
|
|
|
|
goto badget;
|
|
|
|
if (!theDesc.GetUInt32 (kACLFlagsKey, desc->mChannelFlags))
|
|
|
|
goto badget;
|
|
|
|
if (!theDesc.GetFloat32 (kACLCoords0Key, desc->mCoordinates[0]))
|
|
|
|
goto badget;
|
|
|
|
if (!theDesc.GetFloat32 (kACLCoords1Key, desc->mCoordinates[1]))
|
|
|
|
goto badget;
|
|
|
|
if (!theDesc.GetFloat32 (kACLCoords2Key, desc->mCoordinates[2]))
|
|
|
|
goto badget;
|
|
|
|
}
|
|
|
|
}
|
|
|
|
if (mLayout)
|
|
|
|
mLayout->release();
|
|
|
|
|
|
|
|
mLayout = temp;
|
2015-10-26 14:35:06 -04:00
|
|
|
|
2015-10-17 20:46:58 -04:00
|
|
|
return noErr;
|
|
|
|
|
|
|
|
badget:
|
|
|
|
delete temp;
|
|
|
|
return paramErr;
|
|
|
|
}
|
|
|
|
|
|
|
|
#pragma mark __AudioUnitParameter
|
|
|
|
|
|
|
|
static const CFStringRef kAUScopeStr = CFSTR("scope");
|
|
|
|
static const CFStringRef kAUElementIDStr = CFSTR("element ID");
|
|
|
|
static const CFStringRef kAUParameterIDStr = CFSTR("paramID");
|
|
|
|
|
2015-10-26 14:35:06 -04:00
|
|
|
void CAAUParameter::Save (CFPropertyListRef &outData) const
|
|
|
|
{
|
|
|
|
return CAAUParameter::Save (*this, outData);
|
2015-10-17 20:46:58 -04:00
|
|
|
}
|
|
|
|
|
|
|
|
// static functions to save/restore AudioUnitParameter
|
|
|
|
void CAAUParameter::Save (const AudioUnitParameter &inParam, CFPropertyListRef &outData)
|
|
|
|
{
|
|
|
|
CACFDictionary dict(false);
|
|
|
|
dict.AddUInt32 (kAUScopeStr, inParam.mScope);
|
|
|
|
dict.AddUInt32 (kAUElementIDStr, inParam.mElement);
|
|
|
|
dict.AddUInt32 (kAUParameterIDStr, inParam.mParameterID);
|
|
|
|
|
|
|
|
outData = dict.AsPropertyList();
|
|
|
|
}
|
|
|
|
|
|
|
|
OSStatus CAAUParameter::Restore (const CFPropertyListRef inData, AudioUnitParameter &outParam)
|
|
|
|
{
|
|
|
|
if (CFGetTypeID (inData) != CFDictionaryGetTypeID()) return paramErr;
|
|
|
|
CACFDictionary dict(static_cast<CFDictionaryRef>(inData), false);
|
|
|
|
|
|
|
|
if (!dict.GetUInt32 (kAUScopeStr, outParam.mScope)) return paramErr;
|
|
|
|
if (!dict.GetUInt32 (kAUElementIDStr, outParam.mElement)) return paramErr;
|
|
|
|
if (!dict.GetUInt32 (kAUParameterIDStr, outParam.mParameterID)) return paramErr;
|
|
|
|
return noErr;
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
#pragma mark __MIDIMap
|
|
|
|
|
|
|
|
const CFStringRef kParamMIDIStr = CFSTR("param maps");
|
|
|
|
|
|
|
|
const CFStringRef kMIDIFlagsStr = CFSTR("flags");
|
|
|
|
const CFStringRef kMIDISubMinStr = CFSTR("sub min");
|
|
|
|
const CFStringRef kMIDISubMaxStr = CFSTR("sub max");
|
|
|
|
const CFStringRef kMIDIStatusStr = CFSTR("midi status byte");
|
|
|
|
const CFStringRef kMIDIDataByteStr = CFSTR("midi data1 byte");
|
|
|
|
const CFStringRef kAUStr = CFSTR("unit");
|
|
|
|
|
|
|
|
static const CFStringRef kLocalElementIDStr = CFSTR("element ID");
|
|
|
|
static const CFStringRef kLocalScopeStr = CFSTR("scope");
|
|
|
|
static const CFStringRef kLocalParameterIDStr = CFSTR("paramID");
|
|
|
|
|
|
|
|
void CAAUMIDIMap::Save(CFPropertyListRef &outData) const
|
|
|
|
{
|
|
|
|
CACFDictionary paramDict(false);
|
|
|
|
|
|
|
|
paramDict.AddUInt32 (kLocalScopeStr, mScope);
|
|
|
|
paramDict.AddUInt32 (kLocalElementIDStr, mElement);
|
|
|
|
paramDict.AddUInt32 (kLocalParameterIDStr, mParameterID);
|
|
|
|
paramDict.AddUInt32 (kMIDIFlagsStr, mFlags);
|
|
|
|
paramDict.AddFloat32 (kMIDISubMinStr, mSubRangeMin);
|
|
|
|
paramDict.AddFloat32 (kMIDISubMaxStr, mSubRangeMax);
|
|
|
|
|
|
|
|
UInt32 data = mStatus;
|
|
|
|
paramDict.AddUInt32 (kMIDIStatusStr, data);
|
|
|
|
|
|
|
|
data = mData1;
|
|
|
|
paramDict.AddUInt32 (kMIDIDataByteStr, data);
|
|
|
|
|
|
|
|
outData = paramDict.GetCFDictionary();
|
|
|
|
}
|
|
|
|
|
|
|
|
void CAAUMIDIMap::Restore(CFDictionaryRef inData)
|
2015-10-26 14:35:06 -04:00
|
|
|
{
|
2015-10-17 20:46:58 -04:00
|
|
|
CACFDictionary paramDict (inData, false);
|
|
|
|
|
2015-10-26 14:35:06 -04:00
|
|
|
if (!paramDict.GetUInt32 (kLocalScopeStr, mScope)) return;
|
|
|
|
if (!paramDict.GetUInt32 (kLocalElementIDStr, mElement)) return;
|
|
|
|
if (!paramDict.GetUInt32 (kLocalParameterIDStr, mParameterID)) return;
|
2015-10-17 20:46:58 -04:00
|
|
|
if (!paramDict.GetUInt32 (kMIDIFlagsStr, mFlags)) return;
|
2015-10-26 14:35:06 -04:00
|
|
|
if (!paramDict.GetFloat32 (kMIDISubMinStr, mSubRangeMin)) return;
|
|
|
|
if (!paramDict.GetFloat32 (kMIDISubMaxStr, mSubRangeMax)) return;
|
|
|
|
UInt32 data;
|
2015-10-17 20:46:58 -04:00
|
|
|
if (!paramDict.GetUInt32 (kMIDIStatusStr, data)) return;
|
|
|
|
mStatus = data;
|
2015-10-26 14:35:06 -04:00
|
|
|
if (!paramDict.GetUInt32 (kMIDIDataByteStr, data)) return;
|
2015-10-17 20:46:58 -04:00
|
|
|
mData1 = data;
|
|
|
|
}
|
|
|
|
|
|
|
|
void CAAUMIDIMap::SaveAsMapPList (AudioUnit inUnit, const AUParameterMIDIMapping* inMappings, UInt32 inNumMappings, CFPropertyListRef &outData, CFStringRef inName)
|
|
|
|
{
|
|
|
|
|
2015-10-26 14:35:06 -04:00
|
|
|
CACFDictionary mappingDict (false);
|
2015-10-17 20:46:58 -04:00
|
|
|
CACFArray maps (true);
|
2015-10-26 14:35:06 -04:00
|
|
|
|
|
|
|
for (UInt32 i = 0; i< inNumMappings; ++i)
|
2015-10-17 20:46:58 -04:00
|
|
|
{
|
|
|
|
CFPropertyListRef data;
|
|
|
|
CAAUMIDIMap paramMap(inMappings[i]);
|
|
|
|
paramMap.Save (data);
|
2015-10-26 14:35:06 -04:00
|
|
|
if (data)
|
2015-10-17 20:46:58 -04:00
|
|
|
{
|
2015-10-26 14:35:06 -04:00
|
|
|
maps.AppendCFType (data);
|
|
|
|
CFRelease(data);
|
|
|
|
}
|
2015-10-17 20:46:58 -04:00
|
|
|
}
|
|
|
|
|
|
|
|
if (maps.GetNumberItems()) {
|
|
|
|
mappingDict.AddCFType (kParamMIDIStr, maps.GetCFArray());
|
2015-10-26 14:35:06 -04:00
|
|
|
|
2015-10-17 20:46:58 -04:00
|
|
|
// Add the AU info here - where this map came from
|
|
|
|
CAAudioUnit au (inUnit);
|
|
|
|
CFPropertyListRef data;
|
|
|
|
au.Comp().Save (&data);
|
2015-10-26 14:35:06 -04:00
|
|
|
|
2015-10-17 20:46:58 -04:00
|
|
|
mappingDict.AddCFType (kAUStr, data);
|
|
|
|
CFRelease(data);
|
2015-10-26 14:35:06 -04:00
|
|
|
|
2015-10-17 20:46:58 -04:00
|
|
|
if (!inName) inName = CFSTR("Untitled");
|
|
|
|
mappingDict.AddString (CFSTR("name"), inName);
|
2015-10-26 14:35:06 -04:00
|
|
|
|
2015-10-17 20:46:58 -04:00
|
|
|
mappingDict.AddUInt32 (CFSTR("version"), 1);
|
2015-10-26 14:35:06 -04:00
|
|
|
|
2015-10-17 20:46:58 -04:00
|
|
|
outData = mappingDict.AsPropertyList();
|
|
|
|
} else {
|
|
|
|
mappingDict.ShouldRelease(true);
|
|
|
|
outData = NULL;
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
UInt32 CAAUMIDIMap::NumberOfMaps (const CFDictionaryRef inData)
|
|
|
|
{
|
|
|
|
CACFDictionary dict (inData, false);
|
2015-10-26 14:35:06 -04:00
|
|
|
|
|
|
|
if (dict.HasKey (kParamMIDIStr))
|
2015-10-17 20:46:58 -04:00
|
|
|
{
|
|
|
|
CFArrayRef cfArray;
|
2015-10-26 14:35:06 -04:00
|
|
|
dict.GetArray (kParamMIDIStr, cfArray);
|
|
|
|
|
2015-10-17 20:46:58 -04:00
|
|
|
CACFArray array (cfArray, false);
|
2015-10-26 14:35:06 -04:00
|
|
|
|
2015-10-17 20:46:58 -04:00
|
|
|
return array.GetNumberItems();
|
|
|
|
}
|
|
|
|
return 0;
|
|
|
|
}
|
2015-10-26 14:35:06 -04:00
|
|
|
|
2015-10-17 20:46:58 -04:00
|
|
|
void CAAUMIDIMap::RestoreFromMapPList (const CFDictionaryRef inData, AUParameterMIDIMapping* outMappings, UInt32 inNumMappings)
|
|
|
|
{
|
|
|
|
|
|
|
|
CACFDictionary dict (inData, false);
|
2015-10-26 14:35:06 -04:00
|
|
|
|
|
|
|
if (dict.HasKey (kParamMIDIStr))
|
2015-10-17 20:46:58 -04:00
|
|
|
{
|
|
|
|
CFArrayRef cfArray;
|
2015-10-26 14:35:06 -04:00
|
|
|
dict.GetArray (kParamMIDIStr, cfArray);
|
|
|
|
|
2015-10-17 20:46:58 -04:00
|
|
|
CACFArray array (cfArray, false);
|
2015-10-26 14:35:06 -04:00
|
|
|
|
2015-10-17 20:46:58 -04:00
|
|
|
UInt32 count = array.GetNumberItems();
|
|
|
|
if (count > inNumMappings)
|
|
|
|
count = inNumMappings;
|
2015-10-26 14:35:06 -04:00
|
|
|
|
2015-10-17 20:46:58 -04:00
|
|
|
for (unsigned int i = 0; i < count; ++i)
|
|
|
|
{
|
|
|
|
CFDictionaryRef paramsDictRef;
|
2015-10-26 14:35:06 -04:00
|
|
|
if (!array.GetDictionary(i, paramsDictRef))
|
2015-10-17 20:46:58 -04:00
|
|
|
return;
|
2015-10-26 14:35:06 -04:00
|
|
|
|
2015-10-17 20:46:58 -04:00
|
|
|
CAAUMIDIMap parameterMap;
|
|
|
|
parameterMap.Restore(paramsDictRef);
|
|
|
|
outMappings[i] = parameterMap;
|
|
|
|
}
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
|