migrating to the latest JUCE version
This commit is contained in:
@@ -1,46 +1,46 @@
|
||||
/*
|
||||
==============================================================================
|
||||
|
||||
This file is part of the JUCE library.
|
||||
Copyright (c) 2020 - Raw Material Software Limited
|
||||
|
||||
JUCE is an open source library subject to commercial or open-source
|
||||
licensing.
|
||||
|
||||
By using JUCE, you agree to the terms of both the JUCE 6 End-User License
|
||||
Agreement and JUCE Privacy Policy (both effective as of the 16th June 2020).
|
||||
|
||||
End User License Agreement: www.juce.com/juce-6-licence
|
||||
Privacy Policy: www.juce.com/juce-privacy-policy
|
||||
|
||||
Or: You may also use this code under the terms of the GPL v3 (see
|
||||
www.gnu.org/licenses).
|
||||
|
||||
JUCE IS PROVIDED "AS IS" WITHOUT ANY WARRANTY, AND ALL WARRANTIES, WHETHER
|
||||
EXPRESSED OR IMPLIED, INCLUDING MERCHANTABILITY AND FITNESS FOR PURPOSE, ARE
|
||||
DISCLAIMED.
|
||||
|
||||
==============================================================================
|
||||
*/
|
||||
|
||||
namespace juce
|
||||
{
|
||||
|
||||
#ifndef DOXYGEN
|
||||
|
||||
struct ModifierKeyProvider
|
||||
{
|
||||
virtual ~ModifierKeyProvider() {}
|
||||
virtual int getWin32Modifiers() const = 0;
|
||||
};
|
||||
|
||||
struct ModifierKeyReceiver
|
||||
{
|
||||
virtual ~ModifierKeyReceiver() {}
|
||||
virtual void setModifierKeyProvider (ModifierKeyProvider*) = 0;
|
||||
virtual void removeModifierKeyProvider() = 0;
|
||||
};
|
||||
|
||||
#endif
|
||||
|
||||
} // namespace juce
|
||||
/*
|
||||
==============================================================================
|
||||
|
||||
This file is part of the JUCE library.
|
||||
Copyright (c) 2022 - Raw Material Software Limited
|
||||
|
||||
JUCE is an open source library subject to commercial or open-source
|
||||
licensing.
|
||||
|
||||
By using JUCE, you agree to the terms of both the JUCE 7 End-User License
|
||||
Agreement and JUCE Privacy Policy.
|
||||
|
||||
End User License Agreement: www.juce.com/juce-7-licence
|
||||
Privacy Policy: www.juce.com/juce-privacy-policy
|
||||
|
||||
Or: You may also use this code under the terms of the GPL v3 (see
|
||||
www.gnu.org/licenses).
|
||||
|
||||
JUCE IS PROVIDED "AS IS" WITHOUT ANY WARRANTY, AND ALL WARRANTIES, WHETHER
|
||||
EXPRESSED OR IMPLIED, INCLUDING MERCHANTABILITY AND FITNESS FOR PURPOSE, ARE
|
||||
DISCLAIMED.
|
||||
|
||||
==============================================================================
|
||||
*/
|
||||
|
||||
namespace juce
|
||||
{
|
||||
|
||||
#ifndef DOXYGEN
|
||||
|
||||
struct ModifierKeyProvider
|
||||
{
|
||||
virtual ~ModifierKeyProvider() {}
|
||||
virtual int getWin32Modifiers() const = 0;
|
||||
};
|
||||
|
||||
struct ModifierKeyReceiver
|
||||
{
|
||||
virtual ~ModifierKeyReceiver() {}
|
||||
virtual void setModifierKeyProvider (ModifierKeyProvider*) = 0;
|
||||
virtual void removeModifierKeyProvider() = 0;
|
||||
};
|
||||
|
||||
#endif
|
||||
|
||||
} // namespace juce
|
||||
|
||||
File diff suppressed because it is too large
Load Diff
44
deps/juce/modules/juce_audio_plugin_client/ARA/juce_ARA_Wrapper.cpp
vendored
Normal file
44
deps/juce/modules/juce_audio_plugin_client/ARA/juce_ARA_Wrapper.cpp
vendored
Normal file
@@ -0,0 +1,44 @@
|
||||
/*
|
||||
==============================================================================
|
||||
|
||||
This file is part of the JUCE library.
|
||||
Copyright (c) 2022 - Raw Material Software Limited
|
||||
|
||||
JUCE is an open source library subject to commercial or open-source
|
||||
licensing.
|
||||
|
||||
By using JUCE, you agree to the terms of both the JUCE 7 End-User License
|
||||
Agreement and JUCE Privacy Policy.
|
||||
|
||||
End User License Agreement: www.juce.com/juce-7-licence
|
||||
Privacy Policy: www.juce.com/juce-privacy-policy
|
||||
|
||||
Or: You may also use this code under the terms of the GPL v3 (see
|
||||
www.gnu.org/licenses).
|
||||
|
||||
JUCE IS PROVIDED "AS IS" WITHOUT ANY WARRANTY, AND ALL WARRANTIES, WHETHER
|
||||
EXPRESSED OR IMPLIED, INCLUDING MERCHANTABILITY AND FITNESS FOR PURPOSE, ARE
|
||||
DISCLAIMED.
|
||||
|
||||
==============================================================================
|
||||
*/
|
||||
|
||||
#include <juce_core/system/juce_TargetPlatform.h>
|
||||
#include "../utility/juce_CheckSettingMacros.h"
|
||||
|
||||
#if JucePlugin_Enable_ARA
|
||||
|
||||
#include "../utility/juce_IncludeSystemHeaders.h"
|
||||
#include "../utility/juce_IncludeModuleHeaders.h"
|
||||
|
||||
JUCE_BEGIN_IGNORE_WARNINGS_GCC_LIKE ("-Wunused-parameter", "-Wgnu-zero-variadic-macro-arguments", "-Wmissing-prototypes")
|
||||
JUCE_BEGIN_IGNORE_WARNINGS_MSVC (4100)
|
||||
|
||||
#include <ARA_Library/PlugIn/ARAPlug.cpp>
|
||||
#include <ARA_Library/Dispatch/ARAPlugInDispatch.cpp>
|
||||
#include <ARA_Library/Utilities/ARAPitchInterpretation.cpp>
|
||||
|
||||
JUCE_END_IGNORE_WARNINGS_MSVC
|
||||
JUCE_END_IGNORE_WARNINGS_GCC_LIKE
|
||||
|
||||
#endif
|
||||
File diff suppressed because it is too large
Load Diff
File diff suppressed because it is too large
Load Diff
@@ -1,75 +1,75 @@
|
||||
/*
|
||||
File: AUBaseHelper.h
|
||||
Abstract: Part of CoreAudio Utility Classes
|
||||
Version: 1.1
|
||||
|
||||
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.
|
||||
|
||||
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.
|
||||
|
||||
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.
|
||||
|
||||
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.
|
||||
|
||||
Copyright (C) 2014 Apple Inc. All Rights Reserved.
|
||||
|
||||
*/
|
||||
#ifndef __AUBaseHelper_h__
|
||||
#define __AUBaseHelper_h__
|
||||
|
||||
#if !defined(__COREAUDIO_USE_FLAT_INCLUDES__)
|
||||
#include <CoreFoundation/CoreFoundation.h>
|
||||
#include <AudioUnit/AUComponent.h>
|
||||
#else
|
||||
#include <CoreFoundation.h>
|
||||
#include <AUComponent.h>
|
||||
#endif
|
||||
|
||||
#include "AUBase.h"
|
||||
|
||||
// helpers for dealing with the file-references dictionary in an AUPreset
|
||||
OSStatus GetFileRefPath (CFDictionaryRef parent, CFStringRef frKey, CFStringRef * fPath);
|
||||
|
||||
// if fileRefDict is NULL, this call creates one
|
||||
// if not NULL, then the key value is added to it
|
||||
CFMutableDictionaryRef CreateFileRefDict (CFStringRef fKey, CFStringRef fPath, CFMutableDictionaryRef fileRefDict);
|
||||
|
||||
int AccessURLAsset(const CFURLRef inURL, int mode);
|
||||
|
||||
#if DEBUG
|
||||
void PrintAUParamEvent (AudioUnitParameterEvent& event, FILE* f);
|
||||
#endif
|
||||
|
||||
|
||||
|
||||
#endif // __AUBaseHelper_h__
|
||||
/*
|
||||
File: AUBaseHelper.h
|
||||
Abstract: Part of CoreAudio Utility Classes
|
||||
Version: 1.1
|
||||
|
||||
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.
|
||||
|
||||
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.
|
||||
|
||||
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.
|
||||
|
||||
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.
|
||||
|
||||
Copyright (C) 2014 Apple Inc. All Rights Reserved.
|
||||
|
||||
*/
|
||||
#ifndef __AUBaseHelper_h__
|
||||
#define __AUBaseHelper_h__
|
||||
|
||||
#if !defined(__COREAUDIO_USE_FLAT_INCLUDES__)
|
||||
#include <CoreFoundation/CoreFoundation.h>
|
||||
#include <AudioUnit/AUComponent.h>
|
||||
#else
|
||||
#include <CoreFoundation.h>
|
||||
#include <AUComponent.h>
|
||||
#endif
|
||||
|
||||
#include "AUBase.h"
|
||||
|
||||
// helpers for dealing with the file-references dictionary in an AUPreset
|
||||
OSStatus GetFileRefPath (CFDictionaryRef parent, CFStringRef frKey, CFStringRef * fPath);
|
||||
|
||||
// if fileRefDict is NULL, this call creates one
|
||||
// if not NULL, then the key value is added to it
|
||||
CFMutableDictionaryRef CreateFileRefDict (CFStringRef fKey, CFStringRef fPath, CFMutableDictionaryRef fileRefDict);
|
||||
|
||||
int AccessURLAsset(const CFURLRef inURL, int mode);
|
||||
|
||||
#if DEBUG
|
||||
void PrintAUParamEvent (AudioUnitParameterEvent& event, FILE* f);
|
||||
#endif
|
||||
|
||||
|
||||
|
||||
#endif // __AUBaseHelper_h__
|
||||
|
||||
@@ -1,219 +1,219 @@
|
||||
/*
|
||||
File: AUBuffer.cpp
|
||||
Abstract: AUBuffer.h
|
||||
Version: 1.1
|
||||
|
||||
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.
|
||||
|
||||
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.
|
||||
|
||||
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.
|
||||
|
||||
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.
|
||||
|
||||
Copyright (C) 2014 Apple Inc. All Rights Reserved.
|
||||
|
||||
*/
|
||||
#include "AUBuffer.h"
|
||||
#include <stdlib.h>
|
||||
|
||||
AUBufferList::~AUBufferList()
|
||||
{
|
||||
Deallocate();
|
||||
if (mPtrs)
|
||||
free(mPtrs);
|
||||
}
|
||||
|
||||
// a * b + c
|
||||
static UInt32 SafeMultiplyAddUInt32(UInt32 a, UInt32 b, UInt32 c)
|
||||
{
|
||||
if (a == 0 || b == 0) return c; // prevent zero divide
|
||||
|
||||
if (a > (0xFFFFFFFF - c) / b)
|
||||
throw std::bad_alloc();
|
||||
|
||||
return a * b + c;
|
||||
}
|
||||
|
||||
void AUBufferList::Allocate(const CAStreamBasicDescription &format, UInt32 nFrames)
|
||||
{
|
||||
UInt32 nStreams;
|
||||
if (format.IsInterleaved()) {
|
||||
nStreams = 1;
|
||||
} else {
|
||||
nStreams = format.mChannelsPerFrame;
|
||||
}
|
||||
|
||||
// careful -- the I/O thread could be running!
|
||||
if (nStreams > mAllocatedStreams) {
|
||||
size_t theHeaderSize = sizeof(AudioBufferList) - sizeof(AudioBuffer);
|
||||
mPtrs = (AudioBufferList *)CA_realloc(mPtrs,
|
||||
SafeMultiplyAddUInt32(nStreams, sizeof(AudioBuffer), theHeaderSize));
|
||||
mAllocatedStreams = nStreams;
|
||||
}
|
||||
UInt32 bytesPerStream = SafeMultiplyAddUInt32(nFrames, format.mBytesPerFrame, 0xF) & ~0xF;
|
||||
UInt32 nBytes = SafeMultiplyAddUInt32(nStreams, bytesPerStream, 0);
|
||||
if (nBytes > mAllocatedBytes) {
|
||||
if (mExternalMemory) {
|
||||
mExternalMemory = false;
|
||||
mMemory = NULL;
|
||||
}
|
||||
mMemory = (Byte *)CA_realloc(mMemory, nBytes);
|
||||
mAllocatedBytes = nBytes;
|
||||
}
|
||||
mAllocatedFrames = nFrames;
|
||||
mPtrState = kPtrsInvalid;
|
||||
}
|
||||
|
||||
void AUBufferList::Deallocate()
|
||||
{
|
||||
mAllocatedStreams = 0;
|
||||
mAllocatedFrames = 0;
|
||||
mAllocatedBytes = 0;
|
||||
// this causes a world of hurt if someone upstream disconnects during I/O (SysSoundGraph)
|
||||
/* if (mPtrs) {
|
||||
printf("deallocating bufferlist %08X\n", int(mPtrs));
|
||||
free(mPtrs);
|
||||
mPtrs = NULL;
|
||||
} */
|
||||
if (mMemory) {
|
||||
if (mExternalMemory)
|
||||
mExternalMemory = false;
|
||||
else
|
||||
free(mMemory);
|
||||
mMemory = NULL;
|
||||
}
|
||||
mPtrState = kPtrsInvalid;
|
||||
}
|
||||
|
||||
AudioBufferList & AUBufferList::PrepareBuffer(const CAStreamBasicDescription &format, UInt32 nFrames)
|
||||
{
|
||||
if (nFrames > mAllocatedFrames)
|
||||
COMPONENT_THROW(kAudioUnitErr_TooManyFramesToProcess);
|
||||
|
||||
UInt32 nStreams;
|
||||
UInt32 channelsPerStream;
|
||||
if (format.IsInterleaved()) {
|
||||
nStreams = 1;
|
||||
channelsPerStream = format.mChannelsPerFrame;
|
||||
} else {
|
||||
nStreams = format.mChannelsPerFrame;
|
||||
channelsPerStream = 1;
|
||||
if (nStreams > mAllocatedStreams)
|
||||
COMPONENT_THROW(kAudioUnitErr_FormatNotSupported);
|
||||
}
|
||||
|
||||
AudioBufferList *abl = mPtrs;
|
||||
abl->mNumberBuffers = nStreams;
|
||||
AudioBuffer *buf = abl->mBuffers;
|
||||
Byte *mem = mMemory;
|
||||
UInt32 streamInterval = (mAllocatedFrames * format.mBytesPerFrame + 0xF) & ~0xF;
|
||||
UInt32 bytesPerBuffer = nFrames * format.mBytesPerFrame;
|
||||
for ( ; nStreams--; ++buf) {
|
||||
buf->mNumberChannels = channelsPerStream;
|
||||
buf->mData = mem;
|
||||
buf->mDataByteSize = bytesPerBuffer;
|
||||
mem += streamInterval;
|
||||
}
|
||||
if (UInt32(mem - mMemory) > mAllocatedBytes)
|
||||
COMPONENT_THROW(kAudioUnitErr_TooManyFramesToProcess);
|
||||
mPtrState = kPtrsToMyMemory;
|
||||
return *mPtrs;
|
||||
}
|
||||
|
||||
AudioBufferList & AUBufferList::PrepareNullBuffer(const CAStreamBasicDescription &format, UInt32 nFrames)
|
||||
{
|
||||
UInt32 nStreams;
|
||||
UInt32 channelsPerStream;
|
||||
if (format.IsInterleaved()) {
|
||||
nStreams = 1;
|
||||
channelsPerStream = format.mChannelsPerFrame;
|
||||
} else {
|
||||
nStreams = format.mChannelsPerFrame;
|
||||
channelsPerStream = 1;
|
||||
if (nStreams > mAllocatedStreams)
|
||||
COMPONENT_THROW(kAudioUnitErr_FormatNotSupported);
|
||||
}
|
||||
AudioBufferList *abl = mPtrs;
|
||||
abl->mNumberBuffers = nStreams;
|
||||
AudioBuffer *buf = abl->mBuffers;
|
||||
UInt32 bytesPerBuffer = nFrames * format.mBytesPerFrame;
|
||||
for ( ; nStreams--; ++buf) {
|
||||
buf->mNumberChannels = channelsPerStream;
|
||||
buf->mData = NULL;
|
||||
buf->mDataByteSize = bytesPerBuffer;
|
||||
}
|
||||
mPtrState = kPtrsToExternalMemory;
|
||||
return *mPtrs;
|
||||
}
|
||||
|
||||
// this should NOT be called while I/O is in process
|
||||
void AUBufferList::UseExternalBuffer(const CAStreamBasicDescription &format, const AudioUnitExternalBuffer &buf)
|
||||
{
|
||||
UInt32 alignedSize = buf.size & ~0xF;
|
||||
if (mMemory != NULL && alignedSize >= mAllocatedBytes) {
|
||||
// don't accept the buffer if we already have one and it's big enough
|
||||
// if we don't already have one, we don't need one
|
||||
Byte *oldMemory = mMemory;
|
||||
mMemory = buf.buffer;
|
||||
mAllocatedBytes = alignedSize;
|
||||
// from Allocate(): nBytes = nStreams * nFrames * format.mBytesPerFrame;
|
||||
// thus: nFrames = nBytes / (nStreams * format.mBytesPerFrame)
|
||||
mAllocatedFrames = mAllocatedBytes / (format.NumberChannelStreams() * format.mBytesPerFrame);
|
||||
mExternalMemory = true;
|
||||
free(oldMemory);
|
||||
}
|
||||
}
|
||||
|
||||
#if DEBUG
|
||||
void AUBufferList::PrintBuffer(const char *label, int subscript, const AudioBufferList &abl, UInt32 nFrames, bool asFloats)
|
||||
{
|
||||
printf(" %s [%d] 0x%08lX:\n", label, subscript, long(&abl));
|
||||
const AudioBuffer *buf = abl.mBuffers;
|
||||
for (UInt32 i = 0; i < abl.mNumberBuffers; ++buf, ++i) {
|
||||
printf(" [%2d] %5dbytes %dch @ %p: ", (int)i, (int)buf->mDataByteSize, (int)buf->mNumberChannels, buf->mData);
|
||||
if (buf->mData != NULL) {
|
||||
UInt32 nSamples = nFrames * buf->mNumberChannels;
|
||||
for (UInt32 j = 0; j < nSamples; ++j) {
|
||||
if (nSamples > 16 && (j % 16) == 0)
|
||||
printf("\n\t");
|
||||
if (asFloats)
|
||||
printf(" %6.3f", ((float *)buf->mData)[j]);
|
||||
else
|
||||
printf(" %08X", (unsigned)((UInt32 *)buf->mData)[j]);
|
||||
}
|
||||
}
|
||||
printf("\n");
|
||||
}
|
||||
}
|
||||
#endif
|
||||
/*
|
||||
File: AUBuffer.cpp
|
||||
Abstract: AUBuffer.h
|
||||
Version: 1.1
|
||||
|
||||
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.
|
||||
|
||||
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.
|
||||
|
||||
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.
|
||||
|
||||
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.
|
||||
|
||||
Copyright (C) 2014 Apple Inc. All Rights Reserved.
|
||||
|
||||
*/
|
||||
#include "AUBuffer.h"
|
||||
#include <stdlib.h>
|
||||
|
||||
AUBufferList::~AUBufferList()
|
||||
{
|
||||
Deallocate();
|
||||
if (mPtrs)
|
||||
free(mPtrs);
|
||||
}
|
||||
|
||||
// a * b + c
|
||||
static UInt32 SafeMultiplyAddUInt32(UInt32 a, UInt32 b, UInt32 c)
|
||||
{
|
||||
if (a == 0 || b == 0) return c; // prevent zero divide
|
||||
|
||||
if (a > (0xFFFFFFFF - c) / b)
|
||||
throw std::bad_alloc();
|
||||
|
||||
return a * b + c;
|
||||
}
|
||||
|
||||
void AUBufferList::Allocate(const CAStreamBasicDescription &format, UInt32 nFrames)
|
||||
{
|
||||
UInt32 nStreams;
|
||||
if (format.IsInterleaved()) {
|
||||
nStreams = 1;
|
||||
} else {
|
||||
nStreams = format.mChannelsPerFrame;
|
||||
}
|
||||
|
||||
// careful -- the I/O thread could be running!
|
||||
if (nStreams > mAllocatedStreams) {
|
||||
size_t theHeaderSize = sizeof(AudioBufferList) - sizeof(AudioBuffer);
|
||||
mPtrs = (AudioBufferList *)CA_realloc(mPtrs,
|
||||
SafeMultiplyAddUInt32(nStreams, sizeof(AudioBuffer), theHeaderSize));
|
||||
mAllocatedStreams = nStreams;
|
||||
}
|
||||
UInt32 bytesPerStream = SafeMultiplyAddUInt32(nFrames, format.mBytesPerFrame, 0xF) & ~0xF;
|
||||
UInt32 nBytes = SafeMultiplyAddUInt32(nStreams, bytesPerStream, 0);
|
||||
if (nBytes > mAllocatedBytes) {
|
||||
if (mExternalMemory) {
|
||||
mExternalMemory = false;
|
||||
mMemory = NULL;
|
||||
}
|
||||
mMemory = (Byte *)CA_realloc(mMemory, nBytes);
|
||||
mAllocatedBytes = nBytes;
|
||||
}
|
||||
mAllocatedFrames = nFrames;
|
||||
mPtrState = kPtrsInvalid;
|
||||
}
|
||||
|
||||
void AUBufferList::Deallocate()
|
||||
{
|
||||
mAllocatedStreams = 0;
|
||||
mAllocatedFrames = 0;
|
||||
mAllocatedBytes = 0;
|
||||
// this causes a world of hurt if someone upstream disconnects during I/O (SysSoundGraph)
|
||||
/* if (mPtrs) {
|
||||
printf("deallocating bufferlist %08X\n", int(mPtrs));
|
||||
free(mPtrs);
|
||||
mPtrs = NULL;
|
||||
} */
|
||||
if (mMemory) {
|
||||
if (mExternalMemory)
|
||||
mExternalMemory = false;
|
||||
else
|
||||
free(mMemory);
|
||||
mMemory = NULL;
|
||||
}
|
||||
mPtrState = kPtrsInvalid;
|
||||
}
|
||||
|
||||
AudioBufferList & AUBufferList::PrepareBuffer(const CAStreamBasicDescription &format, UInt32 nFrames)
|
||||
{
|
||||
if (nFrames > mAllocatedFrames)
|
||||
COMPONENT_THROW(kAudioUnitErr_TooManyFramesToProcess);
|
||||
|
||||
UInt32 nStreams;
|
||||
UInt32 channelsPerStream;
|
||||
if (format.IsInterleaved()) {
|
||||
nStreams = 1;
|
||||
channelsPerStream = format.mChannelsPerFrame;
|
||||
} else {
|
||||
nStreams = format.mChannelsPerFrame;
|
||||
channelsPerStream = 1;
|
||||
if (nStreams > mAllocatedStreams)
|
||||
COMPONENT_THROW(kAudioUnitErr_FormatNotSupported);
|
||||
}
|
||||
|
||||
AudioBufferList *abl = mPtrs;
|
||||
abl->mNumberBuffers = nStreams;
|
||||
AudioBuffer *buf = abl->mBuffers;
|
||||
Byte *mem = mMemory;
|
||||
UInt32 streamInterval = (mAllocatedFrames * format.mBytesPerFrame + 0xF) & ~0xF;
|
||||
UInt32 bytesPerBuffer = nFrames * format.mBytesPerFrame;
|
||||
for ( ; nStreams--; ++buf) {
|
||||
buf->mNumberChannels = channelsPerStream;
|
||||
buf->mData = mem;
|
||||
buf->mDataByteSize = bytesPerBuffer;
|
||||
mem += streamInterval;
|
||||
}
|
||||
if (UInt32(mem - mMemory) > mAllocatedBytes)
|
||||
COMPONENT_THROW(kAudioUnitErr_TooManyFramesToProcess);
|
||||
mPtrState = kPtrsToMyMemory;
|
||||
return *mPtrs;
|
||||
}
|
||||
|
||||
AudioBufferList & AUBufferList::PrepareNullBuffer(const CAStreamBasicDescription &format, UInt32 nFrames)
|
||||
{
|
||||
UInt32 nStreams;
|
||||
UInt32 channelsPerStream;
|
||||
if (format.IsInterleaved()) {
|
||||
nStreams = 1;
|
||||
channelsPerStream = format.mChannelsPerFrame;
|
||||
} else {
|
||||
nStreams = format.mChannelsPerFrame;
|
||||
channelsPerStream = 1;
|
||||
if (nStreams > mAllocatedStreams)
|
||||
COMPONENT_THROW(kAudioUnitErr_FormatNotSupported);
|
||||
}
|
||||
AudioBufferList *abl = mPtrs;
|
||||
abl->mNumberBuffers = nStreams;
|
||||
AudioBuffer *buf = abl->mBuffers;
|
||||
UInt32 bytesPerBuffer = nFrames * format.mBytesPerFrame;
|
||||
for ( ; nStreams--; ++buf) {
|
||||
buf->mNumberChannels = channelsPerStream;
|
||||
buf->mData = NULL;
|
||||
buf->mDataByteSize = bytesPerBuffer;
|
||||
}
|
||||
mPtrState = kPtrsToExternalMemory;
|
||||
return *mPtrs;
|
||||
}
|
||||
|
||||
// this should NOT be called while I/O is in process
|
||||
void AUBufferList::UseExternalBuffer(const CAStreamBasicDescription &format, const AudioUnitExternalBuffer &buf)
|
||||
{
|
||||
UInt32 alignedSize = buf.size & ~0xF;
|
||||
if (mMemory != NULL && alignedSize >= mAllocatedBytes) {
|
||||
// don't accept the buffer if we already have one and it's big enough
|
||||
// if we don't already have one, we don't need one
|
||||
Byte *oldMemory = mMemory;
|
||||
mMemory = buf.buffer;
|
||||
mAllocatedBytes = alignedSize;
|
||||
// from Allocate(): nBytes = nStreams * nFrames * format.mBytesPerFrame;
|
||||
// thus: nFrames = nBytes / (nStreams * format.mBytesPerFrame)
|
||||
mAllocatedFrames = mAllocatedBytes / (format.NumberChannelStreams() * format.mBytesPerFrame);
|
||||
mExternalMemory = true;
|
||||
free(oldMemory);
|
||||
}
|
||||
}
|
||||
|
||||
#if DEBUG
|
||||
void AUBufferList::PrintBuffer(const char *label, int subscript, const AudioBufferList &abl, UInt32 nFrames, bool asFloats)
|
||||
{
|
||||
printf(" %s [%d] 0x%08lX:\n", label, subscript, long(&abl));
|
||||
const AudioBuffer *buf = abl.mBuffers;
|
||||
for (UInt32 i = 0; i < abl.mNumberBuffers; ++buf, ++i) {
|
||||
printf(" [%2d] %5dbytes %dch @ %p: ", (int)i, (int)buf->mDataByteSize, (int)buf->mNumberChannels, buf->mData);
|
||||
if (buf->mData != NULL) {
|
||||
UInt32 nSamples = nFrames * buf->mNumberChannels;
|
||||
for (UInt32 j = 0; j < nSamples; ++j) {
|
||||
if (nSamples > 16 && (j % 16) == 0)
|
||||
printf("\n\t");
|
||||
if (asFloats)
|
||||
printf(" %6.3f", ((float *)buf->mData)[j]);
|
||||
else
|
||||
printf(" %08X", (unsigned)((UInt32 *)buf->mData)[j]);
|
||||
}
|
||||
}
|
||||
printf("\n");
|
||||
}
|
||||
}
|
||||
#endif
|
||||
|
||||
@@ -1,267 +1,267 @@
|
||||
/*
|
||||
File: AUBuffer.h
|
||||
Abstract: Part of CoreAudio Utility Classes
|
||||
Version: 1.1
|
||||
|
||||
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.
|
||||
|
||||
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.
|
||||
|
||||
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.
|
||||
|
||||
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.
|
||||
|
||||
Copyright (C) 2014 Apple Inc. All Rights Reserved.
|
||||
|
||||
*/
|
||||
#ifndef __AUBuffer_h__
|
||||
#define __AUBuffer_h__
|
||||
|
||||
#include <TargetConditionals.h>
|
||||
#if !defined(__COREAUDIO_USE_FLAT_INCLUDES__)
|
||||
#include <AudioUnit/AudioUnit.h>
|
||||
#else
|
||||
#include <AudioUnit.h>
|
||||
#endif
|
||||
|
||||
#include <string.h>
|
||||
#include "CAStreamBasicDescription.h"
|
||||
#include "CAAutoDisposer.h"
|
||||
#include "CADebugMacros.h"
|
||||
|
||||
// make this usable outside the stricter context of AudiUnits
|
||||
#ifndef COMPONENT_THROW
|
||||
#define COMPONENT_THROW(err) \
|
||||
do { DebugMessage(#err); throw static_cast<OSStatus>(err); } while (0)
|
||||
#endif
|
||||
|
||||
|
||||
/*! @class AUBufferList */
|
||||
class AUBufferList {
|
||||
enum EPtrState {
|
||||
kPtrsInvalid,
|
||||
kPtrsToMyMemory,
|
||||
kPtrsToExternalMemory
|
||||
};
|
||||
public:
|
||||
/*! @ctor AUBufferList */
|
||||
AUBufferList() : mPtrState(kPtrsInvalid), mExternalMemory(false), mPtrs(NULL), mMemory(NULL),
|
||||
mAllocatedStreams(0), mAllocatedFrames(0), mAllocatedBytes(0) { }
|
||||
/*! @dtor ~AUBufferList */
|
||||
~AUBufferList();
|
||||
|
||||
/*! @method PrepareBuffer */
|
||||
AudioBufferList & PrepareBuffer(const CAStreamBasicDescription &format, UInt32 nFrames);
|
||||
/*! @method PrepareNullBuffer */
|
||||
AudioBufferList & PrepareNullBuffer(const CAStreamBasicDescription &format, UInt32 nFrames);
|
||||
|
||||
/*! @method SetBufferList */
|
||||
AudioBufferList & SetBufferList(const AudioBufferList &abl) {
|
||||
if (mAllocatedStreams < abl.mNumberBuffers)
|
||||
COMPONENT_THROW(-1);
|
||||
mPtrState = kPtrsToExternalMemory;
|
||||
memcpy(mPtrs, &abl, (char *)&abl.mBuffers[abl.mNumberBuffers] - (char *)&abl);
|
||||
return *mPtrs;
|
||||
}
|
||||
|
||||
/*! @method SetBuffer */
|
||||
void SetBuffer(UInt32 index, const AudioBuffer &ab) {
|
||||
if (mPtrState == kPtrsInvalid || index >= mPtrs->mNumberBuffers)
|
||||
COMPONENT_THROW(-1);
|
||||
mPtrState = kPtrsToExternalMemory;
|
||||
mPtrs->mBuffers[index] = ab;
|
||||
}
|
||||
|
||||
/*! @method InvalidateBufferList */
|
||||
void InvalidateBufferList() { mPtrState = kPtrsInvalid; }
|
||||
|
||||
/*! @method GetBufferList */
|
||||
AudioBufferList & GetBufferList() const {
|
||||
if (mPtrState == kPtrsInvalid)
|
||||
COMPONENT_THROW(-1);
|
||||
return *mPtrs;
|
||||
}
|
||||
|
||||
/*! @method CopyBufferListTo */
|
||||
void CopyBufferListTo(AudioBufferList &abl) const {
|
||||
if (mPtrState == kPtrsInvalid)
|
||||
COMPONENT_THROW(-1);
|
||||
memcpy(&abl, mPtrs, (char *)&abl.mBuffers[abl.mNumberBuffers] - (char *)&abl);
|
||||
}
|
||||
|
||||
/*! @method CopyBufferContentsTo */
|
||||
void CopyBufferContentsTo(AudioBufferList &abl) const {
|
||||
if (mPtrState == kPtrsInvalid)
|
||||
COMPONENT_THROW(-1);
|
||||
const AudioBuffer *srcbuf = mPtrs->mBuffers;
|
||||
AudioBuffer *destbuf = abl.mBuffers;
|
||||
|
||||
for (UInt32 i = 0; i < abl.mNumberBuffers; ++i, ++srcbuf, ++destbuf) {
|
||||
if (i >= mPtrs->mNumberBuffers) // duplicate last source to additional outputs [4341137]
|
||||
--srcbuf;
|
||||
if (destbuf->mData != srcbuf->mData)
|
||||
memmove(destbuf->mData, srcbuf->mData, srcbuf->mDataByteSize);
|
||||
destbuf->mDataByteSize = srcbuf->mDataByteSize;
|
||||
}
|
||||
}
|
||||
|
||||
/*! @method Allocate */
|
||||
void Allocate(const CAStreamBasicDescription &format, UInt32 nFrames);
|
||||
/*! @method Deallocate */
|
||||
void Deallocate();
|
||||
|
||||
/*! @method UseExternalBuffer */
|
||||
void UseExternalBuffer(const CAStreamBasicDescription &format, const AudioUnitExternalBuffer &buf);
|
||||
|
||||
// AudioBufferList utilities
|
||||
/*! @method ZeroBuffer */
|
||||
static void ZeroBuffer(AudioBufferList &abl) {
|
||||
AudioBuffer *buf = abl.mBuffers;
|
||||
for (UInt32 i = abl.mNumberBuffers ; i--; ++buf)
|
||||
memset(buf->mData, 0, buf->mDataByteSize);
|
||||
}
|
||||
#if DEBUG
|
||||
/*! @method PrintBuffer */
|
||||
static void PrintBuffer(const char *label, int subscript, const AudioBufferList &abl, UInt32 nFrames = 8, bool asFloats = true);
|
||||
#endif
|
||||
|
||||
/*! @method GetAllocatedFrames */
|
||||
UInt32 GetAllocatedFrames() const { return mAllocatedFrames; }
|
||||
|
||||
private:
|
||||
/*! @ctor AUBufferList */
|
||||
AUBufferList(AUBufferList &) { } // prohibit copy constructor
|
||||
|
||||
/*! @var mPtrState */
|
||||
EPtrState mPtrState;
|
||||
/*! @var mExternalMemory */
|
||||
bool mExternalMemory;
|
||||
/*! @var mPtrs */
|
||||
AudioBufferList * mPtrs;
|
||||
/*! @var mMemory */
|
||||
Byte * mMemory;
|
||||
/*! @var mAllocatedStreams */
|
||||
UInt32 mAllocatedStreams;
|
||||
/*! @var mAllocatedFrames */
|
||||
UInt32 mAllocatedFrames;
|
||||
/*! @var mAllocatedBytes */
|
||||
UInt32 mAllocatedBytes;
|
||||
};
|
||||
|
||||
|
||||
// Allocates an array of samples (type T), to be optimally aligned for the processor
|
||||
/*! @class TAUBuffer */
|
||||
template <class T>
|
||||
class TAUBuffer {
|
||||
public:
|
||||
enum {
|
||||
kAlignInterval = 0x10,
|
||||
kAlignMask = kAlignInterval - 1
|
||||
};
|
||||
|
||||
/*! @ctor TAUBuffer.0 */
|
||||
TAUBuffer() : mMemObject(NULL), mAlignedBuffer(NULL), mBufferSizeBytes(0)
|
||||
{
|
||||
}
|
||||
|
||||
/*! @ctor TAUBuffer.1 */
|
||||
TAUBuffer(UInt32 numElems, UInt32 numChannels) : mMemObject(NULL), mAlignedBuffer(NULL),
|
||||
mBufferSizeBytes(0)
|
||||
{
|
||||
Allocate(numElems, numChannels);
|
||||
}
|
||||
|
||||
/*! @dtor ~TAUBuffer */
|
||||
~TAUBuffer()
|
||||
{
|
||||
Deallocate();
|
||||
}
|
||||
|
||||
/*! @method Allocate */
|
||||
void Allocate(UInt32 numElems) // can also re-allocate
|
||||
{
|
||||
UInt32 reqSize = numElems * sizeof(T);
|
||||
|
||||
if (mMemObject != NULL && reqSize == mBufferSizeBytes)
|
||||
return; // already allocated
|
||||
|
||||
mBufferSizeBytes = reqSize;
|
||||
mMemObject = CA_realloc(mMemObject, reqSize);
|
||||
UInt32 misalign = (uintptr_t)mMemObject & kAlignMask;
|
||||
if (misalign) {
|
||||
mMemObject = CA_realloc(mMemObject, reqSize + kAlignMask);
|
||||
mAlignedBuffer = (T *)((char *)mMemObject + kAlignInterval - misalign);
|
||||
} else
|
||||
mAlignedBuffer = (T *)mMemObject;
|
||||
}
|
||||
|
||||
/*! @method Deallocate */
|
||||
void Deallocate()
|
||||
{
|
||||
if (mMemObject == NULL) return; // so this method has no effect if we're using
|
||||
// an external buffer
|
||||
|
||||
free(mMemObject);
|
||||
mMemObject = NULL;
|
||||
mAlignedBuffer = NULL;
|
||||
mBufferSizeBytes = 0;
|
||||
}
|
||||
|
||||
/*! @method AllocateClear */
|
||||
void AllocateClear(UInt32 numElems) // can also re-allocate
|
||||
{
|
||||
Allocate(numElems);
|
||||
Clear();
|
||||
}
|
||||
|
||||
/*! @method Clear */
|
||||
void Clear()
|
||||
{
|
||||
memset(mAlignedBuffer, 0, mBufferSizeBytes);
|
||||
}
|
||||
|
||||
// accessors
|
||||
|
||||
/*! @method operator T *()@ */
|
||||
operator T *() { return mAlignedBuffer; }
|
||||
|
||||
private:
|
||||
/*! @var mMemObject */
|
||||
void * mMemObject; // null when using an external buffer
|
||||
/*! @var mAlignedBuffer */
|
||||
T * mAlignedBuffer; // always valid once allocated
|
||||
/*! @var mBufferSizeBytes */
|
||||
UInt32 mBufferSizeBytes;
|
||||
};
|
||||
|
||||
#endif // __AUBuffer_h__
|
||||
/*
|
||||
File: AUBuffer.h
|
||||
Abstract: Part of CoreAudio Utility Classes
|
||||
Version: 1.1
|
||||
|
||||
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.
|
||||
|
||||
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.
|
||||
|
||||
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.
|
||||
|
||||
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.
|
||||
|
||||
Copyright (C) 2014 Apple Inc. All Rights Reserved.
|
||||
|
||||
*/
|
||||
#ifndef __AUBuffer_h__
|
||||
#define __AUBuffer_h__
|
||||
|
||||
#include <TargetConditionals.h>
|
||||
#if !defined(__COREAUDIO_USE_FLAT_INCLUDES__)
|
||||
#include <AudioUnit/AudioUnit.h>
|
||||
#else
|
||||
#include <AudioUnit.h>
|
||||
#endif
|
||||
|
||||
#include <string.h>
|
||||
#include "CAStreamBasicDescription.h"
|
||||
#include "CAAutoDisposer.h"
|
||||
#include "CADebugMacros.h"
|
||||
|
||||
// make this usable outside the stricter context of AudiUnits
|
||||
#ifndef COMPONENT_THROW
|
||||
#define COMPONENT_THROW(err) \
|
||||
do { DebugMessage(#err); throw static_cast<OSStatus>(err); } while (0)
|
||||
#endif
|
||||
|
||||
|
||||
/*! @class AUBufferList */
|
||||
class AUBufferList {
|
||||
enum EPtrState {
|
||||
kPtrsInvalid,
|
||||
kPtrsToMyMemory,
|
||||
kPtrsToExternalMemory
|
||||
};
|
||||
public:
|
||||
/*! @ctor AUBufferList */
|
||||
AUBufferList() : mPtrState(kPtrsInvalid), mExternalMemory(false), mPtrs(NULL), mMemory(NULL),
|
||||
mAllocatedStreams(0), mAllocatedFrames(0), mAllocatedBytes(0) { }
|
||||
/*! @dtor ~AUBufferList */
|
||||
~AUBufferList();
|
||||
|
||||
/*! @method PrepareBuffer */
|
||||
AudioBufferList & PrepareBuffer(const CAStreamBasicDescription &format, UInt32 nFrames);
|
||||
/*! @method PrepareNullBuffer */
|
||||
AudioBufferList & PrepareNullBuffer(const CAStreamBasicDescription &format, UInt32 nFrames);
|
||||
|
||||
/*! @method SetBufferList */
|
||||
AudioBufferList & SetBufferList(const AudioBufferList &abl) {
|
||||
if (mAllocatedStreams < abl.mNumberBuffers)
|
||||
COMPONENT_THROW(-1);
|
||||
mPtrState = kPtrsToExternalMemory;
|
||||
memcpy(mPtrs, &abl, (char *)&abl.mBuffers[abl.mNumberBuffers] - (char *)&abl);
|
||||
return *mPtrs;
|
||||
}
|
||||
|
||||
/*! @method SetBuffer */
|
||||
void SetBuffer(UInt32 index, const AudioBuffer &ab) {
|
||||
if (mPtrState == kPtrsInvalid || index >= mPtrs->mNumberBuffers)
|
||||
COMPONENT_THROW(-1);
|
||||
mPtrState = kPtrsToExternalMemory;
|
||||
mPtrs->mBuffers[index] = ab;
|
||||
}
|
||||
|
||||
/*! @method InvalidateBufferList */
|
||||
void InvalidateBufferList() { mPtrState = kPtrsInvalid; }
|
||||
|
||||
/*! @method GetBufferList */
|
||||
AudioBufferList & GetBufferList() const {
|
||||
if (mPtrState == kPtrsInvalid)
|
||||
COMPONENT_THROW(-1);
|
||||
return *mPtrs;
|
||||
}
|
||||
|
||||
/*! @method CopyBufferListTo */
|
||||
void CopyBufferListTo(AudioBufferList &abl) const {
|
||||
if (mPtrState == kPtrsInvalid)
|
||||
COMPONENT_THROW(-1);
|
||||
memcpy(&abl, mPtrs, (char *)&abl.mBuffers[abl.mNumberBuffers] - (char *)&abl);
|
||||
}
|
||||
|
||||
/*! @method CopyBufferContentsTo */
|
||||
void CopyBufferContentsTo(AudioBufferList &abl) const {
|
||||
if (mPtrState == kPtrsInvalid)
|
||||
COMPONENT_THROW(-1);
|
||||
const AudioBuffer *srcbuf = mPtrs->mBuffers;
|
||||
AudioBuffer *destbuf = abl.mBuffers;
|
||||
|
||||
for (UInt32 i = 0; i < abl.mNumberBuffers; ++i, ++srcbuf, ++destbuf) {
|
||||
if (i >= mPtrs->mNumberBuffers) // duplicate last source to additional outputs [4341137]
|
||||
--srcbuf;
|
||||
if (destbuf->mData != srcbuf->mData)
|
||||
memmove(destbuf->mData, srcbuf->mData, srcbuf->mDataByteSize);
|
||||
destbuf->mDataByteSize = srcbuf->mDataByteSize;
|
||||
}
|
||||
}
|
||||
|
||||
/*! @method Allocate */
|
||||
void Allocate(const CAStreamBasicDescription &format, UInt32 nFrames);
|
||||
/*! @method Deallocate */
|
||||
void Deallocate();
|
||||
|
||||
/*! @method UseExternalBuffer */
|
||||
void UseExternalBuffer(const CAStreamBasicDescription &format, const AudioUnitExternalBuffer &buf);
|
||||
|
||||
// AudioBufferList utilities
|
||||
/*! @method ZeroBuffer */
|
||||
static void ZeroBuffer(AudioBufferList &abl) {
|
||||
AudioBuffer *buf = abl.mBuffers;
|
||||
for (UInt32 i = abl.mNumberBuffers ; i--; ++buf)
|
||||
memset(buf->mData, 0, buf->mDataByteSize);
|
||||
}
|
||||
#if DEBUG
|
||||
/*! @method PrintBuffer */
|
||||
static void PrintBuffer(const char *label, int subscript, const AudioBufferList &abl, UInt32 nFrames = 8, bool asFloats = true);
|
||||
#endif
|
||||
|
||||
/*! @method GetAllocatedFrames */
|
||||
UInt32 GetAllocatedFrames() const { return mAllocatedFrames; }
|
||||
|
||||
private:
|
||||
/*! @ctor AUBufferList */
|
||||
AUBufferList(AUBufferList &) { } // prohibit copy constructor
|
||||
|
||||
/*! @var mPtrState */
|
||||
EPtrState mPtrState;
|
||||
/*! @var mExternalMemory */
|
||||
bool mExternalMemory;
|
||||
/*! @var mPtrs */
|
||||
AudioBufferList * mPtrs;
|
||||
/*! @var mMemory */
|
||||
Byte * mMemory;
|
||||
/*! @var mAllocatedStreams */
|
||||
UInt32 mAllocatedStreams;
|
||||
/*! @var mAllocatedFrames */
|
||||
UInt32 mAllocatedFrames;
|
||||
/*! @var mAllocatedBytes */
|
||||
UInt32 mAllocatedBytes;
|
||||
};
|
||||
|
||||
|
||||
// Allocates an array of samples (type T), to be optimally aligned for the processor
|
||||
/*! @class TAUBuffer */
|
||||
template <class T>
|
||||
class TAUBuffer {
|
||||
public:
|
||||
enum {
|
||||
kAlignInterval = 0x10,
|
||||
kAlignMask = kAlignInterval - 1
|
||||
};
|
||||
|
||||
/*! @ctor TAUBuffer.0 */
|
||||
TAUBuffer() : mMemObject(NULL), mAlignedBuffer(NULL), mBufferSizeBytes(0)
|
||||
{
|
||||
}
|
||||
|
||||
/*! @ctor TAUBuffer.1 */
|
||||
TAUBuffer(UInt32 numElems, UInt32 numChannels) : mMemObject(NULL), mAlignedBuffer(NULL),
|
||||
mBufferSizeBytes(0)
|
||||
{
|
||||
Allocate(numElems, numChannels);
|
||||
}
|
||||
|
||||
/*! @dtor ~TAUBuffer */
|
||||
~TAUBuffer()
|
||||
{
|
||||
Deallocate();
|
||||
}
|
||||
|
||||
/*! @method Allocate */
|
||||
void Allocate(UInt32 numElems) // can also re-allocate
|
||||
{
|
||||
UInt32 reqSize = numElems * sizeof(T);
|
||||
|
||||
if (mMemObject != NULL && reqSize == mBufferSizeBytes)
|
||||
return; // already allocated
|
||||
|
||||
mBufferSizeBytes = reqSize;
|
||||
mMemObject = CA_realloc(mMemObject, reqSize);
|
||||
UInt32 misalign = (uintptr_t)mMemObject & kAlignMask;
|
||||
if (misalign) {
|
||||
mMemObject = CA_realloc(mMemObject, reqSize + kAlignMask);
|
||||
mAlignedBuffer = (T *)((char *)mMemObject + kAlignInterval - misalign);
|
||||
} else
|
||||
mAlignedBuffer = (T *)mMemObject;
|
||||
}
|
||||
|
||||
/*! @method Deallocate */
|
||||
void Deallocate()
|
||||
{
|
||||
if (mMemObject == NULL) return; // so this method has no effect if we're using
|
||||
// an external buffer
|
||||
|
||||
free(mMemObject);
|
||||
mMemObject = NULL;
|
||||
mAlignedBuffer = NULL;
|
||||
mBufferSizeBytes = 0;
|
||||
}
|
||||
|
||||
/*! @method AllocateClear */
|
||||
void AllocateClear(UInt32 numElems) // can also re-allocate
|
||||
{
|
||||
Allocate(numElems);
|
||||
Clear();
|
||||
}
|
||||
|
||||
/*! @method Clear */
|
||||
void Clear()
|
||||
{
|
||||
memset(mAlignedBuffer, 0, mBufferSizeBytes);
|
||||
}
|
||||
|
||||
// accessors
|
||||
|
||||
/*! @method operator T *()@ */
|
||||
operator T *() { return mAlignedBuffer; }
|
||||
|
||||
private:
|
||||
/*! @var mMemObject */
|
||||
void * mMemObject; // null when using an external buffer
|
||||
/*! @var mAlignedBuffer */
|
||||
T * mAlignedBuffer; // always valid once allocated
|
||||
/*! @var mBufferSizeBytes */
|
||||
UInt32 mBufferSizeBytes;
|
||||
};
|
||||
|
||||
#endif // __AUBuffer_h__
|
||||
|
||||
@@ -1,403 +0,0 @@
|
||||
/*
|
||||
File: AUCarbonViewBase.cpp
|
||||
Abstract: AUCarbonViewBase.h
|
||||
Version: 1.1
|
||||
|
||||
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.
|
||||
|
||||
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.
|
||||
|
||||
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.
|
||||
|
||||
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.
|
||||
|
||||
Copyright (C) 2014 Apple Inc. All Rights Reserved.
|
||||
|
||||
*/
|
||||
#include "AUCarbonViewBase.h"
|
||||
#include "AUCarbonViewControl.h"
|
||||
#include <algorithm>
|
||||
|
||||
AUCarbonViewBase::AUCarbonViewBase(AudioUnitCarbonView inInstance, Float32 inNotificationInterval /* in seconds */) :
|
||||
ComponentBase(inInstance),
|
||||
mEditAudioUnit(0),
|
||||
mParameterListener(NULL),
|
||||
#if !__LP64__
|
||||
mEventListener(NULL),
|
||||
#endif
|
||||
mTimerRef (NULL),
|
||||
mTimerUPP (NULL),
|
||||
mCarbonWindow(NULL),
|
||||
mCarbonPane(NULL),
|
||||
mXOffset(0),
|
||||
mYOffset(0)
|
||||
{
|
||||
AUEventListenerCreate (ParameterListener, this,
|
||||
CFRunLoopGetCurrent(), kCFRunLoopCommonModes,
|
||||
inNotificationInterval, inNotificationInterval,
|
||||
&mParameterListener);
|
||||
}
|
||||
|
||||
AUCarbonViewBase::~AUCarbonViewBase()
|
||||
{
|
||||
#if !__LP64__
|
||||
if (mCarbonPane)
|
||||
DisposeControl(mCarbonPane);
|
||||
|
||||
for (ControlList::iterator it = mControlList.begin(); it != mControlList.end(); ++it) {
|
||||
AUCarbonViewControl *ctl = *it;
|
||||
delete ctl;
|
||||
}
|
||||
AUListenerDispose(mParameterListener);
|
||||
|
||||
if (mTimerRef)
|
||||
::RemoveEventLoopTimer (mTimerRef);
|
||||
|
||||
if (mTimerUPP)
|
||||
DisposeEventLoopTimerUPP (mTimerUPP);
|
||||
#endif
|
||||
}
|
||||
|
||||
void AUCarbonViewBase::AddControl(AUCarbonViewControl *control)
|
||||
{
|
||||
ControlList::iterator it = find(mControlList.begin(), mControlList.end(), control);
|
||||
if (it == mControlList.end())
|
||||
mControlList.push_back(control);
|
||||
}
|
||||
|
||||
void AUCarbonViewBase::RemoveControl(AUCarbonViewControl *control)
|
||||
{
|
||||
ControlList::iterator it = find(mControlList.begin(), mControlList.end(), control);
|
||||
if (it != mControlList.end()) {
|
||||
AUCarbonViewControl *ctl = *it;
|
||||
mControlList.erase(it);
|
||||
delete ctl;
|
||||
}
|
||||
}
|
||||
|
||||
void AUCarbonViewBase::ClearControls ()
|
||||
{
|
||||
for (ControlList::iterator it = mControlList.begin(); it != mControlList.end(); ++it) {
|
||||
AUCarbonViewControl *ctl = *it;
|
||||
delete ctl;
|
||||
}
|
||||
mControlList.clear();
|
||||
}
|
||||
|
||||
void AUCarbonViewBase::ParameterListener(void * inCallbackRefCon,
|
||||
void * inObject,
|
||||
const AudioUnitEvent * inEvent,
|
||||
UInt64 inEventHostTime,
|
||||
Float32 inParameterValue)
|
||||
{
|
||||
if (inEvent->mEventType == kAudioUnitEvent_ParameterValueChange) {
|
||||
AUCarbonViewControl *ctl = (AUCarbonViewControl *)inObject;
|
||||
ctl->ParameterToControl(inParameterValue);
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
OSStatus AUCarbonViewBase::CreateCarbonView(AudioUnit inAudioUnit, WindowRef inWindow, ControlRef inParentControl, const Float32Point &inLocation, const Float32Point &inSize, ControlRef &outParentControl)
|
||||
{
|
||||
#if !__LP64__
|
||||
mEditAudioUnit = inAudioUnit;
|
||||
mCarbonWindow = inWindow;
|
||||
|
||||
WindowAttributes attributes;
|
||||
verify_noerr(GetWindowAttributes(mCarbonWindow, &attributes));
|
||||
mCompositWindow = (attributes & kWindowCompositingAttribute) != 0;
|
||||
|
||||
Rect area;
|
||||
area.left = short(inLocation.x); area.top = short(inLocation.y);
|
||||
area.right = short(area.left + inSize.x); area.bottom = short(area.top + inSize.y);
|
||||
OSStatus err = ::CreateUserPaneControl(inWindow, &area,
|
||||
kControlSupportsEmbedding,
|
||||
&mCarbonPane); // subclass can resize mCarbonPane to taste
|
||||
verify_noerr(err);
|
||||
if (err) return err;
|
||||
outParentControl = mCarbonPane;
|
||||
|
||||
// register for mouse-down in our pane -- we want to clear focus
|
||||
EventTypeSpec paneEvents[] = {
|
||||
{ kEventClassControl, kEventControlClick }
|
||||
};
|
||||
WantEventTypes(GetControlEventTarget(mCarbonPane), GetEventTypeCount(paneEvents), paneEvents);
|
||||
|
||||
if (IsCompositWindow()) {
|
||||
verify_noerr(::HIViewAddSubview(inParentControl, mCarbonPane));
|
||||
mXOffset = 0;
|
||||
mYOffset = 0;
|
||||
}
|
||||
else {
|
||||
verify_noerr(::EmbedControl(mCarbonPane, inParentControl));
|
||||
mXOffset = inLocation.x;
|
||||
mYOffset = inLocation.y;
|
||||
}
|
||||
mBottomRight.h = mBottomRight.v = 0;
|
||||
|
||||
SizeControl(mCarbonPane, 0, 0);
|
||||
if (err = CreateUI(mXOffset, mYOffset))
|
||||
return err;
|
||||
|
||||
// we should only resize the control if a subclass has embedded
|
||||
// controls in this AND this is done with the EmbedControl call below
|
||||
// if mBottomRight is STILL equal to zero, then that wasn't done
|
||||
// so don't size the control
|
||||
Rect paneBounds;
|
||||
GetControlBounds(mCarbonPane, &paneBounds);
|
||||
// only resize mCarbonPane if it has not already been resized during CreateUI
|
||||
if ((paneBounds.top == paneBounds.bottom) && (paneBounds.left == paneBounds.right)) {
|
||||
if (mBottomRight.h != 0 && mBottomRight.v != 0)
|
||||
SizeControl(mCarbonPane, (short) (mBottomRight.h - mXOffset), (short) (mBottomRight.v - mYOffset));
|
||||
}
|
||||
|
||||
if (IsCompositWindow()) {
|
||||
// prepare for handling scroll-events
|
||||
EventTypeSpec scrollEvents[] = {
|
||||
{ kEventClassScrollable, kEventScrollableGetInfo },
|
||||
{ kEventClassScrollable, kEventScrollableScrollTo }
|
||||
};
|
||||
|
||||
WantEventTypes(GetControlEventTarget(mCarbonPane), GetEventTypeCount(scrollEvents), scrollEvents);
|
||||
|
||||
mCurrentScrollPoint.x = mCurrentScrollPoint.y = 0.0f;
|
||||
}
|
||||
|
||||
return err;
|
||||
#else
|
||||
return noErr;
|
||||
#endif
|
||||
}
|
||||
|
||||
OSStatus AUCarbonViewBase::CreateUI(Float32 inXOffset, Float32 inYOffset)
|
||||
{
|
||||
return noErr;
|
||||
}
|
||||
|
||||
OSStatus AUCarbonViewBase::EmbedControl(ControlRef ctl)
|
||||
{
|
||||
#if !__LP64__
|
||||
Rect r;
|
||||
::GetControlBounds(ctl, &r);
|
||||
if (r.right > mBottomRight.h) mBottomRight.h = r.right;
|
||||
if (r.bottom > mBottomRight.v) mBottomRight.v = r.bottom;
|
||||
|
||||
if (IsCompositWindow())
|
||||
return ::HIViewAddSubview(mCarbonPane, ctl);
|
||||
else
|
||||
return ::EmbedControl(ctl, mCarbonPane);
|
||||
#else
|
||||
return noErr;
|
||||
#endif
|
||||
}
|
||||
|
||||
void AUCarbonViewBase::AddCarbonControl(AUCarbonViewControl::ControlType type, const CAAUParameter ¶m, ControlRef control)
|
||||
{
|
||||
verify_noerr(EmbedControl(control));
|
||||
|
||||
AUCarbonViewControl *auvc = new AUCarbonViewControl(this, mParameterListener, type, param, control);
|
||||
auvc->Bind();
|
||||
AddControl(auvc);
|
||||
}
|
||||
|
||||
bool AUCarbonViewBase::HandleEvent(EventHandlerCallRef inHandlerRef, EventRef event)
|
||||
{
|
||||
#if !__LP64__
|
||||
UInt32 eclass = GetEventClass(event);
|
||||
UInt32 ekind = GetEventKind(event);
|
||||
ControlRef control;
|
||||
|
||||
switch (eclass) {
|
||||
case kEventClassControl:
|
||||
{
|
||||
switch (ekind) {
|
||||
case kEventControlClick:
|
||||
GetEventParameter(event, kEventParamDirectObject, typeControlRef, NULL, sizeof(ControlRef), NULL, &control);
|
||||
if (control == mCarbonPane) {
|
||||
ClearKeyboardFocus(mCarbonWindow);
|
||||
return true;
|
||||
}
|
||||
}
|
||||
}
|
||||
break;
|
||||
|
||||
case kEventClassScrollable:
|
||||
{
|
||||
switch (ekind) {
|
||||
case kEventScrollableGetInfo:
|
||||
{
|
||||
// [1/4]
|
||||
/* <-- kEventParamImageSize (out, typeHISize)
|
||||
* On exit, contains the size of the entire scrollable view.
|
||||
*/
|
||||
HISize originalSize = { static_cast<CGFloat>(mBottomRight.h), static_cast<CGFloat>(mBottomRight.v) };
|
||||
verify_noerr(SetEventParameter(event, kEventParamImageSize, typeHISize, sizeof(HISize), &originalSize));
|
||||
|
||||
// [2/4]
|
||||
/* <-- kEventParamViewSize (out, typeHISize)
|
||||
* On exit, contains the amount of the scrollable view that is
|
||||
* visible.
|
||||
*/
|
||||
HIViewRef parentView = HIViewGetSuperview(mCarbonPane);
|
||||
HIRect parentBounds;
|
||||
verify_noerr(HIViewGetBounds(parentView, &parentBounds));
|
||||
//HISize windowSize = { float(windowBounds.right - windowBounds.left),
|
||||
// float(windowBounds.bottom - windowBounds.top) };
|
||||
verify_noerr(SetEventParameter(event, kEventParamViewSize, typeHISize, sizeof(HISize), &(parentBounds.size)));
|
||||
|
||||
// [3/4]
|
||||
/* <-- kEventParamLineSize (out, typeHISize)
|
||||
* On exit, contains the amount that should be scrolled in
|
||||
* response to a single click on a scrollbar arrow.
|
||||
*/
|
||||
HISize scrollIncrementSize = { 16.0f, float(20) };
|
||||
verify_noerr(SetEventParameter(event, kEventParamLineSize, typeHISize, sizeof(HISize), &scrollIncrementSize));
|
||||
|
||||
// [4/4]
|
||||
/* <-- kEventParamOrigin (out, typeHIPoint)
|
||||
* On exit, contains the scrollable view<65>s current origin (the
|
||||
* view-relative coordinate that is drawn at the top left
|
||||
* corner of its frame). These coordinates should always be
|
||||
* greater than or equal to zero. They should be less than or
|
||||
* equal to the view<65>s image size minus its view size.
|
||||
*/
|
||||
verify_noerr(SetEventParameter(event, kEventParamOrigin, typeHIPoint, sizeof(HIPoint), &mCurrentScrollPoint));
|
||||
}
|
||||
return true;
|
||||
|
||||
case kEventScrollableScrollTo:
|
||||
{
|
||||
/*
|
||||
* kEventClassScrollable / kEventScrollableScrollTo
|
||||
*
|
||||
* Summary:
|
||||
* Requests that an HIScrollView<65>s scrollable view should scroll to
|
||||
* a particular origin.
|
||||
*/
|
||||
|
||||
/* --> kEventParamOrigin (in, typeHIPoint)
|
||||
* The new origin for the scrollable view. The origin
|
||||
* coordinates will vary from (0,0) to scrollable view<65>s image
|
||||
* size minus its view size.
|
||||
*/
|
||||
HIPoint pointToScrollTo;
|
||||
verify_noerr(GetEventParameter(event, kEventParamOrigin, typeHIPoint, NULL, sizeof(HIPoint), NULL, &pointToScrollTo));
|
||||
|
||||
float xDelta = mCurrentScrollPoint.x - pointToScrollTo.x;
|
||||
float yDelta = mCurrentScrollPoint.y - pointToScrollTo.y;
|
||||
// move visible portion the appropriate amount
|
||||
verify_noerr(HIViewScrollRect(mCarbonPane, NULL, xDelta, yDelta));
|
||||
// set new content to be drawn
|
||||
verify_noerr(HIViewSetBoundsOrigin(mCarbonPane, pointToScrollTo.x, pointToScrollTo.y));
|
||||
|
||||
mCurrentScrollPoint = pointToScrollTo;
|
||||
}
|
||||
return true;
|
||||
|
||||
default:
|
||||
break;
|
||||
}
|
||||
}
|
||||
break;
|
||||
|
||||
default:
|
||||
break;
|
||||
}
|
||||
#endif
|
||||
return false;
|
||||
}
|
||||
|
||||
/*! @method TellListener */
|
||||
void AUCarbonViewBase::TellListener (const CAAUParameter &auvp, AudioUnitCarbonViewEventID event, void *evpar)
|
||||
{
|
||||
#if !__LP64__
|
||||
if (mEventListener)
|
||||
(*mEventListener)(mEventListenerUserData, mComponentInstance, &auvp, event, evpar);
|
||||
#endif
|
||||
|
||||
AudioUnitEvent auEvent;
|
||||
auEvent.mArgument.mParameter = auvp;
|
||||
if (event == kAudioUnitCarbonViewEvent_MouseDownInControl) {
|
||||
auEvent.mEventType = kAudioUnitEvent_BeginParameterChangeGesture;
|
||||
} else {
|
||||
auEvent.mEventType = kAudioUnitEvent_EndParameterChangeGesture;
|
||||
}
|
||||
AUEventListenerNotify(mParameterListener, this, &auEvent);
|
||||
}
|
||||
|
||||
|
||||
void AUCarbonViewBase::Update (bool inUIThread)
|
||||
{
|
||||
for (ControlList::iterator iter = mControlList.begin(); iter != mControlList.end(); ++iter)
|
||||
{
|
||||
(*iter)->Update(inUIThread);
|
||||
}
|
||||
}
|
||||
|
||||
pascal void AUCarbonViewBase::TheTimerProc (EventLoopTimerRef inTimer, void *inUserData)
|
||||
{
|
||||
AUCarbonViewBase* This = reinterpret_cast<AUCarbonViewBase*>(inUserData);
|
||||
This->RespondToEventTimer (inTimer);
|
||||
}
|
||||
|
||||
void AUCarbonViewBase::RespondToEventTimer (EventLoopTimerRef inTimer)
|
||||
{}
|
||||
|
||||
/*
|
||||
THESE are reasonable values for these two times
|
||||
0.005 // delay
|
||||
0.050 // interval
|
||||
*/
|
||||
|
||||
OSStatus AUCarbonViewBase::CreateEventLoopTimer (Float32 inDelay, Float32 inInterval)
|
||||
{
|
||||
if (mTimerUPP)
|
||||
return noErr;
|
||||
|
||||
mTimerUPP = NewEventLoopTimerUPP(TheTimerProc);
|
||||
|
||||
EventLoopRef mainEventLoop = GetMainEventLoop();
|
||||
|
||||
//doesn't seem to like too small a value
|
||||
if (inDelay < 0.005)
|
||||
inDelay = 0.005;
|
||||
|
||||
OSStatus timerResult = ::InstallEventLoopTimer(
|
||||
mainEventLoop,
|
||||
inDelay,
|
||||
inInterval,
|
||||
mTimerUPP,
|
||||
this,
|
||||
&mTimerRef);
|
||||
return timerResult;
|
||||
}
|
||||
@@ -1,190 +0,0 @@
|
||||
/*
|
||||
File: AUCarbonViewBase.h
|
||||
Abstract: Part of CoreAudio Utility Classes
|
||||
Version: 1.1
|
||||
|
||||
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.
|
||||
|
||||
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.
|
||||
|
||||
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.
|
||||
|
||||
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.
|
||||
|
||||
Copyright (C) 2014 Apple Inc. All Rights Reserved.
|
||||
|
||||
*/
|
||||
#ifndef __AUCarbonViewBase_h__
|
||||
#define __AUCarbonViewBase_h__
|
||||
|
||||
#pragma clang diagnostic ignored "-Wdeprecated-declarations"
|
||||
|
||||
#include <vector>
|
||||
#include "AUCarbonViewControl.h"
|
||||
#include "ComponentBase.h"
|
||||
|
||||
static const Float32 kDefaultNotificationInterval = 0.100;
|
||||
|
||||
/*! @class AUCarbonViewBase */
|
||||
class AUCarbonViewBase : public ComponentBase, public CarbonEventHandler
|
||||
{
|
||||
public:
|
||||
/*! @ctor AUCarbonViewBase */
|
||||
AUCarbonViewBase ( AudioUnitCarbonView inInstance,
|
||||
Float32 inNotificationInterval = kDefaultNotificationInterval /* in seconds */);
|
||||
/*! @dtor ~AUCarbonViewBase */
|
||||
virtual ~AUCarbonViewBase();
|
||||
|
||||
// AUViewBase overrides
|
||||
/*! @method CreateCarbonView */
|
||||
virtual OSStatus CreateCarbonView (AudioUnit inAudioUnit, WindowRef inWindow, ControlRef inParentControl, const Float32Point &inLocation, const Float32Point &inSize, ControlRef &outParentControl);
|
||||
|
||||
// our own virtual methods
|
||||
/*! @method CreateUI */
|
||||
virtual OSStatus CreateUI (Float32 inXOffset, Float32 inYOffset);
|
||||
|
||||
/*! @method HandleEvent */
|
||||
virtual bool HandleEvent (EventHandlerCallRef inHandlerRef, EventRef event);
|
||||
|
||||
/*! @method GetEditAudioUnit */
|
||||
const AudioUnit GetEditAudioUnit () const { return mEditAudioUnit; }
|
||||
//
|
||||
/*! @method ComponentEntryDispatch */
|
||||
static OSStatus ComponentEntryDispatch (
|
||||
ComponentParameters * params,
|
||||
AUCarbonViewBase * This);
|
||||
|
||||
/*! @method AddCarbonControl */
|
||||
void AddCarbonControl (
|
||||
AUCarbonViewControl::ControlType type,
|
||||
const CAAUParameter & param,
|
||||
ControlRef control);
|
||||
|
||||
/*! @method GetCarbonWindow */
|
||||
WindowRef GetCarbonWindow () { return mCarbonWindow; }
|
||||
/*! @method GetCarbonPane */
|
||||
ControlRef GetCarbonPane () { return mCarbonPane; }
|
||||
/*! @method EmbedControl */
|
||||
OSStatus EmbedControl (ControlRef ctl);
|
||||
|
||||
/*! @method TellListener */
|
||||
void TellListener (const CAAUParameter &auvp, AudioUnitCarbonViewEventID event, void *evpar);
|
||||
|
||||
// pass in true if wanting an update to the view and you're calling this from a thread
|
||||
// that is safe to do UI in.
|
||||
// If you don't know, pass in false!
|
||||
/*! @method Update */
|
||||
void Update (bool inUIThread);
|
||||
|
||||
/*! @method GetXOffset */
|
||||
Float32 GetXOffset () { return mXOffset; }
|
||||
/*! @method GetYOffset */
|
||||
Float32 GetYOffset () { return mYOffset; }
|
||||
|
||||
/*! @method ClearControls */
|
||||
void ClearControls ();
|
||||
|
||||
/*! @method IsCompositWindow */
|
||||
bool IsCompositWindow () const { return mCompositWindow; }
|
||||
|
||||
protected:
|
||||
#if !__LP64__
|
||||
/*! @method SetEventListener */
|
||||
void SetEventListener (AudioUnitCarbonViewEventListener listener, void *userData)
|
||||
{
|
||||
mEventListener = listener;
|
||||
mEventListenerUserData = userData;
|
||||
}
|
||||
#endif
|
||||
|
||||
/*! @method AddControl */
|
||||
void AddControl (AUCarbonViewControl *control);
|
||||
/*! @method RemoveControl */
|
||||
void RemoveControl (AUCarbonViewControl *control);
|
||||
|
||||
OSStatus CreateEventLoopTimer (Float32 inDelay, Float32 inInterval);
|
||||
|
||||
/*! @method ParameterListener */
|
||||
static void ParameterListener (void * inCallbackRefCon,
|
||||
void * inObject,
|
||||
const AudioUnitEvent * inEvent,
|
||||
UInt64 inEventHostTime,
|
||||
Float32 inParameterValue);
|
||||
|
||||
static pascal void TheTimerProc ( EventLoopTimerRef inTimer,
|
||||
void * inUserData);
|
||||
|
||||
virtual void RespondToEventTimer (EventLoopTimerRef inTimer);
|
||||
|
||||
/*! @var mEditAudioUnit */
|
||||
AudioUnit mEditAudioUnit; // the AU we're controlling
|
||||
/*! @var mParameterListener */
|
||||
AUEventListenerRef mParameterListener;
|
||||
|
||||
#if !__LP64__
|
||||
/*! @var mEventListener */
|
||||
AudioUnitCarbonViewEventListener
|
||||
mEventListener;
|
||||
#endif
|
||||
|
||||
/*! @var mEventListenerUserData */
|
||||
void * mEventListenerUserData;
|
||||
|
||||
private:
|
||||
typedef std::vector<AUCarbonViewControl *> ControlList;
|
||||
/*! @var mControlList */
|
||||
ControlList mControlList;
|
||||
|
||||
EventLoopTimerRef mTimerRef;
|
||||
|
||||
EventLoopTimerUPP mTimerUPP;
|
||||
|
||||
protected:
|
||||
/*! @var mCarbonWindow */
|
||||
WindowRef mCarbonWindow;
|
||||
/*! @var mCarbonPane */
|
||||
ControlRef mCarbonPane; // user pane, contains all other controls
|
||||
/*! @var mBottomRight */
|
||||
Point mBottomRight; // largest width and height of child controls
|
||||
/*! @var mXOffset */
|
||||
Float32 mXOffset;
|
||||
/*! @var mYOffset */
|
||||
Float32 mYOffset;
|
||||
/*! @var mCompositWindow */
|
||||
bool mCompositWindow;
|
||||
/*! @var mCurrentScrollPoint */
|
||||
HIPoint mCurrentScrollPoint; // needed for scrolling
|
||||
};
|
||||
|
||||
|
||||
#endif // __AUCarbonViewBase_h__
|
||||
@@ -1,710 +0,0 @@
|
||||
/*
|
||||
File: AUCarbonViewControl.cpp
|
||||
Abstract: AUCarbonViewControl.h
|
||||
Version: 1.1
|
||||
|
||||
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.
|
||||
|
||||
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.
|
||||
|
||||
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.
|
||||
|
||||
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.
|
||||
|
||||
Copyright (C) 2014 Apple Inc. All Rights Reserved.
|
||||
|
||||
*/
|
||||
#include "AUCarbonViewControl.h"
|
||||
#include "AUCarbonViewBase.h"
|
||||
#include "AUViewLocalizedStringKeys.h"
|
||||
|
||||
AUCarbonViewControl::AUCarbonViewControl(AUCarbonViewBase *ownerView, AUParameterListenerRef listener, ControlType type, const CAAUParameter ¶m, ControlRef control) :
|
||||
mOwnerView(ownerView),
|
||||
mListener(listener),
|
||||
mType(type),
|
||||
mParam(param),
|
||||
mControl(control),
|
||||
mInControlInitialization(0)
|
||||
{
|
||||
#if !__LP64__
|
||||
SetControlReference(control, SRefCon(this));
|
||||
#endif
|
||||
}
|
||||
|
||||
AUCarbonViewControl::~AUCarbonViewControl()
|
||||
{
|
||||
AUListenerRemoveParameter(mListener, this, &mParam);
|
||||
}
|
||||
|
||||
AUCarbonViewControl* AUCarbonViewControl::mLastControl = NULL;
|
||||
|
||||
void AUCarbonViewControl::Bind()
|
||||
{
|
||||
#if !__LP64__
|
||||
mInControlInitialization = 1; // true
|
||||
AUListenerAddParameter(mListener, this, &mParam);
|
||||
// will cause an almost-immediate callback
|
||||
|
||||
EventTypeSpec events[] = {
|
||||
{ kEventClassControl, kEventControlValueFieldChanged } // N.B. OS X only
|
||||
};
|
||||
|
||||
WantEventTypes(GetControlEventTarget(mControl), GetEventTypeCount(events), events);
|
||||
|
||||
if (mType == kTypeContinuous || mType == kTypeText || mType == kTypeDiscrete) {
|
||||
EventTypeSpec controlEvents[] = {
|
||||
{ kEventClassControl, kEventControlHit },
|
||||
{ kEventClassControl, kEventControlClick },
|
||||
{ kEventClassControl, kEventControlTrack }
|
||||
};
|
||||
WantEventTypes(GetControlEventTarget(mControl), GetEventTypeCount(controlEvents), controlEvents);
|
||||
}
|
||||
|
||||
if (mType == kTypeText) {
|
||||
EventTypeSpec controlFocusEvents[] = {
|
||||
{ kEventClassControl, kEventControlSetFocusPart }
|
||||
};
|
||||
WantEventTypes(GetControlEventTarget(mControl), GetEventTypeCount(controlFocusEvents), controlFocusEvents);
|
||||
ControlKeyFilterUPP proc = mParam.ValuesHaveStrings() ? StdKeyFilterCallback : NumericKeyFilterCallback;
|
||||
// this will fail for a static text field
|
||||
SetControlData(mControl, 0, kControlEditTextKeyFilterTag, sizeof(proc), &proc);
|
||||
}
|
||||
|
||||
Update(true);
|
||||
mInControlInitialization = 0; // false
|
||||
#endif
|
||||
}
|
||||
|
||||
void AUCarbonViewControl::ParameterToControl(Float32 paramValue)
|
||||
{
|
||||
#if !__LP64__
|
||||
++mInControlInitialization;
|
||||
switch (mType) {
|
||||
case kTypeContinuous:
|
||||
SetValueFract(AUParameterValueToLinear(paramValue, &mParam));
|
||||
break;
|
||||
case kTypeDiscrete:
|
||||
{
|
||||
long value = long(paramValue);
|
||||
|
||||
// special case [1] -- menu parameters
|
||||
if (mParam.HasNamedParams()) {
|
||||
// if we're dealing with menus they behave differently!
|
||||
// becaue setting min and max doesn't work correctly for the control value
|
||||
// first menu item always reports a control value of 1
|
||||
ControlKind ctrlKind;
|
||||
if (GetControlKind(mControl, &ctrlKind) == noErr) {
|
||||
if ((ctrlKind.kind == kControlKindPopupArrow)
|
||||
|| (ctrlKind.kind == kControlKindPopupButton))
|
||||
{
|
||||
value = value - long(mParam.ParamInfo().minValue) + 1;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
// special case [2] -- Write-only boolean parameters
|
||||
AudioUnitParameterInfo AUPI = mParam.ParamInfo();
|
||||
|
||||
bool isWriteOnlyBoolParameter = ( (AUPI.unit == kAudioUnitParameterUnit_Boolean) &&
|
||||
(AUPI.flags & kAudioUnitParameterFlag_IsWritable) &&
|
||||
!(AUPI.flags & kAudioUnitParameterFlag_IsReadable) );
|
||||
if (!isWriteOnlyBoolParameter) {
|
||||
SetValue (value);
|
||||
}
|
||||
}
|
||||
break;
|
||||
case kTypeText:
|
||||
{
|
||||
CFStringRef cfstr = mParam.GetStringFromValueCopy(¶mValue);
|
||||
|
||||
if ( !(mParam.ParamInfo().flags & kAudioUnitParameterFlag_IsWritable) //READ ONLY PARAMS
|
||||
&& (mParam.ParamInfo().flags & kAudioUnitParameterFlag_IsReadable))
|
||||
{
|
||||
if (mParam.GetParamTag()) {
|
||||
CFMutableStringRef str = CFStringCreateMutableCopy(NULL, 256, cfstr);
|
||||
CFRelease (cfstr);
|
||||
CFStringAppend (str, CFSTR(" "));
|
||||
CFStringAppend (str, mParam.GetParamTag());
|
||||
cfstr = str;
|
||||
}
|
||||
}
|
||||
SetTextValue(cfstr);
|
||||
CFRelease (cfstr);
|
||||
}
|
||||
break;
|
||||
}
|
||||
--mInControlInitialization;
|
||||
#endif
|
||||
}
|
||||
|
||||
void AUCarbonViewControl::ControlToParameter()
|
||||
{
|
||||
#if !__LP64__
|
||||
if (mInControlInitialization)
|
||||
return;
|
||||
|
||||
switch (mType) {
|
||||
case kTypeContinuous:
|
||||
{
|
||||
double controlValue = GetValueFract();
|
||||
Float32 paramValue = AUParameterValueFromLinear(controlValue, &mParam);
|
||||
mParam.SetValue(mListener, this, paramValue);
|
||||
}
|
||||
break;
|
||||
case kTypeDiscrete:
|
||||
{
|
||||
long value = GetValue();
|
||||
|
||||
// special case [1] -- Menus
|
||||
if (mParam.HasNamedParams()) {
|
||||
// if we're dealing with menus they behave differently!
|
||||
// becaue setting min and max doesn't work correctly for the control value
|
||||
// first menu item always reports a control value of 1
|
||||
ControlKind ctrlKind;
|
||||
if (GetControlKind(mControl, &ctrlKind) == noErr) {
|
||||
if ((ctrlKind.kind == kControlKindPopupArrow)
|
||||
|| (ctrlKind.kind == kControlKindPopupButton))
|
||||
{
|
||||
value = value + long(mParam.ParamInfo().minValue) - 1;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
// special case [2] -- Write-only boolean parameters
|
||||
AudioUnitParameterInfo AUPI = mParam.ParamInfo();
|
||||
|
||||
bool isWriteOnlyBoolParameter = ( (AUPI.unit == kAudioUnitParameterUnit_Boolean) &&
|
||||
(AUPI.flags & kAudioUnitParameterFlag_IsWritable) &&
|
||||
!(AUPI.flags & kAudioUnitParameterFlag_IsReadable) );
|
||||
if (isWriteOnlyBoolParameter) {
|
||||
value = 1;
|
||||
}
|
||||
|
||||
mParam.SetValue (mListener, this, value);
|
||||
}
|
||||
break;
|
||||
case kTypeText:
|
||||
{
|
||||
Float32 val = mParam.GetValueFromString (GetTextValue());
|
||||
mParam.SetValue(mListener, this, (mParam.IsIndexedParam() ? (int)val : val));
|
||||
if (mParam.ValuesHaveStrings())
|
||||
ParameterToControl(val); //make sure we display the correct text (from the AU)
|
||||
}
|
||||
break;
|
||||
}
|
||||
#endif
|
||||
}
|
||||
|
||||
void AUCarbonViewControl::SetValueFract(double value)
|
||||
{
|
||||
#if !__LP64__
|
||||
SInt32 minimum = GetControl32BitMinimum(mControl);
|
||||
SInt32 maximum = GetControl32BitMaximum(mControl);
|
||||
SInt32 cval = SInt32(value * (maximum - minimum) + minimum + 0.5);
|
||||
SetControl32BitValue(mControl, cval);
|
||||
// printf("set: value=%lf, min=%ld, max=%ld, ctl value=%ld\n", value, minimum, maximum, cval);
|
||||
#endif
|
||||
}
|
||||
|
||||
double AUCarbonViewControl::GetValueFract()
|
||||
{
|
||||
#if !__LP64__
|
||||
SInt32 minimum = GetControl32BitMinimum(mControl);
|
||||
SInt32 maximum = GetControl32BitMaximum(mControl);
|
||||
SInt32 cval = GetControl32BitValue(mControl);
|
||||
double result = double(cval - minimum) / double(maximum - minimum);
|
||||
// printf("get: min=%ld, max=%ld, value=%ld, result=%f\n", minimum, maximum, cval, result);
|
||||
return result;
|
||||
#else
|
||||
return 0;
|
||||
#endif
|
||||
}
|
||||
|
||||
void AUCarbonViewControl::SetTextValue(CFStringRef cfstr)
|
||||
{
|
||||
#if !__LP64__
|
||||
verify_noerr(SetControlData(mControl, 0, kControlEditTextCFStringTag, sizeof(CFStringRef), &cfstr));
|
||||
#endif
|
||||
}
|
||||
|
||||
CFStringRef AUCarbonViewControl::GetTextValue()
|
||||
{
|
||||
#if !__LP64__
|
||||
CFStringRef cfstr;
|
||||
verify_noerr(GetControlData(mControl, 0, kControlEditTextCFStringTag, sizeof(CFStringRef), &cfstr, NULL));
|
||||
return cfstr;
|
||||
#else
|
||||
return CFSTR("");
|
||||
#endif
|
||||
}
|
||||
|
||||
void AUCarbonViewControl::SetValue(long value)
|
||||
{
|
||||
#if !__LP64__
|
||||
SetControl32BitValue(mControl, value);
|
||||
#endif
|
||||
}
|
||||
|
||||
long AUCarbonViewControl::GetValue()
|
||||
{
|
||||
#if !__LP64__
|
||||
return GetControl32BitValue(mControl);
|
||||
#else
|
||||
return 0;
|
||||
#endif
|
||||
}
|
||||
|
||||
/* Notes on event handling
|
||||
|
||||
Button (Click and release on button)
|
||||
kEventControlClick received
|
||||
kEventControlTrack received
|
||||
kEventControlValueFieldChanged received
|
||||
kEventControlHit received
|
||||
|
||||
Button (Click and release outside of button bounds)
|
||||
kEventControlClick received
|
||||
kEventControlTrack received
|
||||
|
||||
Slider (Click, drag, and release)
|
||||
kEventControlClick received
|
||||
kEventControlTrack received
|
||||
kEventControlValueFieldChanged received
|
||||
kEventControlValueFieldChanged received
|
||||
kEventControlHit received
|
||||
|
||||
Slider (Click, release without changing value)
|
||||
kEventControlClick received
|
||||
kEventControlTrack received
|
||||
*/
|
||||
bool AUCarbonViewControl::HandleEvent(EventHandlerCallRef inHandlerRef, EventRef event)
|
||||
{
|
||||
UInt32 eclass = GetEventClass(event);
|
||||
UInt32 ekind = GetEventKind(event);
|
||||
ControlRef control;
|
||||
bool handled = true;
|
||||
|
||||
switch (eclass) {
|
||||
case kEventClassControl:
|
||||
{
|
||||
AudioUnitParameterInfo AUPI = mParam.ParamInfo();
|
||||
|
||||
bool isWriteOnlyBoolParameter = ( (AUPI.unit == kAudioUnitParameterUnit_Boolean) &&
|
||||
(AUPI.flags & kAudioUnitParameterFlag_IsWritable) &&
|
||||
!(AUPI.flags & kAudioUnitParameterFlag_IsReadable) );
|
||||
|
||||
switch (ekind) {
|
||||
case kEventControlSetFocusPart: // tab
|
||||
handled = !handled; // fall through to next case
|
||||
mLastControl = this;
|
||||
case kEventControlValueFieldChanged:
|
||||
GetEventParameter(event, kEventParamDirectObject, typeControlRef, NULL, sizeof(ControlRef), NULL, &control);
|
||||
verify(control == mControl);
|
||||
ControlToParameter();
|
||||
return handled;
|
||||
case kEventControlClick:
|
||||
if (isWriteOnlyBoolParameter) {
|
||||
GetEventParameter(event, kEventParamDirectObject, typeControlRef, NULL, sizeof(ControlRef), NULL, &control);
|
||||
verify(control == mControl);
|
||||
ControlToParameter();
|
||||
} else if (mLastControl != this) {
|
||||
if (mLastControl != NULL) {
|
||||
mLastControl->Update(false);
|
||||
}
|
||||
mLastControl = this;
|
||||
}
|
||||
mOwnerView->TellListener(mParam, kAudioUnitCarbonViewEvent_MouseDownInControl, NULL);
|
||||
break; // don't return true, continue normal processing
|
||||
case kEventControlHit:
|
||||
if (mLastControl != this) {
|
||||
if (mLastControl != NULL)
|
||||
mLastControl->Update(false);
|
||||
mLastControl = this;
|
||||
}
|
||||
mOwnerView->TellListener(mParam, kAudioUnitCarbonViewEvent_MouseUpInControl, NULL);
|
||||
break; // don't return true, continue normal processing
|
||||
case kEventControlTrack:
|
||||
if (mLastControl != this) {
|
||||
if (mLastControl != NULL)
|
||||
mLastControl->Update(false);
|
||||
mLastControl = this;
|
||||
}
|
||||
|
||||
CallNextEventHandler(inHandlerRef, event);
|
||||
ControlToParameter(); // new code
|
||||
mOwnerView->TellListener(mParam, kAudioUnitCarbonViewEvent_MouseUpInControl, NULL);
|
||||
// old code:
|
||||
// break; // don't return true, continue normal processing
|
||||
|
||||
return handled; // don't return true, continue normal processing
|
||||
}
|
||||
}
|
||||
}
|
||||
return !handled;
|
||||
}
|
||||
|
||||
pascal void AUCarbonViewControl::SliderTrackProc(ControlRef theControl, ControlPartCode partCode)
|
||||
{
|
||||
// this doesn't need to actually do anything
|
||||
// AUCarbonViewControl *This = (AUCarbonViewControl *)GetControlReference(theControl);
|
||||
}
|
||||
|
||||
pascal ControlKeyFilterResult AUCarbonViewControl::StdKeyFilterCallback(ControlRef theControl,
|
||||
SInt16 *keyCode, SInt16 *charCode,
|
||||
EventModifiers *modifiers)
|
||||
{
|
||||
#if !__LP64__
|
||||
SInt16 c = *charCode;
|
||||
if (c >= ' ' || c == '\b' || c == 0x7F || (c >= 0x1c && c <= 0x1f) || c == '\t')
|
||||
return kControlKeyFilterPassKey;
|
||||
if (c == '\r' || c == 3) { // return or Enter
|
||||
AUCarbonViewControl *This = (AUCarbonViewControl *)GetControlReference(theControl);
|
||||
ControlEditTextSelectionRec sel = { 0, 32767 };
|
||||
SetControlData(This->mControl, 0, kControlEditTextSelectionTag, sizeof(sel), &sel);
|
||||
This->ControlToParameter();
|
||||
}
|
||||
#endif
|
||||
return kControlKeyFilterBlockKey;
|
||||
}
|
||||
|
||||
pascal ControlKeyFilterResult AUCarbonViewControl::NumericKeyFilterCallback(ControlRef theControl,
|
||||
SInt16 *keyCode, SInt16 *charCode,
|
||||
EventModifiers *modifiers)
|
||||
{
|
||||
#if !__LP64__
|
||||
SInt16 c = *charCode;
|
||||
if (isdigit(c) || c == '+' || c == '-' || c == '.' || c == '\b' || c == 0x7F || (c >= 0x1c && c <= 0x1f)
|
||||
|| c == '\t')
|
||||
return kControlKeyFilterPassKey;
|
||||
if (c == '\r' || c == 3) { // return or Enter
|
||||
AUCarbonViewControl *This = (AUCarbonViewControl *)GetControlReference(theControl);
|
||||
ControlEditTextSelectionRec sel = { 0, 32767 };
|
||||
SetControlData(This->mControl, 0, kControlEditTextSelectionTag, sizeof(sel), &sel);
|
||||
This->ControlToParameter();
|
||||
}
|
||||
#endif
|
||||
return kControlKeyFilterBlockKey;
|
||||
}
|
||||
|
||||
Boolean AUCarbonViewControl::SizeControlToFit(ControlRef inControl, SInt16 *outWidth, SInt16 *outHeight)
|
||||
{
|
||||
#if !__LP64__
|
||||
if (inControl == 0) return false;
|
||||
|
||||
Boolean bValue = false;
|
||||
// this only works on text controls -- returns an error for other controls, but doesn't do anything,
|
||||
// so the error is irrelevant
|
||||
SetControlData(inControl, kControlEntireControl, 'stim' /* kControlStaticTextIsMultilineTag */, sizeof(Boolean), &bValue);
|
||||
|
||||
SInt16 baseLineOffset;
|
||||
Rect bestRect;
|
||||
OSErr err = GetBestControlRect(inControl, &bestRect, &baseLineOffset);
|
||||
if (err != noErr) return false;
|
||||
|
||||
int width = (bestRect.right - bestRect.left) + 1;
|
||||
int height = (bestRect.bottom - bestRect.top) + 1;
|
||||
|
||||
Rect boundsRect;
|
||||
GetControlBounds (inControl, &boundsRect);
|
||||
|
||||
Rect newRect;
|
||||
newRect.top = boundsRect.top;
|
||||
newRect.bottom = newRect.top + height;
|
||||
newRect.left = boundsRect.left;
|
||||
newRect.right = newRect.left + width;
|
||||
|
||||
SetControlBounds (inControl, &newRect);
|
||||
|
||||
if (outWidth)
|
||||
*outWidth = width;
|
||||
|
||||
if (outHeight)
|
||||
*outHeight = height;
|
||||
#endif
|
||||
return true;
|
||||
}
|
||||
|
||||
#pragma mark ___AUPropertyControl
|
||||
bool AUPropertyControl::HandleEvent(EventHandlerCallRef inHandlerRef, EventRef event)
|
||||
{
|
||||
UInt32 eclass = GetEventClass(event);
|
||||
UInt32 ekind = GetEventKind(event);
|
||||
switch (eclass) {
|
||||
case kEventClassControl:
|
||||
switch (ekind) {
|
||||
case kEventControlValueFieldChanged:
|
||||
HandleControlChange();
|
||||
return true; // handled
|
||||
}
|
||||
}
|
||||
|
||||
return false;
|
||||
}
|
||||
|
||||
void AUPropertyControl::RegisterEvents ()
|
||||
{
|
||||
#if !__LP64__
|
||||
EventTypeSpec events[] = {
|
||||
{ kEventClassControl, kEventControlValueFieldChanged } // N.B. OS X only
|
||||
};
|
||||
|
||||
WantEventTypes(GetControlEventTarget(mControl), GetEventTypeCount(events), events);
|
||||
#endif
|
||||
}
|
||||
|
||||
void AUPropertyControl::EmbedControl (ControlRef theControl)
|
||||
{
|
||||
mView->EmbedControl (theControl);
|
||||
}
|
||||
|
||||
WindowRef AUPropertyControl::GetCarbonWindow()
|
||||
{
|
||||
return mView->GetCarbonWindow();
|
||||
}
|
||||
|
||||
#pragma mark ___AUVPreset
|
||||
#if !__LP64__
|
||||
static CFStringRef kStringFactoryPreset = kAUViewLocalizedStringKey_FactoryPreset;
|
||||
static bool sAUVPresetLocalized = false;
|
||||
#endif
|
||||
|
||||
AUVPresets::AUVPresets (AUCarbonViewBase* inParentView,
|
||||
CFArrayRef& inPresets,
|
||||
Point inLocation,
|
||||
int nameWidth,
|
||||
int controlWidth,
|
||||
ControlFontStyleRec & inFontStyle)
|
||||
: AUPropertyControl (inParentView),
|
||||
mPresets (inPresets),
|
||||
mView (inParentView)
|
||||
{
|
||||
#if !__LP64__
|
||||
Rect r;
|
||||
|
||||
// ok we now have an array of factory presets
|
||||
// get their strings and display them
|
||||
|
||||
r.top = inLocation.v; r.bottom = r.top;
|
||||
r.left = inLocation.h; r.right = r.left;
|
||||
|
||||
// localize as necessary
|
||||
if (!sAUVPresetLocalized) {
|
||||
CFBundleRef mainBundle = CFBundleGetBundleWithIdentifier(kLocalizedStringBundle_AUView);
|
||||
if (mainBundle) {
|
||||
kStringFactoryPreset = CFCopyLocalizedStringFromTableInBundle(
|
||||
kAUViewLocalizedStringKey_FactoryPreset, kLocalizedStringTable_AUView,
|
||||
mainBundle, CFSTR("FactoryPreset title string"));
|
||||
sAUVPresetLocalized = true;
|
||||
}
|
||||
}
|
||||
|
||||
// create localized title string
|
||||
CFMutableStringRef factoryPresetsTitle = CFStringCreateMutable(NULL, 0);
|
||||
CFStringAppend(factoryPresetsTitle, kStringFactoryPreset);
|
||||
CFStringAppend(factoryPresetsTitle, kAUViewUnlocalizedString_TitleSeparator);
|
||||
|
||||
ControlRef theControl;
|
||||
verify_noerr(CreateStaticTextControl(mView->GetCarbonWindow(), &r, factoryPresetsTitle, &inFontStyle, &theControl));
|
||||
SInt16 width = 0;
|
||||
AUCarbonViewControl::SizeControlToFit(theControl, &width, &mHeight);
|
||||
CFRelease(factoryPresetsTitle);
|
||||
EmbedControl(theControl);
|
||||
|
||||
r.top -= 2;
|
||||
r.left += width + 10;
|
||||
r.right = r.left;
|
||||
r.bottom = r.top;
|
||||
|
||||
verify_noerr(CreatePopupButtonControl ( mView->GetCarbonWindow(), &r, NULL,
|
||||
-12345, // DON'T GET MENU FROM RESOURCE mMenuID,!!!
|
||||
FALSE, // variableWidth,
|
||||
0, // titleWidth,
|
||||
0, // titleJustification,
|
||||
0, // titleStyle,
|
||||
&mControl));
|
||||
|
||||
MenuRef menuRef;
|
||||
verify_noerr(CreateNewMenu(1, 0, &menuRef));
|
||||
|
||||
int numPresets = CFArrayGetCount(mPresets);
|
||||
|
||||
for (int i = 0; i < numPresets; ++i)
|
||||
{
|
||||
AUPreset* preset = (AUPreset*) CFArrayGetValueAtIndex (mPresets, i);
|
||||
verify_noerr(AppendMenuItemTextWithCFString (menuRef, preset->presetName, 0, 0, 0));
|
||||
}
|
||||
|
||||
verify_noerr(SetControlData(mControl, 0, kControlPopupButtonMenuRefTag, sizeof(menuRef), &menuRef));
|
||||
verify_noerr (SetControlFontStyle (mControl, &inFontStyle));
|
||||
|
||||
SetControl32BitMaximum (mControl, numPresets);
|
||||
|
||||
// size popup
|
||||
SInt16 height = 0;
|
||||
|
||||
AUCarbonViewControl::SizeControlToFit(mControl, &width, &height);
|
||||
|
||||
if (height > mHeight) mHeight = height;
|
||||
if (mHeight < 0) mHeight = 0;
|
||||
|
||||
// find which menu item is the Default preset
|
||||
UInt32 propertySize = sizeof(AUPreset);
|
||||
AUPreset defaultPreset;
|
||||
OSStatus result = AudioUnitGetProperty (mView->GetEditAudioUnit(),
|
||||
kAudioUnitProperty_PresentPreset,
|
||||
kAudioUnitScope_Global,
|
||||
0,
|
||||
&defaultPreset,
|
||||
&propertySize);
|
||||
|
||||
mPropertyID = kAudioUnitProperty_PresentPreset;
|
||||
#endif
|
||||
#ifndef __LP64__
|
||||
if (result != noErr) { // if the PresentPreset property is not implemented, fall back to the CurrentPreset property
|
||||
result = AudioUnitGetProperty (mView->GetEditAudioUnit(),
|
||||
kAudioUnitProperty_CurrentPreset,
|
||||
kAudioUnitScope_Global,
|
||||
0,
|
||||
&defaultPreset,
|
||||
&propertySize);
|
||||
mPropertyID = kAudioUnitProperty_CurrentPreset;
|
||||
if (result == noErr)
|
||||
CFRetain (defaultPreset.presetName);
|
||||
}
|
||||
#endif
|
||||
#if !__LP64__
|
||||
EmbedControl (mControl);
|
||||
|
||||
HandlePropertyChange(defaultPreset);
|
||||
|
||||
RegisterEvents();
|
||||
#endif
|
||||
}
|
||||
|
||||
void AUVPresets::AddInterest (AUEventListenerRef inListener,
|
||||
void * inObject)
|
||||
{
|
||||
AudioUnitEvent e;
|
||||
e.mEventType = kAudioUnitEvent_PropertyChange;
|
||||
e.mArgument.mProperty.mAudioUnit = mView->GetEditAudioUnit();
|
||||
e.mArgument.mProperty.mPropertyID = mPropertyID;
|
||||
e.mArgument.mProperty.mScope = kAudioUnitScope_Global;
|
||||
e.mArgument.mProperty.mElement = 0;
|
||||
|
||||
AUEventListenerAddEventType(inListener, inObject, &e);
|
||||
}
|
||||
|
||||
void AUVPresets::RemoveInterest (AUEventListenerRef inListener,
|
||||
void * inObject)
|
||||
{
|
||||
AudioUnitEvent e;
|
||||
e.mEventType = kAudioUnitEvent_PropertyChange;
|
||||
e.mArgument.mProperty.mAudioUnit = mView->GetEditAudioUnit();
|
||||
e.mArgument.mProperty.mPropertyID = mPropertyID;
|
||||
e.mArgument.mProperty.mScope = kAudioUnitScope_Global;
|
||||
e.mArgument.mProperty.mElement = 0;
|
||||
|
||||
AUEventListenerRemoveEventType(inListener, inObject, &e);
|
||||
}
|
||||
|
||||
void AUVPresets::HandleControlChange ()
|
||||
{
|
||||
#if !__LP64__
|
||||
SInt32 i = GetControl32BitValue(mControl);
|
||||
if (i > 0)
|
||||
{
|
||||
AUPreset* preset = (AUPreset*) CFArrayGetValueAtIndex (mPresets, i-1);
|
||||
|
||||
verify_noerr(AudioUnitSetProperty (mView->GetEditAudioUnit(),
|
||||
mPropertyID, // either currentPreset or PresentPreset depending on which is supported
|
||||
kAudioUnitScope_Global,
|
||||
0,
|
||||
preset,
|
||||
sizeof(AUPreset)));
|
||||
|
||||
// when we change a preset we can't expect the AU to update its state
|
||||
// as it isn't meant to know that its being viewed!
|
||||
// so we broadcast a notification to all listeners that all parameters on this AU have changed
|
||||
AudioUnitParameter changedUnit;
|
||||
changedUnit.mAudioUnit = mView->GetEditAudioUnit();
|
||||
changedUnit.mParameterID = kAUParameterListener_AnyParameter;
|
||||
verify_noerr (AUParameterListenerNotify (NULL, NULL, &changedUnit) );
|
||||
}
|
||||
#endif
|
||||
}
|
||||
|
||||
void AUVPresets::HandlePropertyChange(AUPreset &preset)
|
||||
{
|
||||
#if !__LP64__
|
||||
// check to see if the preset is in our menu
|
||||
int numPresets = CFArrayGetCount(mPresets);
|
||||
if (preset.presetNumber < 0) {
|
||||
SetControl32BitValue (mControl, 0); //controls are one-based
|
||||
} else {
|
||||
for (SInt32 i = 0; i < numPresets; ++i) {
|
||||
AUPreset* currPreset = (AUPreset*) CFArrayGetValueAtIndex (mPresets, i);
|
||||
if (preset.presetNumber == currPreset->presetNumber) {
|
||||
SetControl32BitValue (mControl, ++i); //controls are one-based
|
||||
break;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
if (preset.presetName)
|
||||
CFRelease (preset.presetName);
|
||||
#endif
|
||||
}
|
||||
|
||||
bool AUVPresets::HandlePropertyChange (const AudioUnitProperty &inProp)
|
||||
{
|
||||
if (inProp.mPropertyID == mPropertyID)
|
||||
{
|
||||
UInt32 theSize = sizeof(AUPreset);
|
||||
AUPreset currentPreset;
|
||||
|
||||
OSStatus result = AudioUnitGetProperty(inProp.mAudioUnit,
|
||||
inProp.mPropertyID,
|
||||
inProp.mScope,
|
||||
inProp.mElement, ¤tPreset, &theSize);
|
||||
|
||||
if (result == noErr) {
|
||||
#ifndef __LP64__
|
||||
if (inProp.mPropertyID == kAudioUnitProperty_CurrentPreset && currentPreset.presetName)
|
||||
CFRetain (currentPreset.presetName);
|
||||
#endif
|
||||
HandlePropertyChange(currentPreset);
|
||||
return true;
|
||||
}
|
||||
}
|
||||
return false;
|
||||
}
|
||||
@@ -1,230 +0,0 @@
|
||||
/*
|
||||
File: AUCarbonViewControl.h
|
||||
Abstract: Part of CoreAudio Utility Classes
|
||||
Version: 1.1
|
||||
|
||||
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.
|
||||
|
||||
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.
|
||||
|
||||
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.
|
||||
|
||||
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.
|
||||
|
||||
Copyright (C) 2014 Apple Inc. All Rights Reserved.
|
||||
|
||||
*/
|
||||
#ifndef __AUCarbonViewControl_h__
|
||||
#define __AUCarbonViewControl_h__
|
||||
|
||||
#include <Carbon/Carbon.h>
|
||||
#include <AudioUnit/AudioUnitCarbonView.h>
|
||||
#include <AudioToolbox/AudioUnitUtilities.h>
|
||||
#include "CarbonEventHandler.h"
|
||||
#include "CAAUParameter.h"
|
||||
|
||||
class AUCarbonViewBase;
|
||||
|
||||
// ____________________________________________________________________________
|
||||
// AUCarbonViewControl
|
||||
// Wrapper for a control that is wired to an AudioUnit parameter.
|
||||
/*! @class AUCarbonViewControl */
|
||||
class AUCarbonViewControl : public CarbonEventHandler {
|
||||
// note that the controls are never disposed; that's managed by the AUCarbonViewBase's
|
||||
// parent pane which contains all of them ... if we later need to be able to delete
|
||||
// individual controls on the fly, extra work needed
|
||||
public:
|
||||
enum ControlType {
|
||||
kTypeContinuous, // e.g. slider
|
||||
kTypeDiscrete, // e.g. pop-up menu
|
||||
kTypeText
|
||||
};
|
||||
|
||||
AUCarbonViewControl(AUCarbonViewBase *ownerView, AUParameterListenerRef listener, ControlType type, const CAAUParameter ¶m, ControlRef control);
|
||||
~AUCarbonViewControl();
|
||||
|
||||
/*! @method Bind */
|
||||
virtual void Bind(); // second-stage construction
|
||||
|
||||
/*! @method ControlToParameter */
|
||||
virtual void ControlToParameter();
|
||||
/*! @method ParameterToControl */
|
||||
virtual void ParameterToControl(Float32 newValue);
|
||||
|
||||
/*! @method SetValueFract */
|
||||
virtual void SetValueFract(double value);
|
||||
/*! @method GetValueFract */
|
||||
virtual double GetValueFract();
|
||||
/*! @method SetTextValue */
|
||||
virtual void SetTextValue(CFStringRef str);
|
||||
/*! @method GetTextValue */
|
||||
virtual CFStringRef GetTextValue();
|
||||
/*! @method SetValue */
|
||||
virtual void SetValue(long value);
|
||||
/*! @method GetValue */
|
||||
virtual long GetValue();
|
||||
|
||||
/*! @method GetOwnerView */
|
||||
AUCarbonViewBase * GetOwnerView() {return mOwnerView;}
|
||||
|
||||
/*! @method Update */
|
||||
void Update (bool inUIThread)
|
||||
{
|
||||
if (inUIThread)
|
||||
ParameterToControl (mParam.GetValue());
|
||||
else
|
||||
AUParameterListenerNotify (mListener, this, &mParam);
|
||||
}
|
||||
|
||||
|
||||
// CarbonEventHandler overrides
|
||||
/*! @method HandleEvent */
|
||||
virtual bool HandleEvent(EventHandlerCallRef inHandlerRef, EventRef event);
|
||||
|
||||
/*! @method ControlRef */
|
||||
operator ControlRef() { return mControl; }
|
||||
|
||||
/*! @method SizeControlToFit */
|
||||
static Boolean SizeControlToFit(ControlRef inControl, SInt16 *outWidth = NULL, SInt16 *outHeight = NULL);
|
||||
|
||||
/*! @method SliderTrackProc */
|
||||
static pascal void SliderTrackProc(ControlRef theControl, ControlPartCode partCode);
|
||||
/*! @method NumericKeyFilterCallback */
|
||||
static pascal ControlKeyFilterResult NumericKeyFilterCallback(ControlRef theControl, SInt16 *keyCode, SInt16 *charCode,
|
||||
EventModifiers *modifiers);
|
||||
protected:
|
||||
/*! @method ParamInfo */
|
||||
const AudioUnitParameterInfo &ParamInfo() { return mParam.ParamInfo(); }
|
||||
|
||||
/*! @var mOwnerView */
|
||||
AUCarbonViewBase * mOwnerView;
|
||||
/*! @var mListener */
|
||||
AUParameterListenerRef mListener;
|
||||
/*! @var mType */
|
||||
ControlType mType;
|
||||
/*! @var mParam */
|
||||
CAAUParameter mParam;
|
||||
|
||||
/*! @var mControl */
|
||||
ControlRef mControl;
|
||||
|
||||
/*! @method StdKeyFilterCallback */
|
||||
static pascal ControlKeyFilterResult StdKeyFilterCallback(ControlRef theControl, SInt16 *keyCode, SInt16 *charCode,
|
||||
EventModifiers *modifiers);
|
||||
SInt16 mInControlInitialization;
|
||||
|
||||
static AUCarbonViewControl* mLastControl;
|
||||
};
|
||||
|
||||
/*! @class AUPropertyControl */
|
||||
class AUPropertyControl : public CarbonEventHandler {
|
||||
public:
|
||||
/*! @ctor AUPropertyControl */
|
||||
AUPropertyControl (AUCarbonViewBase * inBase) : mControl(0), mView (inBase), mHeight(0) {}
|
||||
|
||||
/*! @method HandleEvent */
|
||||
virtual bool HandleEvent(EventHandlerCallRef inHandlerRef, EventRef event);
|
||||
|
||||
/*! @method HandlePropertyChange */
|
||||
virtual bool HandlePropertyChange (const AudioUnitProperty &inProp) = 0;
|
||||
|
||||
/*! @method AddInterest */
|
||||
virtual void AddInterest (AUEventListenerRef inListener,
|
||||
void * inObject) = 0;
|
||||
|
||||
/*! @method RemoveInterest */
|
||||
virtual void RemoveInterest (AUEventListenerRef inListener,
|
||||
void * inObject) = 0;
|
||||
|
||||
/*! @method GetHeight */
|
||||
int GetHeight() { return mHeight;}
|
||||
|
||||
protected:
|
||||
/*! @method HandleControlChange */
|
||||
virtual void HandleControlChange () = 0;
|
||||
|
||||
/*! @method RegisterEvents */
|
||||
void RegisterEvents ();
|
||||
|
||||
/*! @method EmbedControl */
|
||||
void EmbedControl (ControlRef theControl);
|
||||
|
||||
/*! @method GetCarbonWindow */
|
||||
WindowRef GetCarbonWindow();
|
||||
|
||||
/*! @var mControl */
|
||||
ControlRef mControl;
|
||||
/*! @var mView */
|
||||
AUCarbonViewBase* mView;
|
||||
/*! @var mHeight */
|
||||
SInt16 mHeight;
|
||||
};
|
||||
|
||||
/*! @class AUVPresets */
|
||||
class AUVPresets : public AUPropertyControl {
|
||||
public:
|
||||
/*! @ctor HandleControlChange */
|
||||
AUVPresets (AUCarbonViewBase * inBase,
|
||||
CFArrayRef& inPresets,
|
||||
Point inLocation,
|
||||
int nameWidth,
|
||||
int controlWidth,
|
||||
ControlFontStyleRec & inFontStyle);
|
||||
|
||||
virtual ~AUVPresets () { CFRelease (mPresets); }
|
||||
|
||||
/*! @method HandlePropertyChange */
|
||||
virtual bool HandlePropertyChange (const AudioUnitProperty &inProp);
|
||||
|
||||
/*! @method AddInterest */
|
||||
virtual void AddInterest (AUEventListenerRef inListener,
|
||||
void * inObject);
|
||||
|
||||
/*! @method RemoveInterest */
|
||||
virtual void RemoveInterest (AUEventListenerRef inListener,
|
||||
void * inObject);
|
||||
|
||||
protected:
|
||||
/*! @method HandleControlChange */
|
||||
virtual void HandleControlChange ();
|
||||
|
||||
/*! @var mPresets */
|
||||
CFArrayRef mPresets;
|
||||
/*! @var mView */
|
||||
AUCarbonViewBase* mView;
|
||||
AudioUnitPropertyID mPropertyID;
|
||||
|
||||
void HandlePropertyChange(AUPreset &preset);
|
||||
};
|
||||
|
||||
#endif // __AUCarbonViewControl_h__
|
||||
@@ -1,125 +0,0 @@
|
||||
/*
|
||||
File: AUCarbonViewDispatch.cpp
|
||||
Abstract: AUCarbonViewDispatch.h
|
||||
Version: 1.1
|
||||
|
||||
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.
|
||||
|
||||
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.
|
||||
|
||||
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.
|
||||
|
||||
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.
|
||||
|
||||
Copyright (C) 2014 Apple Inc. All Rights Reserved.
|
||||
|
||||
*/
|
||||
#include "AUCarbonViewBase.h"
|
||||
|
||||
// ____________________________________________________________________________
|
||||
// component dispatch
|
||||
|
||||
#if PRAGMA_STRUCT_ALIGN
|
||||
#pragma options align=mac68k
|
||||
#elif PRAGMA_STRUCT_PACKPUSH
|
||||
#pragma pack(push, 2)
|
||||
#elif PRAGMA_STRUCT_PACK
|
||||
#pragma pack(2)
|
||||
#endif
|
||||
struct AudioUnitCarbonViewCreateGluePB {
|
||||
unsigned char componentFlags;
|
||||
unsigned char componentParamSize;
|
||||
short componentWhat;
|
||||
ControlRef* outControl;
|
||||
const Float32Point* inSize;
|
||||
const Float32Point* inLocation;
|
||||
ControlRef inParentControl;
|
||||
WindowRef inWindow;
|
||||
AudioUnit inAudioUnit;
|
||||
AudioUnitCarbonView inView;
|
||||
};
|
||||
#if !__LP64__
|
||||
struct AudioUnitCarbonViewSetEventListenerGluePB {
|
||||
unsigned char componentFlags;
|
||||
unsigned char componentParamSize;
|
||||
short componentWhat;
|
||||
void* inUserData;
|
||||
AudioUnitCarbonViewEventListener inCallback;
|
||||
AudioUnitCarbonView inView;
|
||||
};
|
||||
#endif
|
||||
#if PRAGMA_STRUCT_ALIGN
|
||||
#pragma options align=reset
|
||||
#elif PRAGMA_STRUCT_PACKPUSH
|
||||
#pragma pack(pop)
|
||||
#elif PRAGMA_STRUCT_PACK
|
||||
#pragma pack()
|
||||
#endif
|
||||
|
||||
#define CheckNull(x) if ((x) == NULL) return paramErr;
|
||||
|
||||
OSStatus AUCarbonViewBase::ComponentEntryDispatch(ComponentParameters *p, AUCarbonViewBase *This)
|
||||
{
|
||||
if (This == NULL) return paramErr;
|
||||
|
||||
OSStatus result = noErr;
|
||||
|
||||
switch (p->what) {
|
||||
case kAudioUnitCarbonViewCreateSelect:
|
||||
{
|
||||
AudioUnitCarbonViewCreateGluePB *pb = (AudioUnitCarbonViewCreateGluePB *)p;
|
||||
CheckNull(pb->inAudioUnit);
|
||||
CheckNull(pb->inWindow);
|
||||
CheckNull(pb->inParentControl);
|
||||
CheckNull(pb->inSize);
|
||||
CheckNull(pb->inLocation);
|
||||
CheckNull(pb->outControl);
|
||||
result = This->CreateCarbonView(pb->inAudioUnit, pb->inWindow, pb->inParentControl,
|
||||
*pb->inLocation, *pb->inSize, *pb->outControl);
|
||||
}
|
||||
break;
|
||||
#if !__LP64__
|
||||
case kAudioUnitCarbonViewSetEventListenerSelect:
|
||||
{
|
||||
AudioUnitCarbonViewSetEventListenerGluePB *pb = (AudioUnitCarbonViewSetEventListenerGluePB *)p;
|
||||
This->SetEventListener(pb->inCallback, pb->inUserData);
|
||||
}
|
||||
break;
|
||||
#endif
|
||||
|
||||
default:
|
||||
result = ComponentBase::ComponentEntryDispatch(p, This);
|
||||
break;
|
||||
}
|
||||
return result;
|
||||
}
|
||||
@@ -1,438 +1,438 @@
|
||||
/*
|
||||
File: AUDispatch.cpp
|
||||
Abstract: AUDispatch.h
|
||||
Version: 1.1
|
||||
|
||||
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.
|
||||
|
||||
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.
|
||||
|
||||
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.
|
||||
|
||||
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.
|
||||
|
||||
Copyright (C) 2014 Apple Inc. All Rights Reserved.
|
||||
|
||||
*/
|
||||
#include "AUBase.h"
|
||||
#include "CAXException.h"
|
||||
#include "AUDispatch.h"
|
||||
|
||||
|
||||
|
||||
#if TARGET_OS_MAC
|
||||
#if __LP64__
|
||||
// comp instance, parameters in forward order
|
||||
#define PARAM(_typ, _name, _index, _nparams) \
|
||||
_typ _name = *(_typ *)¶ms->params[_index + 1];
|
||||
#else
|
||||
// parameters in reverse order, then comp instance
|
||||
#define PARAM(_typ, _name, _index, _nparams) \
|
||||
_typ _name = *(_typ *)¶ms->params[_nparams - 1 - _index];
|
||||
#endif
|
||||
#elif TARGET_OS_WIN32
|
||||
// (no comp instance), parameters in forward order
|
||||
#define PARAM(_typ, _name, _index, _nparams) \
|
||||
_typ _name = *(_typ *)¶ms->params[_index];
|
||||
#endif
|
||||
|
||||
|
||||
OSStatus AUBase::ComponentEntryDispatch(ComponentParameters *params, AUBase *This)
|
||||
{
|
||||
if (This == NULL) return kAudio_ParamError;
|
||||
|
||||
OSStatus result = noErr;
|
||||
|
||||
switch (params->what) {
|
||||
case kComponentCanDoSelect:
|
||||
switch (GetSelectorForCanDo(params)) {
|
||||
// any selectors
|
||||
case kAudioUnitInitializeSelect:
|
||||
case kAudioUnitUninitializeSelect:
|
||||
case kAudioUnitGetPropertyInfoSelect:
|
||||
case kAudioUnitGetPropertySelect:
|
||||
case kAudioUnitSetPropertySelect:
|
||||
case kAudioUnitAddPropertyListenerSelect:
|
||||
#if (!__LP64__)
|
||||
case kAudioUnitRemovePropertyListenerSelect:
|
||||
#endif
|
||||
case kAudioUnitGetParameterSelect:
|
||||
case kAudioUnitSetParameterSelect:
|
||||
case kAudioUnitResetSelect:
|
||||
result = 1;
|
||||
break;
|
||||
// v1 selectors
|
||||
|
||||
// v2 selectors
|
||||
case kAudioUnitRemovePropertyListenerWithUserDataSelect:
|
||||
case kAudioUnitAddRenderNotifySelect:
|
||||
case kAudioUnitRemoveRenderNotifySelect:
|
||||
case kAudioUnitScheduleParametersSelect:
|
||||
case kAudioUnitRenderSelect:
|
||||
result = (This->AudioUnitAPIVersion() > 1);
|
||||
break;
|
||||
|
||||
default:
|
||||
return ComponentBase::ComponentEntryDispatch(params, This);
|
||||
}
|
||||
break;
|
||||
|
||||
case kAudioUnitInitializeSelect:
|
||||
{
|
||||
CAMutex::Locker lock2(This->GetMutex());
|
||||
result = This->DoInitialize();
|
||||
}
|
||||
break;
|
||||
|
||||
case kAudioUnitUninitializeSelect:
|
||||
{
|
||||
CAMutex::Locker lock2(This->GetMutex());
|
||||
This->DoCleanup();
|
||||
result = noErr;
|
||||
}
|
||||
break;
|
||||
|
||||
case kAudioUnitGetPropertyInfoSelect:
|
||||
{
|
||||
CAMutex::Locker lock(This->GetMutex());
|
||||
PARAM(AudioUnitPropertyID, pinID, 0, 5);
|
||||
PARAM(AudioUnitScope, pinScope, 1, 5);
|
||||
PARAM(AudioUnitElement, pinElement, 2, 5);
|
||||
PARAM(UInt32 *, poutDataSize, 3, 5);
|
||||
PARAM(Boolean *, poutWritable, 4, 5);
|
||||
|
||||
// pass our own copies so that we assume responsibility for testing
|
||||
// the caller's pointers against null and our C++ classes can
|
||||
// always assume they're non-null
|
||||
UInt32 dataSize;
|
||||
Boolean writable;
|
||||
|
||||
result = This->DispatchGetPropertyInfo(pinID, pinScope, pinElement, dataSize, writable);
|
||||
if (poutDataSize != NULL)
|
||||
*poutDataSize = dataSize;
|
||||
if (poutWritable != NULL)
|
||||
*poutWritable = writable;
|
||||
}
|
||||
break;
|
||||
|
||||
case kAudioUnitGetPropertySelect:
|
||||
{
|
||||
CAMutex::Locker lock(This->GetMutex());
|
||||
PARAM(AudioUnitPropertyID, pinID, 0, 5);
|
||||
PARAM(AudioUnitScope, pinScope, 1, 5);
|
||||
PARAM(AudioUnitElement, pinElement, 2, 5);
|
||||
PARAM(void *, poutData, 3, 5);
|
||||
PARAM(UInt32 *, pioDataSize, 4, 5);
|
||||
|
||||
UInt32 actualPropertySize, clientBufferSize;
|
||||
Boolean writable;
|
||||
char *tempBuffer;
|
||||
void *destBuffer;
|
||||
|
||||
if (pioDataSize == NULL) {
|
||||
ca_debug_string("AudioUnitGetProperty: null size pointer");
|
||||
result = kAudio_ParamError;
|
||||
goto finishGetProperty;
|
||||
}
|
||||
if (poutData == NULL) {
|
||||
UInt32 dataSize;
|
||||
|
||||
result = This->DispatchGetPropertyInfo(pinID, pinScope, pinElement, dataSize, writable);
|
||||
*pioDataSize = dataSize;
|
||||
goto finishGetProperty;
|
||||
}
|
||||
|
||||
clientBufferSize = *pioDataSize;
|
||||
if (clientBufferSize == 0)
|
||||
{
|
||||
ca_debug_string("AudioUnitGetProperty: *ioDataSize == 0 on entry");
|
||||
// $$$ or should we allow this as a shortcut for finding the size?
|
||||
result = kAudio_ParamError;
|
||||
goto finishGetProperty;
|
||||
}
|
||||
|
||||
result = This->DispatchGetPropertyInfo(pinID, pinScope, pinElement,
|
||||
actualPropertySize, writable);
|
||||
if (result)
|
||||
goto finishGetProperty;
|
||||
|
||||
if (clientBufferSize < actualPropertySize)
|
||||
{
|
||||
tempBuffer = new char[actualPropertySize];
|
||||
destBuffer = tempBuffer;
|
||||
} else {
|
||||
tempBuffer = NULL;
|
||||
destBuffer = poutData;
|
||||
}
|
||||
|
||||
result = This->DispatchGetProperty(pinID, pinScope, pinElement, destBuffer);
|
||||
|
||||
if (result == noErr) {
|
||||
if (clientBufferSize < actualPropertySize && tempBuffer != NULL)
|
||||
{
|
||||
memcpy(poutData, tempBuffer, clientBufferSize);
|
||||
delete[] tempBuffer;
|
||||
// pioDataSize remains correct, the number of bytes we wrote
|
||||
} else
|
||||
*pioDataSize = actualPropertySize;
|
||||
} else
|
||||
*pioDataSize = 0;
|
||||
|
||||
finishGetProperty:
|
||||
;
|
||||
|
||||
}
|
||||
break;
|
||||
|
||||
case kAudioUnitSetPropertySelect:
|
||||
{
|
||||
CAMutex::Locker lock(This->GetMutex());
|
||||
PARAM(AudioUnitPropertyID, pinID, 0, 5);
|
||||
PARAM(AudioUnitScope, pinScope, 1, 5);
|
||||
PARAM(AudioUnitElement, pinElement, 2, 5);
|
||||
PARAM(const void *, pinData, 3, 5);
|
||||
PARAM(UInt32, pinDataSize, 4, 5);
|
||||
|
||||
if (pinData && pinDataSize)
|
||||
result = This->DispatchSetProperty(pinID, pinScope, pinElement, pinData, pinDataSize);
|
||||
else {
|
||||
if (pinData == NULL && pinDataSize == 0) {
|
||||
result = This->DispatchRemovePropertyValue (pinID, pinScope, pinElement);
|
||||
} else {
|
||||
if (pinData == NULL) {
|
||||
ca_debug_string("AudioUnitSetProperty: inData == NULL");
|
||||
result = kAudio_ParamError;
|
||||
goto finishSetProperty;
|
||||
}
|
||||
|
||||
if (pinDataSize == 0) {
|
||||
ca_debug_string("AudioUnitSetProperty: inDataSize == 0");
|
||||
result = kAudio_ParamError;
|
||||
goto finishSetProperty;
|
||||
}
|
||||
}
|
||||
}
|
||||
finishSetProperty:
|
||||
;
|
||||
|
||||
}
|
||||
break;
|
||||
|
||||
case kAudioUnitAddPropertyListenerSelect:
|
||||
{
|
||||
CAMutex::Locker lock(This->GetMutex());
|
||||
PARAM(AudioUnitPropertyID, pinID, 0, 3);
|
||||
PARAM(AudioUnitPropertyListenerProc, pinProc, 1, 3);
|
||||
PARAM(void *, pinProcRefCon, 2, 3);
|
||||
result = This->AddPropertyListener(pinID, pinProc, pinProcRefCon);
|
||||
}
|
||||
break;
|
||||
|
||||
#if (!__LP64__)
|
||||
case kAudioUnitRemovePropertyListenerSelect:
|
||||
{
|
||||
CAMutex::Locker lock(This->GetMutex());
|
||||
PARAM(AudioUnitPropertyID, pinID, 0, 2);
|
||||
PARAM(AudioUnitPropertyListenerProc, pinProc, 1, 2);
|
||||
result = This->RemovePropertyListener(pinID, pinProc, NULL, false);
|
||||
}
|
||||
break;
|
||||
#endif
|
||||
|
||||
case kAudioUnitRemovePropertyListenerWithUserDataSelect:
|
||||
{
|
||||
CAMutex::Locker lock(This->GetMutex());
|
||||
PARAM(AudioUnitPropertyID, pinID, 0, 3);
|
||||
PARAM(AudioUnitPropertyListenerProc, pinProc, 1, 3);
|
||||
PARAM(void *, pinProcRefCon, 2, 3);
|
||||
result = This->RemovePropertyListener(pinID, pinProc, pinProcRefCon, true);
|
||||
}
|
||||
break;
|
||||
|
||||
case kAudioUnitAddRenderNotifySelect:
|
||||
{
|
||||
CAMutex::Locker lock(This->GetMutex());
|
||||
PARAM(AURenderCallback, pinProc, 0, 2);
|
||||
PARAM(void *, pinProcRefCon, 1, 2);
|
||||
result = This->SetRenderNotification (pinProc, pinProcRefCon);
|
||||
}
|
||||
break;
|
||||
|
||||
case kAudioUnitRemoveRenderNotifySelect:
|
||||
{
|
||||
CAMutex::Locker lock(This->GetMutex());
|
||||
PARAM(AURenderCallback, pinProc, 0, 2);
|
||||
PARAM(void *, pinProcRefCon, 1, 2);
|
||||
result = This->RemoveRenderNotification (pinProc, pinProcRefCon);
|
||||
}
|
||||
break;
|
||||
|
||||
case kAudioUnitGetParameterSelect:
|
||||
{
|
||||
CAMutex::Locker lock(This->GetMutex());
|
||||
PARAM(AudioUnitParameterID, pinID, 0, 4);
|
||||
PARAM(AudioUnitScope, pinScope, 1, 4);
|
||||
PARAM(AudioUnitElement, pinElement, 2, 4);
|
||||
PARAM(AudioUnitParameterValue *, poutValue, 3, 4);
|
||||
result = (poutValue == NULL ? kAudio_ParamError : This->GetParameter(pinID, pinScope, pinElement, *poutValue));
|
||||
}
|
||||
break;
|
||||
|
||||
case kAudioUnitSetParameterSelect:
|
||||
{
|
||||
CAMutex::Locker lock(This->GetMutex()); // is this realtime or no???
|
||||
PARAM(AudioUnitParameterID, pinID, 0, 5);
|
||||
PARAM(AudioUnitScope, pinScope, 1, 5);
|
||||
PARAM(AudioUnitElement, pinElement, 2, 5);
|
||||
PARAM(AudioUnitParameterValue, pinValue, 3, 5);
|
||||
PARAM(UInt32, pinBufferOffsetInFrames, 4, 5);
|
||||
result = This->SetParameter(pinID, pinScope, pinElement, pinValue, pinBufferOffsetInFrames);
|
||||
}
|
||||
break;
|
||||
|
||||
case kAudioUnitScheduleParametersSelect:
|
||||
{
|
||||
CAMutex::Locker lock(This->GetMutex()); // is this realtime or no???
|
||||
if (This->AudioUnitAPIVersion() > 1)
|
||||
{
|
||||
PARAM(AudioUnitParameterEvent *, pinParameterEvent, 0, 2);
|
||||
PARAM(UInt32, pinNumParamEvents, 1, 2);
|
||||
result = This->ScheduleParameter (pinParameterEvent, pinNumParamEvents);
|
||||
} else
|
||||
result = badComponentSelector;
|
||||
}
|
||||
break;
|
||||
|
||||
|
||||
case kAudioUnitRenderSelect:
|
||||
{
|
||||
// realtime; no lock
|
||||
{
|
||||
PARAM(AudioUnitRenderActionFlags *, pinActionFlags, 0, 5);
|
||||
PARAM(const AudioTimeStamp *, pinTimeStamp, 1, 5);
|
||||
PARAM(UInt32, pinOutputBusNumber, 2, 5);
|
||||
PARAM(UInt32, pinNumberFrames, 3, 5);
|
||||
PARAM(AudioBufferList *, pioData, 4, 5);
|
||||
AudioUnitRenderActionFlags tempFlags;
|
||||
|
||||
if (pinTimeStamp == NULL || pioData == NULL)
|
||||
result = kAudio_ParamError;
|
||||
else {
|
||||
if (pinActionFlags == NULL) {
|
||||
tempFlags = 0;
|
||||
pinActionFlags = &tempFlags;
|
||||
}
|
||||
result = This->DoRender(*pinActionFlags, *pinTimeStamp, pinOutputBusNumber, pinNumberFrames, *pioData);
|
||||
}
|
||||
}
|
||||
}
|
||||
break;
|
||||
|
||||
case kAudioUnitResetSelect:
|
||||
{
|
||||
CAMutex::Locker lock(This->GetMutex());
|
||||
PARAM(AudioUnitScope, pinScope, 0, 2);
|
||||
PARAM(AudioUnitElement, pinElement, 1, 2);
|
||||
This->ResetRenderTime();
|
||||
result = This->Reset(pinScope, pinElement);
|
||||
}
|
||||
break;
|
||||
|
||||
default:
|
||||
result = ComponentBase::ComponentEntryDispatch(params, This);
|
||||
break;
|
||||
}
|
||||
|
||||
return result;
|
||||
}
|
||||
|
||||
// Fast dispatch entry points -- these need to replicate all error-checking logic from above
|
||||
|
||||
OSStatus CMgr_AudioUnitBaseGetParameter( AUBase * This,
|
||||
AudioUnitParameterID inID,
|
||||
AudioUnitScope inScope,
|
||||
AudioUnitElement inElement,
|
||||
float *outValue)
|
||||
{
|
||||
OSStatus result = AUBase::noErr;
|
||||
|
||||
try {
|
||||
if (This == NULL || outValue == NULL) return kAudio_ParamError;
|
||||
result = This->GetParameter(inID, inScope, inElement, *outValue);
|
||||
}
|
||||
COMPONENT_CATCH
|
||||
|
||||
return result;
|
||||
}
|
||||
|
||||
OSStatus CMgr_AudioUnitBaseSetParameter( AUBase * This,
|
||||
AudioUnitParameterID inID,
|
||||
AudioUnitScope inScope,
|
||||
AudioUnitElement inElement,
|
||||
float inValue,
|
||||
UInt32 inBufferOffset)
|
||||
{
|
||||
OSStatus result = AUBase::noErr;
|
||||
|
||||
try {
|
||||
if (This == NULL) return kAudio_ParamError;
|
||||
result = This->SetParameter(inID, inScope, inElement, inValue, inBufferOffset);
|
||||
}
|
||||
COMPONENT_CATCH
|
||||
|
||||
return result;
|
||||
}
|
||||
|
||||
OSStatus CMgr_AudioUnitBaseRender( AUBase * This,
|
||||
AudioUnitRenderActionFlags *ioActionFlags,
|
||||
const AudioTimeStamp * inTimeStamp,
|
||||
UInt32 inBusNumber,
|
||||
UInt32 inNumberFrames,
|
||||
AudioBufferList * ioData)
|
||||
{
|
||||
if (inTimeStamp == NULL || ioData == NULL) return kAudio_ParamError;
|
||||
|
||||
OSStatus result = AUBase::noErr;
|
||||
AudioUnitRenderActionFlags tempFlags;
|
||||
|
||||
try {
|
||||
if (ioActionFlags == NULL) {
|
||||
tempFlags = 0;
|
||||
ioActionFlags = &tempFlags;
|
||||
}
|
||||
result = This->DoRender(*ioActionFlags, *inTimeStamp, inBusNumber, inNumberFrames, *ioData);
|
||||
}
|
||||
COMPONENT_CATCH
|
||||
|
||||
return result;
|
||||
}
|
||||
/*
|
||||
File: AUDispatch.cpp
|
||||
Abstract: AUDispatch.h
|
||||
Version: 1.1
|
||||
|
||||
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.
|
||||
|
||||
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.
|
||||
|
||||
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.
|
||||
|
||||
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.
|
||||
|
||||
Copyright (C) 2014 Apple Inc. All Rights Reserved.
|
||||
|
||||
*/
|
||||
#include "AUBase.h"
|
||||
#include "CAXException.h"
|
||||
#include "AUDispatch.h"
|
||||
|
||||
|
||||
|
||||
#if TARGET_OS_MAC
|
||||
#if __LP64__
|
||||
// comp instance, parameters in forward order
|
||||
#define PARAM(_typ, _name, _index, _nparams) \
|
||||
_typ _name = *(_typ *)¶ms->params[_index + 1];
|
||||
#else
|
||||
// parameters in reverse order, then comp instance
|
||||
#define PARAM(_typ, _name, _index, _nparams) \
|
||||
_typ _name = *(_typ *)¶ms->params[_nparams - 1 - _index];
|
||||
#endif
|
||||
#elif TARGET_OS_WIN32
|
||||
// (no comp instance), parameters in forward order
|
||||
#define PARAM(_typ, _name, _index, _nparams) \
|
||||
_typ _name = *(_typ *)¶ms->params[_index];
|
||||
#endif
|
||||
|
||||
|
||||
OSStatus AUBase::ComponentEntryDispatch(ComponentParameters *params, AUBase *This)
|
||||
{
|
||||
if (This == NULL) return kAudio_ParamError;
|
||||
|
||||
OSStatus result = noErr;
|
||||
|
||||
switch (params->what) {
|
||||
case kComponentCanDoSelect:
|
||||
switch (GetSelectorForCanDo(params)) {
|
||||
// any selectors
|
||||
case kAudioUnitInitializeSelect:
|
||||
case kAudioUnitUninitializeSelect:
|
||||
case kAudioUnitGetPropertyInfoSelect:
|
||||
case kAudioUnitGetPropertySelect:
|
||||
case kAudioUnitSetPropertySelect:
|
||||
case kAudioUnitAddPropertyListenerSelect:
|
||||
#if (!__LP64__)
|
||||
case kAudioUnitRemovePropertyListenerSelect:
|
||||
#endif
|
||||
case kAudioUnitGetParameterSelect:
|
||||
case kAudioUnitSetParameterSelect:
|
||||
case kAudioUnitResetSelect:
|
||||
result = 1;
|
||||
break;
|
||||
// v1 selectors
|
||||
|
||||
// v2 selectors
|
||||
case kAudioUnitRemovePropertyListenerWithUserDataSelect:
|
||||
case kAudioUnitAddRenderNotifySelect:
|
||||
case kAudioUnitRemoveRenderNotifySelect:
|
||||
case kAudioUnitScheduleParametersSelect:
|
||||
case kAudioUnitRenderSelect:
|
||||
result = (This->AudioUnitAPIVersion() > 1);
|
||||
break;
|
||||
|
||||
default:
|
||||
return ComponentBase::ComponentEntryDispatch(params, This);
|
||||
}
|
||||
break;
|
||||
|
||||
case kAudioUnitInitializeSelect:
|
||||
{
|
||||
CAMutex::Locker lock2(This->GetMutex());
|
||||
result = This->DoInitialize();
|
||||
}
|
||||
break;
|
||||
|
||||
case kAudioUnitUninitializeSelect:
|
||||
{
|
||||
CAMutex::Locker lock2(This->GetMutex());
|
||||
This->DoCleanup();
|
||||
result = noErr;
|
||||
}
|
||||
break;
|
||||
|
||||
case kAudioUnitGetPropertyInfoSelect:
|
||||
{
|
||||
CAMutex::Locker lock(This->GetMutex());
|
||||
PARAM(AudioUnitPropertyID, pinID, 0, 5);
|
||||
PARAM(AudioUnitScope, pinScope, 1, 5);
|
||||
PARAM(AudioUnitElement, pinElement, 2, 5);
|
||||
PARAM(UInt32 *, poutDataSize, 3, 5);
|
||||
PARAM(Boolean *, poutWritable, 4, 5);
|
||||
|
||||
// pass our own copies so that we assume responsibility for testing
|
||||
// the caller's pointers against null and our C++ classes can
|
||||
// always assume they're non-null
|
||||
UInt32 dataSize;
|
||||
Boolean writable;
|
||||
|
||||
result = This->DispatchGetPropertyInfo(pinID, pinScope, pinElement, dataSize, writable);
|
||||
if (poutDataSize != NULL)
|
||||
*poutDataSize = dataSize;
|
||||
if (poutWritable != NULL)
|
||||
*poutWritable = writable;
|
||||
}
|
||||
break;
|
||||
|
||||
case kAudioUnitGetPropertySelect:
|
||||
{
|
||||
CAMutex::Locker lock(This->GetMutex());
|
||||
PARAM(AudioUnitPropertyID, pinID, 0, 5);
|
||||
PARAM(AudioUnitScope, pinScope, 1, 5);
|
||||
PARAM(AudioUnitElement, pinElement, 2, 5);
|
||||
PARAM(void *, poutData, 3, 5);
|
||||
PARAM(UInt32 *, pioDataSize, 4, 5);
|
||||
|
||||
UInt32 actualPropertySize, clientBufferSize;
|
||||
Boolean writable;
|
||||
char *tempBuffer;
|
||||
void *destBuffer;
|
||||
|
||||
if (pioDataSize == NULL) {
|
||||
ca_debug_string("AudioUnitGetProperty: null size pointer");
|
||||
result = kAudio_ParamError;
|
||||
goto finishGetProperty;
|
||||
}
|
||||
if (poutData == NULL) {
|
||||
UInt32 dataSize;
|
||||
|
||||
result = This->DispatchGetPropertyInfo(pinID, pinScope, pinElement, dataSize, writable);
|
||||
*pioDataSize = dataSize;
|
||||
goto finishGetProperty;
|
||||
}
|
||||
|
||||
clientBufferSize = *pioDataSize;
|
||||
if (clientBufferSize == 0)
|
||||
{
|
||||
ca_debug_string("AudioUnitGetProperty: *ioDataSize == 0 on entry");
|
||||
// $$$ or should we allow this as a shortcut for finding the size?
|
||||
result = kAudio_ParamError;
|
||||
goto finishGetProperty;
|
||||
}
|
||||
|
||||
result = This->DispatchGetPropertyInfo(pinID, pinScope, pinElement,
|
||||
actualPropertySize, writable);
|
||||
if (result)
|
||||
goto finishGetProperty;
|
||||
|
||||
if (clientBufferSize < actualPropertySize)
|
||||
{
|
||||
tempBuffer = new char[actualPropertySize];
|
||||
destBuffer = tempBuffer;
|
||||
} else {
|
||||
tempBuffer = NULL;
|
||||
destBuffer = poutData;
|
||||
}
|
||||
|
||||
result = This->DispatchGetProperty(pinID, pinScope, pinElement, destBuffer);
|
||||
|
||||
if (result == noErr) {
|
||||
if (clientBufferSize < actualPropertySize && tempBuffer != NULL)
|
||||
{
|
||||
memcpy(poutData, tempBuffer, clientBufferSize);
|
||||
delete[] tempBuffer;
|
||||
// pioDataSize remains correct, the number of bytes we wrote
|
||||
} else
|
||||
*pioDataSize = actualPropertySize;
|
||||
} else
|
||||
*pioDataSize = 0;
|
||||
|
||||
finishGetProperty:
|
||||
;
|
||||
|
||||
}
|
||||
break;
|
||||
|
||||
case kAudioUnitSetPropertySelect:
|
||||
{
|
||||
CAMutex::Locker lock(This->GetMutex());
|
||||
PARAM(AudioUnitPropertyID, pinID, 0, 5);
|
||||
PARAM(AudioUnitScope, pinScope, 1, 5);
|
||||
PARAM(AudioUnitElement, pinElement, 2, 5);
|
||||
PARAM(const void *, pinData, 3, 5);
|
||||
PARAM(UInt32, pinDataSize, 4, 5);
|
||||
|
||||
if (pinData && pinDataSize)
|
||||
result = This->DispatchSetProperty(pinID, pinScope, pinElement, pinData, pinDataSize);
|
||||
else {
|
||||
if (pinData == NULL && pinDataSize == 0) {
|
||||
result = This->DispatchRemovePropertyValue (pinID, pinScope, pinElement);
|
||||
} else {
|
||||
if (pinData == NULL) {
|
||||
ca_debug_string("AudioUnitSetProperty: inData == NULL");
|
||||
result = kAudio_ParamError;
|
||||
goto finishSetProperty;
|
||||
}
|
||||
|
||||
if (pinDataSize == 0) {
|
||||
ca_debug_string("AudioUnitSetProperty: inDataSize == 0");
|
||||
result = kAudio_ParamError;
|
||||
goto finishSetProperty;
|
||||
}
|
||||
}
|
||||
}
|
||||
finishSetProperty:
|
||||
;
|
||||
|
||||
}
|
||||
break;
|
||||
|
||||
case kAudioUnitAddPropertyListenerSelect:
|
||||
{
|
||||
CAMutex::Locker lock(This->GetMutex());
|
||||
PARAM(AudioUnitPropertyID, pinID, 0, 3);
|
||||
PARAM(AudioUnitPropertyListenerProc, pinProc, 1, 3);
|
||||
PARAM(void *, pinProcRefCon, 2, 3);
|
||||
result = This->AddPropertyListener(pinID, pinProc, pinProcRefCon);
|
||||
}
|
||||
break;
|
||||
|
||||
#if (!__LP64__)
|
||||
case kAudioUnitRemovePropertyListenerSelect:
|
||||
{
|
||||
CAMutex::Locker lock(This->GetMutex());
|
||||
PARAM(AudioUnitPropertyID, pinID, 0, 2);
|
||||
PARAM(AudioUnitPropertyListenerProc, pinProc, 1, 2);
|
||||
result = This->RemovePropertyListener(pinID, pinProc, NULL, false);
|
||||
}
|
||||
break;
|
||||
#endif
|
||||
|
||||
case kAudioUnitRemovePropertyListenerWithUserDataSelect:
|
||||
{
|
||||
CAMutex::Locker lock(This->GetMutex());
|
||||
PARAM(AudioUnitPropertyID, pinID, 0, 3);
|
||||
PARAM(AudioUnitPropertyListenerProc, pinProc, 1, 3);
|
||||
PARAM(void *, pinProcRefCon, 2, 3);
|
||||
result = This->RemovePropertyListener(pinID, pinProc, pinProcRefCon, true);
|
||||
}
|
||||
break;
|
||||
|
||||
case kAudioUnitAddRenderNotifySelect:
|
||||
{
|
||||
CAMutex::Locker lock(This->GetMutex());
|
||||
PARAM(AURenderCallback, pinProc, 0, 2);
|
||||
PARAM(void *, pinProcRefCon, 1, 2);
|
||||
result = This->SetRenderNotification (pinProc, pinProcRefCon);
|
||||
}
|
||||
break;
|
||||
|
||||
case kAudioUnitRemoveRenderNotifySelect:
|
||||
{
|
||||
CAMutex::Locker lock(This->GetMutex());
|
||||
PARAM(AURenderCallback, pinProc, 0, 2);
|
||||
PARAM(void *, pinProcRefCon, 1, 2);
|
||||
result = This->RemoveRenderNotification (pinProc, pinProcRefCon);
|
||||
}
|
||||
break;
|
||||
|
||||
case kAudioUnitGetParameterSelect:
|
||||
{
|
||||
CAMutex::Locker lock(This->GetMutex());
|
||||
PARAM(AudioUnitParameterID, pinID, 0, 4);
|
||||
PARAM(AudioUnitScope, pinScope, 1, 4);
|
||||
PARAM(AudioUnitElement, pinElement, 2, 4);
|
||||
PARAM(AudioUnitParameterValue *, poutValue, 3, 4);
|
||||
result = (poutValue == NULL ? kAudio_ParamError : This->GetParameter(pinID, pinScope, pinElement, *poutValue));
|
||||
}
|
||||
break;
|
||||
|
||||
case kAudioUnitSetParameterSelect:
|
||||
{
|
||||
CAMutex::Locker lock(This->GetMutex()); // is this realtime or no???
|
||||
PARAM(AudioUnitParameterID, pinID, 0, 5);
|
||||
PARAM(AudioUnitScope, pinScope, 1, 5);
|
||||
PARAM(AudioUnitElement, pinElement, 2, 5);
|
||||
PARAM(AudioUnitParameterValue, pinValue, 3, 5);
|
||||
PARAM(UInt32, pinBufferOffsetInFrames, 4, 5);
|
||||
result = This->SetParameter(pinID, pinScope, pinElement, pinValue, pinBufferOffsetInFrames);
|
||||
}
|
||||
break;
|
||||
|
||||
case kAudioUnitScheduleParametersSelect:
|
||||
{
|
||||
CAMutex::Locker lock(This->GetMutex()); // is this realtime or no???
|
||||
if (This->AudioUnitAPIVersion() > 1)
|
||||
{
|
||||
PARAM(AudioUnitParameterEvent *, pinParameterEvent, 0, 2);
|
||||
PARAM(UInt32, pinNumParamEvents, 1, 2);
|
||||
result = This->ScheduleParameter (pinParameterEvent, pinNumParamEvents);
|
||||
} else
|
||||
result = badComponentSelector;
|
||||
}
|
||||
break;
|
||||
|
||||
|
||||
case kAudioUnitRenderSelect:
|
||||
{
|
||||
// realtime; no lock
|
||||
{
|
||||
PARAM(AudioUnitRenderActionFlags *, pinActionFlags, 0, 5);
|
||||
PARAM(const AudioTimeStamp *, pinTimeStamp, 1, 5);
|
||||
PARAM(UInt32, pinOutputBusNumber, 2, 5);
|
||||
PARAM(UInt32, pinNumberFrames, 3, 5);
|
||||
PARAM(AudioBufferList *, pioData, 4, 5);
|
||||
AudioUnitRenderActionFlags tempFlags;
|
||||
|
||||
if (pinTimeStamp == NULL || pioData == NULL)
|
||||
result = kAudio_ParamError;
|
||||
else {
|
||||
if (pinActionFlags == NULL) {
|
||||
tempFlags = 0;
|
||||
pinActionFlags = &tempFlags;
|
||||
}
|
||||
result = This->DoRender(*pinActionFlags, *pinTimeStamp, pinOutputBusNumber, pinNumberFrames, *pioData);
|
||||
}
|
||||
}
|
||||
}
|
||||
break;
|
||||
|
||||
case kAudioUnitResetSelect:
|
||||
{
|
||||
CAMutex::Locker lock(This->GetMutex());
|
||||
PARAM(AudioUnitScope, pinScope, 0, 2);
|
||||
PARAM(AudioUnitElement, pinElement, 1, 2);
|
||||
This->ResetRenderTime();
|
||||
result = This->Reset(pinScope, pinElement);
|
||||
}
|
||||
break;
|
||||
|
||||
default:
|
||||
result = ComponentBase::ComponentEntryDispatch(params, This);
|
||||
break;
|
||||
}
|
||||
|
||||
return result;
|
||||
}
|
||||
|
||||
// Fast dispatch entry points -- these need to replicate all error-checking logic from above
|
||||
|
||||
OSStatus CMgr_AudioUnitBaseGetParameter( AUBase * This,
|
||||
AudioUnitParameterID inID,
|
||||
AudioUnitScope inScope,
|
||||
AudioUnitElement inElement,
|
||||
float *outValue)
|
||||
{
|
||||
OSStatus result = AUBase::noErr;
|
||||
|
||||
try {
|
||||
if (This == NULL || outValue == NULL) return kAudio_ParamError;
|
||||
result = This->GetParameter(inID, inScope, inElement, *outValue);
|
||||
}
|
||||
COMPONENT_CATCH
|
||||
|
||||
return result;
|
||||
}
|
||||
|
||||
OSStatus CMgr_AudioUnitBaseSetParameter( AUBase * This,
|
||||
AudioUnitParameterID inID,
|
||||
AudioUnitScope inScope,
|
||||
AudioUnitElement inElement,
|
||||
float inValue,
|
||||
UInt32 inBufferOffset)
|
||||
{
|
||||
OSStatus result = AUBase::noErr;
|
||||
|
||||
try {
|
||||
if (This == NULL) return kAudio_ParamError;
|
||||
result = This->SetParameter(inID, inScope, inElement, inValue, inBufferOffset);
|
||||
}
|
||||
COMPONENT_CATCH
|
||||
|
||||
return result;
|
||||
}
|
||||
|
||||
OSStatus CMgr_AudioUnitBaseRender( AUBase * This,
|
||||
AudioUnitRenderActionFlags *ioActionFlags,
|
||||
const AudioTimeStamp * inTimeStamp,
|
||||
UInt32 inBusNumber,
|
||||
UInt32 inNumberFrames,
|
||||
AudioBufferList * ioData)
|
||||
{
|
||||
if (inTimeStamp == NULL || ioData == NULL) return kAudio_ParamError;
|
||||
|
||||
OSStatus result = AUBase::noErr;
|
||||
AudioUnitRenderActionFlags tempFlags;
|
||||
|
||||
try {
|
||||
if (ioActionFlags == NULL) {
|
||||
tempFlags = 0;
|
||||
ioActionFlags = &tempFlags;
|
||||
}
|
||||
result = This->DoRender(*ioActionFlags, *inTimeStamp, inBusNumber, inNumberFrames, *ioData);
|
||||
}
|
||||
COMPONENT_CATCH
|
||||
|
||||
return result;
|
||||
}
|
||||
|
||||
@@ -1,82 +1,82 @@
|
||||
/*
|
||||
File: AUDispatch.h
|
||||
Abstract: Part of CoreAudio Utility Classes
|
||||
Version: 1.1
|
||||
|
||||
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.
|
||||
|
||||
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.
|
||||
|
||||
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.
|
||||
|
||||
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.
|
||||
|
||||
Copyright (C) 2014 Apple Inc. All Rights Reserved.
|
||||
|
||||
*/
|
||||
#ifndef __AUDispatch_h__
|
||||
#define __AUDispatch_h__
|
||||
|
||||
|
||||
#if !defined(__COREAUDIO_USE_FLAT_INCLUDES__)
|
||||
#include <AudioUnit/AudioUnit.h>
|
||||
#else
|
||||
#include "AudioUnit.h"
|
||||
#endif
|
||||
|
||||
#if !CA_USE_AUDIO_PLUGIN_ONLY
|
||||
/*! @function AudioUnitBaseGetParameter */
|
||||
OSStatus CMgr_AudioUnitBaseGetParameter( AUBase * This,
|
||||
AudioUnitParameterID inID,
|
||||
AudioUnitScope inScope,
|
||||
AudioUnitElement inElement,
|
||||
float * outValue);
|
||||
|
||||
/*! @function AudioUnitBaseSetParameter */
|
||||
OSStatus CMgr_AudioUnitBaseSetParameter( AUBase * This,
|
||||
AudioUnitParameterID inID,
|
||||
AudioUnitScope inScope,
|
||||
AudioUnitElement inElement,
|
||||
float inValue,
|
||||
UInt32 inBufferOffset);
|
||||
|
||||
/*! @function AudioUnitBaseRender */
|
||||
OSStatus CMgr_AudioUnitBaseRender( AUBase * This,
|
||||
AudioUnitRenderActionFlags *ioActionFlags,
|
||||
const AudioTimeStamp * inTimeStamp,
|
||||
UInt32 inBusNumber,
|
||||
UInt32 inNumberFrames,
|
||||
AudioBufferList * ioData);
|
||||
#endif
|
||||
|
||||
#endif // __AUDispatch_h__
|
||||
/*
|
||||
File: AUDispatch.h
|
||||
Abstract: Part of CoreAudio Utility Classes
|
||||
Version: 1.1
|
||||
|
||||
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.
|
||||
|
||||
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.
|
||||
|
||||
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.
|
||||
|
||||
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.
|
||||
|
||||
Copyright (C) 2014 Apple Inc. All Rights Reserved.
|
||||
|
||||
*/
|
||||
#ifndef __AUDispatch_h__
|
||||
#define __AUDispatch_h__
|
||||
|
||||
|
||||
#if !defined(__COREAUDIO_USE_FLAT_INCLUDES__)
|
||||
#include <AudioUnit/AudioUnit.h>
|
||||
#else
|
||||
#include "AudioUnit.h"
|
||||
#endif
|
||||
|
||||
#if !CA_USE_AUDIO_PLUGIN_ONLY
|
||||
/*! @function AudioUnitBaseGetParameter */
|
||||
OSStatus CMgr_AudioUnitBaseGetParameter( AUBase * This,
|
||||
AudioUnitParameterID inID,
|
||||
AudioUnitScope inScope,
|
||||
AudioUnitElement inElement,
|
||||
float * outValue);
|
||||
|
||||
/*! @function AudioUnitBaseSetParameter */
|
||||
OSStatus CMgr_AudioUnitBaseSetParameter( AUBase * This,
|
||||
AudioUnitParameterID inID,
|
||||
AudioUnitScope inScope,
|
||||
AudioUnitElement inElement,
|
||||
float inValue,
|
||||
UInt32 inBufferOffset);
|
||||
|
||||
/*! @function AudioUnitBaseRender */
|
||||
OSStatus CMgr_AudioUnitBaseRender( AUBase * This,
|
||||
AudioUnitRenderActionFlags *ioActionFlags,
|
||||
const AudioTimeStamp * inTimeStamp,
|
||||
UInt32 inBusNumber,
|
||||
UInt32 inNumberFrames,
|
||||
AudioBufferList * ioData);
|
||||
#endif
|
||||
|
||||
#endif // __AUDispatch_h__
|
||||
|
||||
@@ -1,151 +1,151 @@
|
||||
/*
|
||||
File: AUInputElement.cpp
|
||||
Abstract: AUInputElement.h
|
||||
Version: 1.1
|
||||
|
||||
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.
|
||||
|
||||
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.
|
||||
|
||||
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.
|
||||
|
||||
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.
|
||||
|
||||
Copyright (C) 2014 Apple Inc. All Rights Reserved.
|
||||
|
||||
*/
|
||||
#include "AUBase.h"
|
||||
|
||||
inline bool HasGoodBufferPointers(const AudioBufferList &abl, UInt32 nBytes)
|
||||
{
|
||||
const AudioBuffer *buf = abl.mBuffers;
|
||||
for (UInt32 i = abl.mNumberBuffers; i--;++buf) {
|
||||
if (buf->mData == NULL || buf->mDataByteSize < nBytes)
|
||||
return false;
|
||||
}
|
||||
return true;
|
||||
}
|
||||
|
||||
|
||||
//~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
|
||||
// AUInputElement::AUInputElement
|
||||
//
|
||||
//~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
|
||||
AUInputElement::AUInputElement(AUBase *audioUnit) :
|
||||
AUIOElement(audioUnit),
|
||||
mInputType(kNoInput)
|
||||
{
|
||||
}
|
||||
|
||||
//~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
|
||||
// AUInputElement::SetConnection
|
||||
//
|
||||
//~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
|
||||
void AUInputElement::SetConnection(const AudioUnitConnection &conn)
|
||||
{
|
||||
if (conn.sourceAudioUnit == 0) {
|
||||
Disconnect();
|
||||
return;
|
||||
}
|
||||
|
||||
mInputType = kFromConnection;
|
||||
mConnection = conn;
|
||||
AllocateBuffer();
|
||||
|
||||
mConnInstanceStorage = NULL;
|
||||
|
||||
#if !CA_USE_AUDIO_PLUGIN_ONLY
|
||||
mConnRenderProc = NULL;
|
||||
UInt32 size = sizeof(AudioUnitRenderProc);
|
||||
OSStatus result = AudioUnitGetProperty( conn.sourceAudioUnit,
|
||||
kAudioUnitProperty_FastDispatch,
|
||||
kAudioUnitScope_Global,
|
||||
kAudioUnitRenderSelect,
|
||||
&mConnRenderProc,
|
||||
&size);
|
||||
if (result == noErr)
|
||||
mConnInstanceStorage = CMgr_GetComponentInstanceStorage (conn.sourceAudioUnit);
|
||||
else
|
||||
mConnRenderProc = NULL;
|
||||
#endif
|
||||
}
|
||||
|
||||
void AUInputElement::Disconnect()
|
||||
{
|
||||
mInputType = kNoInput;
|
||||
mIOBuffer.Deallocate();
|
||||
}
|
||||
|
||||
|
||||
|
||||
//~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
|
||||
// AUInputElement::SetInputCallback
|
||||
//
|
||||
//~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
|
||||
void AUInputElement::SetInputCallback(AURenderCallback proc, void *refCon)
|
||||
{
|
||||
if (proc == NULL)
|
||||
Disconnect();
|
||||
else {
|
||||
mInputType = kFromCallback;
|
||||
mInputProc = proc;
|
||||
mInputProcRefCon = refCon;
|
||||
AllocateBuffer();
|
||||
}
|
||||
}
|
||||
|
||||
OSStatus AUInputElement::SetStreamFormat(const CAStreamBasicDescription &fmt)
|
||||
{
|
||||
OSStatus err = AUIOElement::SetStreamFormat(fmt);
|
||||
if (err == AUBase::noErr)
|
||||
AllocateBuffer();
|
||||
return err;
|
||||
}
|
||||
|
||||
OSStatus AUInputElement::PullInput( AudioUnitRenderActionFlags & ioActionFlags,
|
||||
const AudioTimeStamp & inTimeStamp,
|
||||
AudioUnitElement inElement,
|
||||
UInt32 nFrames)
|
||||
{
|
||||
if (!IsActive())
|
||||
return kAudioUnitErr_NoConnection;
|
||||
|
||||
AudioBufferList *pullBuffer;
|
||||
|
||||
if (HasConnection() || !WillAllocateBuffer())
|
||||
pullBuffer = &mIOBuffer.PrepareNullBuffer(mStreamFormat, nFrames);
|
||||
else
|
||||
pullBuffer = &mIOBuffer.PrepareBuffer(mStreamFormat, nFrames);
|
||||
|
||||
return PullInputWithBufferList (ioActionFlags, inTimeStamp, inElement, nFrames, pullBuffer);
|
||||
}
|
||||
/*
|
||||
File: AUInputElement.cpp
|
||||
Abstract: AUInputElement.h
|
||||
Version: 1.1
|
||||
|
||||
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.
|
||||
|
||||
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.
|
||||
|
||||
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.
|
||||
|
||||
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.
|
||||
|
||||
Copyright (C) 2014 Apple Inc. All Rights Reserved.
|
||||
|
||||
*/
|
||||
#include "AUBase.h"
|
||||
|
||||
inline bool HasGoodBufferPointers(const AudioBufferList &abl, UInt32 nBytes)
|
||||
{
|
||||
const AudioBuffer *buf = abl.mBuffers;
|
||||
for (UInt32 i = abl.mNumberBuffers; i--;++buf) {
|
||||
if (buf->mData == NULL || buf->mDataByteSize < nBytes)
|
||||
return false;
|
||||
}
|
||||
return true;
|
||||
}
|
||||
|
||||
|
||||
//~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
|
||||
// AUInputElement::AUInputElement
|
||||
//
|
||||
//~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
|
||||
AUInputElement::AUInputElement(AUBase *audioUnit) :
|
||||
AUIOElement(audioUnit),
|
||||
mInputType(kNoInput)
|
||||
{
|
||||
}
|
||||
|
||||
//~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
|
||||
// AUInputElement::SetConnection
|
||||
//
|
||||
//~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
|
||||
void AUInputElement::SetConnection(const AudioUnitConnection &conn)
|
||||
{
|
||||
if (conn.sourceAudioUnit == 0) {
|
||||
Disconnect();
|
||||
return;
|
||||
}
|
||||
|
||||
mInputType = kFromConnection;
|
||||
mConnection = conn;
|
||||
AllocateBuffer();
|
||||
|
||||
mConnInstanceStorage = NULL;
|
||||
|
||||
#if !CA_USE_AUDIO_PLUGIN_ONLY
|
||||
mConnRenderProc = NULL;
|
||||
UInt32 size = sizeof(AudioUnitRenderProc);
|
||||
OSStatus result = AudioUnitGetProperty( conn.sourceAudioUnit,
|
||||
kAudioUnitProperty_FastDispatch,
|
||||
kAudioUnitScope_Global,
|
||||
kAudioUnitRenderSelect,
|
||||
&mConnRenderProc,
|
||||
&size);
|
||||
if (result == noErr)
|
||||
mConnInstanceStorage = CMgr_GetComponentInstanceStorage (conn.sourceAudioUnit);
|
||||
else
|
||||
mConnRenderProc = NULL;
|
||||
#endif
|
||||
}
|
||||
|
||||
void AUInputElement::Disconnect()
|
||||
{
|
||||
mInputType = kNoInput;
|
||||
mIOBuffer.Deallocate();
|
||||
}
|
||||
|
||||
|
||||
|
||||
//~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
|
||||
// AUInputElement::SetInputCallback
|
||||
//
|
||||
//~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
|
||||
void AUInputElement::SetInputCallback(AURenderCallback proc, void *refCon)
|
||||
{
|
||||
if (proc == NULL)
|
||||
Disconnect();
|
||||
else {
|
||||
mInputType = kFromCallback;
|
||||
mInputProc = proc;
|
||||
mInputProcRefCon = refCon;
|
||||
AllocateBuffer();
|
||||
}
|
||||
}
|
||||
|
||||
OSStatus AUInputElement::SetStreamFormat(const CAStreamBasicDescription &fmt)
|
||||
{
|
||||
OSStatus err = AUIOElement::SetStreamFormat(fmt);
|
||||
if (err == AUBase::noErr)
|
||||
AllocateBuffer();
|
||||
return err;
|
||||
}
|
||||
|
||||
OSStatus AUInputElement::PullInput( AudioUnitRenderActionFlags & ioActionFlags,
|
||||
const AudioTimeStamp & inTimeStamp,
|
||||
AudioUnitElement inElement,
|
||||
UInt32 nFrames)
|
||||
{
|
||||
if (!IsActive())
|
||||
return kAudioUnitErr_NoConnection;
|
||||
|
||||
AudioBufferList *pullBuffer;
|
||||
|
||||
if (HasConnection() || !WillAllocateBuffer())
|
||||
pullBuffer = &mIOBuffer.PrepareNullBuffer(mStreamFormat, nFrames);
|
||||
else
|
||||
pullBuffer = &mIOBuffer.PrepareBuffer(mStreamFormat, nFrames);
|
||||
|
||||
return PullInputWithBufferList (ioActionFlags, inTimeStamp, inElement, nFrames, pullBuffer);
|
||||
}
|
||||
|
||||
@@ -1,119 +1,119 @@
|
||||
/*
|
||||
File: AUInputElement.h
|
||||
Abstract: Part of CoreAudio Utility Classes
|
||||
Version: 1.1
|
||||
|
||||
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.
|
||||
|
||||
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.
|
||||
|
||||
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.
|
||||
|
||||
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.
|
||||
|
||||
Copyright (C) 2014 Apple Inc. All Rights Reserved.
|
||||
|
||||
*/
|
||||
#ifndef __AUInput_h__
|
||||
#define __AUInput_h__
|
||||
|
||||
#include "AUScopeElement.h"
|
||||
#include "AUBuffer.h"
|
||||
|
||||
/*! @class AUInputElement */
|
||||
class AUInputElement : public AUIOElement {
|
||||
public:
|
||||
|
||||
/*! @ctor AUInputElement */
|
||||
AUInputElement(AUBase *audioUnit);
|
||||
/*! @dtor ~AUInputElement */
|
||||
virtual ~AUInputElement() { }
|
||||
|
||||
// AUElement override
|
||||
/*! @method SetStreamFormat */
|
||||
virtual OSStatus SetStreamFormat(const CAStreamBasicDescription &desc);
|
||||
/*! @method NeedsBufferSpace */
|
||||
virtual bool NeedsBufferSpace() const { return IsCallback(); }
|
||||
|
||||
/*! @method SetConnection */
|
||||
void SetConnection(const AudioUnitConnection &conn);
|
||||
/*! @method SetInputCallback */
|
||||
void SetInputCallback(AURenderCallback proc, void *refCon);
|
||||
|
||||
/*! @method IsActive */
|
||||
bool IsActive() const { return mInputType != kNoInput; }
|
||||
/*! @method IsCallback */
|
||||
bool IsCallback() const { return mInputType == kFromCallback; }
|
||||
/*! @method HasConnection */
|
||||
bool HasConnection() const { return mInputType == kFromConnection; }
|
||||
|
||||
/*! @method PullInput */
|
||||
OSStatus PullInput( AudioUnitRenderActionFlags & ioActionFlags,
|
||||
const AudioTimeStamp & inTimeStamp,
|
||||
AudioUnitElement inElement,
|
||||
UInt32 inNumberFrames);
|
||||
|
||||
/*! @method PullInputWithBufferList */
|
||||
OSStatus PullInputWithBufferList( AudioUnitRenderActionFlags & ioActionFlags,
|
||||
const AudioTimeStamp & inTimeStamp,
|
||||
AudioUnitElement inElement,
|
||||
UInt32 nFrames,
|
||||
AudioBufferList * inBufferList);
|
||||
protected:
|
||||
/*! @method Disconnect */
|
||||
void Disconnect();
|
||||
|
||||
enum EInputType { kNoInput, kFromConnection, kFromCallback };
|
||||
|
||||
/*! @var mInputType */
|
||||
EInputType mInputType;
|
||||
|
||||
// if from callback:
|
||||
/*! @var mInputProc */
|
||||
AURenderCallback mInputProc;
|
||||
/*! @var mInputProcRefCon */
|
||||
void * mInputProcRefCon;
|
||||
|
||||
// if from connection:
|
||||
/*! @var mConnection */
|
||||
AudioUnitConnection mConnection;
|
||||
#if !CA_USE_AUDIO_PLUGIN_ONLY
|
||||
/*! @var mConnRenderProc */
|
||||
AudioUnitRenderProc mConnRenderProc;
|
||||
#endif
|
||||
/*! @var mConnInstanceStorage */
|
||||
void * mConnInstanceStorage; // for the input component
|
||||
};
|
||||
|
||||
|
||||
#endif // __AUInput_h__
|
||||
/*
|
||||
File: AUInputElement.h
|
||||
Abstract: Part of CoreAudio Utility Classes
|
||||
Version: 1.1
|
||||
|
||||
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.
|
||||
|
||||
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.
|
||||
|
||||
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.
|
||||
|
||||
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.
|
||||
|
||||
Copyright (C) 2014 Apple Inc. All Rights Reserved.
|
||||
|
||||
*/
|
||||
#ifndef __AUInput_h__
|
||||
#define __AUInput_h__
|
||||
|
||||
#include "AUScopeElement.h"
|
||||
#include "AUBuffer.h"
|
||||
|
||||
/*! @class AUInputElement */
|
||||
class AUInputElement : public AUIOElement {
|
||||
public:
|
||||
|
||||
/*! @ctor AUInputElement */
|
||||
AUInputElement(AUBase *audioUnit);
|
||||
/*! @dtor ~AUInputElement */
|
||||
virtual ~AUInputElement() { }
|
||||
|
||||
// AUElement override
|
||||
/*! @method SetStreamFormat */
|
||||
virtual OSStatus SetStreamFormat(const CAStreamBasicDescription &desc);
|
||||
/*! @method NeedsBufferSpace */
|
||||
virtual bool NeedsBufferSpace() const { return IsCallback(); }
|
||||
|
||||
/*! @method SetConnection */
|
||||
void SetConnection(const AudioUnitConnection &conn);
|
||||
/*! @method SetInputCallback */
|
||||
void SetInputCallback(AURenderCallback proc, void *refCon);
|
||||
|
||||
/*! @method IsActive */
|
||||
bool IsActive() const { return mInputType != kNoInput; }
|
||||
/*! @method IsCallback */
|
||||
bool IsCallback() const { return mInputType == kFromCallback; }
|
||||
/*! @method HasConnection */
|
||||
bool HasConnection() const { return mInputType == kFromConnection; }
|
||||
|
||||
/*! @method PullInput */
|
||||
OSStatus PullInput( AudioUnitRenderActionFlags & ioActionFlags,
|
||||
const AudioTimeStamp & inTimeStamp,
|
||||
AudioUnitElement inElement,
|
||||
UInt32 inNumberFrames);
|
||||
|
||||
/*! @method PullInputWithBufferList */
|
||||
OSStatus PullInputWithBufferList( AudioUnitRenderActionFlags & ioActionFlags,
|
||||
const AudioTimeStamp & inTimeStamp,
|
||||
AudioUnitElement inElement,
|
||||
UInt32 nFrames,
|
||||
AudioBufferList * inBufferList);
|
||||
protected:
|
||||
/*! @method Disconnect */
|
||||
void Disconnect();
|
||||
|
||||
enum EInputType { kNoInput, kFromConnection, kFromCallback };
|
||||
|
||||
/*! @var mInputType */
|
||||
EInputType mInputType;
|
||||
|
||||
// if from callback:
|
||||
/*! @var mInputProc */
|
||||
AURenderCallback mInputProc;
|
||||
/*! @var mInputProcRefCon */
|
||||
void * mInputProcRefCon;
|
||||
|
||||
// if from connection:
|
||||
/*! @var mConnection */
|
||||
AudioUnitConnection mConnection;
|
||||
#if !CA_USE_AUDIO_PLUGIN_ONLY
|
||||
/*! @var mConnRenderProc */
|
||||
AudioUnitRenderProc mConnRenderProc;
|
||||
#endif
|
||||
/*! @var mConnInstanceStorage */
|
||||
void * mConnInstanceStorage; // for the input component
|
||||
};
|
||||
|
||||
|
||||
#endif // __AUInput_h__
|
||||
|
||||
@@ -1,155 +1,155 @@
|
||||
/*
|
||||
File: AUInputFormatConverter.h
|
||||
Abstract: Part of CoreAudio Utility Classes
|
||||
Version: 1.1
|
||||
|
||||
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.
|
||||
|
||||
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.
|
||||
|
||||
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.
|
||||
|
||||
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.
|
||||
|
||||
Copyright (C) 2014 Apple Inc. All Rights Reserved.
|
||||
|
||||
*/
|
||||
#ifndef __AUInputFormatConverter_h__
|
||||
#define __AUInputFormatConverter_h__
|
||||
|
||||
#include "FormatConverterClient.h"
|
||||
#include "AUTimestampGenerator.h"
|
||||
|
||||
// ____________________________________________________________________________
|
||||
// AUInputFormatConverter
|
||||
//
|
||||
// Subclass of FormatConverterClient that applies a format conversion
|
||||
// to an input of an AudioUnit.
|
||||
/*! @class AUInputFormatConverter */
|
||||
class AUInputFormatConverter : public FormatConverterClient {
|
||||
public:
|
||||
/*! @ctor AUInputFormatConverter */
|
||||
AUInputFormatConverter(AUBase *hostAU, int inputBus) :
|
||||
mHost(hostAU),
|
||||
mHostBus(inputBus),
|
||||
mPreviousSilentFrames(0x1000)
|
||||
{
|
||||
#if DEBUG
|
||||
mTimestampGenerator.mVerbosity = 0;
|
||||
strcpy(mTimestampGenerator.mDebugName, "AUConverter");
|
||||
#endif
|
||||
}
|
||||
|
||||
// need to subsequently call Initialize, with the desired formats
|
||||
|
||||
/*! @dtor ~AUInputFormatConverter */
|
||||
~AUInputFormatConverter()
|
||||
{
|
||||
}
|
||||
|
||||
virtual OSStatus Initialize(const AudioStreamBasicDescription &src, const AudioStreamBasicDescription &dest)
|
||||
{
|
||||
OSStatus err = FormatConverterClient::Initialize(src, dest);
|
||||
if (err) return err;
|
||||
mIsPCMToPCM = (src.mFormatID == kAudioFormatLinearPCM) && (dest.mFormatID == kAudioFormatLinearPCM);
|
||||
mHasSRC = (fnonzero(src.mSampleRate) && fnonzero(dest.mSampleRate) && fnotequal(src.mSampleRate, dest.mSampleRate));
|
||||
return ca_noErr;
|
||||
}
|
||||
|
||||
virtual OSStatus Reset()
|
||||
{
|
||||
mPreviousSilentFrames = 0x1000;
|
||||
mTimestampGenerator.Reset();
|
||||
return FormatConverterClient::Reset();
|
||||
}
|
||||
|
||||
void SetStartInputTimeAtZero(bool b)
|
||||
{
|
||||
mTimestampGenerator.SetStartInputAtZero(b);
|
||||
}
|
||||
|
||||
/*! @method FillComplexBuffer */
|
||||
OSStatus AUFillComplexBuffer(const AudioTimeStamp & inTimeStamp,
|
||||
UInt32 & ioOutputDataPacketSize,
|
||||
AudioBufferList & outOutputData,
|
||||
AudioStreamPacketDescription* outPacketDescription,
|
||||
bool& outSilence)
|
||||
{
|
||||
mTimestampGenerator.AddOutputTime(inTimeStamp, ioOutputDataPacketSize, mOutputFormat.mSampleRate);
|
||||
mSilentOutput = true;
|
||||
OSStatus err = FillComplexBuffer(ioOutputDataPacketSize, outOutputData, outPacketDescription);
|
||||
if (mSilentOutput) {
|
||||
if (!mIsPCMToPCM || (mHasSRC && mPreviousSilentFrames < 32))
|
||||
mSilentOutput = false;
|
||||
mPreviousSilentFrames += ioOutputDataPacketSize;
|
||||
} else
|
||||
mPreviousSilentFrames = 0;
|
||||
outSilence = mSilentOutput;
|
||||
return err;
|
||||
}
|
||||
|
||||
/*! @method FormatConverterInputProc */
|
||||
virtual OSStatus FormatConverterInputProc(
|
||||
UInt32 & ioNumberDataPackets,
|
||||
AudioBufferList & ioData,
|
||||
AudioStreamPacketDescription** outDataPacketDescription)
|
||||
{
|
||||
OSStatus err = ca_noErr;
|
||||
|
||||
AudioUnitRenderActionFlags actionFlags = 0;
|
||||
AUInputElement *input = mHost->GetInput(mHostBus);
|
||||
*ioNumberDataPackets = std::min(*ioNumberDataPackets, This->mHost->GetMaxFramesPerSlice());
|
||||
const AudioTimeStamp &inputTime = mTimestampGenerator.GenerateInputTime(ioNumberDataPackets, mInputFormat.mSampleRate);
|
||||
err = input->PullInput(actionFlags, inputTime, mHostBus, ioNumberDataPackets);
|
||||
if (!err) {
|
||||
input->CopyBufferListTo(ioData);
|
||||
if (!(actionFlags & kAudioUnitRenderAction_OutputIsSilence))
|
||||
mSilentOutput = false;
|
||||
}
|
||||
return err;
|
||||
}
|
||||
|
||||
protected:
|
||||
/*! @var mHost */
|
||||
AUBase * mHost;
|
||||
/*! @var mHostBus */
|
||||
int mHostBus;
|
||||
|
||||
AUTimestampGenerator mTimestampGenerator;
|
||||
bool mIsPCMToPCM;
|
||||
bool mHasSRC;
|
||||
bool mSilentOutput;
|
||||
UInt32 mPreviousSilentFrames;
|
||||
};
|
||||
|
||||
#endif // __AUInputFormatConverter_h__
|
||||
/*
|
||||
File: AUInputFormatConverter.h
|
||||
Abstract: Part of CoreAudio Utility Classes
|
||||
Version: 1.1
|
||||
|
||||
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.
|
||||
|
||||
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.
|
||||
|
||||
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.
|
||||
|
||||
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.
|
||||
|
||||
Copyright (C) 2014 Apple Inc. All Rights Reserved.
|
||||
|
||||
*/
|
||||
#ifndef __AUInputFormatConverter_h__
|
||||
#define __AUInputFormatConverter_h__
|
||||
|
||||
#include "FormatConverterClient.h"
|
||||
#include "AUTimestampGenerator.h"
|
||||
|
||||
// ____________________________________________________________________________
|
||||
// AUInputFormatConverter
|
||||
//
|
||||
// Subclass of FormatConverterClient that applies a format conversion
|
||||
// to an input of an AudioUnit.
|
||||
/*! @class AUInputFormatConverter */
|
||||
class AUInputFormatConverter : public FormatConverterClient {
|
||||
public:
|
||||
/*! @ctor AUInputFormatConverter */
|
||||
AUInputFormatConverter(AUBase *hostAU, int inputBus) :
|
||||
mHost(hostAU),
|
||||
mHostBus(inputBus),
|
||||
mPreviousSilentFrames(0x1000)
|
||||
{
|
||||
#if DEBUG
|
||||
mTimestampGenerator.mVerbosity = 0;
|
||||
strcpy(mTimestampGenerator.mDebugName, "AUConverter");
|
||||
#endif
|
||||
}
|
||||
|
||||
// need to subsequently call Initialize, with the desired formats
|
||||
|
||||
/*! @dtor ~AUInputFormatConverter */
|
||||
~AUInputFormatConverter()
|
||||
{
|
||||
}
|
||||
|
||||
virtual OSStatus Initialize(const AudioStreamBasicDescription &src, const AudioStreamBasicDescription &dest)
|
||||
{
|
||||
OSStatus err = FormatConverterClient::Initialize(src, dest);
|
||||
if (err) return err;
|
||||
mIsPCMToPCM = (src.mFormatID == kAudioFormatLinearPCM) && (dest.mFormatID == kAudioFormatLinearPCM);
|
||||
mHasSRC = (fnonzero(src.mSampleRate) && fnonzero(dest.mSampleRate) && fnotequal(src.mSampleRate, dest.mSampleRate));
|
||||
return ca_noErr;
|
||||
}
|
||||
|
||||
virtual OSStatus Reset()
|
||||
{
|
||||
mPreviousSilentFrames = 0x1000;
|
||||
mTimestampGenerator.Reset();
|
||||
return FormatConverterClient::Reset();
|
||||
}
|
||||
|
||||
void SetStartInputTimeAtZero(bool b)
|
||||
{
|
||||
mTimestampGenerator.SetStartInputAtZero(b);
|
||||
}
|
||||
|
||||
/*! @method FillComplexBuffer */
|
||||
OSStatus AUFillComplexBuffer(const AudioTimeStamp & inTimeStamp,
|
||||
UInt32 & ioOutputDataPacketSize,
|
||||
AudioBufferList & outOutputData,
|
||||
AudioStreamPacketDescription* outPacketDescription,
|
||||
bool& outSilence)
|
||||
{
|
||||
mTimestampGenerator.AddOutputTime(inTimeStamp, ioOutputDataPacketSize, mOutputFormat.mSampleRate);
|
||||
mSilentOutput = true;
|
||||
OSStatus err = FillComplexBuffer(ioOutputDataPacketSize, outOutputData, outPacketDescription);
|
||||
if (mSilentOutput) {
|
||||
if (!mIsPCMToPCM || (mHasSRC && mPreviousSilentFrames < 32))
|
||||
mSilentOutput = false;
|
||||
mPreviousSilentFrames += ioOutputDataPacketSize;
|
||||
} else
|
||||
mPreviousSilentFrames = 0;
|
||||
outSilence = mSilentOutput;
|
||||
return err;
|
||||
}
|
||||
|
||||
/*! @method FormatConverterInputProc */
|
||||
virtual OSStatus FormatConverterInputProc(
|
||||
UInt32 & ioNumberDataPackets,
|
||||
AudioBufferList & ioData,
|
||||
AudioStreamPacketDescription** outDataPacketDescription)
|
||||
{
|
||||
OSStatus err = ca_noErr;
|
||||
|
||||
AudioUnitRenderActionFlags actionFlags = 0;
|
||||
AUInputElement *input = mHost->GetInput(mHostBus);
|
||||
*ioNumberDataPackets = std::min(*ioNumberDataPackets, This->mHost->GetMaxFramesPerSlice());
|
||||
const AudioTimeStamp &inputTime = mTimestampGenerator.GenerateInputTime(ioNumberDataPackets, mInputFormat.mSampleRate);
|
||||
err = input->PullInput(actionFlags, inputTime, mHostBus, ioNumberDataPackets);
|
||||
if (!err) {
|
||||
input->CopyBufferListTo(ioData);
|
||||
if (!(actionFlags & kAudioUnitRenderAction_OutputIsSilence))
|
||||
mSilentOutput = false;
|
||||
}
|
||||
return err;
|
||||
}
|
||||
|
||||
protected:
|
||||
/*! @var mHost */
|
||||
AUBase * mHost;
|
||||
/*! @var mHostBus */
|
||||
int mHostBus;
|
||||
|
||||
AUTimestampGenerator mTimestampGenerator;
|
||||
bool mIsPCMToPCM;
|
||||
bool mHasSRC;
|
||||
bool mSilentOutput;
|
||||
UInt32 mPreviousSilentFrames;
|
||||
};
|
||||
|
||||
#endif // __AUInputFormatConverter_h__
|
||||
|
||||
@@ -1,495 +1,495 @@
|
||||
/*
|
||||
File: AUMIDIBase.cpp
|
||||
Abstract: AUMIDIBase.h
|
||||
Version: 1.1
|
||||
|
||||
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.
|
||||
|
||||
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.
|
||||
|
||||
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.
|
||||
|
||||
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.
|
||||
|
||||
Copyright (C) 2014 Apple Inc. All Rights Reserved.
|
||||
|
||||
*/
|
||||
#include "AUMIDIBase.h"
|
||||
#include <CoreMIDI/CoreMIDI.h>
|
||||
#include "CAXException.h"
|
||||
|
||||
//temporary location
|
||||
enum
|
||||
{
|
||||
kMidiMessage_NoteOff = 0x80,
|
||||
kMidiMessage_NoteOn = 0x90,
|
||||
kMidiMessage_PolyPressure = 0xA0,
|
||||
kMidiMessage_ControlChange = 0xB0,
|
||||
kMidiMessage_ProgramChange = 0xC0,
|
||||
kMidiMessage_ChannelPressure = 0xD0,
|
||||
kMidiMessage_PitchWheel = 0xE0,
|
||||
|
||||
kMidiController_AllSoundOff = 120,
|
||||
kMidiController_ResetAllControllers = 121,
|
||||
kMidiController_AllNotesOff = 123
|
||||
};
|
||||
|
||||
AUMIDIBase::AUMIDIBase(AUBase* inBase)
|
||||
: mAUBaseInstance (*inBase)
|
||||
{
|
||||
#if CA_AUTO_MIDI_MAP
|
||||
mMapManager = new CAAUMIDIMapManager();
|
||||
#endif
|
||||
}
|
||||
|
||||
AUMIDIBase::~AUMIDIBase()
|
||||
{
|
||||
#if CA_AUTO_MIDI_MAP
|
||||
if (mMapManager)
|
||||
delete mMapManager;
|
||||
#endif
|
||||
}
|
||||
|
||||
#if TARGET_API_MAC_OSX
|
||||
OSStatus AUMIDIBase::DelegateGetPropertyInfo(AudioUnitPropertyID inID,
|
||||
AudioUnitScope inScope,
|
||||
AudioUnitElement inElement,
|
||||
UInt32 & outDataSize,
|
||||
Boolean & outWritable)
|
||||
{
|
||||
OSStatus result = noErr;
|
||||
|
||||
switch (inID) {
|
||||
#if !TARGET_OS_IPHONE
|
||||
case kMusicDeviceProperty_MIDIXMLNames:
|
||||
ca_require(inScope == kAudioUnitScope_Global, InvalidScope);
|
||||
ca_require(inElement == 0, InvalidElement);
|
||||
if (GetXMLNames(NULL) == noErr) {
|
||||
outDataSize = sizeof(CFURLRef);
|
||||
outWritable = false;
|
||||
} else
|
||||
result = kAudioUnitErr_InvalidProperty;
|
||||
break;
|
||||
#endif
|
||||
#if CA_AUTO_MIDI_MAP
|
||||
case kAudioUnitProperty_AllParameterMIDIMappings:
|
||||
ca_require(inScope == kAudioUnitScope_Global, InvalidScope);
|
||||
ca_require(inElement == 0, InvalidElement);
|
||||
outWritable = true;
|
||||
outDataSize = sizeof (AUParameterMIDIMapping)*mMapManager->NumMaps();
|
||||
result = noErr;
|
||||
break;
|
||||
|
||||
case kAudioUnitProperty_HotMapParameterMIDIMapping:
|
||||
ca_require(inScope == kAudioUnitScope_Global, InvalidScope);
|
||||
ca_require(inElement == 0, InvalidElement);
|
||||
outWritable = true;
|
||||
outDataSize = sizeof (AUParameterMIDIMapping);
|
||||
result = noErr;
|
||||
break;
|
||||
|
||||
case kAudioUnitProperty_AddParameterMIDIMapping:
|
||||
ca_require(inScope == kAudioUnitScope_Global, InvalidScope);
|
||||
ca_require(inElement == 0, InvalidElement);
|
||||
outWritable = true;
|
||||
outDataSize = sizeof (AUParameterMIDIMapping);
|
||||
result = noErr;
|
||||
break;
|
||||
|
||||
case kAudioUnitProperty_RemoveParameterMIDIMapping:
|
||||
ca_require(inScope == kAudioUnitScope_Global, InvalidScope);
|
||||
ca_require(inElement == 0, InvalidElement);
|
||||
outWritable = true;
|
||||
outDataSize = sizeof (AUParameterMIDIMapping);
|
||||
result = noErr;
|
||||
break;
|
||||
#endif
|
||||
|
||||
default:
|
||||
result = kAudioUnitErr_InvalidProperty;
|
||||
break;
|
||||
}
|
||||
return result;
|
||||
|
||||
#if CA_AUTO_MIDI_MAP || (!TARGET_OS_IPHONE)
|
||||
InvalidScope:
|
||||
return kAudioUnitErr_InvalidScope;
|
||||
InvalidElement:
|
||||
return kAudioUnitErr_InvalidElement;
|
||||
#endif
|
||||
}
|
||||
|
||||
OSStatus AUMIDIBase::DelegateGetProperty( AudioUnitPropertyID inID,
|
||||
AudioUnitScope inScope,
|
||||
AudioUnitElement inElement,
|
||||
void * outData)
|
||||
{
|
||||
OSStatus result;
|
||||
|
||||
switch (inID) {
|
||||
#if !TARGET_OS_IPHONE
|
||||
case kMusicDeviceProperty_MIDIXMLNames:
|
||||
ca_require(inScope == kAudioUnitScope_Global, InvalidScope);
|
||||
ca_require(inElement == 0, InvalidElement);
|
||||
result = GetXMLNames((CFURLRef *)outData);
|
||||
break;
|
||||
#endif
|
||||
#if CA_AUTO_MIDI_MAP
|
||||
case kAudioUnitProperty_AllParameterMIDIMappings:{
|
||||
ca_require(inScope == kAudioUnitScope_Global, InvalidScope);
|
||||
ca_require(inElement == 0, InvalidElement);
|
||||
AUParameterMIDIMapping* maps = (static_cast<AUParameterMIDIMapping*>(outData));
|
||||
mMapManager->GetMaps(maps);
|
||||
// printf ("GETTING MAPS\n");
|
||||
// mMapManager->Print();
|
||||
result = noErr;
|
||||
break;
|
||||
}
|
||||
|
||||
case kAudioUnitProperty_HotMapParameterMIDIMapping:{
|
||||
ca_require(inScope == kAudioUnitScope_Global, InvalidScope);
|
||||
ca_require(inElement == 0, InvalidElement);
|
||||
AUParameterMIDIMapping * map = (static_cast<AUParameterMIDIMapping*>(outData));
|
||||
mMapManager->GetHotParameterMap (*map);
|
||||
result = noErr;
|
||||
break;
|
||||
}
|
||||
#endif
|
||||
|
||||
default:
|
||||
result = kAudioUnitErr_InvalidProperty;
|
||||
break;
|
||||
}
|
||||
return result;
|
||||
|
||||
#if CA_AUTO_MIDI_MAP || (!TARGET_OS_IPHONE)
|
||||
InvalidScope:
|
||||
return kAudioUnitErr_InvalidScope;
|
||||
InvalidElement:
|
||||
return kAudioUnitErr_InvalidElement;
|
||||
#endif
|
||||
}
|
||||
|
||||
OSStatus AUMIDIBase::DelegateSetProperty( AudioUnitPropertyID inID,
|
||||
AudioUnitScope inScope,
|
||||
AudioUnitElement inElement,
|
||||
const void * inData,
|
||||
UInt32 inDataSize)
|
||||
{
|
||||
OSStatus result;
|
||||
|
||||
switch (inID) {
|
||||
#if CA_AUTO_MIDI_MAP
|
||||
case kAudioUnitProperty_AddParameterMIDIMapping:{
|
||||
ca_require(inScope == kAudioUnitScope_Global, InvalidScope);
|
||||
ca_require(inElement == 0, InvalidElement);
|
||||
AUParameterMIDIMapping * maps = (AUParameterMIDIMapping*)inData;
|
||||
mMapManager->SortedInsertToParamaterMaps (maps, (inDataSize / sizeof(AUParameterMIDIMapping)), mAUBaseInstance);
|
||||
mAUBaseInstance.PropertyChanged (kAudioUnitProperty_AllParameterMIDIMappings, kAudioUnitScope_Global, 0);
|
||||
result = noErr;
|
||||
break;
|
||||
}
|
||||
|
||||
case kAudioUnitProperty_RemoveParameterMIDIMapping:{
|
||||
ca_require(inScope == kAudioUnitScope_Global, InvalidScope);
|
||||
ca_require(inElement == 0, InvalidElement);
|
||||
AUParameterMIDIMapping * maps = (AUParameterMIDIMapping*)inData;
|
||||
bool didChange;
|
||||
mMapManager->SortedRemoveFromParameterMaps(maps, (inDataSize / sizeof(AUParameterMIDIMapping)), didChange);
|
||||
if (didChange)
|
||||
mAUBaseInstance.PropertyChanged (kAudioUnitProperty_AllParameterMIDIMappings, kAudioUnitScope_Global, 0);
|
||||
result = noErr;
|
||||
break;
|
||||
}
|
||||
|
||||
case kAudioUnitProperty_HotMapParameterMIDIMapping:{
|
||||
ca_require(inScope == kAudioUnitScope_Global, InvalidScope);
|
||||
ca_require(inElement == 0, InvalidElement);
|
||||
AUParameterMIDIMapping & map = *((AUParameterMIDIMapping*)inData);
|
||||
mMapManager->SetHotMapping (map);
|
||||
result = noErr;
|
||||
break;
|
||||
}
|
||||
case kAudioUnitProperty_AllParameterMIDIMappings:{
|
||||
ca_require(inScope == kAudioUnitScope_Global, InvalidScope);
|
||||
ca_require(inElement == 0, InvalidElement);
|
||||
AUParameterMIDIMapping * mappings = (AUParameterMIDIMapping*)inData;
|
||||
mMapManager->ReplaceAllMaps (mappings, (inDataSize / sizeof(AUParameterMIDIMapping)), mAUBaseInstance);
|
||||
result = noErr;
|
||||
break;
|
||||
}
|
||||
#endif
|
||||
|
||||
default:
|
||||
result = kAudioUnitErr_InvalidProperty;
|
||||
break;
|
||||
}
|
||||
return result;
|
||||
#if CA_AUTO_MIDI_MAP
|
||||
InvalidScope:
|
||||
return kAudioUnitErr_InvalidScope;
|
||||
InvalidElement:
|
||||
return kAudioUnitErr_InvalidElement;
|
||||
#endif
|
||||
}
|
||||
|
||||
|
||||
|
||||
#endif //TARGET_API_MAC_OSX
|
||||
|
||||
|
||||
//~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
|
||||
#pragma mark ____MidiDispatch
|
||||
|
||||
|
||||
inline const Byte * NextMIDIEvent(const Byte *event, const Byte *end)
|
||||
{
|
||||
Byte c = *event;
|
||||
switch (c >> 4) {
|
||||
default: // data byte -- assume in sysex
|
||||
while ((*++event & 0x80) == 0 && event < end)
|
||||
;
|
||||
break;
|
||||
case 0x8:
|
||||
case 0x9:
|
||||
case 0xA:
|
||||
case 0xB:
|
||||
case 0xE:
|
||||
event += 3;
|
||||
break;
|
||||
case 0xC:
|
||||
case 0xD:
|
||||
event += 2;
|
||||
break;
|
||||
case 0xF:
|
||||
switch (c) {
|
||||
case 0xF0:
|
||||
while ((*++event & 0x80) == 0 && event < end)
|
||||
;
|
||||
break;
|
||||
case 0xF1:
|
||||
case 0xF3:
|
||||
event += 2;
|
||||
break;
|
||||
case 0xF2:
|
||||
event += 3;
|
||||
break;
|
||||
default:
|
||||
++event;
|
||||
break;
|
||||
}
|
||||
}
|
||||
return (event >= end) ? end : event;
|
||||
}
|
||||
|
||||
//~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
|
||||
// AUMIDIBase::HandleMIDIPacketList
|
||||
//
|
||||
//~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
|
||||
OSStatus AUMIDIBase::HandleMIDIPacketList(const MIDIPacketList *pktlist)
|
||||
{
|
||||
if (!mAUBaseInstance.IsInitialized()) return kAudioUnitErr_Uninitialized;
|
||||
|
||||
int nPackets = pktlist->numPackets;
|
||||
const MIDIPacket *pkt = pktlist->packet;
|
||||
|
||||
while (nPackets-- > 0) {
|
||||
const Byte *event = pkt->data, *packetEnd = event + pkt->length;
|
||||
long startFrame = (long)pkt->timeStamp;
|
||||
while (event < packetEnd) {
|
||||
Byte status = event[0];
|
||||
if (status & 0x80) {
|
||||
// really a status byte (not sysex continuation)
|
||||
HandleMidiEvent(status & 0xF0, status & 0x0F, event[1], event[2], static_cast<UInt32>(startFrame));
|
||||
// note that we're generating a bogus channel number for system messages (0xF0-FF)
|
||||
}
|
||||
event = NextMIDIEvent(event, packetEnd);
|
||||
}
|
||||
pkt = reinterpret_cast<const MIDIPacket *>(packetEnd);
|
||||
}
|
||||
return noErr;
|
||||
}
|
||||
|
||||
//~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
|
||||
// AUMIDIBase::HandleMidiEvent
|
||||
//
|
||||
//~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
|
||||
OSStatus AUMIDIBase::HandleMidiEvent(UInt8 status, UInt8 channel, UInt8 data1, UInt8 data2, UInt32 inStartFrame)
|
||||
{
|
||||
if (!mAUBaseInstance.IsInitialized()) return kAudioUnitErr_Uninitialized;
|
||||
|
||||
#if CA_AUTO_MIDI_MAP
|
||||
// you potentially have a choice to make here - if a param mapping matches, do you still want to process the
|
||||
// MIDI event or not. The default behaviour is to continue on with the MIDI event.
|
||||
if (mMapManager->HandleHotMapping (status, channel, data1, mAUBaseInstance)) {
|
||||
mAUBaseInstance.PropertyChanged (kAudioUnitProperty_HotMapParameterMIDIMapping, kAudioUnitScope_Global, 0);
|
||||
}
|
||||
else {
|
||||
mMapManager->FindParameterMapEventMatch(status, channel, data1, data2, inStartFrame, mAUBaseInstance);
|
||||
}
|
||||
#endif
|
||||
|
||||
OSStatus result = noErr;
|
||||
|
||||
switch(status)
|
||||
{
|
||||
case kMidiMessage_NoteOn:
|
||||
if(data2)
|
||||
{
|
||||
result = HandleNoteOn(channel, data1, data2, inStartFrame);
|
||||
}
|
||||
else
|
||||
{
|
||||
// zero velocity translates to note off
|
||||
result = HandleNoteOff(channel, data1, data2, inStartFrame);
|
||||
}
|
||||
break;
|
||||
|
||||
case kMidiMessage_NoteOff:
|
||||
result = HandleNoteOff(channel, data1, data2, inStartFrame);
|
||||
break;
|
||||
|
||||
default:
|
||||
result = HandleNonNoteEvent (status, channel, data1, data2, inStartFrame);
|
||||
break;
|
||||
}
|
||||
|
||||
return result;
|
||||
}
|
||||
|
||||
OSStatus AUMIDIBase::HandleNonNoteEvent (UInt8 status, UInt8 channel, UInt8 data1, UInt8 data2, UInt32 inStartFrame)
|
||||
{
|
||||
OSStatus result = noErr;
|
||||
|
||||
switch (status)
|
||||
{
|
||||
case kMidiMessage_PitchWheel:
|
||||
result = HandlePitchWheel(channel, data1, data2, inStartFrame);
|
||||
break;
|
||||
|
||||
case kMidiMessage_ProgramChange:
|
||||
result = HandleProgramChange(channel, data1);
|
||||
break;
|
||||
|
||||
case kMidiMessage_ChannelPressure:
|
||||
result = HandleChannelPressure(channel, data1, inStartFrame);
|
||||
break;
|
||||
|
||||
case kMidiMessage_ControlChange:
|
||||
{
|
||||
switch (data1) {
|
||||
case kMidiController_AllNotesOff:
|
||||
result = HandleAllNotesOff(channel);
|
||||
break;
|
||||
|
||||
case kMidiController_ResetAllControllers:
|
||||
result = HandleResetAllControllers(channel);
|
||||
break;
|
||||
|
||||
case kMidiController_AllSoundOff:
|
||||
result = HandleAllSoundOff(channel);
|
||||
break;
|
||||
|
||||
default:
|
||||
result = HandleControlChange(channel, data1, data2, inStartFrame);
|
||||
break;
|
||||
}
|
||||
break;
|
||||
}
|
||||
case kMidiMessage_PolyPressure:
|
||||
result = HandlePolyPressure (channel, data1, data2, inStartFrame);
|
||||
break;
|
||||
}
|
||||
return result;
|
||||
}
|
||||
|
||||
OSStatus AUMIDIBase::SysEx (const UInt8 * inData,
|
||||
UInt32 inLength)
|
||||
{
|
||||
if (!mAUBaseInstance.IsInitialized()) return kAudioUnitErr_Uninitialized;
|
||||
|
||||
return HandleSysEx(inData, inLength );
|
||||
}
|
||||
|
||||
|
||||
|
||||
#if TARGET_OS_MAC
|
||||
#if __LP64__
|
||||
// comp instance, parameters in forward order
|
||||
#define PARAM(_typ, _name, _index, _nparams) \
|
||||
_typ _name = *(_typ *)¶ms->params[_index + 1];
|
||||
#else
|
||||
// parameters in reverse order, then comp instance
|
||||
#define PARAM(_typ, _name, _index, _nparams) \
|
||||
_typ _name = *(_typ *)¶ms->params[_nparams - 1 - _index];
|
||||
#endif
|
||||
#elif TARGET_OS_WIN32
|
||||
// (no comp instance), parameters in forward order
|
||||
#define PARAM(_typ, _name, _index, _nparams) \
|
||||
_typ _name = *(_typ *)¶ms->params[_index];
|
||||
#endif
|
||||
|
||||
#if !CA_USE_AUDIO_PLUGIN_ONLY
|
||||
OSStatus AUMIDIBase::ComponentEntryDispatch( ComponentParameters * params,
|
||||
AUMIDIBase * This)
|
||||
{
|
||||
if (This == NULL) return kAudio_ParamError;
|
||||
|
||||
OSStatus result;
|
||||
|
||||
switch (params->what) {
|
||||
case kMusicDeviceMIDIEventSelect:
|
||||
{
|
||||
PARAM(UInt32, pbinStatus, 0, 4);
|
||||
PARAM(UInt32, pbinData1, 1, 4);
|
||||
PARAM(UInt32, pbinData2, 2, 4);
|
||||
PARAM(UInt32, pbinOffsetSampleFrame, 3, 4);
|
||||
result = This->MIDIEvent(pbinStatus, pbinData1, pbinData2, pbinOffsetSampleFrame);
|
||||
}
|
||||
break;
|
||||
case kMusicDeviceSysExSelect:
|
||||
{
|
||||
PARAM(const UInt8 *, pbinData, 0, 2);
|
||||
PARAM(UInt32, pbinLength, 1, 2);
|
||||
result = This->SysEx(pbinData, pbinLength);
|
||||
}
|
||||
break;
|
||||
|
||||
default:
|
||||
result = badComponentSelector;
|
||||
break;
|
||||
}
|
||||
|
||||
return result;
|
||||
}
|
||||
#endif
|
||||
/*
|
||||
File: AUMIDIBase.cpp
|
||||
Abstract: AUMIDIBase.h
|
||||
Version: 1.1
|
||||
|
||||
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.
|
||||
|
||||
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.
|
||||
|
||||
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.
|
||||
|
||||
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.
|
||||
|
||||
Copyright (C) 2014 Apple Inc. All Rights Reserved.
|
||||
|
||||
*/
|
||||
#include "AUMIDIBase.h"
|
||||
#include <CoreMIDI/CoreMIDI.h>
|
||||
#include "CAXException.h"
|
||||
|
||||
//temporary location
|
||||
enum
|
||||
{
|
||||
kMidiMessage_NoteOff = 0x80,
|
||||
kMidiMessage_NoteOn = 0x90,
|
||||
kMidiMessage_PolyPressure = 0xA0,
|
||||
kMidiMessage_ControlChange = 0xB0,
|
||||
kMidiMessage_ProgramChange = 0xC0,
|
||||
kMidiMessage_ChannelPressure = 0xD0,
|
||||
kMidiMessage_PitchWheel = 0xE0,
|
||||
|
||||
kMidiController_AllSoundOff = 120,
|
||||
kMidiController_ResetAllControllers = 121,
|
||||
kMidiController_AllNotesOff = 123
|
||||
};
|
||||
|
||||
AUMIDIBase::AUMIDIBase(AUBase* inBase)
|
||||
: mAUBaseInstance (*inBase)
|
||||
{
|
||||
#if CA_AUTO_MIDI_MAP
|
||||
mMapManager = new CAAUMIDIMapManager();
|
||||
#endif
|
||||
}
|
||||
|
||||
AUMIDIBase::~AUMIDIBase()
|
||||
{
|
||||
#if CA_AUTO_MIDI_MAP
|
||||
if (mMapManager)
|
||||
delete mMapManager;
|
||||
#endif
|
||||
}
|
||||
|
||||
#if TARGET_API_MAC_OSX
|
||||
OSStatus AUMIDIBase::DelegateGetPropertyInfo(AudioUnitPropertyID inID,
|
||||
AudioUnitScope inScope,
|
||||
AudioUnitElement inElement,
|
||||
UInt32 & outDataSize,
|
||||
Boolean & outWritable)
|
||||
{
|
||||
OSStatus result = noErr;
|
||||
|
||||
switch (inID) {
|
||||
#if !TARGET_OS_IPHONE
|
||||
case kMusicDeviceProperty_MIDIXMLNames:
|
||||
ca_require(inScope == kAudioUnitScope_Global, InvalidScope);
|
||||
ca_require(inElement == 0, InvalidElement);
|
||||
if (GetXMLNames(NULL) == noErr) {
|
||||
outDataSize = sizeof(CFURLRef);
|
||||
outWritable = false;
|
||||
} else
|
||||
result = kAudioUnitErr_InvalidProperty;
|
||||
break;
|
||||
#endif
|
||||
#if CA_AUTO_MIDI_MAP
|
||||
case kAudioUnitProperty_AllParameterMIDIMappings:
|
||||
ca_require(inScope == kAudioUnitScope_Global, InvalidScope);
|
||||
ca_require(inElement == 0, InvalidElement);
|
||||
outWritable = true;
|
||||
outDataSize = sizeof (AUParameterMIDIMapping)*mMapManager->NumMaps();
|
||||
result = noErr;
|
||||
break;
|
||||
|
||||
case kAudioUnitProperty_HotMapParameterMIDIMapping:
|
||||
ca_require(inScope == kAudioUnitScope_Global, InvalidScope);
|
||||
ca_require(inElement == 0, InvalidElement);
|
||||
outWritable = true;
|
||||
outDataSize = sizeof (AUParameterMIDIMapping);
|
||||
result = noErr;
|
||||
break;
|
||||
|
||||
case kAudioUnitProperty_AddParameterMIDIMapping:
|
||||
ca_require(inScope == kAudioUnitScope_Global, InvalidScope);
|
||||
ca_require(inElement == 0, InvalidElement);
|
||||
outWritable = true;
|
||||
outDataSize = sizeof (AUParameterMIDIMapping);
|
||||
result = noErr;
|
||||
break;
|
||||
|
||||
case kAudioUnitProperty_RemoveParameterMIDIMapping:
|
||||
ca_require(inScope == kAudioUnitScope_Global, InvalidScope);
|
||||
ca_require(inElement == 0, InvalidElement);
|
||||
outWritable = true;
|
||||
outDataSize = sizeof (AUParameterMIDIMapping);
|
||||
result = noErr;
|
||||
break;
|
||||
#endif
|
||||
|
||||
default:
|
||||
result = kAudioUnitErr_InvalidProperty;
|
||||
break;
|
||||
}
|
||||
return result;
|
||||
|
||||
#if CA_AUTO_MIDI_MAP || (!TARGET_OS_IPHONE)
|
||||
InvalidScope:
|
||||
return kAudioUnitErr_InvalidScope;
|
||||
InvalidElement:
|
||||
return kAudioUnitErr_InvalidElement;
|
||||
#endif
|
||||
}
|
||||
|
||||
OSStatus AUMIDIBase::DelegateGetProperty( AudioUnitPropertyID inID,
|
||||
AudioUnitScope inScope,
|
||||
AudioUnitElement inElement,
|
||||
void * outData)
|
||||
{
|
||||
OSStatus result;
|
||||
|
||||
switch (inID) {
|
||||
#if !TARGET_OS_IPHONE
|
||||
case kMusicDeviceProperty_MIDIXMLNames:
|
||||
ca_require(inScope == kAudioUnitScope_Global, InvalidScope);
|
||||
ca_require(inElement == 0, InvalidElement);
|
||||
result = GetXMLNames((CFURLRef *)outData);
|
||||
break;
|
||||
#endif
|
||||
#if CA_AUTO_MIDI_MAP
|
||||
case kAudioUnitProperty_AllParameterMIDIMappings:{
|
||||
ca_require(inScope == kAudioUnitScope_Global, InvalidScope);
|
||||
ca_require(inElement == 0, InvalidElement);
|
||||
AUParameterMIDIMapping* maps = (static_cast<AUParameterMIDIMapping*>(outData));
|
||||
mMapManager->GetMaps(maps);
|
||||
// printf ("GETTING MAPS\n");
|
||||
// mMapManager->Print();
|
||||
result = noErr;
|
||||
break;
|
||||
}
|
||||
|
||||
case kAudioUnitProperty_HotMapParameterMIDIMapping:{
|
||||
ca_require(inScope == kAudioUnitScope_Global, InvalidScope);
|
||||
ca_require(inElement == 0, InvalidElement);
|
||||
AUParameterMIDIMapping * map = (static_cast<AUParameterMIDIMapping*>(outData));
|
||||
mMapManager->GetHotParameterMap (*map);
|
||||
result = noErr;
|
||||
break;
|
||||
}
|
||||
#endif
|
||||
|
||||
default:
|
||||
result = kAudioUnitErr_InvalidProperty;
|
||||
break;
|
||||
}
|
||||
return result;
|
||||
|
||||
#if CA_AUTO_MIDI_MAP || (!TARGET_OS_IPHONE)
|
||||
InvalidScope:
|
||||
return kAudioUnitErr_InvalidScope;
|
||||
InvalidElement:
|
||||
return kAudioUnitErr_InvalidElement;
|
||||
#endif
|
||||
}
|
||||
|
||||
OSStatus AUMIDIBase::DelegateSetProperty( AudioUnitPropertyID inID,
|
||||
AudioUnitScope inScope,
|
||||
AudioUnitElement inElement,
|
||||
const void * inData,
|
||||
UInt32 inDataSize)
|
||||
{
|
||||
OSStatus result;
|
||||
|
||||
switch (inID) {
|
||||
#if CA_AUTO_MIDI_MAP
|
||||
case kAudioUnitProperty_AddParameterMIDIMapping:{
|
||||
ca_require(inScope == kAudioUnitScope_Global, InvalidScope);
|
||||
ca_require(inElement == 0, InvalidElement);
|
||||
AUParameterMIDIMapping * maps = (AUParameterMIDIMapping*)inData;
|
||||
mMapManager->SortedInsertToParamaterMaps (maps, (inDataSize / sizeof(AUParameterMIDIMapping)), mAUBaseInstance);
|
||||
mAUBaseInstance.PropertyChanged (kAudioUnitProperty_AllParameterMIDIMappings, kAudioUnitScope_Global, 0);
|
||||
result = noErr;
|
||||
break;
|
||||
}
|
||||
|
||||
case kAudioUnitProperty_RemoveParameterMIDIMapping:{
|
||||
ca_require(inScope == kAudioUnitScope_Global, InvalidScope);
|
||||
ca_require(inElement == 0, InvalidElement);
|
||||
AUParameterMIDIMapping * maps = (AUParameterMIDIMapping*)inData;
|
||||
bool didChange;
|
||||
mMapManager->SortedRemoveFromParameterMaps(maps, (inDataSize / sizeof(AUParameterMIDIMapping)), didChange);
|
||||
if (didChange)
|
||||
mAUBaseInstance.PropertyChanged (kAudioUnitProperty_AllParameterMIDIMappings, kAudioUnitScope_Global, 0);
|
||||
result = noErr;
|
||||
break;
|
||||
}
|
||||
|
||||
case kAudioUnitProperty_HotMapParameterMIDIMapping:{
|
||||
ca_require(inScope == kAudioUnitScope_Global, InvalidScope);
|
||||
ca_require(inElement == 0, InvalidElement);
|
||||
AUParameterMIDIMapping & map = *((AUParameterMIDIMapping*)inData);
|
||||
mMapManager->SetHotMapping (map);
|
||||
result = noErr;
|
||||
break;
|
||||
}
|
||||
case kAudioUnitProperty_AllParameterMIDIMappings:{
|
||||
ca_require(inScope == kAudioUnitScope_Global, InvalidScope);
|
||||
ca_require(inElement == 0, InvalidElement);
|
||||
AUParameterMIDIMapping * mappings = (AUParameterMIDIMapping*)inData;
|
||||
mMapManager->ReplaceAllMaps (mappings, (inDataSize / sizeof(AUParameterMIDIMapping)), mAUBaseInstance);
|
||||
result = noErr;
|
||||
break;
|
||||
}
|
||||
#endif
|
||||
|
||||
default:
|
||||
result = kAudioUnitErr_InvalidProperty;
|
||||
break;
|
||||
}
|
||||
return result;
|
||||
#if CA_AUTO_MIDI_MAP
|
||||
InvalidScope:
|
||||
return kAudioUnitErr_InvalidScope;
|
||||
InvalidElement:
|
||||
return kAudioUnitErr_InvalidElement;
|
||||
#endif
|
||||
}
|
||||
|
||||
|
||||
|
||||
#endif //TARGET_API_MAC_OSX
|
||||
|
||||
|
||||
//~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
|
||||
#pragma mark ____MidiDispatch
|
||||
|
||||
|
||||
inline const Byte * NextMIDIEvent(const Byte *event, const Byte *end)
|
||||
{
|
||||
Byte c = *event;
|
||||
switch (c >> 4) {
|
||||
default: // data byte -- assume in sysex
|
||||
while ((*++event & 0x80) == 0 && event < end)
|
||||
;
|
||||
break;
|
||||
case 0x8:
|
||||
case 0x9:
|
||||
case 0xA:
|
||||
case 0xB:
|
||||
case 0xE:
|
||||
event += 3;
|
||||
break;
|
||||
case 0xC:
|
||||
case 0xD:
|
||||
event += 2;
|
||||
break;
|
||||
case 0xF:
|
||||
switch (c) {
|
||||
case 0xF0:
|
||||
while ((*++event & 0x80) == 0 && event < end)
|
||||
;
|
||||
break;
|
||||
case 0xF1:
|
||||
case 0xF3:
|
||||
event += 2;
|
||||
break;
|
||||
case 0xF2:
|
||||
event += 3;
|
||||
break;
|
||||
default:
|
||||
++event;
|
||||
break;
|
||||
}
|
||||
}
|
||||
return (event >= end) ? end : event;
|
||||
}
|
||||
|
||||
//~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
|
||||
// AUMIDIBase::HandleMIDIPacketList
|
||||
//
|
||||
//~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
|
||||
OSStatus AUMIDIBase::HandleMIDIPacketList(const MIDIPacketList *pktlist)
|
||||
{
|
||||
if (!mAUBaseInstance.IsInitialized()) return kAudioUnitErr_Uninitialized;
|
||||
|
||||
int nPackets = pktlist->numPackets;
|
||||
const MIDIPacket *pkt = pktlist->packet;
|
||||
|
||||
while (nPackets-- > 0) {
|
||||
const Byte *event = pkt->data, *packetEnd = event + pkt->length;
|
||||
long startFrame = (long)pkt->timeStamp;
|
||||
while (event < packetEnd) {
|
||||
Byte status = event[0];
|
||||
if (status & 0x80) {
|
||||
// really a status byte (not sysex continuation)
|
||||
HandleMidiEvent(status & 0xF0, status & 0x0F, event[1], event[2], static_cast<UInt32>(startFrame));
|
||||
// note that we're generating a bogus channel number for system messages (0xF0-FF)
|
||||
}
|
||||
event = NextMIDIEvent(event, packetEnd);
|
||||
}
|
||||
pkt = reinterpret_cast<const MIDIPacket *>(packetEnd);
|
||||
}
|
||||
return noErr;
|
||||
}
|
||||
|
||||
//~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
|
||||
// AUMIDIBase::HandleMidiEvent
|
||||
//
|
||||
//~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
|
||||
OSStatus AUMIDIBase::HandleMidiEvent(UInt8 status, UInt8 channel, UInt8 data1, UInt8 data2, UInt32 inStartFrame)
|
||||
{
|
||||
if (!mAUBaseInstance.IsInitialized()) return kAudioUnitErr_Uninitialized;
|
||||
|
||||
#if CA_AUTO_MIDI_MAP
|
||||
// you potentially have a choice to make here - if a param mapping matches, do you still want to process the
|
||||
// MIDI event or not. The default behaviour is to continue on with the MIDI event.
|
||||
if (mMapManager->HandleHotMapping (status, channel, data1, mAUBaseInstance)) {
|
||||
mAUBaseInstance.PropertyChanged (kAudioUnitProperty_HotMapParameterMIDIMapping, kAudioUnitScope_Global, 0);
|
||||
}
|
||||
else {
|
||||
mMapManager->FindParameterMapEventMatch(status, channel, data1, data2, inStartFrame, mAUBaseInstance);
|
||||
}
|
||||
#endif
|
||||
|
||||
OSStatus result = noErr;
|
||||
|
||||
switch(status)
|
||||
{
|
||||
case kMidiMessage_NoteOn:
|
||||
if(data2)
|
||||
{
|
||||
result = HandleNoteOn(channel, data1, data2, inStartFrame);
|
||||
}
|
||||
else
|
||||
{
|
||||
// zero velocity translates to note off
|
||||
result = HandleNoteOff(channel, data1, data2, inStartFrame);
|
||||
}
|
||||
break;
|
||||
|
||||
case kMidiMessage_NoteOff:
|
||||
result = HandleNoteOff(channel, data1, data2, inStartFrame);
|
||||
break;
|
||||
|
||||
default:
|
||||
result = HandleNonNoteEvent (status, channel, data1, data2, inStartFrame);
|
||||
break;
|
||||
}
|
||||
|
||||
return result;
|
||||
}
|
||||
|
||||
OSStatus AUMIDIBase::HandleNonNoteEvent (UInt8 status, UInt8 channel, UInt8 data1, UInt8 data2, UInt32 inStartFrame)
|
||||
{
|
||||
OSStatus result = noErr;
|
||||
|
||||
switch (status)
|
||||
{
|
||||
case kMidiMessage_PitchWheel:
|
||||
result = HandlePitchWheel(channel, data1, data2, inStartFrame);
|
||||
break;
|
||||
|
||||
case kMidiMessage_ProgramChange:
|
||||
result = HandleProgramChange(channel, data1);
|
||||
break;
|
||||
|
||||
case kMidiMessage_ChannelPressure:
|
||||
result = HandleChannelPressure(channel, data1, inStartFrame);
|
||||
break;
|
||||
|
||||
case kMidiMessage_ControlChange:
|
||||
{
|
||||
switch (data1) {
|
||||
case kMidiController_AllNotesOff:
|
||||
result = HandleAllNotesOff(channel);
|
||||
break;
|
||||
|
||||
case kMidiController_ResetAllControllers:
|
||||
result = HandleResetAllControllers(channel);
|
||||
break;
|
||||
|
||||
case kMidiController_AllSoundOff:
|
||||
result = HandleAllSoundOff(channel);
|
||||
break;
|
||||
|
||||
default:
|
||||
result = HandleControlChange(channel, data1, data2, inStartFrame);
|
||||
break;
|
||||
}
|
||||
break;
|
||||
}
|
||||
case kMidiMessage_PolyPressure:
|
||||
result = HandlePolyPressure (channel, data1, data2, inStartFrame);
|
||||
break;
|
||||
}
|
||||
return result;
|
||||
}
|
||||
|
||||
OSStatus AUMIDIBase::SysEx (const UInt8 * inData,
|
||||
UInt32 inLength)
|
||||
{
|
||||
if (!mAUBaseInstance.IsInitialized()) return kAudioUnitErr_Uninitialized;
|
||||
|
||||
return HandleSysEx(inData, inLength );
|
||||
}
|
||||
|
||||
|
||||
|
||||
#if TARGET_OS_MAC
|
||||
#if __LP64__
|
||||
// comp instance, parameters in forward order
|
||||
#define PARAM(_typ, _name, _index, _nparams) \
|
||||
_typ _name = *(_typ *)¶ms->params[_index + 1];
|
||||
#else
|
||||
// parameters in reverse order, then comp instance
|
||||
#define PARAM(_typ, _name, _index, _nparams) \
|
||||
_typ _name = *(_typ *)¶ms->params[_nparams - 1 - _index];
|
||||
#endif
|
||||
#elif TARGET_OS_WIN32
|
||||
// (no comp instance), parameters in forward order
|
||||
#define PARAM(_typ, _name, _index, _nparams) \
|
||||
_typ _name = *(_typ *)¶ms->params[_index];
|
||||
#endif
|
||||
|
||||
#if !CA_USE_AUDIO_PLUGIN_ONLY
|
||||
OSStatus AUMIDIBase::ComponentEntryDispatch( ComponentParameters * params,
|
||||
AUMIDIBase * This)
|
||||
{
|
||||
if (This == NULL) return kAudio_ParamError;
|
||||
|
||||
OSStatus result;
|
||||
|
||||
switch (params->what) {
|
||||
case kMusicDeviceMIDIEventSelect:
|
||||
{
|
||||
PARAM(UInt32, pbinStatus, 0, 4);
|
||||
PARAM(UInt32, pbinData1, 1, 4);
|
||||
PARAM(UInt32, pbinData2, 2, 4);
|
||||
PARAM(UInt32, pbinOffsetSampleFrame, 3, 4);
|
||||
result = This->MIDIEvent(pbinStatus, pbinData1, pbinData2, pbinOffsetSampleFrame);
|
||||
}
|
||||
break;
|
||||
case kMusicDeviceSysExSelect:
|
||||
{
|
||||
PARAM(const UInt8 *, pbinData, 0, 2);
|
||||
PARAM(UInt32, pbinLength, 1, 2);
|
||||
result = This->SysEx(pbinData, pbinLength);
|
||||
}
|
||||
break;
|
||||
|
||||
default:
|
||||
result = badComponentSelector;
|
||||
break;
|
||||
}
|
||||
|
||||
return result;
|
||||
}
|
||||
#endif
|
||||
|
||||
@@ -1,213 +1,213 @@
|
||||
/*
|
||||
File: AUMIDIBase.h
|
||||
Abstract: Part of CoreAudio Utility Classes
|
||||
Version: 1.1
|
||||
|
||||
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.
|
||||
|
||||
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.
|
||||
|
||||
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.
|
||||
|
||||
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.
|
||||
|
||||
Copyright (C) 2014 Apple Inc. All Rights Reserved.
|
||||
|
||||
*/
|
||||
#ifndef __AUMIDIBase_h__
|
||||
#define __AUMIDIBase_h__
|
||||
|
||||
#include "AUBase.h"
|
||||
|
||||
#if CA_AUTO_MIDI_MAP
|
||||
#include "CAAUMIDIMapManager.h"
|
||||
#endif
|
||||
|
||||
struct MIDIPacketList;
|
||||
|
||||
// ________________________________________________________________________
|
||||
// MusicDeviceBase
|
||||
//
|
||||
/*! @class AUMIDIBase */
|
||||
class AUMIDIBase {
|
||||
public:
|
||||
// this is NOT a copy constructor!
|
||||
/*! @ctor AUMIDIBase */
|
||||
AUMIDIBase(AUBase* inBase);
|
||||
/*! @dtor ~AUMIDIBase */
|
||||
virtual ~AUMIDIBase();
|
||||
|
||||
/*! @method MIDIEvent */
|
||||
virtual OSStatus MIDIEvent( UInt32 inStatus,
|
||||
UInt32 inData1,
|
||||
UInt32 inData2,
|
||||
UInt32 inOffsetSampleFrame)
|
||||
{
|
||||
UInt32 strippedStatus = inStatus & 0xf0;
|
||||
UInt32 channel = inStatus & 0x0f;
|
||||
|
||||
return HandleMidiEvent(strippedStatus, channel, inData1, inData2, inOffsetSampleFrame);
|
||||
}
|
||||
|
||||
/*! @method HandleMIDIPacketList */
|
||||
OSStatus HandleMIDIPacketList(const MIDIPacketList *pktlist);
|
||||
|
||||
/*! @method SysEx */
|
||||
virtual OSStatus SysEx( const UInt8 * inData,
|
||||
UInt32 inLength);
|
||||
|
||||
#if TARGET_API_MAC_OSX
|
||||
/*! @method DelegateGetPropertyInfo */
|
||||
virtual OSStatus DelegateGetPropertyInfo(AudioUnitPropertyID inID,
|
||||
AudioUnitScope inScope,
|
||||
AudioUnitElement inElement,
|
||||
UInt32 & outDataSize,
|
||||
Boolean & outWritable);
|
||||
|
||||
/*! @method DelegateGetProperty */
|
||||
virtual OSStatus DelegateGetProperty( AudioUnitPropertyID inID,
|
||||
AudioUnitScope inScope,
|
||||
AudioUnitElement inElement,
|
||||
void * outData);
|
||||
|
||||
/*! @method DelegateSetProperty */
|
||||
virtual OSStatus DelegateSetProperty( AudioUnitPropertyID inID,
|
||||
AudioUnitScope inScope,
|
||||
AudioUnitElement inElement,
|
||||
const void * inData,
|
||||
UInt32 inDataSize);
|
||||
#endif
|
||||
|
||||
protected:
|
||||
// MIDI dispatch
|
||||
/*! @method HandleMidiEvent */
|
||||
virtual OSStatus HandleMidiEvent( UInt8 inStatus,
|
||||
UInt8 inChannel,
|
||||
UInt8 inData1,
|
||||
UInt8 inData2,
|
||||
UInt32 inStartFrame);
|
||||
|
||||
/*! @method HandleNonNoteEvent */
|
||||
virtual OSStatus HandleNonNoteEvent ( UInt8 status,
|
||||
UInt8 channel,
|
||||
UInt8 data1,
|
||||
UInt8 data2,
|
||||
UInt32 inStartFrame);
|
||||
|
||||
#if TARGET_API_MAC_OSX
|
||||
/*! @method GetXMLNames */
|
||||
virtual OSStatus GetXMLNames(CFURLRef *outNameDocument)
|
||||
{ return kAudioUnitErr_InvalidProperty; } // if not overridden, it's unsupported
|
||||
#endif
|
||||
|
||||
// channel messages
|
||||
/*! @method HandleNoteOn */
|
||||
virtual OSStatus HandleNoteOn( UInt8 inChannel,
|
||||
UInt8 inNoteNumber,
|
||||
UInt8 inVelocity,
|
||||
UInt32 inStartFrame) { return noErr; }
|
||||
|
||||
/*! @method HandleNoteOff */
|
||||
virtual OSStatus HandleNoteOff( UInt8 inChannel,
|
||||
UInt8 inNoteNumber,
|
||||
UInt8 inVelocity,
|
||||
UInt32 inStartFrame) { return noErr; }
|
||||
|
||||
/*! @method HandleControlChange */
|
||||
virtual OSStatus HandleControlChange( UInt8 inChannel,
|
||||
UInt8 inController,
|
||||
UInt8 inValue,
|
||||
UInt32 inStartFrame) { return noErr; }
|
||||
|
||||
/*! @method HandlePitchWheel */
|
||||
virtual OSStatus HandlePitchWheel( UInt8 inChannel,
|
||||
UInt8 inPitch1,
|
||||
UInt8 inPitch2,
|
||||
UInt32 inStartFrame) { return noErr; }
|
||||
|
||||
/*! @method HandleChannelPressure */
|
||||
virtual OSStatus HandleChannelPressure( UInt8 inChannel,
|
||||
UInt8 inValue,
|
||||
UInt32 inStartFrame) { return noErr; }
|
||||
|
||||
/*! @method HandleProgramChange */
|
||||
virtual OSStatus HandleProgramChange( UInt8 inChannel,
|
||||
UInt8 inValue) { return noErr; }
|
||||
|
||||
/*! @method HandlePolyPressure */
|
||||
virtual OSStatus HandlePolyPressure( UInt8 inChannel,
|
||||
UInt8 inKey,
|
||||
UInt8 inValue,
|
||||
UInt32 inStartFrame) { return noErr; }
|
||||
|
||||
/*! @method HandleResetAllControllers */
|
||||
virtual OSStatus HandleResetAllControllers(UInt8 inChannel) { return noErr; }
|
||||
|
||||
/*! @method HandleAllNotesOff */
|
||||
virtual OSStatus HandleAllNotesOff( UInt8 inChannel) { return noErr; }
|
||||
|
||||
/*! @method HandleAllSoundOff */
|
||||
virtual OSStatus HandleAllSoundOff( UInt8 inChannel) { return noErr; }
|
||||
|
||||
|
||||
//System messages
|
||||
/*! @method HandleSysEx */
|
||||
virtual OSStatus HandleSysEx( const UInt8 * inData,
|
||||
UInt32 inLength ) { return noErr; }
|
||||
|
||||
#if CA_AUTO_MIDI_MAP
|
||||
/* map manager */
|
||||
CAAUMIDIMapManager *GetMIDIMapManager() {return mMapManager;};
|
||||
|
||||
#endif
|
||||
|
||||
|
||||
private:
|
||||
/*! @var mAUBaseInstance */
|
||||
AUBase & mAUBaseInstance;
|
||||
|
||||
#if CA_AUTO_MIDI_MAP
|
||||
/* map manager */
|
||||
CAAUMIDIMapManager * mMapManager;
|
||||
#endif
|
||||
|
||||
public:
|
||||
#if !CA_USE_AUDIO_PLUGIN_ONLY
|
||||
// component dispatcher
|
||||
/*! @method ComponentEntryDispatch */
|
||||
static OSStatus ComponentEntryDispatch( ComponentParameters *params,
|
||||
AUMIDIBase *This);
|
||||
#endif
|
||||
};
|
||||
|
||||
#endif // __AUMIDIBase_h__
|
||||
/*
|
||||
File: AUMIDIBase.h
|
||||
Abstract: Part of CoreAudio Utility Classes
|
||||
Version: 1.1
|
||||
|
||||
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.
|
||||
|
||||
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.
|
||||
|
||||
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.
|
||||
|
||||
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.
|
||||
|
||||
Copyright (C) 2014 Apple Inc. All Rights Reserved.
|
||||
|
||||
*/
|
||||
#ifndef __AUMIDIBase_h__
|
||||
#define __AUMIDIBase_h__
|
||||
|
||||
#include "AUBase.h"
|
||||
|
||||
#if CA_AUTO_MIDI_MAP
|
||||
#include "CAAUMIDIMapManager.h"
|
||||
#endif
|
||||
|
||||
struct MIDIPacketList;
|
||||
|
||||
// ________________________________________________________________________
|
||||
// MusicDeviceBase
|
||||
//
|
||||
/*! @class AUMIDIBase */
|
||||
class AUMIDIBase {
|
||||
public:
|
||||
// this is NOT a copy constructor!
|
||||
/*! @ctor AUMIDIBase */
|
||||
AUMIDIBase(AUBase* inBase);
|
||||
/*! @dtor ~AUMIDIBase */
|
||||
virtual ~AUMIDIBase();
|
||||
|
||||
/*! @method MIDIEvent */
|
||||
virtual OSStatus MIDIEvent( UInt32 inStatus,
|
||||
UInt32 inData1,
|
||||
UInt32 inData2,
|
||||
UInt32 inOffsetSampleFrame)
|
||||
{
|
||||
UInt32 strippedStatus = inStatus & 0xf0;
|
||||
UInt32 channel = inStatus & 0x0f;
|
||||
|
||||
return HandleMidiEvent(strippedStatus, channel, inData1, inData2, inOffsetSampleFrame);
|
||||
}
|
||||
|
||||
/*! @method HandleMIDIPacketList */
|
||||
OSStatus HandleMIDIPacketList(const MIDIPacketList *pktlist);
|
||||
|
||||
/*! @method SysEx */
|
||||
virtual OSStatus SysEx( const UInt8 * inData,
|
||||
UInt32 inLength);
|
||||
|
||||
#if TARGET_API_MAC_OSX
|
||||
/*! @method DelegateGetPropertyInfo */
|
||||
virtual OSStatus DelegateGetPropertyInfo(AudioUnitPropertyID inID,
|
||||
AudioUnitScope inScope,
|
||||
AudioUnitElement inElement,
|
||||
UInt32 & outDataSize,
|
||||
Boolean & outWritable);
|
||||
|
||||
/*! @method DelegateGetProperty */
|
||||
virtual OSStatus DelegateGetProperty( AudioUnitPropertyID inID,
|
||||
AudioUnitScope inScope,
|
||||
AudioUnitElement inElement,
|
||||
void * outData);
|
||||
|
||||
/*! @method DelegateSetProperty */
|
||||
virtual OSStatus DelegateSetProperty( AudioUnitPropertyID inID,
|
||||
AudioUnitScope inScope,
|
||||
AudioUnitElement inElement,
|
||||
const void * inData,
|
||||
UInt32 inDataSize);
|
||||
#endif
|
||||
|
||||
protected:
|
||||
// MIDI dispatch
|
||||
/*! @method HandleMidiEvent */
|
||||
virtual OSStatus HandleMidiEvent( UInt8 inStatus,
|
||||
UInt8 inChannel,
|
||||
UInt8 inData1,
|
||||
UInt8 inData2,
|
||||
UInt32 inStartFrame);
|
||||
|
||||
/*! @method HandleNonNoteEvent */
|
||||
virtual OSStatus HandleNonNoteEvent ( UInt8 status,
|
||||
UInt8 channel,
|
||||
UInt8 data1,
|
||||
UInt8 data2,
|
||||
UInt32 inStartFrame);
|
||||
|
||||
#if TARGET_API_MAC_OSX
|
||||
/*! @method GetXMLNames */
|
||||
virtual OSStatus GetXMLNames(CFURLRef *outNameDocument)
|
||||
{ return kAudioUnitErr_InvalidProperty; } // if not overridden, it's unsupported
|
||||
#endif
|
||||
|
||||
// channel messages
|
||||
/*! @method HandleNoteOn */
|
||||
virtual OSStatus HandleNoteOn( UInt8 inChannel,
|
||||
UInt8 inNoteNumber,
|
||||
UInt8 inVelocity,
|
||||
UInt32 inStartFrame) { return noErr; }
|
||||
|
||||
/*! @method HandleNoteOff */
|
||||
virtual OSStatus HandleNoteOff( UInt8 inChannel,
|
||||
UInt8 inNoteNumber,
|
||||
UInt8 inVelocity,
|
||||
UInt32 inStartFrame) { return noErr; }
|
||||
|
||||
/*! @method HandleControlChange */
|
||||
virtual OSStatus HandleControlChange( UInt8 inChannel,
|
||||
UInt8 inController,
|
||||
UInt8 inValue,
|
||||
UInt32 inStartFrame) { return noErr; }
|
||||
|
||||
/*! @method HandlePitchWheel */
|
||||
virtual OSStatus HandlePitchWheel( UInt8 inChannel,
|
||||
UInt8 inPitch1,
|
||||
UInt8 inPitch2,
|
||||
UInt32 inStartFrame) { return noErr; }
|
||||
|
||||
/*! @method HandleChannelPressure */
|
||||
virtual OSStatus HandleChannelPressure( UInt8 inChannel,
|
||||
UInt8 inValue,
|
||||
UInt32 inStartFrame) { return noErr; }
|
||||
|
||||
/*! @method HandleProgramChange */
|
||||
virtual OSStatus HandleProgramChange( UInt8 inChannel,
|
||||
UInt8 inValue) { return noErr; }
|
||||
|
||||
/*! @method HandlePolyPressure */
|
||||
virtual OSStatus HandlePolyPressure( UInt8 inChannel,
|
||||
UInt8 inKey,
|
||||
UInt8 inValue,
|
||||
UInt32 inStartFrame) { return noErr; }
|
||||
|
||||
/*! @method HandleResetAllControllers */
|
||||
virtual OSStatus HandleResetAllControllers(UInt8 inChannel) { return noErr; }
|
||||
|
||||
/*! @method HandleAllNotesOff */
|
||||
virtual OSStatus HandleAllNotesOff( UInt8 inChannel) { return noErr; }
|
||||
|
||||
/*! @method HandleAllSoundOff */
|
||||
virtual OSStatus HandleAllSoundOff( UInt8 inChannel) { return noErr; }
|
||||
|
||||
|
||||
//System messages
|
||||
/*! @method HandleSysEx */
|
||||
virtual OSStatus HandleSysEx( const UInt8 * inData,
|
||||
UInt32 inLength ) { return noErr; }
|
||||
|
||||
#if CA_AUTO_MIDI_MAP
|
||||
/* map manager */
|
||||
CAAUMIDIMapManager *GetMIDIMapManager() {return mMapManager;};
|
||||
|
||||
#endif
|
||||
|
||||
|
||||
private:
|
||||
/*! @var mAUBaseInstance */
|
||||
AUBase & mAUBaseInstance;
|
||||
|
||||
#if CA_AUTO_MIDI_MAP
|
||||
/* map manager */
|
||||
CAAUMIDIMapManager * mMapManager;
|
||||
#endif
|
||||
|
||||
public:
|
||||
#if !CA_USE_AUDIO_PLUGIN_ONLY
|
||||
// component dispatcher
|
||||
/*! @method ComponentEntryDispatch */
|
||||
static OSStatus ComponentEntryDispatch( ComponentParameters *params,
|
||||
AUMIDIBase *This);
|
||||
#endif
|
||||
};
|
||||
|
||||
#endif // __AUMIDIBase_h__
|
||||
|
||||
@@ -1,76 +1,76 @@
|
||||
/*
|
||||
File: AUOutputBase.cpp
|
||||
Abstract: AUOutputBase.h
|
||||
Version: 1.1
|
||||
|
||||
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.
|
||||
|
||||
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.
|
||||
|
||||
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.
|
||||
|
||||
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.
|
||||
|
||||
Copyright (C) 2014 Apple Inc. All Rights Reserved.
|
||||
|
||||
*/
|
||||
#if !CA_USE_AUDIO_PLUGIN_ONLY
|
||||
#include "AUOutputBase.h"
|
||||
|
||||
OSStatus AUOutputBase::ComponentEntryDispatch(ComponentParameters *params, AUOutputBase *This)
|
||||
{
|
||||
if (This == NULL) return paramErr;
|
||||
|
||||
OSStatus result;
|
||||
|
||||
switch (params->what) {
|
||||
case kAudioOutputUnitStartSelect:
|
||||
{
|
||||
result = This->Start();
|
||||
}
|
||||
break;
|
||||
|
||||
case kAudioOutputUnitStopSelect:
|
||||
{
|
||||
result = This->Stop();
|
||||
}
|
||||
break;
|
||||
|
||||
default:
|
||||
result = badComponentSelector;
|
||||
break;
|
||||
}
|
||||
|
||||
return result;
|
||||
}
|
||||
#endif
|
||||
/*
|
||||
File: AUOutputBase.cpp
|
||||
Abstract: AUOutputBase.h
|
||||
Version: 1.1
|
||||
|
||||
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.
|
||||
|
||||
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.
|
||||
|
||||
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.
|
||||
|
||||
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.
|
||||
|
||||
Copyright (C) 2014 Apple Inc. All Rights Reserved.
|
||||
|
||||
*/
|
||||
#if !CA_USE_AUDIO_PLUGIN_ONLY
|
||||
#include "AUOutputBase.h"
|
||||
|
||||
OSStatus AUOutputBase::ComponentEntryDispatch(ComponentParameters *params, AUOutputBase *This)
|
||||
{
|
||||
if (This == NULL) return paramErr;
|
||||
|
||||
OSStatus result;
|
||||
|
||||
switch (params->what) {
|
||||
case kAudioOutputUnitStartSelect:
|
||||
{
|
||||
result = This->Start();
|
||||
}
|
||||
break;
|
||||
|
||||
case kAudioOutputUnitStopSelect:
|
||||
{
|
||||
result = This->Stop();
|
||||
}
|
||||
break;
|
||||
|
||||
default:
|
||||
result = badComponentSelector;
|
||||
break;
|
||||
}
|
||||
|
||||
return result;
|
||||
}
|
||||
#endif
|
||||
|
||||
@@ -1,82 +1,82 @@
|
||||
/*
|
||||
File: AUOutputBase.h
|
||||
Abstract: Part of CoreAudio Utility Classes
|
||||
Version: 1.1
|
||||
|
||||
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.
|
||||
|
||||
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.
|
||||
|
||||
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.
|
||||
|
||||
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.
|
||||
|
||||
Copyright (C) 2014 Apple Inc. All Rights Reserved.
|
||||
|
||||
*/
|
||||
#ifndef __AUOutputBase_h__
|
||||
#define __AUOutputBase_h__
|
||||
|
||||
#include "AUBase.h"
|
||||
|
||||
// ________________________________________________________________________
|
||||
// AUOutputBase
|
||||
// this is now a mix-in rather than an AUBase subclass
|
||||
|
||||
/*! @class AUOutputBase */
|
||||
class AUOutputBase {
|
||||
public:
|
||||
/*! @ctor AUOutputBase */
|
||||
AUOutputBase(AUBase *inBase) : mAUBaseInstance(*inBase) { }
|
||||
virtual ~AUOutputBase() { }
|
||||
|
||||
// additional component entry points
|
||||
/*! @method Start */
|
||||
virtual OSStatus Start() = 0;
|
||||
|
||||
/*! @method Stop */
|
||||
virtual OSStatus Stop() = 0;
|
||||
|
||||
#if !CA_USE_AUDIO_PLUGIN_ONLY
|
||||
// component dispatcher
|
||||
/*! @method ComponentEntryDispatch */
|
||||
static OSStatus ComponentEntryDispatch( ComponentParameters * params,
|
||||
AUOutputBase * This);
|
||||
#endif
|
||||
|
||||
private:
|
||||
/*! @var mAUBaseInstance */
|
||||
AUBase & mAUBaseInstance;
|
||||
};
|
||||
|
||||
#endif // __AUOutputBase_h__
|
||||
/*
|
||||
File: AUOutputBase.h
|
||||
Abstract: Part of CoreAudio Utility Classes
|
||||
Version: 1.1
|
||||
|
||||
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.
|
||||
|
||||
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.
|
||||
|
||||
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.
|
||||
|
||||
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.
|
||||
|
||||
Copyright (C) 2014 Apple Inc. All Rights Reserved.
|
||||
|
||||
*/
|
||||
#ifndef __AUOutputBase_h__
|
||||
#define __AUOutputBase_h__
|
||||
|
||||
#include "AUBase.h"
|
||||
|
||||
// ________________________________________________________________________
|
||||
// AUOutputBase
|
||||
// this is now a mix-in rather than an AUBase subclass
|
||||
|
||||
/*! @class AUOutputBase */
|
||||
class AUOutputBase {
|
||||
public:
|
||||
/*! @ctor AUOutputBase */
|
||||
AUOutputBase(AUBase *inBase) : mAUBaseInstance(*inBase) { }
|
||||
virtual ~AUOutputBase() { }
|
||||
|
||||
// additional component entry points
|
||||
/*! @method Start */
|
||||
virtual OSStatus Start() = 0;
|
||||
|
||||
/*! @method Stop */
|
||||
virtual OSStatus Stop() = 0;
|
||||
|
||||
#if !CA_USE_AUDIO_PLUGIN_ONLY
|
||||
// component dispatcher
|
||||
/*! @method ComponentEntryDispatch */
|
||||
static OSStatus ComponentEntryDispatch( ComponentParameters * params,
|
||||
AUOutputBase * This);
|
||||
#endif
|
||||
|
||||
private:
|
||||
/*! @var mAUBaseInstance */
|
||||
AUBase & mAUBaseInstance;
|
||||
};
|
||||
|
||||
#endif // __AUOutputBase_h__
|
||||
|
||||
@@ -1,63 +1,63 @@
|
||||
/*
|
||||
File: AUOutputElement.cpp
|
||||
Abstract: AUOutputElement.h
|
||||
Version: 1.1
|
||||
|
||||
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.
|
||||
|
||||
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.
|
||||
|
||||
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.
|
||||
|
||||
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.
|
||||
|
||||
Copyright (C) 2014 Apple Inc. All Rights Reserved.
|
||||
|
||||
*/
|
||||
|
||||
#include "AUOutputElement.h"
|
||||
#include "AUBase.h"
|
||||
|
||||
AUOutputElement::AUOutputElement(AUBase *audioUnit) :
|
||||
AUIOElement(audioUnit)
|
||||
{
|
||||
AllocateBuffer();
|
||||
}
|
||||
|
||||
OSStatus AUOutputElement::SetStreamFormat(const CAStreamBasicDescription &desc)
|
||||
{
|
||||
OSStatus result = AUIOElement::SetStreamFormat(desc); // inherited
|
||||
if (result == AUBase::noErr)
|
||||
AllocateBuffer();
|
||||
return result;
|
||||
}
|
||||
/*
|
||||
File: AUOutputElement.cpp
|
||||
Abstract: AUOutputElement.h
|
||||
Version: 1.1
|
||||
|
||||
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.
|
||||
|
||||
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.
|
||||
|
||||
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.
|
||||
|
||||
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.
|
||||
|
||||
Copyright (C) 2014 Apple Inc. All Rights Reserved.
|
||||
|
||||
*/
|
||||
|
||||
#include "AUOutputElement.h"
|
||||
#include "AUBase.h"
|
||||
|
||||
AUOutputElement::AUOutputElement(AUBase *audioUnit) :
|
||||
AUIOElement(audioUnit)
|
||||
{
|
||||
AllocateBuffer();
|
||||
}
|
||||
|
||||
OSStatus AUOutputElement::SetStreamFormat(const CAStreamBasicDescription &desc)
|
||||
{
|
||||
OSStatus result = AUIOElement::SetStreamFormat(desc); // inherited
|
||||
if (result == AUBase::noErr)
|
||||
AllocateBuffer();
|
||||
return result;
|
||||
}
|
||||
|
||||
@@ -1,66 +1,66 @@
|
||||
/*
|
||||
File: AUOutputElement.h
|
||||
Abstract: Part of CoreAudio Utility Classes
|
||||
Version: 1.1
|
||||
|
||||
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.
|
||||
|
||||
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.
|
||||
|
||||
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.
|
||||
|
||||
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.
|
||||
|
||||
Copyright (C) 2014 Apple Inc. All Rights Reserved.
|
||||
|
||||
*/
|
||||
#ifndef __AUOutput_h__
|
||||
#define __AUOutput_h__
|
||||
|
||||
#include "AUScopeElement.h"
|
||||
#include "AUBuffer.h"
|
||||
|
||||
/*! @class AUOutputElement */
|
||||
class AUOutputElement : public AUIOElement {
|
||||
public:
|
||||
/*! @ctor AUOutputElement */
|
||||
AUOutputElement(AUBase *audioUnit);
|
||||
|
||||
// AUElement override
|
||||
/*! @method SetStreamFormat */
|
||||
virtual OSStatus SetStreamFormat(const CAStreamBasicDescription &desc);
|
||||
/*! @method NeedsBufferSpace */
|
||||
virtual bool NeedsBufferSpace() const { return true; }
|
||||
};
|
||||
|
||||
#endif // __AUOutput_h__
|
||||
/*
|
||||
File: AUOutputElement.h
|
||||
Abstract: Part of CoreAudio Utility Classes
|
||||
Version: 1.1
|
||||
|
||||
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.
|
||||
|
||||
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.
|
||||
|
||||
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.
|
||||
|
||||
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.
|
||||
|
||||
Copyright (C) 2014 Apple Inc. All Rights Reserved.
|
||||
|
||||
*/
|
||||
#ifndef __AUOutput_h__
|
||||
#define __AUOutput_h__
|
||||
|
||||
#include "AUScopeElement.h"
|
||||
#include "AUBuffer.h"
|
||||
|
||||
/*! @class AUOutputElement */
|
||||
class AUOutputElement : public AUIOElement {
|
||||
public:
|
||||
/*! @ctor AUOutputElement */
|
||||
AUOutputElement(AUBase *audioUnit);
|
||||
|
||||
// AUElement override
|
||||
/*! @method SetStreamFormat */
|
||||
virtual OSStatus SetStreamFormat(const CAStreamBasicDescription &desc);
|
||||
/*! @method NeedsBufferSpace */
|
||||
virtual bool NeedsBufferSpace() const { return true; }
|
||||
};
|
||||
|
||||
#endif // __AUOutput_h__
|
||||
|
||||
File diff suppressed because it is too large
Load Diff
@@ -1,144 +1,144 @@
|
||||
/*
|
||||
File: AUPlugInDispatch.h
|
||||
Abstract: Part of CoreAudio Utility Classes
|
||||
Version: 1.1
|
||||
|
||||
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.
|
||||
|
||||
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.
|
||||
|
||||
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.
|
||||
|
||||
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.
|
||||
|
||||
Copyright (C) 2014 Apple Inc. All Rights Reserved.
|
||||
|
||||
*/
|
||||
#ifndef __AUPlugInBase_h__
|
||||
#define __AUPlugInBase_h__
|
||||
|
||||
#if !defined(__COREAUDIO_USE_FLAT_INCLUDES__)
|
||||
#include <AudioUnit/AudioComponent.h>
|
||||
#if !CA_BASIC_AU_FEATURES
|
||||
#include <AudioUnit/MusicDevice.h>
|
||||
#endif
|
||||
#else
|
||||
#include "AudioComponent.h"
|
||||
#include "MusicDevice.h"
|
||||
#endif
|
||||
|
||||
#include "ComponentBase.h"
|
||||
|
||||
struct AUBaseLookup {
|
||||
static AudioComponentMethod Lookup (SInt16 selector);
|
||||
};
|
||||
template <class Implementor>
|
||||
class AUBaseFactory : public APFactory<AUBaseLookup, Implementor>
|
||||
{
|
||||
};
|
||||
|
||||
struct AUOutputLookup {
|
||||
static AudioComponentMethod Lookup (SInt16 selector);
|
||||
};
|
||||
template <class Implementor>
|
||||
class AUOutputBaseFactory : public APFactory<AUOutputLookup, Implementor>
|
||||
{
|
||||
};
|
||||
|
||||
struct AUComplexOutputLookup {
|
||||
static AudioComponentMethod Lookup (SInt16 selector);
|
||||
};
|
||||
template <class Implementor>
|
||||
class AUOutputComplexBaseFactory : public APFactory<AUComplexOutputLookup, Implementor>
|
||||
{
|
||||
};
|
||||
|
||||
struct AUBaseProcessLookup {
|
||||
static AudioComponentMethod Lookup (SInt16 selector);
|
||||
};
|
||||
template <class Implementor>
|
||||
class AUBaseProcessFactory : public APFactory<AUBaseProcessLookup, Implementor>
|
||||
{
|
||||
};
|
||||
|
||||
struct AUBaseProcessMultipleLookup {
|
||||
static AudioComponentMethod Lookup (SInt16 selector);
|
||||
};
|
||||
template <class Implementor>
|
||||
class AUBaseProcessMultipleFactory : public APFactory<AUBaseProcessMultipleLookup, Implementor>
|
||||
{
|
||||
};
|
||||
|
||||
struct AUBaseProcessAndMultipleLookup {
|
||||
static AudioComponentMethod Lookup (SInt16 selector);
|
||||
};
|
||||
template <class Implementor>
|
||||
class AUBaseProcessAndMultipleFactory : public APFactory<AUBaseProcessAndMultipleLookup, Implementor>
|
||||
{
|
||||
};
|
||||
|
||||
#if !CA_BASIC_AU_FEATURES
|
||||
struct AUMIDILookup {
|
||||
static AudioComponentMethod Lookup (SInt16 selector);
|
||||
};
|
||||
template <class Implementor>
|
||||
class AUMIDIEffectFactory : public APFactory<AUMIDILookup, Implementor>
|
||||
{
|
||||
};
|
||||
|
||||
struct AUMIDIProcessLookup {
|
||||
static AudioComponentMethod Lookup (SInt16 selector);
|
||||
};
|
||||
template <class Implementor>
|
||||
class AUMIDIProcessFactory : public APFactory<AUMIDIProcessLookup, Implementor>
|
||||
{
|
||||
};
|
||||
|
||||
struct AUMusicLookup {
|
||||
static AudioComponentMethod Lookup (SInt16 selector);
|
||||
};
|
||||
template <class Implementor>
|
||||
class AUMusicDeviceFactory : public APFactory<AUMusicLookup, Implementor>
|
||||
{
|
||||
};
|
||||
|
||||
struct AUAuxBaseLookup {
|
||||
static AudioComponentMethod Lookup (SInt16 selector);
|
||||
};
|
||||
template <class Implementor>
|
||||
class AUAuxBaseFactory : public APFactory<AUAuxBaseLookup, Implementor>
|
||||
{
|
||||
};
|
||||
#endif // CA_BASIC_AU_FEATURES
|
||||
|
||||
#endif // __AUPlugInBase_h__
|
||||
/*
|
||||
File: AUPlugInDispatch.h
|
||||
Abstract: Part of CoreAudio Utility Classes
|
||||
Version: 1.1
|
||||
|
||||
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.
|
||||
|
||||
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.
|
||||
|
||||
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.
|
||||
|
||||
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.
|
||||
|
||||
Copyright (C) 2014 Apple Inc. All Rights Reserved.
|
||||
|
||||
*/
|
||||
#ifndef __AUPlugInBase_h__
|
||||
#define __AUPlugInBase_h__
|
||||
|
||||
#if !defined(__COREAUDIO_USE_FLAT_INCLUDES__)
|
||||
#include <AudioUnit/AudioComponent.h>
|
||||
#if !CA_BASIC_AU_FEATURES
|
||||
#include <AudioUnit/MusicDevice.h>
|
||||
#endif
|
||||
#else
|
||||
#include "AudioComponent.h"
|
||||
#include "MusicDevice.h"
|
||||
#endif
|
||||
|
||||
#include "ComponentBase.h"
|
||||
|
||||
struct AUBaseLookup {
|
||||
static AudioComponentMethod Lookup (SInt16 selector);
|
||||
};
|
||||
template <class Implementor>
|
||||
class AUBaseFactory : public APFactory<AUBaseLookup, Implementor>
|
||||
{
|
||||
};
|
||||
|
||||
struct AUOutputLookup {
|
||||
static AudioComponentMethod Lookup (SInt16 selector);
|
||||
};
|
||||
template <class Implementor>
|
||||
class AUOutputBaseFactory : public APFactory<AUOutputLookup, Implementor>
|
||||
{
|
||||
};
|
||||
|
||||
struct AUComplexOutputLookup {
|
||||
static AudioComponentMethod Lookup (SInt16 selector);
|
||||
};
|
||||
template <class Implementor>
|
||||
class AUOutputComplexBaseFactory : public APFactory<AUComplexOutputLookup, Implementor>
|
||||
{
|
||||
};
|
||||
|
||||
struct AUBaseProcessLookup {
|
||||
static AudioComponentMethod Lookup (SInt16 selector);
|
||||
};
|
||||
template <class Implementor>
|
||||
class AUBaseProcessFactory : public APFactory<AUBaseProcessLookup, Implementor>
|
||||
{
|
||||
};
|
||||
|
||||
struct AUBaseProcessMultipleLookup {
|
||||
static AudioComponentMethod Lookup (SInt16 selector);
|
||||
};
|
||||
template <class Implementor>
|
||||
class AUBaseProcessMultipleFactory : public APFactory<AUBaseProcessMultipleLookup, Implementor>
|
||||
{
|
||||
};
|
||||
|
||||
struct AUBaseProcessAndMultipleLookup {
|
||||
static AudioComponentMethod Lookup (SInt16 selector);
|
||||
};
|
||||
template <class Implementor>
|
||||
class AUBaseProcessAndMultipleFactory : public APFactory<AUBaseProcessAndMultipleLookup, Implementor>
|
||||
{
|
||||
};
|
||||
|
||||
#if !CA_BASIC_AU_FEATURES
|
||||
struct AUMIDILookup {
|
||||
static AudioComponentMethod Lookup (SInt16 selector);
|
||||
};
|
||||
template <class Implementor>
|
||||
class AUMIDIEffectFactory : public APFactory<AUMIDILookup, Implementor>
|
||||
{
|
||||
};
|
||||
|
||||
struct AUMIDIProcessLookup {
|
||||
static AudioComponentMethod Lookup (SInt16 selector);
|
||||
};
|
||||
template <class Implementor>
|
||||
class AUMIDIProcessFactory : public APFactory<AUMIDIProcessLookup, Implementor>
|
||||
{
|
||||
};
|
||||
|
||||
struct AUMusicLookup {
|
||||
static AudioComponentMethod Lookup (SInt16 selector);
|
||||
};
|
||||
template <class Implementor>
|
||||
class AUMusicDeviceFactory : public APFactory<AUMusicLookup, Implementor>
|
||||
{
|
||||
};
|
||||
|
||||
struct AUAuxBaseLookup {
|
||||
static AudioComponentMethod Lookup (SInt16 selector);
|
||||
};
|
||||
template <class Implementor>
|
||||
class AUAuxBaseFactory : public APFactory<AUAuxBaseLookup, Implementor>
|
||||
{
|
||||
};
|
||||
#endif // CA_BASIC_AU_FEATURES
|
||||
|
||||
#endif // __AUPlugInBase_h__
|
||||
|
||||
File diff suppressed because it is too large
Load Diff
File diff suppressed because it is too large
Load Diff
@@ -1,93 +1,93 @@
|
||||
/*
|
||||
File: AUSilentTimeout.h
|
||||
Abstract: Part of CoreAudio Utility Classes
|
||||
Version: 1.1
|
||||
|
||||
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.
|
||||
|
||||
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.
|
||||
|
||||
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.
|
||||
|
||||
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.
|
||||
|
||||
Copyright (C) 2014 Apple Inc. All Rights Reserved.
|
||||
|
||||
*/
|
||||
#ifndef __AUSilentTimeout
|
||||
#define __AUSilentTimeout
|
||||
|
||||
class AUSilentTimeout
|
||||
{
|
||||
public:
|
||||
AUSilentTimeout()
|
||||
: mTimeoutCounter(0),
|
||||
mResetTimer(true)
|
||||
{};
|
||||
|
||||
void Process(UInt32 inFramesToProcess, UInt32 inTimeoutLimit, bool &ioSilence )
|
||||
{
|
||||
if(ioSilence )
|
||||
{
|
||||
if(mResetTimer )
|
||||
{
|
||||
mTimeoutCounter = inTimeoutLimit;
|
||||
mResetTimer = false;
|
||||
}
|
||||
|
||||
if(mTimeoutCounter > 0 )
|
||||
{
|
||||
mTimeoutCounter -= inFramesToProcess;
|
||||
ioSilence = false;
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
// signal to reset the next time we receive silence
|
||||
mResetTimer = true;
|
||||
}
|
||||
}
|
||||
|
||||
void Reset()
|
||||
{
|
||||
mResetTimer = true;
|
||||
};
|
||||
|
||||
|
||||
|
||||
private:
|
||||
SInt32 mTimeoutCounter;
|
||||
bool mResetTimer;
|
||||
};
|
||||
|
||||
#endif // __AUSilentTimeout
|
||||
/*
|
||||
File: AUSilentTimeout.h
|
||||
Abstract: Part of CoreAudio Utility Classes
|
||||
Version: 1.1
|
||||
|
||||
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.
|
||||
|
||||
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.
|
||||
|
||||
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.
|
||||
|
||||
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.
|
||||
|
||||
Copyright (C) 2014 Apple Inc. All Rights Reserved.
|
||||
|
||||
*/
|
||||
#ifndef __AUSilentTimeout
|
||||
#define __AUSilentTimeout
|
||||
|
||||
class AUSilentTimeout
|
||||
{
|
||||
public:
|
||||
AUSilentTimeout()
|
||||
: mTimeoutCounter(0),
|
||||
mResetTimer(true)
|
||||
{};
|
||||
|
||||
void Process(UInt32 inFramesToProcess, UInt32 inTimeoutLimit, bool &ioSilence )
|
||||
{
|
||||
if(ioSilence )
|
||||
{
|
||||
if(mResetTimer )
|
||||
{
|
||||
mTimeoutCounter = inTimeoutLimit;
|
||||
mResetTimer = false;
|
||||
}
|
||||
|
||||
if(mTimeoutCounter > 0 )
|
||||
{
|
||||
mTimeoutCounter -= inFramesToProcess;
|
||||
ioSilence = false;
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
// signal to reset the next time we receive silence
|
||||
mResetTimer = true;
|
||||
}
|
||||
}
|
||||
|
||||
void Reset()
|
||||
{
|
||||
mResetTimer = true;
|
||||
};
|
||||
|
||||
|
||||
|
||||
private:
|
||||
SInt32 mTimeoutCounter;
|
||||
bool mResetTimer;
|
||||
};
|
||||
|
||||
#endif // __AUSilentTimeout
|
||||
|
||||
@@ -1,163 +1,163 @@
|
||||
/*
|
||||
File: AUTimestampGenerator.h
|
||||
Abstract: Part of CoreAudio Utility Classes
|
||||
Version: 1.1
|
||||
|
||||
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.
|
||||
|
||||
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.
|
||||
|
||||
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.
|
||||
|
||||
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.
|
||||
|
||||
Copyright (C) 2014 Apple Inc. All Rights Reserved.
|
||||
|
||||
*/
|
||||
#ifndef __AUTimestampGenerator_h__
|
||||
#define __AUTimestampGenerator_h__
|
||||
|
||||
#include <math.h>
|
||||
#include "CAHostTimeBase.h"
|
||||
#include <stdio.h>
|
||||
|
||||
#define TSGFMT "0x%10qx"
|
||||
//#define TSGFMT "%10qd"
|
||||
|
||||
// This class generates a continuously increasing series of timestamps based
|
||||
// on a series of potentially discontinuous timestamps (as can be delivered from
|
||||
// CoreAudio in the event of an overload or major engine change).
|
||||
// N.B.: "output" = downstream (source) timestamp
|
||||
// "input" = upstream (derived) timestamp
|
||||
class AUTimestampGenerator {
|
||||
public:
|
||||
AUTimestampGenerator(bool hostTimeDiscontinuityCorrection = false)
|
||||
{
|
||||
mState.mStartInputAtZero = true;
|
||||
mState.mBypassed = false;
|
||||
mState.mHostTimeDiscontinuityCorrection = hostTimeDiscontinuityCorrection;
|
||||
#if DEBUG
|
||||
mVerbosity = 0;
|
||||
snprintf(mDebugName, sizeof(mDebugName), "tsg @ %p", this);
|
||||
#endif
|
||||
// CAHostTimeBase should be used instead of the calls in <CoreAudio/HostTime.h>
|
||||
// we make this call here to ensure that this is initialized, otherwise the first time
|
||||
// you do actually call CAHostTimeBase to do work, can be on the render thread, and lead to unwanted VM faults
|
||||
CAHostTimeBase::GetFrequency();
|
||||
Reset();
|
||||
}
|
||||
|
||||
void SetStartInputAtZero(bool b) { mState.mStartInputAtZero = b; }
|
||||
bool GetStartInputAtZero() const { return mState.mStartInputAtZero; }
|
||||
|
||||
// bypassing is intended for a narrow special case. the upstream sample time will always be the same as the downstream time.
|
||||
void SetBypassed(bool b) { mState.mBypassed = b; }
|
||||
bool GetBypassed() const { return mState.mBypassed; }
|
||||
|
||||
// Call this to reset the timeline.
|
||||
void Reset()
|
||||
{
|
||||
mState.mCurrentInputTime.mSampleTime = 0.;
|
||||
mState.mNextInputSampleTime = 0.;
|
||||
mState.mCurrentOutputTime.mSampleTime = 0.;
|
||||
mState.mNextOutputSampleTime = 0.;
|
||||
mState.mLastOutputTime.mFlags = 0;
|
||||
mState.mRateScalarAdj = 1.;
|
||||
|
||||
mFirstTime = true;
|
||||
#if DEBUG
|
||||
if (mVerbosity)
|
||||
printf("%-20.20s: Reset\n", mDebugName);
|
||||
#endif
|
||||
}
|
||||
|
||||
// Call this once per render cycle with the downstream timestamp.
|
||||
// expectedDeltaFrames is the expected difference between the current and NEXT
|
||||
// downstream timestamps.
|
||||
// sampleRate is the OUTPUT sample rate.
|
||||
void AddOutputTime(const AudioTimeStamp &inTimeStamp, Float64 expectedDeltaFrames, double outputSampleRate, double rateScalarAdj=1.0);
|
||||
|
||||
// Call this once per render cycle to obtain the upstream timestamp.
|
||||
// framesToAdvance is the number of frames the input timeline is to be
|
||||
// advanced during this render cycle.
|
||||
// sampleRate is the INPUT sample rate.
|
||||
const AudioTimeStamp & GenerateInputTime(Float64 framesToAdvance, double inputSampleRate, bool advanceHostTime = false);
|
||||
|
||||
// this can be called to override the setting of the next input sample time in GenerateInputTime
|
||||
void Advance(Float64 framesToAdvance)
|
||||
{
|
||||
#if DEBUG
|
||||
if (mVerbosity > 1)
|
||||
printf("%-20.20s: ADVANCE in = " TSGFMT " advance = " TSGFMT "\n", mDebugName, (SInt64)mState.mCurrentInputTime.mSampleTime, (SInt64)framesToAdvance);
|
||||
#endif
|
||||
mState.mNextInputSampleTime = mState.mCurrentInputTime.mSampleTime + framesToAdvance;
|
||||
}
|
||||
|
||||
struct State {
|
||||
AudioTimeStamp mCurrentInputTime;
|
||||
Float64 mNextInputSampleTime;
|
||||
Float64 mNextOutputSampleTime;
|
||||
Float64 mInputSampleTimeForOutputPull;
|
||||
|
||||
AudioTimeStamp mLastOutputTime;
|
||||
AudioTimeStamp mCurrentOutputTime;
|
||||
|
||||
bool mStartInputAtZero; // if true, input timeline starts at 0, else it starts
|
||||
// synced with the output timeline
|
||||
bool mDiscontinuous;
|
||||
bool mBypassed;
|
||||
Float64 mDiscontinuityDeltaSamples;
|
||||
|
||||
double mRateScalarAdj;
|
||||
|
||||
bool mHostTimeDiscontinuityCorrection; // If true, propagate timestamp discontinuities using host time.
|
||||
};
|
||||
|
||||
void GetState(State& outState) const { outState = mState; }
|
||||
void SetState(State const& inState) { mState = inState; mFirstTime = false; }
|
||||
|
||||
private:
|
||||
|
||||
struct State mState;
|
||||
|
||||
bool mFirstTime;
|
||||
|
||||
#if DEBUG
|
||||
public:
|
||||
int mVerbosity;
|
||||
char mDebugName[64];
|
||||
#endif
|
||||
};
|
||||
|
||||
|
||||
#endif // __AUTimestampGenerator_h__
|
||||
/*
|
||||
File: AUTimestampGenerator.h
|
||||
Abstract: Part of CoreAudio Utility Classes
|
||||
Version: 1.1
|
||||
|
||||
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.
|
||||
|
||||
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.
|
||||
|
||||
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.
|
||||
|
||||
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.
|
||||
|
||||
Copyright (C) 2014 Apple Inc. All Rights Reserved.
|
||||
|
||||
*/
|
||||
#ifndef __AUTimestampGenerator_h__
|
||||
#define __AUTimestampGenerator_h__
|
||||
|
||||
#include <math.h>
|
||||
#include "CAHostTimeBase.h"
|
||||
#include <stdio.h>
|
||||
|
||||
#define TSGFMT "0x%10qx"
|
||||
//#define TSGFMT "%10qd"
|
||||
|
||||
// This class generates a continuously increasing series of timestamps based
|
||||
// on a series of potentially discontinuous timestamps (as can be delivered from
|
||||
// CoreAudio in the event of an overload or major engine change).
|
||||
// N.B.: "output" = downstream (source) timestamp
|
||||
// "input" = upstream (derived) timestamp
|
||||
class AUTimestampGenerator {
|
||||
public:
|
||||
AUTimestampGenerator(bool hostTimeDiscontinuityCorrection = false)
|
||||
{
|
||||
mState.mStartInputAtZero = true;
|
||||
mState.mBypassed = false;
|
||||
mState.mHostTimeDiscontinuityCorrection = hostTimeDiscontinuityCorrection;
|
||||
#if DEBUG
|
||||
mVerbosity = 0;
|
||||
snprintf(mDebugName, sizeof(mDebugName), "tsg @ %p", this);
|
||||
#endif
|
||||
// CAHostTimeBase should be used instead of the calls in <CoreAudio/HostTime.h>
|
||||
// we make this call here to ensure that this is initialized, otherwise the first time
|
||||
// you do actually call CAHostTimeBase to do work, can be on the render thread, and lead to unwanted VM faults
|
||||
CAHostTimeBase::GetFrequency();
|
||||
Reset();
|
||||
}
|
||||
|
||||
void SetStartInputAtZero(bool b) { mState.mStartInputAtZero = b; }
|
||||
bool GetStartInputAtZero() const { return mState.mStartInputAtZero; }
|
||||
|
||||
// bypassing is intended for a narrow special case. the upstream sample time will always be the same as the downstream time.
|
||||
void SetBypassed(bool b) { mState.mBypassed = b; }
|
||||
bool GetBypassed() const { return mState.mBypassed; }
|
||||
|
||||
// Call this to reset the timeline.
|
||||
void Reset()
|
||||
{
|
||||
mState.mCurrentInputTime.mSampleTime = 0.;
|
||||
mState.mNextInputSampleTime = 0.;
|
||||
mState.mCurrentOutputTime.mSampleTime = 0.;
|
||||
mState.mNextOutputSampleTime = 0.;
|
||||
mState.mLastOutputTime.mFlags = 0;
|
||||
mState.mRateScalarAdj = 1.;
|
||||
|
||||
mFirstTime = true;
|
||||
#if DEBUG
|
||||
if (mVerbosity)
|
||||
printf("%-20.20s: Reset\n", mDebugName);
|
||||
#endif
|
||||
}
|
||||
|
||||
// Call this once per render cycle with the downstream timestamp.
|
||||
// expectedDeltaFrames is the expected difference between the current and NEXT
|
||||
// downstream timestamps.
|
||||
// sampleRate is the OUTPUT sample rate.
|
||||
void AddOutputTime(const AudioTimeStamp &inTimeStamp, Float64 expectedDeltaFrames, double outputSampleRate, double rateScalarAdj=1.0);
|
||||
|
||||
// Call this once per render cycle to obtain the upstream timestamp.
|
||||
// framesToAdvance is the number of frames the input timeline is to be
|
||||
// advanced during this render cycle.
|
||||
// sampleRate is the INPUT sample rate.
|
||||
const AudioTimeStamp & GenerateInputTime(Float64 framesToAdvance, double inputSampleRate, bool advanceHostTime = false);
|
||||
|
||||
// this can be called to override the setting of the next input sample time in GenerateInputTime
|
||||
void Advance(Float64 framesToAdvance)
|
||||
{
|
||||
#if DEBUG
|
||||
if (mVerbosity > 1)
|
||||
printf("%-20.20s: ADVANCE in = " TSGFMT " advance = " TSGFMT "\n", mDebugName, (SInt64)mState.mCurrentInputTime.mSampleTime, (SInt64)framesToAdvance);
|
||||
#endif
|
||||
mState.mNextInputSampleTime = mState.mCurrentInputTime.mSampleTime + framesToAdvance;
|
||||
}
|
||||
|
||||
struct State {
|
||||
AudioTimeStamp mCurrentInputTime;
|
||||
Float64 mNextInputSampleTime;
|
||||
Float64 mNextOutputSampleTime;
|
||||
Float64 mInputSampleTimeForOutputPull;
|
||||
|
||||
AudioTimeStamp mLastOutputTime;
|
||||
AudioTimeStamp mCurrentOutputTime;
|
||||
|
||||
bool mStartInputAtZero; // if true, input timeline starts at 0, else it starts
|
||||
// synced with the output timeline
|
||||
bool mDiscontinuous;
|
||||
bool mBypassed;
|
||||
Float64 mDiscontinuityDeltaSamples;
|
||||
|
||||
double mRateScalarAdj;
|
||||
|
||||
bool mHostTimeDiscontinuityCorrection; // If true, propagate timestamp discontinuities using host time.
|
||||
};
|
||||
|
||||
void GetState(State& outState) const { outState = mState; }
|
||||
void SetState(State const& inState) { mState = inState; mFirstTime = false; }
|
||||
|
||||
private:
|
||||
|
||||
struct State mState;
|
||||
|
||||
bool mFirstTime;
|
||||
|
||||
#if DEBUG
|
||||
public:
|
||||
int mVerbosity;
|
||||
char mDebugName[64];
|
||||
#endif
|
||||
};
|
||||
|
||||
|
||||
#endif // __AUTimestampGenerator_h__
|
||||
|
||||
@@ -1,88 +1,88 @@
|
||||
/*
|
||||
File: AUViewLocalizedStringKeys.h
|
||||
Abstract: Part of CoreAudio Utility Classes
|
||||
Version: 1.1
|
||||
|
||||
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.
|
||||
|
||||
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.
|
||||
|
||||
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.
|
||||
|
||||
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.
|
||||
|
||||
Copyright (C) 2014 Apple Inc. All Rights Reserved.
|
||||
|
||||
*/
|
||||
#ifndef __AUViewLocalizedStringKeys_h__
|
||||
#define __AUViewLocalizedStringKeys_h__
|
||||
|
||||
// ACCESS POINT:
|
||||
#define kLocalizedStringBundle_AUView CFSTR("com.apple.audio.units.Components")
|
||||
#define kLocalizedStringTable_AUView CFSTR("CustomUI")
|
||||
|
||||
// UNLOCALIZED STRINGS:
|
||||
#define kAUViewUnlocalizedString_TitleSeparator CFSTR(": ")
|
||||
|
||||
// Generic View:
|
||||
#define kAUViewLocalizedStringKey_AudioUnit CFSTR("Audio Unit")
|
||||
#define kAUViewLocalizedStringKey_Manufacturer CFSTR("Manufacturer")
|
||||
|
||||
#define kAUViewLocalizedStringKey_FactoryPreset CFSTR("Factory Preset")
|
||||
|
||||
#define kAUViewLocalizedStringKey_Properties CFSTR("Properties")
|
||||
#define kAUViewLocalizedStringKey_Parameters CFSTR("Parameters")
|
||||
|
||||
#define kAUViewLocalizedStringKey_Standard CFSTR("Standard")
|
||||
#define kAUViewLocalizedStringKey_Expert CFSTR("Expert")
|
||||
|
||||
// AULoadCPU:
|
||||
#define kAUViewLocalizedStringKey_RestrictCPULoad CFSTR("Restrict CPU Load")
|
||||
#define kAUViewLocalizedStringKey_PercentSymbol CFSTR("%")
|
||||
#define kAUViewLocalizedStringKey_NotApplicable CFSTR("n/a")
|
||||
|
||||
// AUDiskStreamingCheckbox:
|
||||
#define kAUViewLocalizedStringKey_StreamFromDisk CFSTR("Stream From Disk")
|
||||
|
||||
// AURenderQualityPopup:
|
||||
#define kAUViewLocalizedStringKey_RenderQuality CFSTR("Render Quality")
|
||||
#define kAUViewLocalizedStringKey_Maximum CFSTR("Maximum")
|
||||
#define kAUViewLocalizedStringKey_High CFSTR("High")
|
||||
#define kAUViewLocalizedStringKey_Medium CFSTR("Medium")
|
||||
#define kAUViewLocalizedStringKey_Low CFSTR("Low")
|
||||
#define kAUViewLocalizedStringKey_Minimum CFSTR("Minimum")
|
||||
|
||||
// AUChannelLayoutPopUp:
|
||||
#define kAUViewLocalizedStringKey_AudioChannelLayout CFSTR("Audio Channel Layout")
|
||||
|
||||
#endif //__AUViewLocalizedStringKeys_h__
|
||||
/*
|
||||
File: AUViewLocalizedStringKeys.h
|
||||
Abstract: Part of CoreAudio Utility Classes
|
||||
Version: 1.1
|
||||
|
||||
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.
|
||||
|
||||
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.
|
||||
|
||||
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.
|
||||
|
||||
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.
|
||||
|
||||
Copyright (C) 2014 Apple Inc. All Rights Reserved.
|
||||
|
||||
*/
|
||||
#ifndef __AUViewLocalizedStringKeys_h__
|
||||
#define __AUViewLocalizedStringKeys_h__
|
||||
|
||||
// ACCESS POINT:
|
||||
#define kLocalizedStringBundle_AUView CFSTR("com.apple.audio.units.Components")
|
||||
#define kLocalizedStringTable_AUView CFSTR("CustomUI")
|
||||
|
||||
// UNLOCALIZED STRINGS:
|
||||
#define kAUViewUnlocalizedString_TitleSeparator CFSTR(": ")
|
||||
|
||||
// Generic View:
|
||||
#define kAUViewLocalizedStringKey_AudioUnit CFSTR("Audio Unit")
|
||||
#define kAUViewLocalizedStringKey_Manufacturer CFSTR("Manufacturer")
|
||||
|
||||
#define kAUViewLocalizedStringKey_FactoryPreset CFSTR("Factory Preset")
|
||||
|
||||
#define kAUViewLocalizedStringKey_Properties CFSTR("Properties")
|
||||
#define kAUViewLocalizedStringKey_Parameters CFSTR("Parameters")
|
||||
|
||||
#define kAUViewLocalizedStringKey_Standard CFSTR("Standard")
|
||||
#define kAUViewLocalizedStringKey_Expert CFSTR("Expert")
|
||||
|
||||
// AULoadCPU:
|
||||
#define kAUViewLocalizedStringKey_RestrictCPULoad CFSTR("Restrict CPU Load")
|
||||
#define kAUViewLocalizedStringKey_PercentSymbol CFSTR("%")
|
||||
#define kAUViewLocalizedStringKey_NotApplicable CFSTR("n/a")
|
||||
|
||||
// AUDiskStreamingCheckbox:
|
||||
#define kAUViewLocalizedStringKey_StreamFromDisk CFSTR("Stream From Disk")
|
||||
|
||||
// AURenderQualityPopup:
|
||||
#define kAUViewLocalizedStringKey_RenderQuality CFSTR("Render Quality")
|
||||
#define kAUViewLocalizedStringKey_Maximum CFSTR("Maximum")
|
||||
#define kAUViewLocalizedStringKey_High CFSTR("High")
|
||||
#define kAUViewLocalizedStringKey_Medium CFSTR("Medium")
|
||||
#define kAUViewLocalizedStringKey_Low CFSTR("Low")
|
||||
#define kAUViewLocalizedStringKey_Minimum CFSTR("Minimum")
|
||||
|
||||
// AUChannelLayoutPopUp:
|
||||
#define kAUViewLocalizedStringKey_AudioChannelLayout CFSTR("Audio Channel Layout")
|
||||
|
||||
#endif //__AUViewLocalizedStringKeys_h__
|
||||
|
||||
@@ -1,401 +1,401 @@
|
||||
/*
|
||||
File: CAAUParameter.cpp
|
||||
Abstract: CAAUParameter.h
|
||||
Version: 1.1
|
||||
|
||||
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.
|
||||
|
||||
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.
|
||||
|
||||
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.
|
||||
|
||||
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.
|
||||
|
||||
Copyright (C) 2014 Apple Inc. All Rights Reserved.
|
||||
|
||||
*/
|
||||
|
||||
#include "CAAUParameter.h"
|
||||
|
||||
CAAUParameter::CAAUParameter()
|
||||
{
|
||||
memset(this, 0, sizeof(CAAUParameter));
|
||||
}
|
||||
|
||||
CAAUParameter::CAAUParameter(AudioUnit au, AudioUnitParameterID param, AudioUnitScope scope, AudioUnitElement element)
|
||||
{
|
||||
memset(this, 0, sizeof(CAAUParameter));
|
||||
Init (au, param, scope, element);
|
||||
}
|
||||
|
||||
CAAUParameter::CAAUParameter (AudioUnitParameter &inParam)
|
||||
{
|
||||
memset(this, 0, sizeof(CAAUParameter));
|
||||
Init (inParam.mAudioUnit, inParam.mParameterID, inParam.mScope, inParam.mElement);
|
||||
}
|
||||
|
||||
CAAUParameter::CAAUParameter(const CAAUParameter &a)
|
||||
{
|
||||
memset(this, 0, sizeof(CAAUParameter));
|
||||
*this = a;
|
||||
}
|
||||
|
||||
CAAUParameter & CAAUParameter::operator = (const CAAUParameter &a)
|
||||
{
|
||||
if (mParamName) CFRelease(mParamName);
|
||||
if (mParamTag) CFRelease(mParamTag);
|
||||
if (mNamedParams) CFRelease(mNamedParams);
|
||||
|
||||
memcpy(this, &a, sizeof(CAAUParameter));
|
||||
|
||||
if (mParamName) CFRetain(mParamName);
|
||||
if (mParamTag) CFRetain(mParamTag);
|
||||
if (mNamedParams) CFRetain(mNamedParams);
|
||||
|
||||
return *this;
|
||||
}
|
||||
|
||||
CAAUParameter::~CAAUParameter()
|
||||
{
|
||||
if (mParamName) CFRelease(mParamName);
|
||||
if (mParamTag) CFRelease(mParamTag);
|
||||
if (mNamedParams) CFRelease (mNamedParams);
|
||||
}
|
||||
|
||||
void CAAUParameter::Init (AudioUnit au, AudioUnitParameterID param, AudioUnitScope scope, AudioUnitElement element)
|
||||
{
|
||||
mAudioUnit = au;
|
||||
mParameterID = param;
|
||||
mScope = scope;
|
||||
mElement = element;
|
||||
|
||||
UInt32 propertySize = sizeof(mParamInfo);
|
||||
OSStatus err = AudioUnitGetProperty(au, kAudioUnitProperty_ParameterInfo,
|
||||
scope, param, &mParamInfo, &propertySize);
|
||||
if (err)
|
||||
memset(&mParamInfo, 0, sizeof(mParamInfo));
|
||||
if (mParamInfo.flags & kAudioUnitParameterFlag_HasCFNameString) {
|
||||
mParamName = mParamInfo.cfNameString;
|
||||
if (!(mParamInfo.flags & kAudioUnitParameterFlag_CFNameRelease))
|
||||
CFRetain (mParamName);
|
||||
} else
|
||||
mParamName = CFStringCreateWithCString(NULL, mParamInfo.name, kCFStringEncodingUTF8);
|
||||
|
||||
const char* str = 0;
|
||||
switch (mParamInfo.unit)
|
||||
{
|
||||
case kAudioUnitParameterUnit_Boolean:
|
||||
str = "T/F";
|
||||
break;
|
||||
case kAudioUnitParameterUnit_Percent:
|
||||
case kAudioUnitParameterUnit_EqualPowerCrossfade:
|
||||
str = "%";
|
||||
break;
|
||||
case kAudioUnitParameterUnit_Seconds:
|
||||
str = "Secs";
|
||||
break;
|
||||
case kAudioUnitParameterUnit_SampleFrames:
|
||||
str = "Samps";
|
||||
break;
|
||||
case kAudioUnitParameterUnit_Phase:
|
||||
case kAudioUnitParameterUnit_Degrees:
|
||||
str = "Degr.";
|
||||
break;
|
||||
case kAudioUnitParameterUnit_Hertz:
|
||||
str = "Hz";
|
||||
break;
|
||||
case kAudioUnitParameterUnit_Cents:
|
||||
case kAudioUnitParameterUnit_AbsoluteCents:
|
||||
str = "Cents";
|
||||
break;
|
||||
case kAudioUnitParameterUnit_RelativeSemiTones:
|
||||
str = "S-T";
|
||||
break;
|
||||
case kAudioUnitParameterUnit_MIDINoteNumber:
|
||||
case kAudioUnitParameterUnit_MIDIController:
|
||||
str = "MIDI";
|
||||
//these are inclusive, so add one value here
|
||||
mNumIndexedParams = short(mParamInfo.maxValue+1 - mParamInfo.minValue);
|
||||
break;
|
||||
case kAudioUnitParameterUnit_Decibels:
|
||||
str = "dB";
|
||||
break;
|
||||
case kAudioUnitParameterUnit_MixerFaderCurve1:
|
||||
case kAudioUnitParameterUnit_LinearGain:
|
||||
str = "Gain";
|
||||
break;
|
||||
case kAudioUnitParameterUnit_Pan:
|
||||
str = "L/R";
|
||||
break;
|
||||
case kAudioUnitParameterUnit_Meters:
|
||||
str = "Mtrs";
|
||||
break;
|
||||
case kAudioUnitParameterUnit_Octaves:
|
||||
str = "8ve";
|
||||
break;
|
||||
case kAudioUnitParameterUnit_BPM:
|
||||
str = "BPM";
|
||||
break;
|
||||
case kAudioUnitParameterUnit_Beats:
|
||||
str = "Beats";
|
||||
break;
|
||||
case kAudioUnitParameterUnit_Milliseconds:
|
||||
str = "msecs";
|
||||
break;
|
||||
case kAudioUnitParameterUnit_Ratio:
|
||||
str = "Ratio";
|
||||
break;
|
||||
case kAudioUnitParameterUnit_Indexed:
|
||||
{
|
||||
propertySize = sizeof(mNamedParams);
|
||||
err = AudioUnitGetProperty (au,
|
||||
kAudioUnitProperty_ParameterValueStrings,
|
||||
scope,
|
||||
param,
|
||||
&mNamedParams,
|
||||
&propertySize);
|
||||
if (!err && mNamedParams) {
|
||||
mNumIndexedParams = CFArrayGetCount(mNamedParams);
|
||||
} else {
|
||||
//these are inclusive, so add one value here
|
||||
mNumIndexedParams = short(mParamInfo.maxValue+1 - mParamInfo.minValue);
|
||||
}
|
||||
str = NULL;
|
||||
}
|
||||
break;
|
||||
case kAudioUnitParameterUnit_CustomUnit:
|
||||
{
|
||||
CFStringRef unitName = mParamInfo.unitName;
|
||||
static char paramStr[256];
|
||||
CFStringGetCString (unitName, paramStr, 256, kCFStringEncodingUTF8);
|
||||
if (mParamInfo.flags & kAudioUnitParameterFlag_CFNameRelease)
|
||||
CFRelease (unitName);
|
||||
str = paramStr;
|
||||
break;
|
||||
}
|
||||
case kAudioUnitParameterUnit_Generic:
|
||||
case kAudioUnitParameterUnit_Rate:
|
||||
default:
|
||||
str = NULL;
|
||||
break;
|
||||
}
|
||||
|
||||
if (str)
|
||||
mParamTag = CFStringCreateWithCString(NULL, str, kCFStringEncodingUTF8);
|
||||
else
|
||||
mParamTag = NULL;
|
||||
}
|
||||
|
||||
|
||||
Float32 CAAUParameter::GetValue() const
|
||||
{
|
||||
Float32 value = 0.;
|
||||
//OSStatus err =
|
||||
AudioUnitGetParameter(mAudioUnit, mParameterID, mScope, mElement, &value);
|
||||
return value;
|
||||
}
|
||||
|
||||
CFStringRef CreateLocalizedStringForParameterValue ( double inParameterValue,
|
||||
const CAAUParameter * inParameter,
|
||||
UInt32 inDigits,
|
||||
UInt32 minDigits) {
|
||||
if (!inParameter) return nil;
|
||||
|
||||
AudioUnitParameterInfo info = inParameter->ParamInfo();
|
||||
int pow10;
|
||||
|
||||
switch (info.unit) {
|
||||
case kAudioUnitParameterUnit_Hertz:
|
||||
// number of significant digits based on value
|
||||
pow10 = int(log10(fmax(inParameterValue, .000001)));
|
||||
break;
|
||||
default:
|
||||
// number of significant digits based on parameter range
|
||||
pow10 = int(log10(fmax(double(info.maxValue - info.minValue), .000001)));
|
||||
break;
|
||||
}
|
||||
|
||||
// pow10 range nDigitsAfterDecimal
|
||||
// -2 .0100-.0999 4
|
||||
// -1 .100-.999 3
|
||||
// 0 1.00-9.99 2
|
||||
// 1 10.0-99.9 1
|
||||
// 2 100-999 0
|
||||
// 3 1000-9990 -1
|
||||
// 4 10000-99900 -2
|
||||
|
||||
int nDigitsAfterDecimal = inDigits - (pow10 + 1);
|
||||
if (nDigitsAfterDecimal < 0)
|
||||
nDigitsAfterDecimal = 0; // the least number of digits possible is zero
|
||||
|
||||
if (info.flags & kAudioUnitParameterFlag_IsHighResolution)
|
||||
nDigitsAfterDecimal = 4;
|
||||
|
||||
CFLocaleRef currentLocale = CFLocaleCopyCurrent();
|
||||
CFNumberFormatterRef numberFormatter = CFNumberFormatterCreate (NULL, currentLocale, kCFNumberFormatterDecimalStyle);
|
||||
|
||||
CFNumberRef maxFractionDigits = CFNumberCreate (NULL, kCFNumberIntType, &nDigitsAfterDecimal);
|
||||
|
||||
if (nDigitsAfterDecimal > 0)
|
||||
nDigitsAfterDecimal = minDigits;
|
||||
|
||||
CFNumberRef minFractionDigits = CFNumberCreate (NULL, kCFNumberIntType, &nDigitsAfterDecimal);
|
||||
|
||||
CFNumberFormatterSetProperty (numberFormatter, kCFNumberFormatterMinFractionDigits, minFractionDigits);
|
||||
CFNumberFormatterSetProperty (numberFormatter, kCFNumberFormatterMaxFractionDigits, maxFractionDigits);
|
||||
CFStringRef formattedNumberString = CFNumberFormatterCreateStringWithValue (NULL, numberFormatter, kCFNumberDoubleType, &inParameterValue);
|
||||
|
||||
CFRelease(currentLocale);
|
||||
CFRelease(numberFormatter);
|
||||
CFRelease(maxFractionDigits);
|
||||
CFRelease(minFractionDigits);
|
||||
|
||||
return formattedNumberString;
|
||||
}
|
||||
|
||||
CFStringRef CreateLocalizedStringForParameterValue ( double inParameterValue,
|
||||
const CAAUParameter * inParameter,
|
||||
UInt32 inDigits) {
|
||||
return CreateLocalizedStringForParameterValue (inParameterValue, inParameter, inDigits, 1);
|
||||
}
|
||||
|
||||
double ValueForLocalizedParameterString (CFStringRef string, const CAAUParameter * inParameter) {
|
||||
CFLocaleRef currentLocale = CFLocaleCopyCurrent();
|
||||
CFNumberFormatterRef numberFormatter = CFNumberFormatterCreate (NULL, currentLocale, kCFNumberFormatterDecimalStyle);
|
||||
|
||||
double value = 0;
|
||||
Boolean worked = CFNumberFormatterGetValueFromString (numberFormatter, string, NULL, kCFNumberDoubleType, &value);
|
||||
|
||||
CFRelease(currentLocale);
|
||||
CFRelease(numberFormatter);
|
||||
|
||||
if (worked)
|
||||
return value;
|
||||
else {
|
||||
AudioUnitParameterInfo info = inParameter->ParamInfo();
|
||||
return info.defaultValue;
|
||||
}
|
||||
}
|
||||
|
||||
CFStringRef CAAUParameter::GetStringFromValueCopy(const Float32 *value) const
|
||||
{
|
||||
if (HasNamedParams())
|
||||
{
|
||||
Float32 val = (value == NULL ? GetValue() : *value);
|
||||
int index = int(mParamInfo.minValue) + int(val);
|
||||
CFStringRef str = GetParamName (index);
|
||||
if (str) {
|
||||
CFRetain (str);
|
||||
return str;
|
||||
}
|
||||
}
|
||||
else if (ValuesHaveStrings())
|
||||
{
|
||||
AudioUnitParameterStringFromValue stringValue;
|
||||
stringValue.inParamID = mParameterID;
|
||||
stringValue.inValue = value;
|
||||
stringValue.outString = NULL;
|
||||
UInt32 propertySize = sizeof(stringValue);
|
||||
|
||||
OSStatus err = AudioUnitGetProperty (mAudioUnit,
|
||||
kAudioUnitProperty_ParameterStringFromValue,
|
||||
mScope,
|
||||
0,
|
||||
&stringValue,
|
||||
&propertySize);
|
||||
|
||||
if (!err && stringValue.outString != NULL)
|
||||
return stringValue.outString;
|
||||
}
|
||||
|
||||
Float32 val = (value == NULL ? GetValue() : *value);
|
||||
AudioUnitParameterUnit unit = this->ParamInfo().unit;
|
||||
if (unit == kAudioUnitParameterUnit_Cents || unit == kAudioUnitParameterUnit_AbsoluteCents)
|
||||
return CreateLocalizedStringForParameterValue(val, this, 4, 0);
|
||||
else
|
||||
return CreateLocalizedStringForParameterValue(val, this, 4);
|
||||
}
|
||||
|
||||
Float32 CAAUParameter::GetValueFromString(CFStringRef str) const
|
||||
{
|
||||
if (ValuesHaveStrings())
|
||||
{
|
||||
AudioUnitParameterValueFromString valueString;
|
||||
valueString.inParamID = mParameterID;
|
||||
valueString.inString = str;
|
||||
UInt32 propertySize = sizeof(valueString);
|
||||
|
||||
OSStatus err = AudioUnitGetProperty (mAudioUnit,
|
||||
kAudioUnitProperty_ParameterValueFromString,
|
||||
mScope,
|
||||
0,
|
||||
&valueString,
|
||||
&propertySize);
|
||||
|
||||
if (!err) {
|
||||
return valueString.outValue;
|
||||
}
|
||||
}
|
||||
|
||||
return (Float32) ValueForLocalizedParameterString(str, this);
|
||||
}
|
||||
|
||||
void CAAUParameter::SetValue( AUParameterListenerRef inListener,
|
||||
void * inObject,
|
||||
Float32 inValue) const
|
||||
{
|
||||
// clip inValue as: maxValue >= inValue >= minValue before setting
|
||||
Float32 valueToSet = inValue;
|
||||
if (valueToSet > mParamInfo.maxValue)
|
||||
valueToSet = mParamInfo.maxValue;
|
||||
if (valueToSet < mParamInfo.minValue)
|
||||
valueToSet = mParamInfo.minValue;
|
||||
|
||||
AUParameterSet(inListener, inObject, this, valueToSet, 0);
|
||||
}
|
||||
|
||||
#if DEBUG
|
||||
void CAAUParameter::Print() const
|
||||
{
|
||||
UInt32 clump = 0;
|
||||
GetClumpID (clump);
|
||||
|
||||
UInt32 len = static_cast<UInt32>(CFStringGetLength(mParamName));
|
||||
char* chars = (char*)malloc (len * 2); // give us plenty of room for unichar chars
|
||||
if (!CFStringGetCString (mParamName, chars, len * 2, kCFStringEncodingUTF8))
|
||||
chars[0] = 0;
|
||||
|
||||
printf ("ID: %ld, Clump: %u, Name: %s\n", (long unsigned int) mParameterID, (unsigned int) clump, chars);
|
||||
free (chars);
|
||||
}
|
||||
#endif
|
||||
/*
|
||||
File: CAAUParameter.cpp
|
||||
Abstract: CAAUParameter.h
|
||||
Version: 1.1
|
||||
|
||||
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.
|
||||
|
||||
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.
|
||||
|
||||
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.
|
||||
|
||||
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.
|
||||
|
||||
Copyright (C) 2014 Apple Inc. All Rights Reserved.
|
||||
|
||||
*/
|
||||
|
||||
#include "CAAUParameter.h"
|
||||
|
||||
CAAUParameter::CAAUParameter()
|
||||
{
|
||||
memset(this, 0, sizeof(CAAUParameter));
|
||||
}
|
||||
|
||||
CAAUParameter::CAAUParameter(AudioUnit au, AudioUnitParameterID param, AudioUnitScope scope, AudioUnitElement element)
|
||||
{
|
||||
memset(this, 0, sizeof(CAAUParameter));
|
||||
Init (au, param, scope, element);
|
||||
}
|
||||
|
||||
CAAUParameter::CAAUParameter (AudioUnitParameter &inParam)
|
||||
{
|
||||
memset(this, 0, sizeof(CAAUParameter));
|
||||
Init (inParam.mAudioUnit, inParam.mParameterID, inParam.mScope, inParam.mElement);
|
||||
}
|
||||
|
||||
CAAUParameter::CAAUParameter(const CAAUParameter &a)
|
||||
{
|
||||
memset(this, 0, sizeof(CAAUParameter));
|
||||
*this = a;
|
||||
}
|
||||
|
||||
CAAUParameter & CAAUParameter::operator = (const CAAUParameter &a)
|
||||
{
|
||||
if (mParamName) CFRelease(mParamName);
|
||||
if (mParamTag) CFRelease(mParamTag);
|
||||
if (mNamedParams) CFRelease(mNamedParams);
|
||||
|
||||
memcpy(this, &a, sizeof(CAAUParameter));
|
||||
|
||||
if (mParamName) CFRetain(mParamName);
|
||||
if (mParamTag) CFRetain(mParamTag);
|
||||
if (mNamedParams) CFRetain(mNamedParams);
|
||||
|
||||
return *this;
|
||||
}
|
||||
|
||||
CAAUParameter::~CAAUParameter()
|
||||
{
|
||||
if (mParamName) CFRelease(mParamName);
|
||||
if (mParamTag) CFRelease(mParamTag);
|
||||
if (mNamedParams) CFRelease (mNamedParams);
|
||||
}
|
||||
|
||||
void CAAUParameter::Init (AudioUnit au, AudioUnitParameterID param, AudioUnitScope scope, AudioUnitElement element)
|
||||
{
|
||||
mAudioUnit = au;
|
||||
mParameterID = param;
|
||||
mScope = scope;
|
||||
mElement = element;
|
||||
|
||||
UInt32 propertySize = sizeof(mParamInfo);
|
||||
OSStatus err = AudioUnitGetProperty(au, kAudioUnitProperty_ParameterInfo,
|
||||
scope, param, &mParamInfo, &propertySize);
|
||||
if (err)
|
||||
memset(&mParamInfo, 0, sizeof(mParamInfo));
|
||||
if (mParamInfo.flags & kAudioUnitParameterFlag_HasCFNameString) {
|
||||
mParamName = mParamInfo.cfNameString;
|
||||
if (!(mParamInfo.flags & kAudioUnitParameterFlag_CFNameRelease))
|
||||
CFRetain (mParamName);
|
||||
} else
|
||||
mParamName = CFStringCreateWithCString(NULL, mParamInfo.name, kCFStringEncodingUTF8);
|
||||
|
||||
const char* str = 0;
|
||||
switch (mParamInfo.unit)
|
||||
{
|
||||
case kAudioUnitParameterUnit_Boolean:
|
||||
str = "T/F";
|
||||
break;
|
||||
case kAudioUnitParameterUnit_Percent:
|
||||
case kAudioUnitParameterUnit_EqualPowerCrossfade:
|
||||
str = "%";
|
||||
break;
|
||||
case kAudioUnitParameterUnit_Seconds:
|
||||
str = "Secs";
|
||||
break;
|
||||
case kAudioUnitParameterUnit_SampleFrames:
|
||||
str = "Samps";
|
||||
break;
|
||||
case kAudioUnitParameterUnit_Phase:
|
||||
case kAudioUnitParameterUnit_Degrees:
|
||||
str = "Degr.";
|
||||
break;
|
||||
case kAudioUnitParameterUnit_Hertz:
|
||||
str = "Hz";
|
||||
break;
|
||||
case kAudioUnitParameterUnit_Cents:
|
||||
case kAudioUnitParameterUnit_AbsoluteCents:
|
||||
str = "Cents";
|
||||
break;
|
||||
case kAudioUnitParameterUnit_RelativeSemiTones:
|
||||
str = "S-T";
|
||||
break;
|
||||
case kAudioUnitParameterUnit_MIDINoteNumber:
|
||||
case kAudioUnitParameterUnit_MIDIController:
|
||||
str = "MIDI";
|
||||
//these are inclusive, so add one value here
|
||||
mNumIndexedParams = short(mParamInfo.maxValue+1 - mParamInfo.minValue);
|
||||
break;
|
||||
case kAudioUnitParameterUnit_Decibels:
|
||||
str = "dB";
|
||||
break;
|
||||
case kAudioUnitParameterUnit_MixerFaderCurve1:
|
||||
case kAudioUnitParameterUnit_LinearGain:
|
||||
str = "Gain";
|
||||
break;
|
||||
case kAudioUnitParameterUnit_Pan:
|
||||
str = "L/R";
|
||||
break;
|
||||
case kAudioUnitParameterUnit_Meters:
|
||||
str = "Mtrs";
|
||||
break;
|
||||
case kAudioUnitParameterUnit_Octaves:
|
||||
str = "8ve";
|
||||
break;
|
||||
case kAudioUnitParameterUnit_BPM:
|
||||
str = "BPM";
|
||||
break;
|
||||
case kAudioUnitParameterUnit_Beats:
|
||||
str = "Beats";
|
||||
break;
|
||||
case kAudioUnitParameterUnit_Milliseconds:
|
||||
str = "msecs";
|
||||
break;
|
||||
case kAudioUnitParameterUnit_Ratio:
|
||||
str = "Ratio";
|
||||
break;
|
||||
case kAudioUnitParameterUnit_Indexed:
|
||||
{
|
||||
propertySize = sizeof(mNamedParams);
|
||||
err = AudioUnitGetProperty (au,
|
||||
kAudioUnitProperty_ParameterValueStrings,
|
||||
scope,
|
||||
param,
|
||||
&mNamedParams,
|
||||
&propertySize);
|
||||
if (!err && mNamedParams) {
|
||||
mNumIndexedParams = CFArrayGetCount(mNamedParams);
|
||||
} else {
|
||||
//these are inclusive, so add one value here
|
||||
mNumIndexedParams = short(mParamInfo.maxValue+1 - mParamInfo.minValue);
|
||||
}
|
||||
str = NULL;
|
||||
}
|
||||
break;
|
||||
case kAudioUnitParameterUnit_CustomUnit:
|
||||
{
|
||||
CFStringRef unitName = mParamInfo.unitName;
|
||||
static char paramStr[256];
|
||||
CFStringGetCString (unitName, paramStr, 256, kCFStringEncodingUTF8);
|
||||
if (mParamInfo.flags & kAudioUnitParameterFlag_CFNameRelease)
|
||||
CFRelease (unitName);
|
||||
str = paramStr;
|
||||
break;
|
||||
}
|
||||
case kAudioUnitParameterUnit_Generic:
|
||||
case kAudioUnitParameterUnit_Rate:
|
||||
default:
|
||||
str = NULL;
|
||||
break;
|
||||
}
|
||||
|
||||
if (str)
|
||||
mParamTag = CFStringCreateWithCString(NULL, str, kCFStringEncodingUTF8);
|
||||
else
|
||||
mParamTag = NULL;
|
||||
}
|
||||
|
||||
|
||||
Float32 CAAUParameter::GetValue() const
|
||||
{
|
||||
Float32 value = 0.;
|
||||
//OSStatus err =
|
||||
AudioUnitGetParameter(mAudioUnit, mParameterID, mScope, mElement, &value);
|
||||
return value;
|
||||
}
|
||||
|
||||
CFStringRef CreateLocalizedStringForParameterValue ( double inParameterValue,
|
||||
const CAAUParameter * inParameter,
|
||||
UInt32 inDigits,
|
||||
UInt32 minDigits) {
|
||||
if (!inParameter) return nil;
|
||||
|
||||
AudioUnitParameterInfo info = inParameter->ParamInfo();
|
||||
int pow10;
|
||||
|
||||
switch (info.unit) {
|
||||
case kAudioUnitParameterUnit_Hertz:
|
||||
// number of significant digits based on value
|
||||
pow10 = int(log10(fmax(inParameterValue, .000001)));
|
||||
break;
|
||||
default:
|
||||
// number of significant digits based on parameter range
|
||||
pow10 = int(log10(fmax(double(info.maxValue - info.minValue), .000001)));
|
||||
break;
|
||||
}
|
||||
|
||||
// pow10 range nDigitsAfterDecimal
|
||||
// -2 .0100-.0999 4
|
||||
// -1 .100-.999 3
|
||||
// 0 1.00-9.99 2
|
||||
// 1 10.0-99.9 1
|
||||
// 2 100-999 0
|
||||
// 3 1000-9990 -1
|
||||
// 4 10000-99900 -2
|
||||
|
||||
int nDigitsAfterDecimal = inDigits - (pow10 + 1);
|
||||
if (nDigitsAfterDecimal < 0)
|
||||
nDigitsAfterDecimal = 0; // the least number of digits possible is zero
|
||||
|
||||
if (info.flags & kAudioUnitParameterFlag_IsHighResolution)
|
||||
nDigitsAfterDecimal = 4;
|
||||
|
||||
CFLocaleRef currentLocale = CFLocaleCopyCurrent();
|
||||
CFNumberFormatterRef numberFormatter = CFNumberFormatterCreate (NULL, currentLocale, kCFNumberFormatterDecimalStyle);
|
||||
|
||||
CFNumberRef maxFractionDigits = CFNumberCreate (NULL, kCFNumberIntType, &nDigitsAfterDecimal);
|
||||
|
||||
if (nDigitsAfterDecimal > 0)
|
||||
nDigitsAfterDecimal = minDigits;
|
||||
|
||||
CFNumberRef minFractionDigits = CFNumberCreate (NULL, kCFNumberIntType, &nDigitsAfterDecimal);
|
||||
|
||||
CFNumberFormatterSetProperty (numberFormatter, kCFNumberFormatterMinFractionDigits, minFractionDigits);
|
||||
CFNumberFormatterSetProperty (numberFormatter, kCFNumberFormatterMaxFractionDigits, maxFractionDigits);
|
||||
CFStringRef formattedNumberString = CFNumberFormatterCreateStringWithValue (NULL, numberFormatter, kCFNumberDoubleType, &inParameterValue);
|
||||
|
||||
CFRelease(currentLocale);
|
||||
CFRelease(numberFormatter);
|
||||
CFRelease(maxFractionDigits);
|
||||
CFRelease(minFractionDigits);
|
||||
|
||||
return formattedNumberString;
|
||||
}
|
||||
|
||||
CFStringRef CreateLocalizedStringForParameterValue ( double inParameterValue,
|
||||
const CAAUParameter * inParameter,
|
||||
UInt32 inDigits) {
|
||||
return CreateLocalizedStringForParameterValue (inParameterValue, inParameter, inDigits, 1);
|
||||
}
|
||||
|
||||
double ValueForLocalizedParameterString (CFStringRef string, const CAAUParameter * inParameter) {
|
||||
CFLocaleRef currentLocale = CFLocaleCopyCurrent();
|
||||
CFNumberFormatterRef numberFormatter = CFNumberFormatterCreate (NULL, currentLocale, kCFNumberFormatterDecimalStyle);
|
||||
|
||||
double value = 0;
|
||||
Boolean worked = CFNumberFormatterGetValueFromString (numberFormatter, string, NULL, kCFNumberDoubleType, &value);
|
||||
|
||||
CFRelease(currentLocale);
|
||||
CFRelease(numberFormatter);
|
||||
|
||||
if (worked)
|
||||
return value;
|
||||
else {
|
||||
AudioUnitParameterInfo info = inParameter->ParamInfo();
|
||||
return info.defaultValue;
|
||||
}
|
||||
}
|
||||
|
||||
CFStringRef CAAUParameter::GetStringFromValueCopy(const Float32 *value) const
|
||||
{
|
||||
if (HasNamedParams())
|
||||
{
|
||||
Float32 val = (value == NULL ? GetValue() : *value);
|
||||
int index = int(mParamInfo.minValue) + int(val);
|
||||
CFStringRef str = GetParamName (index);
|
||||
if (str) {
|
||||
CFRetain (str);
|
||||
return str;
|
||||
}
|
||||
}
|
||||
else if (ValuesHaveStrings())
|
||||
{
|
||||
AudioUnitParameterStringFromValue stringValue;
|
||||
stringValue.inParamID = mParameterID;
|
||||
stringValue.inValue = value;
|
||||
stringValue.outString = NULL;
|
||||
UInt32 propertySize = sizeof(stringValue);
|
||||
|
||||
OSStatus err = AudioUnitGetProperty (mAudioUnit,
|
||||
kAudioUnitProperty_ParameterStringFromValue,
|
||||
mScope,
|
||||
0,
|
||||
&stringValue,
|
||||
&propertySize);
|
||||
|
||||
if (!err && stringValue.outString != NULL)
|
||||
return stringValue.outString;
|
||||
}
|
||||
|
||||
Float32 val = (value == NULL ? GetValue() : *value);
|
||||
AudioUnitParameterUnit unit = this->ParamInfo().unit;
|
||||
if (unit == kAudioUnitParameterUnit_Cents || unit == kAudioUnitParameterUnit_AbsoluteCents)
|
||||
return CreateLocalizedStringForParameterValue(val, this, 4, 0);
|
||||
else
|
||||
return CreateLocalizedStringForParameterValue(val, this, 4);
|
||||
}
|
||||
|
||||
Float32 CAAUParameter::GetValueFromString(CFStringRef str) const
|
||||
{
|
||||
if (ValuesHaveStrings())
|
||||
{
|
||||
AudioUnitParameterValueFromString valueString;
|
||||
valueString.inParamID = mParameterID;
|
||||
valueString.inString = str;
|
||||
UInt32 propertySize = sizeof(valueString);
|
||||
|
||||
OSStatus err = AudioUnitGetProperty (mAudioUnit,
|
||||
kAudioUnitProperty_ParameterValueFromString,
|
||||
mScope,
|
||||
0,
|
||||
&valueString,
|
||||
&propertySize);
|
||||
|
||||
if (!err) {
|
||||
return valueString.outValue;
|
||||
}
|
||||
}
|
||||
|
||||
return (Float32) ValueForLocalizedParameterString(str, this);
|
||||
}
|
||||
|
||||
void CAAUParameter::SetValue( AUParameterListenerRef inListener,
|
||||
void * inObject,
|
||||
Float32 inValue) const
|
||||
{
|
||||
// clip inValue as: maxValue >= inValue >= minValue before setting
|
||||
Float32 valueToSet = inValue;
|
||||
if (valueToSet > mParamInfo.maxValue)
|
||||
valueToSet = mParamInfo.maxValue;
|
||||
if (valueToSet < mParamInfo.minValue)
|
||||
valueToSet = mParamInfo.minValue;
|
||||
|
||||
AUParameterSet(inListener, inObject, this, valueToSet, 0);
|
||||
}
|
||||
|
||||
#if DEBUG
|
||||
void CAAUParameter::Print() const
|
||||
{
|
||||
UInt32 clump = 0;
|
||||
GetClumpID (clump);
|
||||
|
||||
UInt32 len = static_cast<UInt32>(CFStringGetLength(mParamName));
|
||||
char* chars = (char*)malloc (len * 2); // give us plenty of room for unichar chars
|
||||
if (!CFStringGetCString (mParamName, chars, len * 2, kCFStringEncodingUTF8))
|
||||
chars[0] = 0;
|
||||
|
||||
printf ("ID: %ld, Clump: %u, Name: %s\n", (long unsigned int) mParameterID, (unsigned int) clump, chars);
|
||||
free (chars);
|
||||
}
|
||||
#endif
|
||||
|
||||
@@ -1,191 +1,191 @@
|
||||
/*
|
||||
File: CAAUParameter.h
|
||||
Abstract: Part of CoreAudio Utility Classes
|
||||
Version: 1.1
|
||||
|
||||
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.
|
||||
|
||||
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.
|
||||
|
||||
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.
|
||||
|
||||
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.
|
||||
|
||||
Copyright (C) 2014 Apple Inc. All Rights Reserved.
|
||||
|
||||
*/
|
||||
#ifndef __CAAUParameter_h__
|
||||
#define __CAAUParameter_h__
|
||||
|
||||
#include <AudioToolbox/AudioUnitUtilities.h>
|
||||
|
||||
// ____________________________________________________________________________
|
||||
// CAAUParameter
|
||||
// complete parameter specification
|
||||
/*! @class CAAUParameter */
|
||||
class CAAUParameter : public AudioUnitParameter {
|
||||
public:
|
||||
/*! @ctor CAAUParameter.0 */
|
||||
CAAUParameter();
|
||||
/*! @ctor CAAUParameter.1 */
|
||||
CAAUParameter(AudioUnit au, AudioUnitParameterID param, AudioUnitScope scope, AudioUnitElement element);
|
||||
/*! @ctor CAAUParameter.2 */
|
||||
CAAUParameter(AudioUnitParameter &inParam);
|
||||
/*! @ctor CAAUParameter.3 */
|
||||
CAAUParameter(const CAAUParameter &a);
|
||||
/*! @dtor ~CAAUParameter */
|
||||
~CAAUParameter();
|
||||
|
||||
/*! @method operator <@ */
|
||||
bool operator < (const CAAUParameter &a) const
|
||||
{
|
||||
return memcmp(this, &a, sizeof(AudioUnitParameter)) < 0;
|
||||
}
|
||||
|
||||
/*! @method operator ==@ */
|
||||
bool operator == (const CAAUParameter &a) const
|
||||
{
|
||||
return !memcmp(this, &a, sizeof(AudioUnitParameter));
|
||||
}
|
||||
|
||||
/*! @method operator =@ */
|
||||
CAAUParameter & operator = (const CAAUParameter &a);
|
||||
|
||||
/*! @method GetValue */
|
||||
Float32 GetValue() const;
|
||||
/*! @method SetValue */
|
||||
void SetValue( AUParameterListenerRef inListener,
|
||||
void * inObject,
|
||||
Float32 inValue) const;
|
||||
|
||||
/*! @method GetName */
|
||||
CFStringRef GetName() const { return mParamName; }
|
||||
// borrowed reference!
|
||||
|
||||
/*! @method GetStringFromValueCopy */
|
||||
CFStringRef GetStringFromValueCopy(const Float32 *value = NULL) const;
|
||||
// returns a copy of the name of the current parameter value
|
||||
// or null if there is no name associated
|
||||
// caller must release
|
||||
/*! @method ValuesHaveStrings */
|
||||
bool ValuesHaveStrings () const
|
||||
{
|
||||
return (mParamInfo.flags & kAudioUnitParameterFlag_ValuesHaveStrings) != 0;
|
||||
}
|
||||
|
||||
/*! @method GetValueFromString */
|
||||
Float32 GetValueFromString (CFStringRef str) const;
|
||||
// caller must release
|
||||
|
||||
/*! @method ParamInfo */
|
||||
const AudioUnitParameterInfo &
|
||||
ParamInfo() const { return mParamInfo; }
|
||||
|
||||
/*! @method GetParamTag */
|
||||
CFStringRef GetParamTag() const { return mParamTag; }
|
||||
// this may return null! -
|
||||
// in which case there is no descriptive tag for the parameter
|
||||
|
||||
/*! @method GetParamName */
|
||||
CFStringRef GetParamName (int inIndex) const
|
||||
// this can return null if there is no name for the parameter
|
||||
{
|
||||
return (mNamedParams && inIndex < mNumIndexedParams)
|
||||
? (CFStringRef) CFArrayGetValueAtIndex(mNamedParams, inIndex)
|
||||
: 0;
|
||||
}
|
||||
|
||||
/*! @method GetNumIndexedParams */
|
||||
int GetNumIndexedParams () const { return mNumIndexedParams; }
|
||||
|
||||
/*! @method IsIndexedParam */
|
||||
bool IsIndexedParam () const { return mNumIndexedParams != 0; }
|
||||
|
||||
/*! @method HasNamedParams */
|
||||
bool HasNamedParams () const { return IsIndexedParam() && mNamedParams; }
|
||||
|
||||
/*! @method GetClumpID */
|
||||
bool GetClumpID (UInt32 &outClumpID) const
|
||||
{
|
||||
if (mParamInfo.flags & kAudioUnitParameterFlag_HasClump) {
|
||||
outClumpID = mParamInfo.clumpID;
|
||||
return true;
|
||||
}
|
||||
return false;
|
||||
}
|
||||
|
||||
/*! @method HasDisplayTransformation */
|
||||
bool HasDisplayTransformation () const
|
||||
{
|
||||
return GetAudioUnitParameterDisplayType (mParamInfo.flags);
|
||||
}
|
||||
|
||||
/*! @method IsExpert */
|
||||
bool IsExpert () const
|
||||
{
|
||||
return mParamInfo.flags & kAudioUnitParameterFlag_ExpertMode;
|
||||
}
|
||||
#if DEBUG
|
||||
void Print () const;
|
||||
#endif
|
||||
|
||||
// these methods are defined in CAPersistence.cpp
|
||||
// they will persist and restore only the scope, element and param ID's of the AudioUnitParameter
|
||||
// however, this is sufficient to be able to save/restore a CAAUParameter object
|
||||
void Save (CFPropertyListRef &outData) const;
|
||||
|
||||
static void Save (const AudioUnitParameter &inParam, CFPropertyListRef &outData);
|
||||
|
||||
static OSStatus Restore (const CFPropertyListRef inData, AudioUnitParameter &outParam);
|
||||
|
||||
protected:
|
||||
// cached parameter info
|
||||
/*! @var mParamInfo */
|
||||
AudioUnitParameterInfo mParamInfo;
|
||||
/*! @var mParamName */
|
||||
CFStringRef mParamName;
|
||||
/*! @var mParamTag */
|
||||
CFStringRef mParamTag;
|
||||
/*! @var mNumIndexedParams */
|
||||
short mNumIndexedParams;
|
||||
/*! @var mNamedParams */
|
||||
CFArrayRef mNamedParams;
|
||||
|
||||
private:
|
||||
void Init (AudioUnit au, AudioUnitParameterID param, AudioUnitScope scope, AudioUnitElement element);
|
||||
|
||||
};
|
||||
|
||||
|
||||
|
||||
#endif // __CAAUParameter_h__
|
||||
/*
|
||||
File: CAAUParameter.h
|
||||
Abstract: Part of CoreAudio Utility Classes
|
||||
Version: 1.1
|
||||
|
||||
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.
|
||||
|
||||
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.
|
||||
|
||||
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.
|
||||
|
||||
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.
|
||||
|
||||
Copyright (C) 2014 Apple Inc. All Rights Reserved.
|
||||
|
||||
*/
|
||||
#ifndef __CAAUParameter_h__
|
||||
#define __CAAUParameter_h__
|
||||
|
||||
#include <AudioToolbox/AudioUnitUtilities.h>
|
||||
|
||||
// ____________________________________________________________________________
|
||||
// CAAUParameter
|
||||
// complete parameter specification
|
||||
/*! @class CAAUParameter */
|
||||
class CAAUParameter : public AudioUnitParameter {
|
||||
public:
|
||||
/*! @ctor CAAUParameter.0 */
|
||||
CAAUParameter();
|
||||
/*! @ctor CAAUParameter.1 */
|
||||
CAAUParameter(AudioUnit au, AudioUnitParameterID param, AudioUnitScope scope, AudioUnitElement element);
|
||||
/*! @ctor CAAUParameter.2 */
|
||||
CAAUParameter(AudioUnitParameter &inParam);
|
||||
/*! @ctor CAAUParameter.3 */
|
||||
CAAUParameter(const CAAUParameter &a);
|
||||
/*! @dtor ~CAAUParameter */
|
||||
~CAAUParameter();
|
||||
|
||||
/*! @method operator <@ */
|
||||
bool operator < (const CAAUParameter &a) const
|
||||
{
|
||||
return memcmp(this, &a, sizeof(AudioUnitParameter)) < 0;
|
||||
}
|
||||
|
||||
/*! @method operator ==@ */
|
||||
bool operator == (const CAAUParameter &a) const
|
||||
{
|
||||
return !memcmp(this, &a, sizeof(AudioUnitParameter));
|
||||
}
|
||||
|
||||
/*! @method operator =@ */
|
||||
CAAUParameter & operator = (const CAAUParameter &a);
|
||||
|
||||
/*! @method GetValue */
|
||||
Float32 GetValue() const;
|
||||
/*! @method SetValue */
|
||||
void SetValue( AUParameterListenerRef inListener,
|
||||
void * inObject,
|
||||
Float32 inValue) const;
|
||||
|
||||
/*! @method GetName */
|
||||
CFStringRef GetName() const { return mParamName; }
|
||||
// borrowed reference!
|
||||
|
||||
/*! @method GetStringFromValueCopy */
|
||||
CFStringRef GetStringFromValueCopy(const Float32 *value = NULL) const;
|
||||
// returns a copy of the name of the current parameter value
|
||||
// or null if there is no name associated
|
||||
// caller must release
|
||||
/*! @method ValuesHaveStrings */
|
||||
bool ValuesHaveStrings () const
|
||||
{
|
||||
return (mParamInfo.flags & kAudioUnitParameterFlag_ValuesHaveStrings) != 0;
|
||||
}
|
||||
|
||||
/*! @method GetValueFromString */
|
||||
Float32 GetValueFromString (CFStringRef str) const;
|
||||
// caller must release
|
||||
|
||||
/*! @method ParamInfo */
|
||||
const AudioUnitParameterInfo &
|
||||
ParamInfo() const { return mParamInfo; }
|
||||
|
||||
/*! @method GetParamTag */
|
||||
CFStringRef GetParamTag() const { return mParamTag; }
|
||||
// this may return null! -
|
||||
// in which case there is no descriptive tag for the parameter
|
||||
|
||||
/*! @method GetParamName */
|
||||
CFStringRef GetParamName (int inIndex) const
|
||||
// this can return null if there is no name for the parameter
|
||||
{
|
||||
return (mNamedParams && inIndex < mNumIndexedParams)
|
||||
? (CFStringRef) CFArrayGetValueAtIndex(mNamedParams, inIndex)
|
||||
: 0;
|
||||
}
|
||||
|
||||
/*! @method GetNumIndexedParams */
|
||||
int GetNumIndexedParams () const { return mNumIndexedParams; }
|
||||
|
||||
/*! @method IsIndexedParam */
|
||||
bool IsIndexedParam () const { return mNumIndexedParams != 0; }
|
||||
|
||||
/*! @method HasNamedParams */
|
||||
bool HasNamedParams () const { return IsIndexedParam() && mNamedParams; }
|
||||
|
||||
/*! @method GetClumpID */
|
||||
bool GetClumpID (UInt32 &outClumpID) const
|
||||
{
|
||||
if (mParamInfo.flags & kAudioUnitParameterFlag_HasClump) {
|
||||
outClumpID = mParamInfo.clumpID;
|
||||
return true;
|
||||
}
|
||||
return false;
|
||||
}
|
||||
|
||||
/*! @method HasDisplayTransformation */
|
||||
bool HasDisplayTransformation () const
|
||||
{
|
||||
return GetAudioUnitParameterDisplayType (mParamInfo.flags);
|
||||
}
|
||||
|
||||
/*! @method IsExpert */
|
||||
bool IsExpert () const
|
||||
{
|
||||
return mParamInfo.flags & kAudioUnitParameterFlag_ExpertMode;
|
||||
}
|
||||
#if DEBUG
|
||||
void Print () const;
|
||||
#endif
|
||||
|
||||
// these methods are defined in CAPersistence.cpp
|
||||
// they will persist and restore only the scope, element and param ID's of the AudioUnitParameter
|
||||
// however, this is sufficient to be able to save/restore a CAAUParameter object
|
||||
void Save (CFPropertyListRef &outData) const;
|
||||
|
||||
static void Save (const AudioUnitParameter &inParam, CFPropertyListRef &outData);
|
||||
|
||||
static OSStatus Restore (const CFPropertyListRef inData, AudioUnitParameter &outParam);
|
||||
|
||||
protected:
|
||||
// cached parameter info
|
||||
/*! @var mParamInfo */
|
||||
AudioUnitParameterInfo mParamInfo;
|
||||
/*! @var mParamName */
|
||||
CFStringRef mParamName;
|
||||
/*! @var mParamTag */
|
||||
CFStringRef mParamTag;
|
||||
/*! @var mNumIndexedParams */
|
||||
short mNumIndexedParams;
|
||||
/*! @var mNamedParams */
|
||||
CFArrayRef mNamedParams;
|
||||
|
||||
private:
|
||||
void Init (AudioUnit au, AudioUnitParameterID param, AudioUnitScope scope, AudioUnitElement element);
|
||||
|
||||
};
|
||||
|
||||
|
||||
|
||||
#endif // __CAAUParameter_h__
|
||||
|
||||
@@ -1,305 +1,305 @@
|
||||
/*
|
||||
File: CAAtomic.h
|
||||
Abstract: Part of CoreAudio Utility Classes
|
||||
Version: 1.1
|
||||
|
||||
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.
|
||||
|
||||
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.
|
||||
|
||||
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.
|
||||
|
||||
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.
|
||||
|
||||
Copyright (C) 2014 Apple Inc. All Rights Reserved.
|
||||
|
||||
*/
|
||||
/*
|
||||
This file implements all Atomic operations using Interlocked functions specified in
|
||||
Winbase.h
|
||||
NOTE: According to Microsoft documentation, all Interlocked functions generates a
|
||||
full barrier.
|
||||
On Windows:
|
||||
As the Interlocked functions returns the Old value, Extra checks and operations
|
||||
are made after the atomic operation to return value consistent with OSX counterparts.
|
||||
*/
|
||||
#ifndef __CAAtomic_h__
|
||||
#define __CAAtomic_h__
|
||||
|
||||
#if TARGET_OS_WIN32
|
||||
#include <windows.h>
|
||||
#include <intrin.h>
|
||||
#pragma intrinsic(_InterlockedOr)
|
||||
#pragma intrinsic(_InterlockedAnd)
|
||||
#else
|
||||
#include <CoreFoundation/CFBase.h>
|
||||
#include <libkern/OSAtomic.h>
|
||||
#endif
|
||||
|
||||
inline void CAMemoryBarrier()
|
||||
{
|
||||
#if TARGET_OS_WIN32
|
||||
MemoryBarrier();
|
||||
#else
|
||||
OSMemoryBarrier();
|
||||
#endif
|
||||
}
|
||||
|
||||
inline SInt32 CAAtomicAdd32Barrier(SInt32 theAmt, volatile SInt32* theValue)
|
||||
{
|
||||
#if TARGET_OS_WIN32
|
||||
long lRetVal = InterlockedExchangeAdd((volatile long*)theValue, theAmt);
|
||||
// InterlockedExchangeAdd returns the original value which differs from OSX version.
|
||||
// At this point the addition would have occured and hence returning the new value
|
||||
// to keep it sync with OSX.
|
||||
return lRetVal + theAmt;
|
||||
#else
|
||||
return OSAtomicAdd32Barrier(theAmt, (volatile int32_t *)theValue);
|
||||
#endif
|
||||
}
|
||||
|
||||
inline SInt32 CAAtomicOr32Barrier(UInt32 theMask, volatile UInt32* theValue)
|
||||
{
|
||||
#if TARGET_OS_WIN32
|
||||
// InterlockedAnd macro is not defined in x86 platform, and hence using the intrinsic
|
||||
// function instead.
|
||||
long j = _InterlockedOr((volatile long*)theValue, theMask);
|
||||
// _InterlockedOr returns the original value which differs from OSX version.
|
||||
// Returning the new value similar to OSX
|
||||
return (SInt32)(j | theMask);
|
||||
#else
|
||||
return OSAtomicOr32Barrier(theMask, (volatile uint32_t *)theValue);
|
||||
#endif
|
||||
}
|
||||
|
||||
inline SInt32 CAAtomicAnd32Barrier(UInt32 theMask, volatile UInt32* theValue)
|
||||
{
|
||||
#if TARGET_OS_WIN32
|
||||
// InterlockedAnd macro is not defined in x86 platform, and hence using the intrinsic
|
||||
// function instead.
|
||||
long j = _InterlockedAnd((volatile long*)theValue, theMask);
|
||||
// _InterlockedAnd returns the original value which differs from OSX version.
|
||||
// Returning the new value similar to OSX
|
||||
return (SInt32)(j & theMask);
|
||||
#else
|
||||
return OSAtomicAnd32Barrier(theMask, (volatile uint32_t *)theValue);
|
||||
#endif
|
||||
}
|
||||
|
||||
inline bool CAAtomicCompareAndSwap32Barrier(SInt32 oldValue, SInt32 newValue, volatile SInt32 *theValue)
|
||||
{
|
||||
#if TARGET_OS_WIN32
|
||||
// InterlockedCompareExchange returns the old value. But we need to return bool value.
|
||||
long lRetVal = InterlockedCompareExchange((volatile long*)theValue, newValue, oldValue);
|
||||
// Hence we check if the new value is set and if it is we return true else false.
|
||||
// If theValue is equal to oldValue then the swap happens. Otherwise swap doesn't happen.
|
||||
return (oldValue == lRetVal);
|
||||
#else
|
||||
return OSAtomicCompareAndSwap32Barrier(oldValue, newValue, (volatile int32_t *)theValue);
|
||||
#endif
|
||||
}
|
||||
|
||||
|
||||
inline SInt32 CAAtomicIncrement32(volatile SInt32* theValue)
|
||||
{
|
||||
#if TARGET_OS_WIN32
|
||||
return (SInt32)InterlockedIncrement((volatile long*)theValue);
|
||||
#else
|
||||
return OSAtomicIncrement32((volatile int32_t *)theValue);
|
||||
#endif
|
||||
}
|
||||
|
||||
inline SInt32 CAAtomicDecrement32(volatile SInt32* theValue)
|
||||
{
|
||||
#if TARGET_OS_WIN32
|
||||
return (SInt32)InterlockedDecrement((volatile long*)theValue);
|
||||
#else
|
||||
return OSAtomicDecrement32((volatile int32_t *)theValue);
|
||||
#endif
|
||||
}
|
||||
|
||||
inline SInt32 CAAtomicIncrement32Barrier(volatile SInt32* theValue)
|
||||
{
|
||||
#if TARGET_OS_WIN32
|
||||
return CAAtomicIncrement32(theValue);
|
||||
#else
|
||||
return OSAtomicIncrement32Barrier((volatile int32_t *)theValue);
|
||||
#endif
|
||||
}
|
||||
|
||||
inline SInt32 CAAtomicDecrement32Barrier(volatile SInt32* theValue)
|
||||
{
|
||||
#if TARGET_OS_WIN32
|
||||
return CAAtomicDecrement32(theValue);
|
||||
#else
|
||||
return OSAtomicDecrement32Barrier((volatile int32_t *)theValue);
|
||||
#endif
|
||||
}
|
||||
|
||||
inline bool CAAtomicTestAndClearBarrier(int bitToClear, void* theAddress)
|
||||
{
|
||||
#if TARGET_OS_WIN32
|
||||
BOOL bOldVal = InterlockedBitTestAndReset((long*)theAddress, bitToClear);
|
||||
return (bOldVal ? true : false);
|
||||
#else
|
||||
return OSAtomicTestAndClearBarrier(bitToClear, (volatile void *)theAddress);
|
||||
#endif
|
||||
}
|
||||
|
||||
inline bool CAAtomicTestAndClear(int bitToClear, void* theAddress)
|
||||
{
|
||||
#if TARGET_OS_WIN32
|
||||
BOOL bOldVal = CAAtomicTestAndClearBarrier(bitToClear, (long*)theAddress);
|
||||
return (bOldVal ? true : false);
|
||||
#else
|
||||
return OSAtomicTestAndClear(bitToClear, (volatile void *)theAddress);
|
||||
#endif
|
||||
}
|
||||
|
||||
inline bool CAAtomicTestAndSetBarrier(int bitToSet, void* theAddress)
|
||||
{
|
||||
#if TARGET_OS_WIN32
|
||||
BOOL bOldVal = InterlockedBitTestAndSet((long*)theAddress, bitToSet);
|
||||
return (bOldVal ? true : false);
|
||||
#else
|
||||
return OSAtomicTestAndSetBarrier(bitToSet, (volatile void *)theAddress);
|
||||
#endif
|
||||
}
|
||||
|
||||
// int32_t flavors -- for C++ only since we can't overload in C
|
||||
// CFBase.h defines SInt32 as signed int which is similar to int32_t. If CFBase.h is included, then
|
||||
// this will generate redefinition error. But on Mac, CFBase.h, still includes MacTypes.h where
|
||||
// SInt32 is defined as signed long so this would work there.
|
||||
// So in order to fix the redefinition errors, we define these functions only if MacTypes.h is included.
|
||||
#if defined(__cplusplus) && defined(__MACTYPES__) && !__LP64__
|
||||
inline int32_t CAAtomicAdd32Barrier(int32_t theAmt, volatile int32_t* theValue)
|
||||
{
|
||||
return CAAtomicAdd32Barrier(theAmt, (volatile SInt32 *)theValue);
|
||||
}
|
||||
|
||||
inline int32_t CAAtomicOr32Barrier(uint32_t theMask, volatile uint32_t* theValue)
|
||||
{
|
||||
return CAAtomicOr32Barrier(theMask, (volatile UInt32 *)theValue);
|
||||
}
|
||||
|
||||
inline int32_t CAAtomicAnd32Barrier(uint32_t theMask, volatile uint32_t* theValue)
|
||||
{
|
||||
return CAAtomicAnd32Barrier(theMask, (volatile UInt32 *)theValue);
|
||||
}
|
||||
|
||||
inline bool CAAtomicCompareAndSwap32Barrier(int32_t oldValue, int32_t newValue, volatile int32_t *theValue)
|
||||
{
|
||||
return CAAtomicCompareAndSwap32Barrier(oldValue, newValue, (volatile SInt32 *)theValue);
|
||||
}
|
||||
|
||||
inline int32_t CAAtomicIncrement32(volatile int32_t* theValue)
|
||||
{
|
||||
return CAAtomicIncrement32((volatile SInt32 *)theValue);
|
||||
}
|
||||
|
||||
inline int32_t CAAtomicDecrement32(volatile int32_t* theValue)
|
||||
{
|
||||
return CAAtomicDecrement32((volatile SInt32 *)theValue);
|
||||
}
|
||||
|
||||
inline int32_t CAAtomicIncrement32Barrier(volatile int32_t* theValue)
|
||||
{
|
||||
return CAAtomicIncrement32Barrier((volatile SInt32 *)theValue);
|
||||
}
|
||||
|
||||
inline int32_t CAAtomicDecrement32Barrier(volatile int32_t* theValue)
|
||||
{
|
||||
return CAAtomicDecrement32Barrier((volatile SInt32 *)theValue);
|
||||
}
|
||||
#endif // __cplusplus && !__LP64__
|
||||
|
||||
#if __LP64__
|
||||
inline bool CAAtomicCompareAndSwap64Barrier( int64_t __oldValue, int64_t __newValue, volatile int64_t *__theValue )
|
||||
{
|
||||
return OSAtomicCompareAndSwap64Barrier(__oldValue, __newValue, __theValue);
|
||||
}
|
||||
#endif
|
||||
|
||||
inline bool CAAtomicCompareAndSwapPtrBarrier(void *__oldValue, void *__newValue, volatile void ** __theValue)
|
||||
{
|
||||
#if __LP64__
|
||||
return CAAtomicCompareAndSwap64Barrier((int64_t)__oldValue, (int64_t)__newValue, (int64_t *)__theValue);
|
||||
#else
|
||||
return CAAtomicCompareAndSwap32Barrier((int32_t)__oldValue, (int32_t)__newValue, (int32_t *)__theValue);
|
||||
#endif
|
||||
}
|
||||
|
||||
/* Spinlocks. These use memory barriers as required to synchronize access to shared
|
||||
* memory protected by the lock. The lock operation spins, but employs various strategies
|
||||
* to back off if the lock is held, making it immune to most priority-inversion livelocks.
|
||||
* The try operation immediately returns false if the lock was held, true if it took the
|
||||
* lock. The convention is that unlocked is zero, locked is nonzero.
|
||||
*/
|
||||
#define CA_SPINLOCK_INIT 0
|
||||
|
||||
typedef int32_t CASpinLock;
|
||||
|
||||
bool CASpinLockTry( volatile CASpinLock *__lock );
|
||||
void CASpinLockLock( volatile CASpinLock *__lock );
|
||||
void CASpinLockUnlock( volatile CASpinLock *__lock );
|
||||
|
||||
inline void CASpinLockLock( volatile CASpinLock *__lock )
|
||||
{
|
||||
#if TARGET_OS_MAC
|
||||
OSSpinLockLock(__lock);
|
||||
#else
|
||||
while (CAAtomicTestAndSetBarrier(0, (void*)__lock))
|
||||
usleep(1000); // ???
|
||||
#endif
|
||||
}
|
||||
|
||||
inline void CASpinLockUnlock( volatile CASpinLock *__lock )
|
||||
{
|
||||
#if TARGET_OS_MAC
|
||||
OSSpinLockUnlock(__lock);
|
||||
#else
|
||||
CAAtomicTestAndClearBarrier(0, (void*)__lock);
|
||||
#endif
|
||||
}
|
||||
|
||||
inline bool CASpinLockTry( volatile CASpinLock *__lock )
|
||||
{
|
||||
#if TARGET_OS_MAC
|
||||
return OSSpinLockTry(__lock);
|
||||
#else
|
||||
return (CAAtomicTestAndSetBarrier(0, (void*)__lock) == 0);
|
||||
#endif
|
||||
}
|
||||
|
||||
|
||||
#endif // __CAAtomic_h__
|
||||
/*
|
||||
File: CAAtomic.h
|
||||
Abstract: Part of CoreAudio Utility Classes
|
||||
Version: 1.1
|
||||
|
||||
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.
|
||||
|
||||
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.
|
||||
|
||||
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.
|
||||
|
||||
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.
|
||||
|
||||
Copyright (C) 2014 Apple Inc. All Rights Reserved.
|
||||
|
||||
*/
|
||||
/*
|
||||
This file implements all Atomic operations using Interlocked functions specified in
|
||||
Winbase.h
|
||||
NOTE: According to Microsoft documentation, all Interlocked functions generates a
|
||||
full barrier.
|
||||
On Windows:
|
||||
As the Interlocked functions returns the Old value, Extra checks and operations
|
||||
are made after the atomic operation to return value consistent with OSX counterparts.
|
||||
*/
|
||||
#ifndef __CAAtomic_h__
|
||||
#define __CAAtomic_h__
|
||||
|
||||
#if TARGET_OS_WIN32
|
||||
#include <windows.h>
|
||||
#include <intrin.h>
|
||||
#pragma intrinsic(_InterlockedOr)
|
||||
#pragma intrinsic(_InterlockedAnd)
|
||||
#else
|
||||
#include <CoreFoundation/CFBase.h>
|
||||
#include <libkern/OSAtomic.h>
|
||||
#endif
|
||||
|
||||
inline void CAMemoryBarrier()
|
||||
{
|
||||
#if TARGET_OS_WIN32
|
||||
MemoryBarrier();
|
||||
#else
|
||||
OSMemoryBarrier();
|
||||
#endif
|
||||
}
|
||||
|
||||
inline SInt32 CAAtomicAdd32Barrier(SInt32 theAmt, volatile SInt32* theValue)
|
||||
{
|
||||
#if TARGET_OS_WIN32
|
||||
long lRetVal = InterlockedExchangeAdd((volatile long*)theValue, theAmt);
|
||||
// InterlockedExchangeAdd returns the original value which differs from OSX version.
|
||||
// At this point the addition would have occured and hence returning the new value
|
||||
// to keep it sync with OSX.
|
||||
return lRetVal + theAmt;
|
||||
#else
|
||||
return OSAtomicAdd32Barrier(theAmt, (volatile int32_t *)theValue);
|
||||
#endif
|
||||
}
|
||||
|
||||
inline SInt32 CAAtomicOr32Barrier(UInt32 theMask, volatile UInt32* theValue)
|
||||
{
|
||||
#if TARGET_OS_WIN32
|
||||
// InterlockedAnd macro is not defined in x86 platform, and hence using the intrinsic
|
||||
// function instead.
|
||||
long j = _InterlockedOr((volatile long*)theValue, theMask);
|
||||
// _InterlockedOr returns the original value which differs from OSX version.
|
||||
// Returning the new value similar to OSX
|
||||
return (SInt32)(j | theMask);
|
||||
#else
|
||||
return OSAtomicOr32Barrier(theMask, (volatile uint32_t *)theValue);
|
||||
#endif
|
||||
}
|
||||
|
||||
inline SInt32 CAAtomicAnd32Barrier(UInt32 theMask, volatile UInt32* theValue)
|
||||
{
|
||||
#if TARGET_OS_WIN32
|
||||
// InterlockedAnd macro is not defined in x86 platform, and hence using the intrinsic
|
||||
// function instead.
|
||||
long j = _InterlockedAnd((volatile long*)theValue, theMask);
|
||||
// _InterlockedAnd returns the original value which differs from OSX version.
|
||||
// Returning the new value similar to OSX
|
||||
return (SInt32)(j & theMask);
|
||||
#else
|
||||
return OSAtomicAnd32Barrier(theMask, (volatile uint32_t *)theValue);
|
||||
#endif
|
||||
}
|
||||
|
||||
inline bool CAAtomicCompareAndSwap32Barrier(SInt32 oldValue, SInt32 newValue, volatile SInt32 *theValue)
|
||||
{
|
||||
#if TARGET_OS_WIN32
|
||||
// InterlockedCompareExchange returns the old value. But we need to return bool value.
|
||||
long lRetVal = InterlockedCompareExchange((volatile long*)theValue, newValue, oldValue);
|
||||
// Hence we check if the new value is set and if it is we return true else false.
|
||||
// If theValue is equal to oldValue then the swap happens. Otherwise swap doesn't happen.
|
||||
return (oldValue == lRetVal);
|
||||
#else
|
||||
return OSAtomicCompareAndSwap32Barrier(oldValue, newValue, (volatile int32_t *)theValue);
|
||||
#endif
|
||||
}
|
||||
|
||||
|
||||
inline SInt32 CAAtomicIncrement32(volatile SInt32* theValue)
|
||||
{
|
||||
#if TARGET_OS_WIN32
|
||||
return (SInt32)InterlockedIncrement((volatile long*)theValue);
|
||||
#else
|
||||
return OSAtomicIncrement32((volatile int32_t *)theValue);
|
||||
#endif
|
||||
}
|
||||
|
||||
inline SInt32 CAAtomicDecrement32(volatile SInt32* theValue)
|
||||
{
|
||||
#if TARGET_OS_WIN32
|
||||
return (SInt32)InterlockedDecrement((volatile long*)theValue);
|
||||
#else
|
||||
return OSAtomicDecrement32((volatile int32_t *)theValue);
|
||||
#endif
|
||||
}
|
||||
|
||||
inline SInt32 CAAtomicIncrement32Barrier(volatile SInt32* theValue)
|
||||
{
|
||||
#if TARGET_OS_WIN32
|
||||
return CAAtomicIncrement32(theValue);
|
||||
#else
|
||||
return OSAtomicIncrement32Barrier((volatile int32_t *)theValue);
|
||||
#endif
|
||||
}
|
||||
|
||||
inline SInt32 CAAtomicDecrement32Barrier(volatile SInt32* theValue)
|
||||
{
|
||||
#if TARGET_OS_WIN32
|
||||
return CAAtomicDecrement32(theValue);
|
||||
#else
|
||||
return OSAtomicDecrement32Barrier((volatile int32_t *)theValue);
|
||||
#endif
|
||||
}
|
||||
|
||||
inline bool CAAtomicTestAndClearBarrier(int bitToClear, void* theAddress)
|
||||
{
|
||||
#if TARGET_OS_WIN32
|
||||
BOOL bOldVal = InterlockedBitTestAndReset((long*)theAddress, bitToClear);
|
||||
return (bOldVal ? true : false);
|
||||
#else
|
||||
return OSAtomicTestAndClearBarrier(bitToClear, (volatile void *)theAddress);
|
||||
#endif
|
||||
}
|
||||
|
||||
inline bool CAAtomicTestAndClear(int bitToClear, void* theAddress)
|
||||
{
|
||||
#if TARGET_OS_WIN32
|
||||
BOOL bOldVal = CAAtomicTestAndClearBarrier(bitToClear, (long*)theAddress);
|
||||
return (bOldVal ? true : false);
|
||||
#else
|
||||
return OSAtomicTestAndClear(bitToClear, (volatile void *)theAddress);
|
||||
#endif
|
||||
}
|
||||
|
||||
inline bool CAAtomicTestAndSetBarrier(int bitToSet, void* theAddress)
|
||||
{
|
||||
#if TARGET_OS_WIN32
|
||||
BOOL bOldVal = InterlockedBitTestAndSet((long*)theAddress, bitToSet);
|
||||
return (bOldVal ? true : false);
|
||||
#else
|
||||
return OSAtomicTestAndSetBarrier(bitToSet, (volatile void *)theAddress);
|
||||
#endif
|
||||
}
|
||||
|
||||
// int32_t flavors -- for C++ only since we can't overload in C
|
||||
// CFBase.h defines SInt32 as signed int which is similar to int32_t. If CFBase.h is included, then
|
||||
// this will generate redefinition error. But on Mac, CFBase.h, still includes MacTypes.h where
|
||||
// SInt32 is defined as signed long so this would work there.
|
||||
// So in order to fix the redefinition errors, we define these functions only if MacTypes.h is included.
|
||||
#if defined(__cplusplus) && defined(__MACTYPES__) && !__LP64__
|
||||
inline int32_t CAAtomicAdd32Barrier(int32_t theAmt, volatile int32_t* theValue)
|
||||
{
|
||||
return CAAtomicAdd32Barrier(theAmt, (volatile SInt32 *)theValue);
|
||||
}
|
||||
|
||||
inline int32_t CAAtomicOr32Barrier(uint32_t theMask, volatile uint32_t* theValue)
|
||||
{
|
||||
return CAAtomicOr32Barrier(theMask, (volatile UInt32 *)theValue);
|
||||
}
|
||||
|
||||
inline int32_t CAAtomicAnd32Barrier(uint32_t theMask, volatile uint32_t* theValue)
|
||||
{
|
||||
return CAAtomicAnd32Barrier(theMask, (volatile UInt32 *)theValue);
|
||||
}
|
||||
|
||||
inline bool CAAtomicCompareAndSwap32Barrier(int32_t oldValue, int32_t newValue, volatile int32_t *theValue)
|
||||
{
|
||||
return CAAtomicCompareAndSwap32Barrier(oldValue, newValue, (volatile SInt32 *)theValue);
|
||||
}
|
||||
|
||||
inline int32_t CAAtomicIncrement32(volatile int32_t* theValue)
|
||||
{
|
||||
return CAAtomicIncrement32((volatile SInt32 *)theValue);
|
||||
}
|
||||
|
||||
inline int32_t CAAtomicDecrement32(volatile int32_t* theValue)
|
||||
{
|
||||
return CAAtomicDecrement32((volatile SInt32 *)theValue);
|
||||
}
|
||||
|
||||
inline int32_t CAAtomicIncrement32Barrier(volatile int32_t* theValue)
|
||||
{
|
||||
return CAAtomicIncrement32Barrier((volatile SInt32 *)theValue);
|
||||
}
|
||||
|
||||
inline int32_t CAAtomicDecrement32Barrier(volatile int32_t* theValue)
|
||||
{
|
||||
return CAAtomicDecrement32Barrier((volatile SInt32 *)theValue);
|
||||
}
|
||||
#endif // __cplusplus && !__LP64__
|
||||
|
||||
#if __LP64__
|
||||
inline bool CAAtomicCompareAndSwap64Barrier( int64_t __oldValue, int64_t __newValue, volatile int64_t *__theValue )
|
||||
{
|
||||
return OSAtomicCompareAndSwap64Barrier(__oldValue, __newValue, __theValue);
|
||||
}
|
||||
#endif
|
||||
|
||||
inline bool CAAtomicCompareAndSwapPtrBarrier(void *__oldValue, void *__newValue, volatile void ** __theValue)
|
||||
{
|
||||
#if __LP64__
|
||||
return CAAtomicCompareAndSwap64Barrier((int64_t)__oldValue, (int64_t)__newValue, (int64_t *)__theValue);
|
||||
#else
|
||||
return CAAtomicCompareAndSwap32Barrier((int32_t)__oldValue, (int32_t)__newValue, (int32_t *)__theValue);
|
||||
#endif
|
||||
}
|
||||
|
||||
/* Spinlocks. These use memory barriers as required to synchronize access to shared
|
||||
* memory protected by the lock. The lock operation spins, but employs various strategies
|
||||
* to back off if the lock is held, making it immune to most priority-inversion livelocks.
|
||||
* The try operation immediately returns false if the lock was held, true if it took the
|
||||
* lock. The convention is that unlocked is zero, locked is nonzero.
|
||||
*/
|
||||
#define CA_SPINLOCK_INIT 0
|
||||
|
||||
typedef int32_t CASpinLock;
|
||||
|
||||
bool CASpinLockTry( volatile CASpinLock *__lock );
|
||||
void CASpinLockLock( volatile CASpinLock *__lock );
|
||||
void CASpinLockUnlock( volatile CASpinLock *__lock );
|
||||
|
||||
inline void CASpinLockLock( volatile CASpinLock *__lock )
|
||||
{
|
||||
#if TARGET_OS_MAC
|
||||
OSSpinLockLock(__lock);
|
||||
#else
|
||||
while (CAAtomicTestAndSetBarrier(0, (void*)__lock))
|
||||
usleep(1000); // ???
|
||||
#endif
|
||||
}
|
||||
|
||||
inline void CASpinLockUnlock( volatile CASpinLock *__lock )
|
||||
{
|
||||
#if TARGET_OS_MAC
|
||||
OSSpinLockUnlock(__lock);
|
||||
#else
|
||||
CAAtomicTestAndClearBarrier(0, (void*)__lock);
|
||||
#endif
|
||||
}
|
||||
|
||||
inline bool CASpinLockTry( volatile CASpinLock *__lock )
|
||||
{
|
||||
#if TARGET_OS_MAC
|
||||
return OSSpinLockTry(__lock);
|
||||
#else
|
||||
return (CAAtomicTestAndSetBarrier(0, (void*)__lock) == 0);
|
||||
#endif
|
||||
}
|
||||
|
||||
|
||||
#endif // __CAAtomic_h__
|
||||
|
||||
@@ -1,239 +1,239 @@
|
||||
/*
|
||||
File: CAAtomicStack.h
|
||||
Abstract: Part of CoreAudio Utility Classes
|
||||
Version: 1.1
|
||||
|
||||
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.
|
||||
|
||||
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.
|
||||
|
||||
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.
|
||||
|
||||
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.
|
||||
|
||||
Copyright (C) 2014 Apple Inc. All Rights Reserved.
|
||||
|
||||
*/
|
||||
#ifndef __CAAtomicStack_h__
|
||||
#define __CAAtomicStack_h__
|
||||
|
||||
#if !defined(__COREAUDIO_USE_FLAT_INCLUDES__)
|
||||
#include <libkern/OSAtomic.h>
|
||||
#else
|
||||
#include <CAAtomic.h>
|
||||
#endif
|
||||
|
||||
#if MAC_OS_X_VERSION_MAX_ALLOWED < MAC_OS_X_VERSION_10_4
|
||||
#include <CoreServices/CoreServices.h>
|
||||
#endif
|
||||
|
||||
// linked list LIFO or FIFO (pop_all_reversed) stack, elements are pushed and popped atomically
|
||||
// class T must implement T *& next().
|
||||
template <class T>
|
||||
class TAtomicStack {
|
||||
public:
|
||||
TAtomicStack() : mHead(NULL) { }
|
||||
|
||||
// non-atomic routines, for use when initializing/deinitializing, operate NON-atomically
|
||||
void push_NA(T *item)
|
||||
{
|
||||
item->next() = mHead;
|
||||
mHead = item;
|
||||
}
|
||||
|
||||
T * pop_NA()
|
||||
{
|
||||
T *result = mHead;
|
||||
if (result)
|
||||
mHead = result->next();
|
||||
return result;
|
||||
}
|
||||
|
||||
bool empty() const { return mHead == NULL; }
|
||||
|
||||
T * head() { return mHead; }
|
||||
|
||||
// atomic routines
|
||||
void push_atomic(T *item)
|
||||
{
|
||||
T *head_;
|
||||
do {
|
||||
head_ = mHead;
|
||||
item->next() = head_;
|
||||
} while (!compare_and_swap(head_, item, &mHead));
|
||||
}
|
||||
|
||||
void push_multiple_atomic(T *item)
|
||||
// pushes entire linked list headed by item
|
||||
{
|
||||
T *head_, *p = item, *tail;
|
||||
// find the last one -- when done, it will be linked to head
|
||||
do {
|
||||
tail = p;
|
||||
p = p->next();
|
||||
} while (p);
|
||||
do {
|
||||
head_ = mHead;
|
||||
tail->next() = head_;
|
||||
} while (!compare_and_swap(head_, item, &mHead));
|
||||
}
|
||||
|
||||
T * pop_atomic_single_reader()
|
||||
// this may only be used when only one thread may potentially pop from the stack.
|
||||
// if multiple threads may pop, this suffers from the ABA problem.
|
||||
// <rdar://problem/4606346> TAtomicStack suffers from the ABA problem
|
||||
{
|
||||
T *result;
|
||||
do {
|
||||
if ((result = mHead) == NULL)
|
||||
break;
|
||||
} while (!compare_and_swap(result, result->next(), &mHead));
|
||||
return result;
|
||||
}
|
||||
|
||||
T * pop_atomic()
|
||||
// This is inefficient for large linked lists.
|
||||
// prefer pop_all() to a series of calls to pop_atomic.
|
||||
// push_multiple_atomic has to traverse the entire list.
|
||||
{
|
||||
T *result = pop_all();
|
||||
if (result) {
|
||||
T *next = result->next();
|
||||
if (next)
|
||||
// push all the remaining items back onto the stack
|
||||
push_multiple_atomic(next);
|
||||
}
|
||||
return result;
|
||||
}
|
||||
|
||||
T * pop_all()
|
||||
{
|
||||
T *result;
|
||||
do {
|
||||
if ((result = mHead) == NULL)
|
||||
break;
|
||||
} while (!compare_and_swap(result, NULL, &mHead));
|
||||
return result;
|
||||
}
|
||||
|
||||
T* pop_all_reversed()
|
||||
{
|
||||
TAtomicStack<T> reversed;
|
||||
T *p = pop_all(), *next;
|
||||
while (p != NULL) {
|
||||
next = p->next();
|
||||
reversed.push_NA(p);
|
||||
p = next;
|
||||
}
|
||||
return reversed.mHead;
|
||||
}
|
||||
|
||||
static bool compare_and_swap(T *oldvalue, T *newvalue, T **pvalue)
|
||||
{
|
||||
#if TARGET_OS_MAC
|
||||
#if __LP64__
|
||||
return ::OSAtomicCompareAndSwap64Barrier(int64_t(oldvalue), int64_t(newvalue), (int64_t *)pvalue);
|
||||
#elif MAC_OS_X_VERSION_MAX_ALLOWED >= MAC_OS_X_VERSION_10_4
|
||||
return ::OSAtomicCompareAndSwap32Barrier(int32_t(oldvalue), int32_t(newvalue), (int32_t *)pvalue);
|
||||
#else
|
||||
return ::CompareAndSwap(UInt32(oldvalue), UInt32(newvalue), (UInt32 *)pvalue);
|
||||
#endif
|
||||
#else
|
||||
//return ::CompareAndSwap(UInt32(oldvalue), UInt32(newvalue), (UInt32 *)pvalue);
|
||||
return CAAtomicCompareAndSwap32Barrier(SInt32(oldvalue), SInt32(newvalue), (SInt32*)pvalue);
|
||||
#endif
|
||||
}
|
||||
|
||||
protected:
|
||||
T * mHead;
|
||||
};
|
||||
|
||||
#if ((MAC_OS_X_VERSION_MAX_ALLOWED >= MAC_OS_X_VERSION_10_5) && !TARGET_OS_WIN32)
|
||||
#include <libkern/OSAtomic.h>
|
||||
|
||||
class CAAtomicStack {
|
||||
public:
|
||||
CAAtomicStack(size_t nextPtrOffset) : mNextPtrOffset(nextPtrOffset) {
|
||||
/*OSQueueHead h = OS_ATOMIC_QUEUE_INIT; mHead = h;*/
|
||||
mHead.opaque1 = 0; mHead.opaque2 = 0;
|
||||
}
|
||||
// a subset of the above
|
||||
void push_atomic(void *p) { OSAtomicEnqueue(&mHead, p, mNextPtrOffset); }
|
||||
void push_NA(void *p) { push_atomic(p); }
|
||||
|
||||
void * pop_atomic() { return OSAtomicDequeue(&mHead, mNextPtrOffset); }
|
||||
void * pop_atomic_single_reader() { return pop_atomic(); }
|
||||
void * pop_NA() { return pop_atomic(); }
|
||||
|
||||
private:
|
||||
OSQueueHead mHead;
|
||||
size_t mNextPtrOffset;
|
||||
};
|
||||
|
||||
// a more efficient subset of TAtomicStack using OSQueue.
|
||||
template <class T>
|
||||
class TAtomicStack2 {
|
||||
public:
|
||||
TAtomicStack2() {
|
||||
/*OSQueueHead h = OS_ATOMIC_QUEUE_INIT; mHead = h;*/
|
||||
mHead.opaque1 = 0; mHead.opaque2 = 0;
|
||||
mNextPtrOffset = -1;
|
||||
}
|
||||
void push_atomic(T *item) {
|
||||
if (mNextPtrOffset < 0) {
|
||||
T **pnext = &item->next(); // hack around offsetof not working with C++
|
||||
mNextPtrOffset = (Byte *)pnext - (Byte *)item;
|
||||
}
|
||||
OSAtomicEnqueue(&mHead, item, mNextPtrOffset);
|
||||
}
|
||||
void push_NA(T *item) { push_atomic(item); }
|
||||
|
||||
T * pop_atomic() { return (T *)OSAtomicDequeue(&mHead, mNextPtrOffset); }
|
||||
T * pop_atomic_single_reader() { return pop_atomic(); }
|
||||
T * pop_NA() { return pop_atomic(); }
|
||||
|
||||
// caution: do not try to implement pop_all_reversed here. the writer could add new elements
|
||||
// while the reader is trying to pop old ones!
|
||||
|
||||
private:
|
||||
OSQueueHead mHead;
|
||||
ssize_t mNextPtrOffset;
|
||||
};
|
||||
|
||||
#else
|
||||
|
||||
#define TAtomicStack2 TAtomicStack
|
||||
|
||||
#endif // MAC_OS_X_VERSION_MAX_ALLOWED && !TARGET_OS_WIN32
|
||||
|
||||
#endif // __CAAtomicStack_h__
|
||||
/*
|
||||
File: CAAtomicStack.h
|
||||
Abstract: Part of CoreAudio Utility Classes
|
||||
Version: 1.1
|
||||
|
||||
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.
|
||||
|
||||
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.
|
||||
|
||||
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.
|
||||
|
||||
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.
|
||||
|
||||
Copyright (C) 2014 Apple Inc. All Rights Reserved.
|
||||
|
||||
*/
|
||||
#ifndef __CAAtomicStack_h__
|
||||
#define __CAAtomicStack_h__
|
||||
|
||||
#if !defined(__COREAUDIO_USE_FLAT_INCLUDES__)
|
||||
#include <libkern/OSAtomic.h>
|
||||
#else
|
||||
#include <CAAtomic.h>
|
||||
#endif
|
||||
|
||||
#if MAC_OS_X_VERSION_MAX_ALLOWED < MAC_OS_X_VERSION_10_4
|
||||
#include <CoreServices/CoreServices.h>
|
||||
#endif
|
||||
|
||||
// linked list LIFO or FIFO (pop_all_reversed) stack, elements are pushed and popped atomically
|
||||
// class T must implement T *& next().
|
||||
template <class T>
|
||||
class TAtomicStack {
|
||||
public:
|
||||
TAtomicStack() : mHead(NULL) { }
|
||||
|
||||
// non-atomic routines, for use when initializing/deinitializing, operate NON-atomically
|
||||
void push_NA(T *item)
|
||||
{
|
||||
item->next() = mHead;
|
||||
mHead = item;
|
||||
}
|
||||
|
||||
T * pop_NA()
|
||||
{
|
||||
T *result = mHead;
|
||||
if (result)
|
||||
mHead = result->next();
|
||||
return result;
|
||||
}
|
||||
|
||||
bool empty() const { return mHead == NULL; }
|
||||
|
||||
T * head() { return mHead; }
|
||||
|
||||
// atomic routines
|
||||
void push_atomic(T *item)
|
||||
{
|
||||
T *head_;
|
||||
do {
|
||||
head_ = mHead;
|
||||
item->next() = head_;
|
||||
} while (!compare_and_swap(head_, item, &mHead));
|
||||
}
|
||||
|
||||
void push_multiple_atomic(T *item)
|
||||
// pushes entire linked list headed by item
|
||||
{
|
||||
T *head_, *p = item, *tail;
|
||||
// find the last one -- when done, it will be linked to head
|
||||
do {
|
||||
tail = p;
|
||||
p = p->next();
|
||||
} while (p);
|
||||
do {
|
||||
head_ = mHead;
|
||||
tail->next() = head_;
|
||||
} while (!compare_and_swap(head_, item, &mHead));
|
||||
}
|
||||
|
||||
T * pop_atomic_single_reader()
|
||||
// this may only be used when only one thread may potentially pop from the stack.
|
||||
// if multiple threads may pop, this suffers from the ABA problem.
|
||||
// <rdar://problem/4606346> TAtomicStack suffers from the ABA problem
|
||||
{
|
||||
T *result;
|
||||
do {
|
||||
if ((result = mHead) == NULL)
|
||||
break;
|
||||
} while (!compare_and_swap(result, result->next(), &mHead));
|
||||
return result;
|
||||
}
|
||||
|
||||
T * pop_atomic()
|
||||
// This is inefficient for large linked lists.
|
||||
// prefer pop_all() to a series of calls to pop_atomic.
|
||||
// push_multiple_atomic has to traverse the entire list.
|
||||
{
|
||||
T *result = pop_all();
|
||||
if (result) {
|
||||
T *next = result->next();
|
||||
if (next)
|
||||
// push all the remaining items back onto the stack
|
||||
push_multiple_atomic(next);
|
||||
}
|
||||
return result;
|
||||
}
|
||||
|
||||
T * pop_all()
|
||||
{
|
||||
T *result;
|
||||
do {
|
||||
if ((result = mHead) == NULL)
|
||||
break;
|
||||
} while (!compare_and_swap(result, NULL, &mHead));
|
||||
return result;
|
||||
}
|
||||
|
||||
T* pop_all_reversed()
|
||||
{
|
||||
TAtomicStack<T> reversed;
|
||||
T *p = pop_all(), *next;
|
||||
while (p != NULL) {
|
||||
next = p->next();
|
||||
reversed.push_NA(p);
|
||||
p = next;
|
||||
}
|
||||
return reversed.mHead;
|
||||
}
|
||||
|
||||
static bool compare_and_swap(T *oldvalue, T *newvalue, T **pvalue)
|
||||
{
|
||||
#if TARGET_OS_MAC
|
||||
#if __LP64__
|
||||
return ::OSAtomicCompareAndSwap64Barrier(int64_t(oldvalue), int64_t(newvalue), (int64_t *)pvalue);
|
||||
#elif MAC_OS_X_VERSION_MAX_ALLOWED >= MAC_OS_X_VERSION_10_4
|
||||
return ::OSAtomicCompareAndSwap32Barrier(int32_t(oldvalue), int32_t(newvalue), (int32_t *)pvalue);
|
||||
#else
|
||||
return ::CompareAndSwap(UInt32(oldvalue), UInt32(newvalue), (UInt32 *)pvalue);
|
||||
#endif
|
||||
#else
|
||||
//return ::CompareAndSwap(UInt32(oldvalue), UInt32(newvalue), (UInt32 *)pvalue);
|
||||
return CAAtomicCompareAndSwap32Barrier(SInt32(oldvalue), SInt32(newvalue), (SInt32*)pvalue);
|
||||
#endif
|
||||
}
|
||||
|
||||
protected:
|
||||
T * mHead;
|
||||
};
|
||||
|
||||
#if ((MAC_OS_X_VERSION_MAX_ALLOWED >= MAC_OS_X_VERSION_10_5) && !TARGET_OS_WIN32)
|
||||
#include <libkern/OSAtomic.h>
|
||||
|
||||
class CAAtomicStack {
|
||||
public:
|
||||
CAAtomicStack(size_t nextPtrOffset) : mNextPtrOffset(nextPtrOffset) {
|
||||
/*OSQueueHead h = OS_ATOMIC_QUEUE_INIT; mHead = h;*/
|
||||
mHead.opaque1 = 0; mHead.opaque2 = 0;
|
||||
}
|
||||
// a subset of the above
|
||||
void push_atomic(void *p) { OSAtomicEnqueue(&mHead, p, mNextPtrOffset); }
|
||||
void push_NA(void *p) { push_atomic(p); }
|
||||
|
||||
void * pop_atomic() { return OSAtomicDequeue(&mHead, mNextPtrOffset); }
|
||||
void * pop_atomic_single_reader() { return pop_atomic(); }
|
||||
void * pop_NA() { return pop_atomic(); }
|
||||
|
||||
private:
|
||||
OSQueueHead mHead;
|
||||
size_t mNextPtrOffset;
|
||||
};
|
||||
|
||||
// a more efficient subset of TAtomicStack using OSQueue.
|
||||
template <class T>
|
||||
class TAtomicStack2 {
|
||||
public:
|
||||
TAtomicStack2() {
|
||||
/*OSQueueHead h = OS_ATOMIC_QUEUE_INIT; mHead = h;*/
|
||||
mHead.opaque1 = 0; mHead.opaque2 = 0;
|
||||
mNextPtrOffset = -1;
|
||||
}
|
||||
void push_atomic(T *item) {
|
||||
if (mNextPtrOffset < 0) {
|
||||
T **pnext = &item->next(); // hack around offsetof not working with C++
|
||||
mNextPtrOffset = (Byte *)pnext - (Byte *)item;
|
||||
}
|
||||
OSAtomicEnqueue(&mHead, item, mNextPtrOffset);
|
||||
}
|
||||
void push_NA(T *item) { push_atomic(item); }
|
||||
|
||||
T * pop_atomic() { return (T *)OSAtomicDequeue(&mHead, mNextPtrOffset); }
|
||||
T * pop_atomic_single_reader() { return pop_atomic(); }
|
||||
T * pop_NA() { return pop_atomic(); }
|
||||
|
||||
// caution: do not try to implement pop_all_reversed here. the writer could add new elements
|
||||
// while the reader is trying to pop old ones!
|
||||
|
||||
private:
|
||||
OSQueueHead mHead;
|
||||
ssize_t mNextPtrOffset;
|
||||
};
|
||||
|
||||
#else
|
||||
|
||||
#define TAtomicStack2 TAtomicStack
|
||||
|
||||
#endif // MAC_OS_X_VERSION_MAX_ALLOWED && !TARGET_OS_WIN32
|
||||
|
||||
#endif // __CAAtomicStack_h__
|
||||
|
||||
@@ -1,153 +1,153 @@
|
||||
/*
|
||||
File: CAAudioChannelLayout.cpp
|
||||
Abstract: CAAudioChannelLayout.h
|
||||
Version: 1.1
|
||||
|
||||
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.
|
||||
|
||||
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.
|
||||
|
||||
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.
|
||||
|
||||
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.
|
||||
|
||||
Copyright (C) 2014 Apple Inc. All Rights Reserved.
|
||||
|
||||
*/
|
||||
//=============================================================================
|
||||
// Includes
|
||||
//=============================================================================
|
||||
|
||||
// Self Include
|
||||
#include "CAAudioChannelLayout.h"
|
||||
#include "CAAutoDisposer.h"
|
||||
#include <stdlib.h>
|
||||
#include <string.h>
|
||||
|
||||
//=============================================================================
|
||||
// CAAudioChannelLayout
|
||||
//=============================================================================
|
||||
|
||||
AudioChannelLayout* CAAudioChannelLayout::Create(UInt32 inNumberChannelDescriptions)
|
||||
{
|
||||
UInt32 theSize = CalculateByteSize(inNumberChannelDescriptions);
|
||||
AudioChannelLayout* theAnswer = static_cast<AudioChannelLayout*>(CA_calloc(1, theSize));
|
||||
if(theAnswer != NULL)
|
||||
{
|
||||
SetAllToUnknown(*theAnswer, inNumberChannelDescriptions);
|
||||
}
|
||||
return theAnswer;
|
||||
}
|
||||
|
||||
void CAAudioChannelLayout::Destroy(AudioChannelLayout* inChannelLayout)
|
||||
{
|
||||
free(inChannelLayout);
|
||||
}
|
||||
|
||||
void CAAudioChannelLayout::SetAllToUnknown(AudioChannelLayout& outChannelLayout, UInt32 inNumberChannelDescriptions)
|
||||
{
|
||||
outChannelLayout.mChannelLayoutTag = kAudioChannelLayoutTag_UseChannelDescriptions;
|
||||
outChannelLayout.mChannelBitmap = 0;
|
||||
outChannelLayout.mNumberChannelDescriptions = inNumberChannelDescriptions;
|
||||
for(UInt32 theChannelIndex = 0; theChannelIndex < inNumberChannelDescriptions; ++theChannelIndex)
|
||||
{
|
||||
outChannelLayout.mChannelDescriptions[theChannelIndex].mChannelLabel = kAudioChannelLabel_Unknown;
|
||||
outChannelLayout.mChannelDescriptions[theChannelIndex].mChannelFlags = 0;
|
||||
outChannelLayout.mChannelDescriptions[theChannelIndex].mCoordinates[0] = 0;
|
||||
outChannelLayout.mChannelDescriptions[theChannelIndex].mCoordinates[1] = 0;
|
||||
outChannelLayout.mChannelDescriptions[theChannelIndex].mCoordinates[2] = 0;
|
||||
}
|
||||
}
|
||||
|
||||
bool operator== (const AudioChannelLayout &x, const AudioChannelLayout &y)
|
||||
{
|
||||
// compare based on the number of channel descriptions present
|
||||
// (this may be too strict a comparison if all you care about are matching layout tags)
|
||||
UInt32 theSize1 = CAAudioChannelLayout::CalculateByteSize(x.mNumberChannelDescriptions);
|
||||
UInt32 theSize2 = CAAudioChannelLayout::CalculateByteSize(y.mNumberChannelDescriptions);
|
||||
|
||||
if (theSize1 != theSize2)
|
||||
return false;
|
||||
|
||||
return !memcmp (&x, &y, theSize1);
|
||||
}
|
||||
|
||||
bool operator!= (const AudioChannelLayout &x, const AudioChannelLayout &y)
|
||||
{
|
||||
return !(x == y);
|
||||
}
|
||||
|
||||
// counting the one bits in a word
|
||||
inline UInt32 CountOnes(UInt32 x)
|
||||
{
|
||||
// secret magic algorithm for counting bits in a word.
|
||||
UInt32 t;
|
||||
x = x - ((x >> 1) & 0x55555555);
|
||||
t = ((x >> 2) & 0x33333333);
|
||||
x = (x & 0x33333333) + t;
|
||||
x = (x + (x >> 4)) & 0x0F0F0F0F;
|
||||
x = x + (x << 8);
|
||||
x = x + (x << 16);
|
||||
return x >> 24;
|
||||
}
|
||||
|
||||
UInt32 CAAudioChannelLayout::NumberChannels (const AudioChannelLayout& inLayout)
|
||||
{
|
||||
if (inLayout.mChannelLayoutTag == kAudioChannelLayoutTag_UseChannelDescriptions)
|
||||
return inLayout.mNumberChannelDescriptions;
|
||||
|
||||
if (inLayout.mChannelLayoutTag == kAudioChannelLayoutTag_UseChannelBitmap)
|
||||
return CountOnes (inLayout.mChannelBitmap);
|
||||
|
||||
return AudioChannelLayoutTag_GetNumberOfChannels(inLayout.mChannelLayoutTag);
|
||||
}
|
||||
|
||||
void CAShowAudioChannelLayout (FILE* file, const AudioChannelLayout *layout)
|
||||
{
|
||||
if (layout == NULL)
|
||||
{
|
||||
fprintf (file, "\tNULL layout\n");
|
||||
return;
|
||||
}
|
||||
fprintf (file, "\tTag=0x%X, ", (int)layout->mChannelLayoutTag);
|
||||
if (layout->mChannelLayoutTag == kAudioChannelLayoutTag_UseChannelBitmap)
|
||||
fprintf (file, "Using Bitmap:0x%X\n", (int)layout->mChannelBitmap);
|
||||
else {
|
||||
fprintf (file, "Num Chan Descs=%d\n", (int)layout->mNumberChannelDescriptions);
|
||||
const AudioChannelDescription *desc = layout->mChannelDescriptions;
|
||||
for (unsigned int i = 0; i < layout->mNumberChannelDescriptions; ++i, ++desc) {
|
||||
fprintf (file, "\t\tLabel=%d, Flags=0x%X, ", (int)desc->mChannelLabel, (int)desc->mChannelFlags);
|
||||
fprintf (file, "[az=%f,el=%f,dist=%f]\n", desc->mCoordinates[0], desc->mCoordinates[1], desc->mCoordinates[2]);
|
||||
}
|
||||
}
|
||||
}
|
||||
/*
|
||||
File: CAAudioChannelLayout.cpp
|
||||
Abstract: CAAudioChannelLayout.h
|
||||
Version: 1.1
|
||||
|
||||
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.
|
||||
|
||||
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.
|
||||
|
||||
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.
|
||||
|
||||
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.
|
||||
|
||||
Copyright (C) 2014 Apple Inc. All Rights Reserved.
|
||||
|
||||
*/
|
||||
//=============================================================================
|
||||
// Includes
|
||||
//=============================================================================
|
||||
|
||||
// Self Include
|
||||
#include "CAAudioChannelLayout.h"
|
||||
#include "CAAutoDisposer.h"
|
||||
#include <stdlib.h>
|
||||
#include <string.h>
|
||||
|
||||
//=============================================================================
|
||||
// CAAudioChannelLayout
|
||||
//=============================================================================
|
||||
|
||||
AudioChannelLayout* CAAudioChannelLayout::Create(UInt32 inNumberChannelDescriptions)
|
||||
{
|
||||
UInt32 theSize = CalculateByteSize(inNumberChannelDescriptions);
|
||||
AudioChannelLayout* theAnswer = static_cast<AudioChannelLayout*>(CA_calloc(1, theSize));
|
||||
if(theAnswer != NULL)
|
||||
{
|
||||
SetAllToUnknown(*theAnswer, inNumberChannelDescriptions);
|
||||
}
|
||||
return theAnswer;
|
||||
}
|
||||
|
||||
void CAAudioChannelLayout::Destroy(AudioChannelLayout* inChannelLayout)
|
||||
{
|
||||
free(inChannelLayout);
|
||||
}
|
||||
|
||||
void CAAudioChannelLayout::SetAllToUnknown(AudioChannelLayout& outChannelLayout, UInt32 inNumberChannelDescriptions)
|
||||
{
|
||||
outChannelLayout.mChannelLayoutTag = kAudioChannelLayoutTag_UseChannelDescriptions;
|
||||
outChannelLayout.mChannelBitmap = 0;
|
||||
outChannelLayout.mNumberChannelDescriptions = inNumberChannelDescriptions;
|
||||
for(UInt32 theChannelIndex = 0; theChannelIndex < inNumberChannelDescriptions; ++theChannelIndex)
|
||||
{
|
||||
outChannelLayout.mChannelDescriptions[theChannelIndex].mChannelLabel = kAudioChannelLabel_Unknown;
|
||||
outChannelLayout.mChannelDescriptions[theChannelIndex].mChannelFlags = 0;
|
||||
outChannelLayout.mChannelDescriptions[theChannelIndex].mCoordinates[0] = 0;
|
||||
outChannelLayout.mChannelDescriptions[theChannelIndex].mCoordinates[1] = 0;
|
||||
outChannelLayout.mChannelDescriptions[theChannelIndex].mCoordinates[2] = 0;
|
||||
}
|
||||
}
|
||||
|
||||
bool operator== (const AudioChannelLayout &x, const AudioChannelLayout &y)
|
||||
{
|
||||
// compare based on the number of channel descriptions present
|
||||
// (this may be too strict a comparison if all you care about are matching layout tags)
|
||||
UInt32 theSize1 = CAAudioChannelLayout::CalculateByteSize(x.mNumberChannelDescriptions);
|
||||
UInt32 theSize2 = CAAudioChannelLayout::CalculateByteSize(y.mNumberChannelDescriptions);
|
||||
|
||||
if (theSize1 != theSize2)
|
||||
return false;
|
||||
|
||||
return !memcmp (&x, &y, theSize1);
|
||||
}
|
||||
|
||||
bool operator!= (const AudioChannelLayout &x, const AudioChannelLayout &y)
|
||||
{
|
||||
return !(x == y);
|
||||
}
|
||||
|
||||
// counting the one bits in a word
|
||||
inline UInt32 CountOnes(UInt32 x)
|
||||
{
|
||||
// secret magic algorithm for counting bits in a word.
|
||||
UInt32 t;
|
||||
x = x - ((x >> 1) & 0x55555555);
|
||||
t = ((x >> 2) & 0x33333333);
|
||||
x = (x & 0x33333333) + t;
|
||||
x = (x + (x >> 4)) & 0x0F0F0F0F;
|
||||
x = x + (x << 8);
|
||||
x = x + (x << 16);
|
||||
return x >> 24;
|
||||
}
|
||||
|
||||
UInt32 CAAudioChannelLayout::NumberChannels (const AudioChannelLayout& inLayout)
|
||||
{
|
||||
if (inLayout.mChannelLayoutTag == kAudioChannelLayoutTag_UseChannelDescriptions)
|
||||
return inLayout.mNumberChannelDescriptions;
|
||||
|
||||
if (inLayout.mChannelLayoutTag == kAudioChannelLayoutTag_UseChannelBitmap)
|
||||
return CountOnes (inLayout.mChannelBitmap);
|
||||
|
||||
return AudioChannelLayoutTag_GetNumberOfChannels(inLayout.mChannelLayoutTag);
|
||||
}
|
||||
|
||||
void CAShowAudioChannelLayout (FILE* file, const AudioChannelLayout *layout)
|
||||
{
|
||||
if (layout == NULL)
|
||||
{
|
||||
fprintf (file, "\tNULL layout\n");
|
||||
return;
|
||||
}
|
||||
fprintf (file, "\tTag=0x%X, ", (int)layout->mChannelLayoutTag);
|
||||
if (layout->mChannelLayoutTag == kAudioChannelLayoutTag_UseChannelBitmap)
|
||||
fprintf (file, "Using Bitmap:0x%X\n", (int)layout->mChannelBitmap);
|
||||
else {
|
||||
fprintf (file, "Num Chan Descs=%d\n", (int)layout->mNumberChannelDescriptions);
|
||||
const AudioChannelDescription *desc = layout->mChannelDescriptions;
|
||||
for (unsigned int i = 0; i < layout->mNumberChannelDescriptions; ++i, ++desc) {
|
||||
fprintf (file, "\t\tLabel=%d, Flags=0x%X, ", (int)desc->mChannelLabel, (int)desc->mChannelFlags);
|
||||
fprintf (file, "[az=%f,el=%f,dist=%f]\n", desc->mCoordinates[0], desc->mCoordinates[1], desc->mCoordinates[2]);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@@ -1,199 +1,199 @@
|
||||
/*
|
||||
File: CAAudioChannelLayout.h
|
||||
Abstract: Part of CoreAudio Utility Classes
|
||||
Version: 1.1
|
||||
|
||||
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.
|
||||
|
||||
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.
|
||||
|
||||
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.
|
||||
|
||||
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.
|
||||
|
||||
Copyright (C) 2014 Apple Inc. All Rights Reserved.
|
||||
|
||||
*/
|
||||
#if !defined(__CAAudioChannelLayout_h__)
|
||||
#define __CAAudioChannelLayout_h__
|
||||
|
||||
//=============================================================================
|
||||
// Includes
|
||||
//=============================================================================
|
||||
|
||||
// System Includes
|
||||
#if !defined(__COREAUDIO_USE_FLAT_INCLUDES__)
|
||||
#include <CoreAudio/CoreAudioTypes.h>
|
||||
#include <CoreFoundation/CoreFoundation.h>
|
||||
#else
|
||||
#include <CoreAudioTypes.h>
|
||||
#include <CoreFoundation.h>
|
||||
#endif
|
||||
#include <stdio.h>
|
||||
#include <stdlib.h>
|
||||
#include <string.h>
|
||||
|
||||
#include "CADebugMacros.h"
|
||||
#include "CAAutoDisposer.h"
|
||||
|
||||
#if !HAL_Build
|
||||
#include "CAReferenceCounted.h"
|
||||
#endif
|
||||
|
||||
//=============================================================================
|
||||
// CAAudioChannelLayout
|
||||
//=============================================================================
|
||||
|
||||
bool operator== (const AudioChannelLayout &x, const AudioChannelLayout &y);
|
||||
bool operator!= (const AudioChannelLayout &x, const AudioChannelLayout &y);
|
||||
|
||||
extern "C" void CAShowAudioChannelLayout (FILE* file, const AudioChannelLayout *layout);
|
||||
|
||||
class CAAudioChannelLayout
|
||||
{
|
||||
// static Construction/Destruction
|
||||
public:
|
||||
static AudioChannelLayout* Create(UInt32 inNumberChannelDescriptions);
|
||||
static void Destroy(AudioChannelLayout* inChannelLayout);
|
||||
static UInt32 CalculateByteSize(UInt32 inNumberChannelDescriptions) {
|
||||
return SizeOf32(AudioChannelLayout) - SizeOf32(AudioChannelDescription) + (inNumberChannelDescriptions * SizeOf32(AudioChannelDescription));
|
||||
}
|
||||
static void SetAllToUnknown(AudioChannelLayout& outChannelLayout, UInt32 inNumberChannelDescriptions);
|
||||
static UInt32 NumberChannels(const AudioChannelLayout& inLayout);
|
||||
|
||||
#if !HAL_Build
|
||||
// object methods
|
||||
public:
|
||||
CAAudioChannelLayout ();
|
||||
|
||||
CAAudioChannelLayout (UInt32 inNumberChannels, bool inChooseSurround);
|
||||
// if inChooseSurround is false, then symmetrical speaker arrangements
|
||||
// are chosen in place of surround layouts if there is a choice
|
||||
// This call chooses layouts based on the expected defaults in
|
||||
// AudioUnit usage
|
||||
CAAudioChannelLayout (AudioChannelLayoutTag inTag);
|
||||
CAAudioChannelLayout (const CAAudioChannelLayout &c);
|
||||
CAAudioChannelLayout (const AudioChannelLayout* inChannelLayout);
|
||||
~CAAudioChannelLayout();
|
||||
|
||||
CAAudioChannelLayout& operator= (const AudioChannelLayout* inChannelLayout);
|
||||
CAAudioChannelLayout& operator= (const CAAudioChannelLayout& c);
|
||||
bool operator== (const CAAudioChannelLayout &c) const;
|
||||
bool operator!= (const CAAudioChannelLayout &c) const;
|
||||
|
||||
void SetWithTag(AudioChannelLayoutTag inTag);
|
||||
|
||||
bool IsValid() const { return NumberChannels() > 0; }
|
||||
UInt32 Size() const { return mLayout ? mLayout->Size() : 0; }
|
||||
|
||||
UInt32 NumberChannels() const { return mLayout ? mLayout->NumberChannels() : 0; }
|
||||
|
||||
AudioChannelLayoutTag Tag() const { return Layout().mChannelLayoutTag; }
|
||||
const AudioChannelLayout& Layout() const { return mLayout->Layout(); }
|
||||
operator const AudioChannelLayout *() const { return &Layout(); }
|
||||
|
||||
void Print () const { Print (stdout); }
|
||||
void Print (FILE* file) const;
|
||||
|
||||
OSStatus Save (CFPropertyListRef *outData) const;
|
||||
OSStatus Restore (CFPropertyListRef &inData);
|
||||
|
||||
private:
|
||||
class RefCountedLayout : public CAReferenceCounted {
|
||||
void * operator new(size_t /* size */, size_t aclSize)
|
||||
{
|
||||
return CA_malloc(sizeof(RefCountedLayout) - sizeof(AudioChannelLayout) + aclSize);
|
||||
}
|
||||
|
||||
void operator delete(void *mem)
|
||||
{
|
||||
free(mem);
|
||||
}
|
||||
|
||||
|
||||
RefCountedLayout(UInt32 inDataSize) :
|
||||
mByteSize(inDataSize)
|
||||
{
|
||||
memset(&mACL, 0, inDataSize);
|
||||
}
|
||||
|
||||
public:
|
||||
static RefCountedLayout *CreateWithNumberChannelDescriptions(unsigned nChannels) {
|
||||
size_t size = CAAudioChannelLayout::CalculateByteSize(nChannels);
|
||||
return new(size) RefCountedLayout((UInt32)size);
|
||||
}
|
||||
|
||||
static RefCountedLayout *CreateWithLayout(const AudioChannelLayout *layout) {
|
||||
size_t size = CAAudioChannelLayout::CalculateByteSize(layout->mNumberChannelDescriptions);
|
||||
RefCountedLayout *acl = new(size) RefCountedLayout((UInt32)size);
|
||||
memcpy(&acl->mACL, layout, size);
|
||||
return acl;
|
||||
}
|
||||
static RefCountedLayout *CreateWithLayoutTag(AudioChannelLayoutTag layoutTag) {
|
||||
RefCountedLayout *acl = CreateWithNumberChannelDescriptions(0);
|
||||
acl->mACL.mChannelLayoutTag = layoutTag;
|
||||
return acl;
|
||||
}
|
||||
|
||||
const AudioChannelLayout & Layout() const { return mACL; }
|
||||
|
||||
UInt32 Size () const { return mByteSize; }
|
||||
|
||||
UInt32 NumberChannels() { return CAAudioChannelLayout::NumberChannels(Layout()); }
|
||||
|
||||
private:
|
||||
const UInt32 mByteSize;
|
||||
AudioChannelLayout mACL;
|
||||
// * * * mACL is variable length and thus must be last * * *
|
||||
|
||||
// only the constructors can change the actual state of the layout
|
||||
friend CAAudioChannelLayout::CAAudioChannelLayout (UInt32 inNumberChannels, bool inChooseSurround);
|
||||
friend OSStatus CAAudioChannelLayout::Restore (CFPropertyListRef &inData);
|
||||
friend CAAudioChannelLayout& CAAudioChannelLayout::operator= (const AudioChannelLayout* inChannelLayout);
|
||||
friend void CAAudioChannelLayout::SetWithTag(AudioChannelLayoutTag inTag);
|
||||
|
||||
AudioChannelLayout * GetLayout() { return &mACL; }
|
||||
|
||||
private:
|
||||
// prohibited methods: private and unimplemented.
|
||||
RefCountedLayout();
|
||||
RefCountedLayout(const RefCountedLayout& c);
|
||||
RefCountedLayout& operator=(const RefCountedLayout& c);
|
||||
};
|
||||
|
||||
RefCountedLayout *mLayout;
|
||||
#endif // HAL_Build
|
||||
|
||||
};
|
||||
|
||||
#endif
|
||||
/*
|
||||
File: CAAudioChannelLayout.h
|
||||
Abstract: Part of CoreAudio Utility Classes
|
||||
Version: 1.1
|
||||
|
||||
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.
|
||||
|
||||
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.
|
||||
|
||||
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.
|
||||
|
||||
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.
|
||||
|
||||
Copyright (C) 2014 Apple Inc. All Rights Reserved.
|
||||
|
||||
*/
|
||||
#if !defined(__CAAudioChannelLayout_h__)
|
||||
#define __CAAudioChannelLayout_h__
|
||||
|
||||
//=============================================================================
|
||||
// Includes
|
||||
//=============================================================================
|
||||
|
||||
// System Includes
|
||||
#if !defined(__COREAUDIO_USE_FLAT_INCLUDES__)
|
||||
#include <CoreAudio/CoreAudioTypes.h>
|
||||
#include <CoreFoundation/CoreFoundation.h>
|
||||
#else
|
||||
#include <CoreAudioTypes.h>
|
||||
#include <CoreFoundation.h>
|
||||
#endif
|
||||
#include <stdio.h>
|
||||
#include <stdlib.h>
|
||||
#include <string.h>
|
||||
|
||||
#include "CADebugMacros.h"
|
||||
#include "CAAutoDisposer.h"
|
||||
|
||||
#if !HAL_Build
|
||||
#include "CAReferenceCounted.h"
|
||||
#endif
|
||||
|
||||
//=============================================================================
|
||||
// CAAudioChannelLayout
|
||||
//=============================================================================
|
||||
|
||||
bool operator== (const AudioChannelLayout &x, const AudioChannelLayout &y);
|
||||
bool operator!= (const AudioChannelLayout &x, const AudioChannelLayout &y);
|
||||
|
||||
extern "C" void CAShowAudioChannelLayout (FILE* file, const AudioChannelLayout *layout);
|
||||
|
||||
class CAAudioChannelLayout
|
||||
{
|
||||
// static Construction/Destruction
|
||||
public:
|
||||
static AudioChannelLayout* Create(UInt32 inNumberChannelDescriptions);
|
||||
static void Destroy(AudioChannelLayout* inChannelLayout);
|
||||
static UInt32 CalculateByteSize(UInt32 inNumberChannelDescriptions) {
|
||||
return SizeOf32(AudioChannelLayout) - SizeOf32(AudioChannelDescription) + (inNumberChannelDescriptions * SizeOf32(AudioChannelDescription));
|
||||
}
|
||||
static void SetAllToUnknown(AudioChannelLayout& outChannelLayout, UInt32 inNumberChannelDescriptions);
|
||||
static UInt32 NumberChannels(const AudioChannelLayout& inLayout);
|
||||
|
||||
#if !HAL_Build
|
||||
// object methods
|
||||
public:
|
||||
CAAudioChannelLayout ();
|
||||
|
||||
CAAudioChannelLayout (UInt32 inNumberChannels, bool inChooseSurround);
|
||||
// if inChooseSurround is false, then symmetrical speaker arrangements
|
||||
// are chosen in place of surround layouts if there is a choice
|
||||
// This call chooses layouts based on the expected defaults in
|
||||
// AudioUnit usage
|
||||
CAAudioChannelLayout (AudioChannelLayoutTag inTag);
|
||||
CAAudioChannelLayout (const CAAudioChannelLayout &c);
|
||||
CAAudioChannelLayout (const AudioChannelLayout* inChannelLayout);
|
||||
~CAAudioChannelLayout();
|
||||
|
||||
CAAudioChannelLayout& operator= (const AudioChannelLayout* inChannelLayout);
|
||||
CAAudioChannelLayout& operator= (const CAAudioChannelLayout& c);
|
||||
bool operator== (const CAAudioChannelLayout &c) const;
|
||||
bool operator!= (const CAAudioChannelLayout &c) const;
|
||||
|
||||
void SetWithTag(AudioChannelLayoutTag inTag);
|
||||
|
||||
bool IsValid() const { return NumberChannels() > 0; }
|
||||
UInt32 Size() const { return mLayout ? mLayout->Size() : 0; }
|
||||
|
||||
UInt32 NumberChannels() const { return mLayout ? mLayout->NumberChannels() : 0; }
|
||||
|
||||
AudioChannelLayoutTag Tag() const { return Layout().mChannelLayoutTag; }
|
||||
const AudioChannelLayout& Layout() const { return mLayout->Layout(); }
|
||||
operator const AudioChannelLayout *() const { return &Layout(); }
|
||||
|
||||
void Print () const { Print (stdout); }
|
||||
void Print (FILE* file) const;
|
||||
|
||||
OSStatus Save (CFPropertyListRef *outData) const;
|
||||
OSStatus Restore (CFPropertyListRef &inData);
|
||||
|
||||
private:
|
||||
class RefCountedLayout : public CAReferenceCounted {
|
||||
void * operator new(size_t /* size */, size_t aclSize)
|
||||
{
|
||||
return CA_malloc(sizeof(RefCountedLayout) - sizeof(AudioChannelLayout) + aclSize);
|
||||
}
|
||||
|
||||
void operator delete(void *mem)
|
||||
{
|
||||
free(mem);
|
||||
}
|
||||
|
||||
|
||||
RefCountedLayout(UInt32 inDataSize) :
|
||||
mByteSize(inDataSize)
|
||||
{
|
||||
memset(&mACL, 0, inDataSize);
|
||||
}
|
||||
|
||||
public:
|
||||
static RefCountedLayout *CreateWithNumberChannelDescriptions(unsigned nChannels) {
|
||||
size_t size = CAAudioChannelLayout::CalculateByteSize(nChannels);
|
||||
return new(size) RefCountedLayout((UInt32)size);
|
||||
}
|
||||
|
||||
static RefCountedLayout *CreateWithLayout(const AudioChannelLayout *layout) {
|
||||
size_t size = CAAudioChannelLayout::CalculateByteSize(layout->mNumberChannelDescriptions);
|
||||
RefCountedLayout *acl = new(size) RefCountedLayout((UInt32)size);
|
||||
memcpy(&acl->mACL, layout, size);
|
||||
return acl;
|
||||
}
|
||||
static RefCountedLayout *CreateWithLayoutTag(AudioChannelLayoutTag layoutTag) {
|
||||
RefCountedLayout *acl = CreateWithNumberChannelDescriptions(0);
|
||||
acl->mACL.mChannelLayoutTag = layoutTag;
|
||||
return acl;
|
||||
}
|
||||
|
||||
const AudioChannelLayout & Layout() const { return mACL; }
|
||||
|
||||
UInt32 Size () const { return mByteSize; }
|
||||
|
||||
UInt32 NumberChannels() { return CAAudioChannelLayout::NumberChannels(Layout()); }
|
||||
|
||||
private:
|
||||
const UInt32 mByteSize;
|
||||
AudioChannelLayout mACL;
|
||||
// * * * mACL is variable length and thus must be last * * *
|
||||
|
||||
// only the constructors can change the actual state of the layout
|
||||
friend CAAudioChannelLayout::CAAudioChannelLayout (UInt32 inNumberChannels, bool inChooseSurround);
|
||||
friend OSStatus CAAudioChannelLayout::Restore (CFPropertyListRef &inData);
|
||||
friend CAAudioChannelLayout& CAAudioChannelLayout::operator= (const AudioChannelLayout* inChannelLayout);
|
||||
friend void CAAudioChannelLayout::SetWithTag(AudioChannelLayoutTag inTag);
|
||||
|
||||
AudioChannelLayout * GetLayout() { return &mACL; }
|
||||
|
||||
private:
|
||||
// prohibited methods: private and unimplemented.
|
||||
RefCountedLayout();
|
||||
RefCountedLayout(const RefCountedLayout& c);
|
||||
RefCountedLayout& operator=(const RefCountedLayout& c);
|
||||
};
|
||||
|
||||
RefCountedLayout *mLayout;
|
||||
#endif // HAL_Build
|
||||
|
||||
};
|
||||
|
||||
#endif
|
||||
|
||||
File diff suppressed because it is too large
Load Diff
File diff suppressed because it is too large
Load Diff
@@ -1,115 +1,115 @@
|
||||
/*
|
||||
File: CADebugPrintf.h
|
||||
Abstract: Part of CoreAudio Utility Classes
|
||||
Version: 1.1
|
||||
|
||||
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.
|
||||
|
||||
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.
|
||||
|
||||
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.
|
||||
|
||||
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.
|
||||
|
||||
Copyright (C) 2014 Apple Inc. All Rights Reserved.
|
||||
|
||||
*/
|
||||
#if !defined(__CADebugPrintf_h__)
|
||||
#define __CADebugPrintf_h__
|
||||
|
||||
//=============================================================================
|
||||
// Includes
|
||||
//=============================================================================
|
||||
|
||||
#if !defined(__COREAUDIO_USE_FLAT_INCLUDES__)
|
||||
#include <CoreAudio/CoreAudioTypes.h>
|
||||
#else
|
||||
#include "CoreAudioTypes.h"
|
||||
#endif
|
||||
|
||||
//=============================================================================
|
||||
// Macros to redirect debugging output to various logging services
|
||||
//=============================================================================
|
||||
|
||||
//#define CoreAudio_UseSysLog 1
|
||||
//#define CoreAudio_UseSideFile "/CoreAudio-%d.txt"
|
||||
|
||||
#if DEBUG || CoreAudio_Debug
|
||||
|
||||
#if TARGET_OS_WIN32
|
||||
#if defined(__cplusplus)
|
||||
extern "C"
|
||||
#endif
|
||||
extern int CAWin32DebugPrintf(char* inFormat, ...);
|
||||
#define DebugPrintfRtn CAWin32DebugPrintf
|
||||
#define DebugPrintfFile
|
||||
#define DebugPrintfLineEnding "\n"
|
||||
#define DebugPrintfFileComma
|
||||
#else
|
||||
#if CoreAudio_UseSysLog
|
||||
#include <sys/syslog.h>
|
||||
#define DebugPrintfRtn syslog
|
||||
#define DebugPrintfFile LOG_NOTICE
|
||||
#define DebugPrintfLineEnding ""
|
||||
#define DebugPrintfFileComma DebugPrintfFile,
|
||||
#elif defined(CoreAudio_UseSideFile)
|
||||
#include <stdio.h>
|
||||
#if defined(__cplusplus)
|
||||
extern "C"
|
||||
#endif
|
||||
void OpenDebugPrintfSideFile();
|
||||
extern FILE* sDebugPrintfSideFile;
|
||||
#define DebugPrintfRtn fprintf
|
||||
#define DebugPrintfFile ((sDebugPrintfSideFile != NULL) ? sDebugPrintfSideFile : stderr)
|
||||
#define DebugPrintfLineEnding "\n"
|
||||
#define DebugPrintfFileComma DebugPrintfFile,
|
||||
#else
|
||||
#include <stdio.h>
|
||||
#define DebugPrintfRtn fprintf
|
||||
#define DebugPrintfFile stderr
|
||||
#define DebugPrintfLineEnding "\n"
|
||||
#define DebugPrintfFileComma DebugPrintfFile,
|
||||
#endif
|
||||
#endif
|
||||
|
||||
#define DebugPrintf(inFormat, ...) DebugPrintfRtn(DebugPrintfFileComma inFormat DebugPrintfLineEnding, ## __VA_ARGS__)
|
||||
#else
|
||||
#define DebugPrintfRtn
|
||||
#define DebugPrintfFile
|
||||
#define DebugPrintfLineEnding
|
||||
#define DebugPrintfFileComma
|
||||
#define DebugPrintf(inFormat, ...)
|
||||
#endif
|
||||
|
||||
|
||||
#endif
|
||||
/*
|
||||
File: CADebugPrintf.h
|
||||
Abstract: Part of CoreAudio Utility Classes
|
||||
Version: 1.1
|
||||
|
||||
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.
|
||||
|
||||
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.
|
||||
|
||||
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.
|
||||
|
||||
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.
|
||||
|
||||
Copyright (C) 2014 Apple Inc. All Rights Reserved.
|
||||
|
||||
*/
|
||||
#if !defined(__CADebugPrintf_h__)
|
||||
#define __CADebugPrintf_h__
|
||||
|
||||
//=============================================================================
|
||||
// Includes
|
||||
//=============================================================================
|
||||
|
||||
#if !defined(__COREAUDIO_USE_FLAT_INCLUDES__)
|
||||
#include <CoreAudio/CoreAudioTypes.h>
|
||||
#else
|
||||
#include "CoreAudioTypes.h"
|
||||
#endif
|
||||
|
||||
//=============================================================================
|
||||
// Macros to redirect debugging output to various logging services
|
||||
//=============================================================================
|
||||
|
||||
//#define CoreAudio_UseSysLog 1
|
||||
//#define CoreAudio_UseSideFile "/CoreAudio-%d.txt"
|
||||
|
||||
#if DEBUG || CoreAudio_Debug
|
||||
|
||||
#if TARGET_OS_WIN32
|
||||
#if defined(__cplusplus)
|
||||
extern "C"
|
||||
#endif
|
||||
extern int CAWin32DebugPrintf(char* inFormat, ...);
|
||||
#define DebugPrintfRtn CAWin32DebugPrintf
|
||||
#define DebugPrintfFile
|
||||
#define DebugPrintfLineEnding "\n"
|
||||
#define DebugPrintfFileComma
|
||||
#else
|
||||
#if CoreAudio_UseSysLog
|
||||
#include <sys/syslog.h>
|
||||
#define DebugPrintfRtn syslog
|
||||
#define DebugPrintfFile LOG_NOTICE
|
||||
#define DebugPrintfLineEnding ""
|
||||
#define DebugPrintfFileComma DebugPrintfFile,
|
||||
#elif defined(CoreAudio_UseSideFile)
|
||||
#include <stdio.h>
|
||||
#if defined(__cplusplus)
|
||||
extern "C"
|
||||
#endif
|
||||
void OpenDebugPrintfSideFile();
|
||||
extern FILE* sDebugPrintfSideFile;
|
||||
#define DebugPrintfRtn fprintf
|
||||
#define DebugPrintfFile ((sDebugPrintfSideFile != NULL) ? sDebugPrintfSideFile : stderr)
|
||||
#define DebugPrintfLineEnding "\n"
|
||||
#define DebugPrintfFileComma DebugPrintfFile,
|
||||
#else
|
||||
#include <stdio.h>
|
||||
#define DebugPrintfRtn fprintf
|
||||
#define DebugPrintfFile stderr
|
||||
#define DebugPrintfLineEnding "\n"
|
||||
#define DebugPrintfFileComma DebugPrintfFile,
|
||||
#endif
|
||||
#endif
|
||||
|
||||
#define DebugPrintf(inFormat, ...) DebugPrintfRtn(DebugPrintfFileComma inFormat DebugPrintfLineEnding, ## __VA_ARGS__)
|
||||
#else
|
||||
#define DebugPrintfRtn
|
||||
#define DebugPrintfFile
|
||||
#define DebugPrintfLineEnding
|
||||
#define DebugPrintfFileComma
|
||||
#define DebugPrintf(inFormat, ...)
|
||||
#endif
|
||||
|
||||
|
||||
#endif
|
||||
|
||||
@@ -1,83 +1,83 @@
|
||||
/*
|
||||
File: CAException.h
|
||||
Abstract: Part of CoreAudio Utility Classes
|
||||
Version: 1.1
|
||||
|
||||
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.
|
||||
|
||||
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.
|
||||
|
||||
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.
|
||||
|
||||
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.
|
||||
|
||||
Copyright (C) 2014 Apple Inc. All Rights Reserved.
|
||||
|
||||
*/
|
||||
#if !defined(__CAException_h__)
|
||||
#define __CAException_h__
|
||||
|
||||
//=============================================================================
|
||||
// Includes
|
||||
//=============================================================================
|
||||
|
||||
#if !defined(__COREAUDIO_USE_FLAT_INCLUDES__)
|
||||
#include <CoreAudio/CoreAudioTypes.h>
|
||||
#else
|
||||
#include "CoreAudioTypes.h"
|
||||
#endif
|
||||
|
||||
//=============================================================================
|
||||
// CAException
|
||||
//=============================================================================
|
||||
|
||||
class CAException
|
||||
{
|
||||
|
||||
public:
|
||||
CAException(OSStatus inError) : mError(inError) {}
|
||||
CAException(const CAException& inException) : mError(inException.mError) {}
|
||||
CAException& operator=(const CAException& inException) { mError = inException.mError; return *this; }
|
||||
~CAException() {}
|
||||
|
||||
OSStatus GetError() const { return mError; }
|
||||
|
||||
protected:
|
||||
OSStatus mError;
|
||||
};
|
||||
|
||||
#define CATry try{
|
||||
#define CACatch } catch(...) {}
|
||||
#define CASwallowException(inExpression) try { inExpression; } catch(...) {}
|
||||
|
||||
#endif
|
||||
/*
|
||||
File: CAException.h
|
||||
Abstract: Part of CoreAudio Utility Classes
|
||||
Version: 1.1
|
||||
|
||||
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.
|
||||
|
||||
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.
|
||||
|
||||
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.
|
||||
|
||||
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.
|
||||
|
||||
Copyright (C) 2014 Apple Inc. All Rights Reserved.
|
||||
|
||||
*/
|
||||
#if !defined(__CAException_h__)
|
||||
#define __CAException_h__
|
||||
|
||||
//=============================================================================
|
||||
// Includes
|
||||
//=============================================================================
|
||||
|
||||
#if !defined(__COREAUDIO_USE_FLAT_INCLUDES__)
|
||||
#include <CoreAudio/CoreAudioTypes.h>
|
||||
#else
|
||||
#include "CoreAudioTypes.h"
|
||||
#endif
|
||||
|
||||
//=============================================================================
|
||||
// CAException
|
||||
//=============================================================================
|
||||
|
||||
class CAException
|
||||
{
|
||||
|
||||
public:
|
||||
CAException(OSStatus inError) : mError(inError) {}
|
||||
CAException(const CAException& inException) : mError(inException.mError) {}
|
||||
CAException& operator=(const CAException& inException) { mError = inException.mError; return *this; }
|
||||
~CAException() {}
|
||||
|
||||
OSStatus GetError() const { return mError; }
|
||||
|
||||
protected:
|
||||
OSStatus mError;
|
||||
};
|
||||
|
||||
#define CATry try{
|
||||
#define CACatch } catch(...) {}
|
||||
#define CASwallowException(inExpression) try { inExpression; } catch(...) {}
|
||||
|
||||
#endif
|
||||
|
||||
@@ -1,234 +1,234 @@
|
||||
/*
|
||||
File: CAHostTimeBase.h
|
||||
Abstract: Part of CoreAudio Utility Classes
|
||||
Version: 1.1
|
||||
|
||||
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.
|
||||
|
||||
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.
|
||||
|
||||
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.
|
||||
|
||||
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.
|
||||
|
||||
Copyright (C) 2014 Apple Inc. All Rights Reserved.
|
||||
|
||||
*/
|
||||
#if !defined(__CAHostTimeBase_h__)
|
||||
#define __CAHostTimeBase_h__
|
||||
|
||||
//=============================================================================
|
||||
// Includes
|
||||
//=============================================================================
|
||||
|
||||
#if !defined(__COREAUDIO_USE_FLAT_INCLUDES__)
|
||||
#include <CoreAudio/CoreAudioTypes.h>
|
||||
#else
|
||||
#include <CoreAudioTypes.h>
|
||||
#endif
|
||||
|
||||
#if TARGET_OS_MAC
|
||||
#include <mach/mach_time.h>
|
||||
#include <pthread.h>
|
||||
#elif TARGET_OS_WIN32
|
||||
#include <windows.h>
|
||||
#include "WinPThreadDefs.h"
|
||||
#else
|
||||
#error Unsupported operating system
|
||||
#endif
|
||||
|
||||
#include "CADebugPrintf.h"
|
||||
|
||||
//=============================================================================
|
||||
// CAHostTimeBase
|
||||
//
|
||||
// This class provides platform independent access to the host's time base.
|
||||
//=============================================================================
|
||||
|
||||
#if CoreAudio_Debug
|
||||
// #define Log_Host_Time_Base_Parameters 1
|
||||
// #define Track_Host_TimeBase 1
|
||||
#endif
|
||||
|
||||
class CAHostTimeBase
|
||||
{
|
||||
|
||||
public:
|
||||
static UInt64 ConvertToNanos(UInt64 inHostTime);
|
||||
static UInt64 ConvertFromNanos(UInt64 inNanos);
|
||||
|
||||
static UInt64 GetTheCurrentTime();
|
||||
#if TARGET_OS_MAC
|
||||
static UInt64 GetCurrentTime() { return GetTheCurrentTime(); }
|
||||
#endif
|
||||
static UInt64 GetCurrentTimeInNanos();
|
||||
|
||||
static Float64 GetFrequency() { pthread_once(&sIsInited, Initialize); return sFrequency; }
|
||||
static Float64 GetInverseFrequency() { pthread_once(&sIsInited, Initialize); return sInverseFrequency; }
|
||||
static UInt32 GetMinimumDelta() { pthread_once(&sIsInited, Initialize); return sMinDelta; }
|
||||
|
||||
static UInt64 AbsoluteHostDeltaToNanos(UInt64 inStartTime, UInt64 inEndTime);
|
||||
static SInt64 HostDeltaToNanos(UInt64 inStartTime, UInt64 inEndTime);
|
||||
|
||||
static UInt64 MultiplyByRatio(UInt64 inMuliplicand, UInt32 inNumerator, UInt32 inDenominator);
|
||||
|
||||
private:
|
||||
static void Initialize();
|
||||
|
||||
static pthread_once_t sIsInited;
|
||||
|
||||
static Float64 sFrequency;
|
||||
static Float64 sInverseFrequency;
|
||||
static UInt32 sMinDelta;
|
||||
static UInt32 sToNanosNumerator;
|
||||
static UInt32 sToNanosDenominator;
|
||||
#if Track_Host_TimeBase
|
||||
static UInt64 sLastTime;
|
||||
#endif
|
||||
};
|
||||
|
||||
inline UInt64 CAHostTimeBase::GetTheCurrentTime()
|
||||
{
|
||||
UInt64 theTime = 0;
|
||||
|
||||
#if TARGET_OS_MAC
|
||||
theTime = mach_absolute_time();
|
||||
#elif TARGET_OS_WIN32
|
||||
LARGE_INTEGER theValue;
|
||||
QueryPerformanceCounter(&theValue);
|
||||
theTime = *((UInt64*)&theValue);
|
||||
#endif
|
||||
|
||||
#if Track_Host_TimeBase
|
||||
if(sLastTime != 0)
|
||||
{
|
||||
if(theTime <= sLastTime)
|
||||
{
|
||||
DebugPrintf("CAHostTimeBase::GetTheCurrentTime: the current time is earlier than the last time, now: %qd, then: %qd", theTime, sLastTime);
|
||||
}
|
||||
sLastTime = theTime;
|
||||
}
|
||||
else
|
||||
{
|
||||
sLastTime = theTime;
|
||||
}
|
||||
#endif
|
||||
|
||||
return theTime;
|
||||
}
|
||||
|
||||
inline UInt64 CAHostTimeBase::ConvertToNanos(UInt64 inHostTime)
|
||||
{
|
||||
pthread_once(&sIsInited, Initialize);
|
||||
|
||||
UInt64 theAnswer = MultiplyByRatio(inHostTime, sToNanosNumerator, sToNanosDenominator);
|
||||
#if CoreAudio_Debug
|
||||
if(((sToNanosNumerator > sToNanosDenominator) && (theAnswer < inHostTime)) || ((sToNanosDenominator > sToNanosNumerator) && (theAnswer > inHostTime)))
|
||||
{
|
||||
DebugPrintf("CAHostTimeBase::ConvertToNanos: The conversion wrapped");
|
||||
}
|
||||
#endif
|
||||
|
||||
return theAnswer;
|
||||
}
|
||||
|
||||
inline UInt64 CAHostTimeBase::ConvertFromNanos(UInt64 inNanos)
|
||||
{
|
||||
pthread_once(&sIsInited, Initialize);
|
||||
|
||||
UInt64 theAnswer = MultiplyByRatio(inNanos, sToNanosDenominator, sToNanosNumerator);
|
||||
#if CoreAudio_Debug
|
||||
if(((sToNanosDenominator > sToNanosNumerator) && (theAnswer < inNanos)) || ((sToNanosNumerator > sToNanosDenominator) && (theAnswer > inNanos)))
|
||||
{
|
||||
DebugPrintf("CAHostTimeBase::ConvertFromNanos: The conversion wrapped");
|
||||
}
|
||||
#endif
|
||||
|
||||
return theAnswer;
|
||||
}
|
||||
|
||||
inline UInt64 CAHostTimeBase::GetCurrentTimeInNanos()
|
||||
{
|
||||
return ConvertToNanos(GetTheCurrentTime());
|
||||
}
|
||||
|
||||
inline UInt64 CAHostTimeBase::AbsoluteHostDeltaToNanos(UInt64 inStartTime, UInt64 inEndTime)
|
||||
{
|
||||
UInt64 theAnswer;
|
||||
|
||||
if(inStartTime <= inEndTime)
|
||||
{
|
||||
theAnswer = inEndTime - inStartTime;
|
||||
}
|
||||
else
|
||||
{
|
||||
theAnswer = inStartTime - inEndTime;
|
||||
}
|
||||
|
||||
return ConvertToNanos(theAnswer);
|
||||
}
|
||||
|
||||
inline SInt64 CAHostTimeBase::HostDeltaToNanos(UInt64 inStartTime, UInt64 inEndTime)
|
||||
{
|
||||
SInt64 theAnswer;
|
||||
SInt64 theSign = 1;
|
||||
|
||||
if(inStartTime <= inEndTime)
|
||||
{
|
||||
theAnswer = static_cast<SInt64>(inEndTime - inStartTime);
|
||||
}
|
||||
else
|
||||
{
|
||||
theAnswer = static_cast<SInt64>(inStartTime - inEndTime);
|
||||
theSign = -1;
|
||||
}
|
||||
|
||||
return theSign * static_cast<SInt64>(ConvertToNanos(static_cast<UInt64>(theAnswer)));
|
||||
}
|
||||
|
||||
inline UInt64 CAHostTimeBase::MultiplyByRatio(UInt64 inMuliplicand, UInt32 inNumerator, UInt32 inDenominator)
|
||||
{
|
||||
#if TARGET_OS_MAC && TARGET_RT_64_BIT
|
||||
__uint128_t theAnswer = inMuliplicand;
|
||||
#else
|
||||
long double theAnswer = inMuliplicand;
|
||||
#endif
|
||||
if(inNumerator != inDenominator)
|
||||
{
|
||||
theAnswer *= inNumerator;
|
||||
theAnswer /= inDenominator;
|
||||
}
|
||||
return static_cast<UInt64>(theAnswer);
|
||||
}
|
||||
|
||||
#endif
|
||||
/*
|
||||
File: CAHostTimeBase.h
|
||||
Abstract: Part of CoreAudio Utility Classes
|
||||
Version: 1.1
|
||||
|
||||
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.
|
||||
|
||||
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.
|
||||
|
||||
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.
|
||||
|
||||
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.
|
||||
|
||||
Copyright (C) 2014 Apple Inc. All Rights Reserved.
|
||||
|
||||
*/
|
||||
#if !defined(__CAHostTimeBase_h__)
|
||||
#define __CAHostTimeBase_h__
|
||||
|
||||
//=============================================================================
|
||||
// Includes
|
||||
//=============================================================================
|
||||
|
||||
#if !defined(__COREAUDIO_USE_FLAT_INCLUDES__)
|
||||
#include <CoreAudio/CoreAudioTypes.h>
|
||||
#else
|
||||
#include <CoreAudioTypes.h>
|
||||
#endif
|
||||
|
||||
#if TARGET_OS_MAC
|
||||
#include <mach/mach_time.h>
|
||||
#include <pthread.h>
|
||||
#elif TARGET_OS_WIN32
|
||||
#include <windows.h>
|
||||
#include "WinPThreadDefs.h"
|
||||
#else
|
||||
#error Unsupported operating system
|
||||
#endif
|
||||
|
||||
#include "CADebugPrintf.h"
|
||||
|
||||
//=============================================================================
|
||||
// CAHostTimeBase
|
||||
//
|
||||
// This class provides platform independent access to the host's time base.
|
||||
//=============================================================================
|
||||
|
||||
#if CoreAudio_Debug
|
||||
// #define Log_Host_Time_Base_Parameters 1
|
||||
// #define Track_Host_TimeBase 1
|
||||
#endif
|
||||
|
||||
class CAHostTimeBase
|
||||
{
|
||||
|
||||
public:
|
||||
static UInt64 ConvertToNanos(UInt64 inHostTime);
|
||||
static UInt64 ConvertFromNanos(UInt64 inNanos);
|
||||
|
||||
static UInt64 GetTheCurrentTime();
|
||||
#if TARGET_OS_MAC
|
||||
static UInt64 GetCurrentTime() { return GetTheCurrentTime(); }
|
||||
#endif
|
||||
static UInt64 GetCurrentTimeInNanos();
|
||||
|
||||
static Float64 GetFrequency() { pthread_once(&sIsInited, Initialize); return sFrequency; }
|
||||
static Float64 GetInverseFrequency() { pthread_once(&sIsInited, Initialize); return sInverseFrequency; }
|
||||
static UInt32 GetMinimumDelta() { pthread_once(&sIsInited, Initialize); return sMinDelta; }
|
||||
|
||||
static UInt64 AbsoluteHostDeltaToNanos(UInt64 inStartTime, UInt64 inEndTime);
|
||||
static SInt64 HostDeltaToNanos(UInt64 inStartTime, UInt64 inEndTime);
|
||||
|
||||
static UInt64 MultiplyByRatio(UInt64 inMuliplicand, UInt32 inNumerator, UInt32 inDenominator);
|
||||
|
||||
private:
|
||||
static void Initialize();
|
||||
|
||||
static pthread_once_t sIsInited;
|
||||
|
||||
static Float64 sFrequency;
|
||||
static Float64 sInverseFrequency;
|
||||
static UInt32 sMinDelta;
|
||||
static UInt32 sToNanosNumerator;
|
||||
static UInt32 sToNanosDenominator;
|
||||
#if Track_Host_TimeBase
|
||||
static UInt64 sLastTime;
|
||||
#endif
|
||||
};
|
||||
|
||||
inline UInt64 CAHostTimeBase::GetTheCurrentTime()
|
||||
{
|
||||
UInt64 theTime = 0;
|
||||
|
||||
#if TARGET_OS_MAC
|
||||
theTime = mach_absolute_time();
|
||||
#elif TARGET_OS_WIN32
|
||||
LARGE_INTEGER theValue;
|
||||
QueryPerformanceCounter(&theValue);
|
||||
theTime = *((UInt64*)&theValue);
|
||||
#endif
|
||||
|
||||
#if Track_Host_TimeBase
|
||||
if(sLastTime != 0)
|
||||
{
|
||||
if(theTime <= sLastTime)
|
||||
{
|
||||
DebugPrintf("CAHostTimeBase::GetTheCurrentTime: the current time is earlier than the last time, now: %qd, then: %qd", theTime, sLastTime);
|
||||
}
|
||||
sLastTime = theTime;
|
||||
}
|
||||
else
|
||||
{
|
||||
sLastTime = theTime;
|
||||
}
|
||||
#endif
|
||||
|
||||
return theTime;
|
||||
}
|
||||
|
||||
inline UInt64 CAHostTimeBase::ConvertToNanos(UInt64 inHostTime)
|
||||
{
|
||||
pthread_once(&sIsInited, Initialize);
|
||||
|
||||
UInt64 theAnswer = MultiplyByRatio(inHostTime, sToNanosNumerator, sToNanosDenominator);
|
||||
#if CoreAudio_Debug
|
||||
if(((sToNanosNumerator > sToNanosDenominator) && (theAnswer < inHostTime)) || ((sToNanosDenominator > sToNanosNumerator) && (theAnswer > inHostTime)))
|
||||
{
|
||||
DebugPrintf("CAHostTimeBase::ConvertToNanos: The conversion wrapped");
|
||||
}
|
||||
#endif
|
||||
|
||||
return theAnswer;
|
||||
}
|
||||
|
||||
inline UInt64 CAHostTimeBase::ConvertFromNanos(UInt64 inNanos)
|
||||
{
|
||||
pthread_once(&sIsInited, Initialize);
|
||||
|
||||
UInt64 theAnswer = MultiplyByRatio(inNanos, sToNanosDenominator, sToNanosNumerator);
|
||||
#if CoreAudio_Debug
|
||||
if(((sToNanosDenominator > sToNanosNumerator) && (theAnswer < inNanos)) || ((sToNanosNumerator > sToNanosDenominator) && (theAnswer > inNanos)))
|
||||
{
|
||||
DebugPrintf("CAHostTimeBase::ConvertFromNanos: The conversion wrapped");
|
||||
}
|
||||
#endif
|
||||
|
||||
return theAnswer;
|
||||
}
|
||||
|
||||
inline UInt64 CAHostTimeBase::GetCurrentTimeInNanos()
|
||||
{
|
||||
return ConvertToNanos(GetTheCurrentTime());
|
||||
}
|
||||
|
||||
inline UInt64 CAHostTimeBase::AbsoluteHostDeltaToNanos(UInt64 inStartTime, UInt64 inEndTime)
|
||||
{
|
||||
UInt64 theAnswer;
|
||||
|
||||
if(inStartTime <= inEndTime)
|
||||
{
|
||||
theAnswer = inEndTime - inStartTime;
|
||||
}
|
||||
else
|
||||
{
|
||||
theAnswer = inStartTime - inEndTime;
|
||||
}
|
||||
|
||||
return ConvertToNanos(theAnswer);
|
||||
}
|
||||
|
||||
inline SInt64 CAHostTimeBase::HostDeltaToNanos(UInt64 inStartTime, UInt64 inEndTime)
|
||||
{
|
||||
SInt64 theAnswer;
|
||||
SInt64 theSign = 1;
|
||||
|
||||
if(inStartTime <= inEndTime)
|
||||
{
|
||||
theAnswer = static_cast<SInt64>(inEndTime - inStartTime);
|
||||
}
|
||||
else
|
||||
{
|
||||
theAnswer = static_cast<SInt64>(inStartTime - inEndTime);
|
||||
theSign = -1;
|
||||
}
|
||||
|
||||
return theSign * static_cast<SInt64>(ConvertToNanos(static_cast<UInt64>(theAnswer)));
|
||||
}
|
||||
|
||||
inline UInt64 CAHostTimeBase::MultiplyByRatio(UInt64 inMuliplicand, UInt32 inNumerator, UInt32 inDenominator)
|
||||
{
|
||||
#if TARGET_OS_MAC && TARGET_RT_64_BIT
|
||||
__uint128_t theAnswer = inMuliplicand;
|
||||
#else
|
||||
long double theAnswer = inMuliplicand;
|
||||
#endif
|
||||
if(inNumerator != inDenominator)
|
||||
{
|
||||
theAnswer *= inNumerator;
|
||||
theAnswer /= inDenominator;
|
||||
}
|
||||
return static_cast<UInt64>(theAnswer);
|
||||
}
|
||||
|
||||
#endif
|
||||
|
||||
@@ -1,68 +1,68 @@
|
||||
/*
|
||||
File: CAMath.h
|
||||
Abstract: Part of CoreAudio Utility Classes
|
||||
Version: 1.1
|
||||
|
||||
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.
|
||||
|
||||
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.
|
||||
|
||||
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.
|
||||
|
||||
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.
|
||||
|
||||
Copyright (C) 2014 Apple Inc. All Rights Reserved.
|
||||
|
||||
*/
|
||||
#ifndef __CAMath_h__
|
||||
#define __CAMath_h__
|
||||
|
||||
#if !defined(__COREAUDIO_USE_FLAT_INCLUDES__)
|
||||
#include <CoreAudio/CoreAudioTypes.h>
|
||||
#else
|
||||
#include <CoreAudioTypes.h>
|
||||
#endif
|
||||
|
||||
inline bool fiszero(Float64 f) { return (f == 0.); }
|
||||
inline bool fiszero(Float32 f) { return (f == 0.f); }
|
||||
|
||||
inline bool fnonzero(Float64 f) { return !fiszero(f); }
|
||||
inline bool fnonzero(Float32 f) { return !fiszero(f); }
|
||||
|
||||
inline bool fequal(const Float64 &a, const Float64 &b) { return a == b; }
|
||||
inline bool fequal(const Float32 &a, const Float32 &b) { return a == b; }
|
||||
|
||||
inline bool fnotequal(const Float64 &a, const Float64 &b) { return !fequal(a, b); }
|
||||
inline bool fnotequal(const Float32 &a, const Float32 &b) { return !fequal(a, b); }
|
||||
|
||||
#endif // __CAMath_h__
|
||||
/*
|
||||
File: CAMath.h
|
||||
Abstract: Part of CoreAudio Utility Classes
|
||||
Version: 1.1
|
||||
|
||||
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.
|
||||
|
||||
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.
|
||||
|
||||
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.
|
||||
|
||||
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.
|
||||
|
||||
Copyright (C) 2014 Apple Inc. All Rights Reserved.
|
||||
|
||||
*/
|
||||
#ifndef __CAMath_h__
|
||||
#define __CAMath_h__
|
||||
|
||||
#if !defined(__COREAUDIO_USE_FLAT_INCLUDES__)
|
||||
#include <CoreAudio/CoreAudioTypes.h>
|
||||
#else
|
||||
#include <CoreAudioTypes.h>
|
||||
#endif
|
||||
|
||||
inline bool fiszero(Float64 f) { return (f == 0.); }
|
||||
inline bool fiszero(Float32 f) { return (f == 0.f); }
|
||||
|
||||
inline bool fnonzero(Float64 f) { return !fiszero(f); }
|
||||
inline bool fnonzero(Float32 f) { return !fiszero(f); }
|
||||
|
||||
inline bool fequal(const Float64 &a, const Float64 &b) { return a == b; }
|
||||
inline bool fequal(const Float32 &a, const Float32 &b) { return a == b; }
|
||||
|
||||
inline bool fnotequal(const Float64 &a, const Float64 &b) { return !fequal(a, b); }
|
||||
inline bool fnotequal(const Float32 &a, const Float32 &b) { return !fequal(a, b); }
|
||||
|
||||
#endif // __CAMath_h__
|
||||
|
||||
@@ -1,345 +1,345 @@
|
||||
/*
|
||||
File: CAMutex.cpp
|
||||
Abstract: CAMutex.h
|
||||
Version: 1.1
|
||||
|
||||
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.
|
||||
|
||||
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.
|
||||
|
||||
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.
|
||||
|
||||
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.
|
||||
|
||||
Copyright (C) 2014 Apple Inc. All Rights Reserved.
|
||||
|
||||
*/
|
||||
//==================================================================================================
|
||||
// Includes
|
||||
//==================================================================================================
|
||||
|
||||
// Self Include
|
||||
#include "CAMutex.h"
|
||||
|
||||
#if TARGET_OS_MAC
|
||||
#include <errno.h>
|
||||
#endif
|
||||
|
||||
// PublicUtility Includes
|
||||
#include "CADebugMacros.h"
|
||||
#include "CAException.h"
|
||||
#include "CAHostTimeBase.h"
|
||||
|
||||
//==================================================================================================
|
||||
// Logging
|
||||
//==================================================================================================
|
||||
|
||||
#if CoreAudio_Debug
|
||||
// #define Log_Ownership 1
|
||||
// #define Log_Errors 1
|
||||
// #define Log_LongLatencies 1
|
||||
// #define LongLatencyThreshholdNS 1000000ULL // nanoseconds
|
||||
#endif
|
||||
|
||||
//==================================================================================================
|
||||
// CAMutex
|
||||
//==================================================================================================
|
||||
|
||||
CAMutex::CAMutex(const char* inName)
|
||||
:
|
||||
mName(inName),
|
||||
mOwner(0)
|
||||
{
|
||||
#if TARGET_OS_MAC
|
||||
OSStatus theError = pthread_mutex_init(&mMutex, NULL);
|
||||
ThrowIf(theError != 0, CAException(theError), "CAMutex::CAMutex: Could not init the mutex");
|
||||
|
||||
#if Log_Ownership
|
||||
DebugPrintfRtn(DebugPrintfFileComma "%p %.4f: CAMutex::CAMutex: creating %s, owner: %p\n", pthread_self(), ((Float64)(CAHostTimeBase::GetCurrentTimeInNanos()) / 1000000.0), mName, mOwner);
|
||||
#endif
|
||||
#elif TARGET_OS_WIN32
|
||||
mMutex = CreateMutex(NULL, false, NULL);
|
||||
ThrowIfNULL(mMutex, CAException(GetLastError()), "CAMutex::CAMutex: could not create the mutex.");
|
||||
|
||||
#if Log_Ownership
|
||||
DebugPrintfRtn(DebugPrintfFileComma "%lu %.4f: CAMutex::CAMutex: creating %s, owner: %lu\n", GetCurrentThreadId(), ((Float64)(CAHostTimeBase::GetCurrentTimeInNanos()) / 1000000.0), mName, mOwner);
|
||||
#endif
|
||||
#endif
|
||||
}
|
||||
|
||||
CAMutex::~CAMutex()
|
||||
{
|
||||
#if TARGET_OS_MAC
|
||||
#if Log_Ownership
|
||||
DebugPrintfRtn(DebugPrintfFileComma "%p %.4f: CAMutex::~CAMutex: destroying %s, owner: %p\n", pthread_self(), ((Float64)(CAHostTimeBase::GetCurrentTimeInNanos()) / 1000000.0), mName, mOwner);
|
||||
#endif
|
||||
pthread_mutex_destroy(&mMutex);
|
||||
#elif TARGET_OS_WIN32
|
||||
#if Log_Ownership
|
||||
DebugPrintfRtn(DebugPrintfFileComma "%lu %.4f: CAMutex::~CAMutex: destroying %s, owner: %lu\n", GetCurrentThreadId(), ((Float64)(CAHostTimeBase::GetCurrentTimeInNanos()) / 1000000.0), mName, mOwner);
|
||||
#endif
|
||||
if(mMutex != NULL)
|
||||
{
|
||||
CloseHandle(mMutex);
|
||||
}
|
||||
#endif
|
||||
}
|
||||
|
||||
bool CAMutex::Lock()
|
||||
{
|
||||
bool theAnswer = false;
|
||||
|
||||
#if TARGET_OS_MAC
|
||||
pthread_t theCurrentThread = pthread_self();
|
||||
if(!pthread_equal(theCurrentThread, mOwner))
|
||||
{
|
||||
#if Log_Ownership
|
||||
DebugPrintfRtn(DebugPrintfFileComma "%p %.4f: CAMutex::Lock: thread %p is locking %s, owner: %p\n", theCurrentThread, ((Float64)(CAHostTimeBase::GetCurrentTimeInNanos()) / 1000000.0), theCurrentThread, mName, mOwner);
|
||||
#endif
|
||||
|
||||
#if Log_LongLatencies
|
||||
UInt64 lockTryTime = CAHostTimeBase::GetCurrentTimeInNanos();
|
||||
#endif
|
||||
|
||||
OSStatus theError = pthread_mutex_lock(&mMutex);
|
||||
ThrowIf(theError != 0, CAException(theError), "CAMutex::Lock: Could not lock the mutex");
|
||||
mOwner = theCurrentThread;
|
||||
theAnswer = true;
|
||||
|
||||
#if Log_LongLatencies
|
||||
UInt64 lockAcquireTime = CAHostTimeBase::GetCurrentTimeInNanos();
|
||||
if (lockAcquireTime - lockTryTime >= LongLatencyThresholdNS)
|
||||
DebugPrintfRtn(DebugPrintfFileComma "Thread %p took %.6fs to acquire the lock %s\n", theCurrentThread, (lockAcquireTime - lockTryTime) * 1.0e-9 /* nanos to seconds */, mName);
|
||||
#endif
|
||||
|
||||
#if Log_Ownership
|
||||
DebugPrintfRtn(DebugPrintfFileComma "%p %.4f: CAMutex::Lock: thread %p has locked %s, owner: %p\n", pthread_self(), ((Float64)(CAHostTimeBase::GetCurrentTimeInNanos()) / 1000000.0), pthread_self(), mName, mOwner);
|
||||
#endif
|
||||
}
|
||||
#elif TARGET_OS_WIN32
|
||||
if(mOwner != GetCurrentThreadId())
|
||||
{
|
||||
#if Log_Ownership
|
||||
DebugPrintfRtn(DebugPrintfFileComma "%lu %.4f: CAMutex::Lock: thread %lu is locking %s, owner: %lu\n", GetCurrentThreadId(), ((Float64)(CAHostTimeBase::GetCurrentTimeInNanos()) / 1000000.0), GetCurrentThreadId(), mName, mOwner);
|
||||
#endif
|
||||
|
||||
OSStatus theError = WaitForSingleObject(mMutex, INFINITE);
|
||||
ThrowIfError(theError, CAException(theError), "CAMutex::Lock: could not lock the mutex");
|
||||
mOwner = GetCurrentThreadId();
|
||||
theAnswer = true;
|
||||
|
||||
#if Log_Ownership
|
||||
DebugPrintfRtn(DebugPrintfFileComma "%lu %.4f: CAMutex::Lock: thread %lu has locked %s, owner: %lu\n", GetCurrentThreadId(), ((Float64)(CAHostTimeBase::GetCurrentTimeInNanos()) / 1000000.0), GetCurrentThreadId(), mName, mOwner);
|
||||
#endif
|
||||
}
|
||||
#endif
|
||||
|
||||
return theAnswer;
|
||||
}
|
||||
|
||||
void CAMutex::Unlock()
|
||||
{
|
||||
#if TARGET_OS_MAC
|
||||
if(pthread_equal(pthread_self(), mOwner))
|
||||
{
|
||||
#if Log_Ownership
|
||||
DebugPrintfRtn(DebugPrintfFileComma "%p %.4f: CAMutex::Unlock: thread %p is unlocking %s, owner: %p\n", pthread_self(), ((Float64)(CAHostTimeBase::GetCurrentTimeInNanos()) / 1000000.0), pthread_self(), mName, mOwner);
|
||||
#endif
|
||||
|
||||
mOwner = 0;
|
||||
OSStatus theError = pthread_mutex_unlock(&mMutex);
|
||||
ThrowIf(theError != 0, CAException(theError), "CAMutex::Unlock: Could not unlock the mutex");
|
||||
|
||||
#if Log_Ownership
|
||||
DebugPrintfRtn(DebugPrintfFileComma "%p %.4f: CAMutex::Unlock: thread %p has unlocked %s, owner: %p\n", pthread_self(), ((Float64)(CAHostTimeBase::GetCurrentTimeInNanos()) / 1000000.0), pthread_self(), mName, mOwner);
|
||||
#endif
|
||||
}
|
||||
else
|
||||
{
|
||||
DebugMessage("CAMutex::Unlock: A thread is attempting to unlock a Mutex it doesn't own");
|
||||
}
|
||||
#elif TARGET_OS_WIN32
|
||||
if(mOwner == GetCurrentThreadId())
|
||||
{
|
||||
#if Log_Ownership
|
||||
DebugPrintfRtn(DebugPrintfFileComma "%lu %.4f: CAMutex::Unlock: thread %lu is unlocking %s, owner: %lu\n", GetCurrentThreadId(), ((Float64)(CAHostTimeBase::GetCurrentTimeInNanos()) / 1000000.0), GetCurrentThreadId(), mName, mOwner);
|
||||
#endif
|
||||
|
||||
mOwner = 0;
|
||||
bool wasReleased = ReleaseMutex(mMutex);
|
||||
ThrowIf(!wasReleased, CAException(GetLastError()), "CAMutex::Unlock: Could not unlock the mutex");
|
||||
|
||||
#if Log_Ownership
|
||||
DebugPrintfRtn(DebugPrintfFileComma "%lu %.4f: CAMutex::Unlock: thread %lu has unlocked %s, owner: %lu\n", GetCurrentThreadId(), ((Float64)(CAHostTimeBase::GetCurrentTimeInNanos()) / 1000000.0), GetCurrentThreadId(), mName, mOwner);
|
||||
#endif
|
||||
}
|
||||
else
|
||||
{
|
||||
DebugMessage("CAMutex::Unlock: A thread is attempting to unlock a Mutex it doesn't own");
|
||||
}
|
||||
#endif
|
||||
}
|
||||
|
||||
bool CAMutex::Try(bool& outWasLocked)
|
||||
{
|
||||
bool theAnswer = false;
|
||||
outWasLocked = false;
|
||||
|
||||
#if TARGET_OS_MAC
|
||||
pthread_t theCurrentThread = pthread_self();
|
||||
if(!pthread_equal(theCurrentThread, mOwner))
|
||||
{
|
||||
// this means the current thread doesn't already own the lock
|
||||
#if Log_Ownership
|
||||
DebugPrintfRtn(DebugPrintfFileComma "%p %.4f: CAMutex::Try: thread %p is try-locking %s, owner: %p\n", theCurrentThread, ((Float64)(CAHostTimeBase::GetCurrentTimeInNanos()) / 1000000.0), theCurrentThread, mName, mOwner);
|
||||
#endif
|
||||
|
||||
// go ahead and call trylock to see if we can lock it.
|
||||
int theError = pthread_mutex_trylock(&mMutex);
|
||||
if(theError == 0)
|
||||
{
|
||||
// return value of 0 means we successfully locked the lock
|
||||
mOwner = theCurrentThread;
|
||||
theAnswer = true;
|
||||
outWasLocked = true;
|
||||
|
||||
#if Log_Ownership
|
||||
DebugPrintfRtn(DebugPrintfFileComma "%p %.4f: CAMutex::Try: thread %p has locked %s, owner: %p\n", theCurrentThread, ((Float64)(CAHostTimeBase::GetCurrentTimeInNanos()) / 1000000.0), theCurrentThread, mName, mOwner);
|
||||
#endif
|
||||
}
|
||||
else if(theError == EBUSY)
|
||||
{
|
||||
// return value of EBUSY means that the lock was already locked by another thread
|
||||
theAnswer = false;
|
||||
outWasLocked = false;
|
||||
|
||||
#if Log_Ownership
|
||||
DebugPrintfRtn(DebugPrintfFileComma "%p %.4f: CAMutex::Try: thread %p failed to lock %s, owner: %p\n", theCurrentThread, ((Float64)(CAHostTimeBase::GetCurrentTimeInNanos()) / 1000000.0), theCurrentThread, mName, mOwner);
|
||||
#endif
|
||||
}
|
||||
else
|
||||
{
|
||||
// any other return value means something really bad happenned
|
||||
ThrowIfError(theError, CAException(theError), "CAMutex::Try: call to pthread_mutex_trylock failed");
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
// this means the current thread already owns the lock
|
||||
theAnswer = true;
|
||||
outWasLocked = false;
|
||||
}
|
||||
#elif TARGET_OS_WIN32
|
||||
if(mOwner != GetCurrentThreadId())
|
||||
{
|
||||
// this means the current thread doesn't own the lock
|
||||
#if Log_Ownership
|
||||
DebugPrintfRtn(DebugPrintfFileComma "%lu %.4f: CAMutex::Try: thread %lu is try-locking %s, owner: %lu\n", GetCurrentThreadId(), ((Float64)(CAHostTimeBase::GetCurrentTimeInNanos()) / 1000000.0), GetCurrentThreadId(), mName, mOwner);
|
||||
#endif
|
||||
|
||||
// try to acquire the mutex
|
||||
OSStatus theError = WaitForSingleObject(mMutex, 0);
|
||||
if(theError == WAIT_OBJECT_0)
|
||||
{
|
||||
// this means we successfully locked the lock
|
||||
mOwner = GetCurrentThreadId();
|
||||
theAnswer = true;
|
||||
outWasLocked = true;
|
||||
|
||||
#if Log_Ownership
|
||||
DebugPrintfRtn(DebugPrintfFileComma "%lu %.4f: CAMutex::Try: thread %lu has locked %s, owner: %lu\n", GetCurrentThreadId(), ((Float64)(CAHostTimeBase::GetCurrentTimeInNanos()) / 1000000.0), GetCurrentThreadId(), mName, mOwner);
|
||||
#endif
|
||||
}
|
||||
else if(theError == WAIT_TIMEOUT)
|
||||
{
|
||||
// this means that the lock was already locked by another thread
|
||||
theAnswer = false;
|
||||
outWasLocked = false;
|
||||
|
||||
#if Log_Ownership
|
||||
DebugPrintfRtn(DebugPrintfFileComma "%lu %.4f: CAMutex::Try: thread %lu failed to lock %s, owner: %lu\n", GetCurrentThreadId(), ((Float64)(CAHostTimeBase::GetCurrentTimeInNanos()) / 1000000.0), GetCurrentThreadId(), mName, mOwner);
|
||||
#endif
|
||||
}
|
||||
else
|
||||
{
|
||||
// any other return value means something really bad happenned
|
||||
ThrowIfError(theError, CAException(GetLastError()), "CAMutex::Try: call to lock the mutex failed");
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
// this means the current thread already owns the lock
|
||||
theAnswer = true;
|
||||
outWasLocked = false;
|
||||
}
|
||||
#endif
|
||||
|
||||
return theAnswer;
|
||||
}
|
||||
|
||||
bool CAMutex::IsFree() const
|
||||
{
|
||||
return mOwner == 0;
|
||||
}
|
||||
|
||||
bool CAMutex::IsOwnedByCurrentThread() const
|
||||
{
|
||||
bool theAnswer = true;
|
||||
|
||||
#if TARGET_OS_MAC
|
||||
theAnswer = pthread_equal(pthread_self(), mOwner);
|
||||
#elif TARGET_OS_WIN32
|
||||
theAnswer = (mOwner == GetCurrentThreadId());
|
||||
#endif
|
||||
|
||||
return theAnswer;
|
||||
}
|
||||
|
||||
|
||||
CAMutex::Unlocker::Unlocker(CAMutex& inMutex)
|
||||
: mMutex(inMutex),
|
||||
mNeedsLock(false)
|
||||
{
|
||||
Assert(mMutex.IsOwnedByCurrentThread(), "Major problem: Unlocker attempted to unlock a mutex not owned by the current thread!");
|
||||
|
||||
mMutex.Unlock();
|
||||
mNeedsLock = true;
|
||||
}
|
||||
|
||||
CAMutex::Unlocker::~Unlocker()
|
||||
{
|
||||
if(mNeedsLock)
|
||||
{
|
||||
mMutex.Lock();
|
||||
}
|
||||
}
|
||||
/*
|
||||
File: CAMutex.cpp
|
||||
Abstract: CAMutex.h
|
||||
Version: 1.1
|
||||
|
||||
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.
|
||||
|
||||
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.
|
||||
|
||||
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.
|
||||
|
||||
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.
|
||||
|
||||
Copyright (C) 2014 Apple Inc. All Rights Reserved.
|
||||
|
||||
*/
|
||||
//==================================================================================================
|
||||
// Includes
|
||||
//==================================================================================================
|
||||
|
||||
// Self Include
|
||||
#include "CAMutex.h"
|
||||
|
||||
#if TARGET_OS_MAC
|
||||
#include <errno.h>
|
||||
#endif
|
||||
|
||||
// PublicUtility Includes
|
||||
#include "CADebugMacros.h"
|
||||
#include "CAException.h"
|
||||
#include "CAHostTimeBase.h"
|
||||
|
||||
//==================================================================================================
|
||||
// Logging
|
||||
//==================================================================================================
|
||||
|
||||
#if CoreAudio_Debug
|
||||
// #define Log_Ownership 1
|
||||
// #define Log_Errors 1
|
||||
// #define Log_LongLatencies 1
|
||||
// #define LongLatencyThreshholdNS 1000000ULL // nanoseconds
|
||||
#endif
|
||||
|
||||
//==================================================================================================
|
||||
// CAMutex
|
||||
//==================================================================================================
|
||||
|
||||
CAMutex::CAMutex(const char* inName)
|
||||
:
|
||||
mName(inName),
|
||||
mOwner(0)
|
||||
{
|
||||
#if TARGET_OS_MAC
|
||||
OSStatus theError = pthread_mutex_init(&mMutex, NULL);
|
||||
ThrowIf(theError != 0, CAException(theError), "CAMutex::CAMutex: Could not init the mutex");
|
||||
|
||||
#if Log_Ownership
|
||||
DebugPrintfRtn(DebugPrintfFileComma "%p %.4f: CAMutex::CAMutex: creating %s, owner: %p\n", pthread_self(), ((Float64)(CAHostTimeBase::GetCurrentTimeInNanos()) / 1000000.0), mName, mOwner);
|
||||
#endif
|
||||
#elif TARGET_OS_WIN32
|
||||
mMutex = CreateMutex(NULL, false, NULL);
|
||||
ThrowIfNULL(mMutex, CAException(GetLastError()), "CAMutex::CAMutex: could not create the mutex.");
|
||||
|
||||
#if Log_Ownership
|
||||
DebugPrintfRtn(DebugPrintfFileComma "%lu %.4f: CAMutex::CAMutex: creating %s, owner: %lu\n", GetCurrentThreadId(), ((Float64)(CAHostTimeBase::GetCurrentTimeInNanos()) / 1000000.0), mName, mOwner);
|
||||
#endif
|
||||
#endif
|
||||
}
|
||||
|
||||
CAMutex::~CAMutex()
|
||||
{
|
||||
#if TARGET_OS_MAC
|
||||
#if Log_Ownership
|
||||
DebugPrintfRtn(DebugPrintfFileComma "%p %.4f: CAMutex::~CAMutex: destroying %s, owner: %p\n", pthread_self(), ((Float64)(CAHostTimeBase::GetCurrentTimeInNanos()) / 1000000.0), mName, mOwner);
|
||||
#endif
|
||||
pthread_mutex_destroy(&mMutex);
|
||||
#elif TARGET_OS_WIN32
|
||||
#if Log_Ownership
|
||||
DebugPrintfRtn(DebugPrintfFileComma "%lu %.4f: CAMutex::~CAMutex: destroying %s, owner: %lu\n", GetCurrentThreadId(), ((Float64)(CAHostTimeBase::GetCurrentTimeInNanos()) / 1000000.0), mName, mOwner);
|
||||
#endif
|
||||
if(mMutex != NULL)
|
||||
{
|
||||
CloseHandle(mMutex);
|
||||
}
|
||||
#endif
|
||||
}
|
||||
|
||||
bool CAMutex::Lock()
|
||||
{
|
||||
bool theAnswer = false;
|
||||
|
||||
#if TARGET_OS_MAC
|
||||
pthread_t theCurrentThread = pthread_self();
|
||||
if(!pthread_equal(theCurrentThread, mOwner))
|
||||
{
|
||||
#if Log_Ownership
|
||||
DebugPrintfRtn(DebugPrintfFileComma "%p %.4f: CAMutex::Lock: thread %p is locking %s, owner: %p\n", theCurrentThread, ((Float64)(CAHostTimeBase::GetCurrentTimeInNanos()) / 1000000.0), theCurrentThread, mName, mOwner);
|
||||
#endif
|
||||
|
||||
#if Log_LongLatencies
|
||||
UInt64 lockTryTime = CAHostTimeBase::GetCurrentTimeInNanos();
|
||||
#endif
|
||||
|
||||
OSStatus theError = pthread_mutex_lock(&mMutex);
|
||||
ThrowIf(theError != 0, CAException(theError), "CAMutex::Lock: Could not lock the mutex");
|
||||
mOwner = theCurrentThread;
|
||||
theAnswer = true;
|
||||
|
||||
#if Log_LongLatencies
|
||||
UInt64 lockAcquireTime = CAHostTimeBase::GetCurrentTimeInNanos();
|
||||
if (lockAcquireTime - lockTryTime >= LongLatencyThresholdNS)
|
||||
DebugPrintfRtn(DebugPrintfFileComma "Thread %p took %.6fs to acquire the lock %s\n", theCurrentThread, (lockAcquireTime - lockTryTime) * 1.0e-9 /* nanos to seconds */, mName);
|
||||
#endif
|
||||
|
||||
#if Log_Ownership
|
||||
DebugPrintfRtn(DebugPrintfFileComma "%p %.4f: CAMutex::Lock: thread %p has locked %s, owner: %p\n", pthread_self(), ((Float64)(CAHostTimeBase::GetCurrentTimeInNanos()) / 1000000.0), pthread_self(), mName, mOwner);
|
||||
#endif
|
||||
}
|
||||
#elif TARGET_OS_WIN32
|
||||
if(mOwner != GetCurrentThreadId())
|
||||
{
|
||||
#if Log_Ownership
|
||||
DebugPrintfRtn(DebugPrintfFileComma "%lu %.4f: CAMutex::Lock: thread %lu is locking %s, owner: %lu\n", GetCurrentThreadId(), ((Float64)(CAHostTimeBase::GetCurrentTimeInNanos()) / 1000000.0), GetCurrentThreadId(), mName, mOwner);
|
||||
#endif
|
||||
|
||||
OSStatus theError = WaitForSingleObject(mMutex, INFINITE);
|
||||
ThrowIfError(theError, CAException(theError), "CAMutex::Lock: could not lock the mutex");
|
||||
mOwner = GetCurrentThreadId();
|
||||
theAnswer = true;
|
||||
|
||||
#if Log_Ownership
|
||||
DebugPrintfRtn(DebugPrintfFileComma "%lu %.4f: CAMutex::Lock: thread %lu has locked %s, owner: %lu\n", GetCurrentThreadId(), ((Float64)(CAHostTimeBase::GetCurrentTimeInNanos()) / 1000000.0), GetCurrentThreadId(), mName, mOwner);
|
||||
#endif
|
||||
}
|
||||
#endif
|
||||
|
||||
return theAnswer;
|
||||
}
|
||||
|
||||
void CAMutex::Unlock()
|
||||
{
|
||||
#if TARGET_OS_MAC
|
||||
if(pthread_equal(pthread_self(), mOwner))
|
||||
{
|
||||
#if Log_Ownership
|
||||
DebugPrintfRtn(DebugPrintfFileComma "%p %.4f: CAMutex::Unlock: thread %p is unlocking %s, owner: %p\n", pthread_self(), ((Float64)(CAHostTimeBase::GetCurrentTimeInNanos()) / 1000000.0), pthread_self(), mName, mOwner);
|
||||
#endif
|
||||
|
||||
mOwner = 0;
|
||||
OSStatus theError = pthread_mutex_unlock(&mMutex);
|
||||
ThrowIf(theError != 0, CAException(theError), "CAMutex::Unlock: Could not unlock the mutex");
|
||||
|
||||
#if Log_Ownership
|
||||
DebugPrintfRtn(DebugPrintfFileComma "%p %.4f: CAMutex::Unlock: thread %p has unlocked %s, owner: %p\n", pthread_self(), ((Float64)(CAHostTimeBase::GetCurrentTimeInNanos()) / 1000000.0), pthread_self(), mName, mOwner);
|
||||
#endif
|
||||
}
|
||||
else
|
||||
{
|
||||
DebugMessage("CAMutex::Unlock: A thread is attempting to unlock a Mutex it doesn't own");
|
||||
}
|
||||
#elif TARGET_OS_WIN32
|
||||
if(mOwner == GetCurrentThreadId())
|
||||
{
|
||||
#if Log_Ownership
|
||||
DebugPrintfRtn(DebugPrintfFileComma "%lu %.4f: CAMutex::Unlock: thread %lu is unlocking %s, owner: %lu\n", GetCurrentThreadId(), ((Float64)(CAHostTimeBase::GetCurrentTimeInNanos()) / 1000000.0), GetCurrentThreadId(), mName, mOwner);
|
||||
#endif
|
||||
|
||||
mOwner = 0;
|
||||
bool wasReleased = ReleaseMutex(mMutex);
|
||||
ThrowIf(!wasReleased, CAException(GetLastError()), "CAMutex::Unlock: Could not unlock the mutex");
|
||||
|
||||
#if Log_Ownership
|
||||
DebugPrintfRtn(DebugPrintfFileComma "%lu %.4f: CAMutex::Unlock: thread %lu has unlocked %s, owner: %lu\n", GetCurrentThreadId(), ((Float64)(CAHostTimeBase::GetCurrentTimeInNanos()) / 1000000.0), GetCurrentThreadId(), mName, mOwner);
|
||||
#endif
|
||||
}
|
||||
else
|
||||
{
|
||||
DebugMessage("CAMutex::Unlock: A thread is attempting to unlock a Mutex it doesn't own");
|
||||
}
|
||||
#endif
|
||||
}
|
||||
|
||||
bool CAMutex::Try(bool& outWasLocked)
|
||||
{
|
||||
bool theAnswer = false;
|
||||
outWasLocked = false;
|
||||
|
||||
#if TARGET_OS_MAC
|
||||
pthread_t theCurrentThread = pthread_self();
|
||||
if(!pthread_equal(theCurrentThread, mOwner))
|
||||
{
|
||||
// this means the current thread doesn't already own the lock
|
||||
#if Log_Ownership
|
||||
DebugPrintfRtn(DebugPrintfFileComma "%p %.4f: CAMutex::Try: thread %p is try-locking %s, owner: %p\n", theCurrentThread, ((Float64)(CAHostTimeBase::GetCurrentTimeInNanos()) / 1000000.0), theCurrentThread, mName, mOwner);
|
||||
#endif
|
||||
|
||||
// go ahead and call trylock to see if we can lock it.
|
||||
int theError = pthread_mutex_trylock(&mMutex);
|
||||
if(theError == 0)
|
||||
{
|
||||
// return value of 0 means we successfully locked the lock
|
||||
mOwner = theCurrentThread;
|
||||
theAnswer = true;
|
||||
outWasLocked = true;
|
||||
|
||||
#if Log_Ownership
|
||||
DebugPrintfRtn(DebugPrintfFileComma "%p %.4f: CAMutex::Try: thread %p has locked %s, owner: %p\n", theCurrentThread, ((Float64)(CAHostTimeBase::GetCurrentTimeInNanos()) / 1000000.0), theCurrentThread, mName, mOwner);
|
||||
#endif
|
||||
}
|
||||
else if(theError == EBUSY)
|
||||
{
|
||||
// return value of EBUSY means that the lock was already locked by another thread
|
||||
theAnswer = false;
|
||||
outWasLocked = false;
|
||||
|
||||
#if Log_Ownership
|
||||
DebugPrintfRtn(DebugPrintfFileComma "%p %.4f: CAMutex::Try: thread %p failed to lock %s, owner: %p\n", theCurrentThread, ((Float64)(CAHostTimeBase::GetCurrentTimeInNanos()) / 1000000.0), theCurrentThread, mName, mOwner);
|
||||
#endif
|
||||
}
|
||||
else
|
||||
{
|
||||
// any other return value means something really bad happenned
|
||||
ThrowIfError(theError, CAException(theError), "CAMutex::Try: call to pthread_mutex_trylock failed");
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
// this means the current thread already owns the lock
|
||||
theAnswer = true;
|
||||
outWasLocked = false;
|
||||
}
|
||||
#elif TARGET_OS_WIN32
|
||||
if(mOwner != GetCurrentThreadId())
|
||||
{
|
||||
// this means the current thread doesn't own the lock
|
||||
#if Log_Ownership
|
||||
DebugPrintfRtn(DebugPrintfFileComma "%lu %.4f: CAMutex::Try: thread %lu is try-locking %s, owner: %lu\n", GetCurrentThreadId(), ((Float64)(CAHostTimeBase::GetCurrentTimeInNanos()) / 1000000.0), GetCurrentThreadId(), mName, mOwner);
|
||||
#endif
|
||||
|
||||
// try to acquire the mutex
|
||||
OSStatus theError = WaitForSingleObject(mMutex, 0);
|
||||
if(theError == WAIT_OBJECT_0)
|
||||
{
|
||||
// this means we successfully locked the lock
|
||||
mOwner = GetCurrentThreadId();
|
||||
theAnswer = true;
|
||||
outWasLocked = true;
|
||||
|
||||
#if Log_Ownership
|
||||
DebugPrintfRtn(DebugPrintfFileComma "%lu %.4f: CAMutex::Try: thread %lu has locked %s, owner: %lu\n", GetCurrentThreadId(), ((Float64)(CAHostTimeBase::GetCurrentTimeInNanos()) / 1000000.0), GetCurrentThreadId(), mName, mOwner);
|
||||
#endif
|
||||
}
|
||||
else if(theError == WAIT_TIMEOUT)
|
||||
{
|
||||
// this means that the lock was already locked by another thread
|
||||
theAnswer = false;
|
||||
outWasLocked = false;
|
||||
|
||||
#if Log_Ownership
|
||||
DebugPrintfRtn(DebugPrintfFileComma "%lu %.4f: CAMutex::Try: thread %lu failed to lock %s, owner: %lu\n", GetCurrentThreadId(), ((Float64)(CAHostTimeBase::GetCurrentTimeInNanos()) / 1000000.0), GetCurrentThreadId(), mName, mOwner);
|
||||
#endif
|
||||
}
|
||||
else
|
||||
{
|
||||
// any other return value means something really bad happenned
|
||||
ThrowIfError(theError, CAException(GetLastError()), "CAMutex::Try: call to lock the mutex failed");
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
// this means the current thread already owns the lock
|
||||
theAnswer = true;
|
||||
outWasLocked = false;
|
||||
}
|
||||
#endif
|
||||
|
||||
return theAnswer;
|
||||
}
|
||||
|
||||
bool CAMutex::IsFree() const
|
||||
{
|
||||
return mOwner == 0;
|
||||
}
|
||||
|
||||
bool CAMutex::IsOwnedByCurrentThread() const
|
||||
{
|
||||
bool theAnswer = true;
|
||||
|
||||
#if TARGET_OS_MAC
|
||||
theAnswer = pthread_equal(pthread_self(), mOwner);
|
||||
#elif TARGET_OS_WIN32
|
||||
theAnswer = (mOwner == GetCurrentThreadId());
|
||||
#endif
|
||||
|
||||
return theAnswer;
|
||||
}
|
||||
|
||||
|
||||
CAMutex::Unlocker::Unlocker(CAMutex& inMutex)
|
||||
: mMutex(inMutex),
|
||||
mNeedsLock(false)
|
||||
{
|
||||
Assert(mMutex.IsOwnedByCurrentThread(), "Major problem: Unlocker attempted to unlock a mutex not owned by the current thread!");
|
||||
|
||||
mMutex.Unlock();
|
||||
mNeedsLock = true;
|
||||
}
|
||||
|
||||
CAMutex::Unlocker::~Unlocker()
|
||||
{
|
||||
if(mNeedsLock)
|
||||
{
|
||||
mMutex.Lock();
|
||||
}
|
||||
}
|
||||
|
||||
@@ -1,163 +1,163 @@
|
||||
/*
|
||||
File: CAMutex.h
|
||||
Abstract: Part of CoreAudio Utility Classes
|
||||
Version: 1.1
|
||||
|
||||
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.
|
||||
|
||||
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.
|
||||
|
||||
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.
|
||||
|
||||
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.
|
||||
|
||||
Copyright (C) 2014 Apple Inc. All Rights Reserved.
|
||||
|
||||
*/
|
||||
#ifndef __CAMutex_h__
|
||||
#define __CAMutex_h__
|
||||
|
||||
//==================================================================================================
|
||||
// Includes
|
||||
//==================================================================================================
|
||||
|
||||
// System Includes
|
||||
#if !defined(__COREAUDIO_USE_FLAT_INCLUDES__)
|
||||
#include <CoreAudio/CoreAudioTypes.h>
|
||||
#else
|
||||
#include <CoreAudioTypes.h>
|
||||
#endif
|
||||
|
||||
#if TARGET_OS_MAC
|
||||
#include <pthread.h>
|
||||
#elif TARGET_OS_WIN32
|
||||
#include <windows.h>
|
||||
#else
|
||||
#error Unsupported operating system
|
||||
#endif
|
||||
|
||||
//==================================================================================================
|
||||
// A recursive mutex.
|
||||
//==================================================================================================
|
||||
|
||||
class CAMutex
|
||||
{
|
||||
// Construction/Destruction
|
||||
public:
|
||||
CAMutex(const char* inName);
|
||||
virtual ~CAMutex();
|
||||
|
||||
// Actions
|
||||
public:
|
||||
virtual bool Lock();
|
||||
virtual void Unlock();
|
||||
virtual bool Try(bool& outWasLocked); // returns true if lock is free, false if not
|
||||
|
||||
virtual bool IsFree() const;
|
||||
virtual bool IsOwnedByCurrentThread() const;
|
||||
|
||||
// Implementation
|
||||
protected:
|
||||
const char* mName;
|
||||
#if TARGET_OS_MAC
|
||||
pthread_t mOwner;
|
||||
pthread_mutex_t mMutex;
|
||||
#elif TARGET_OS_WIN32
|
||||
UInt32 mOwner;
|
||||
HANDLE mMutex;
|
||||
#endif
|
||||
|
||||
// Helper class to manage taking and releasing recursively
|
||||
public:
|
||||
class Locker
|
||||
{
|
||||
|
||||
// Construction/Destruction
|
||||
public:
|
||||
Locker(CAMutex& inMutex) : mMutex(&inMutex), mNeedsRelease(false) { mNeedsRelease = mMutex->Lock(); }
|
||||
Locker(CAMutex* inMutex) : mMutex(inMutex), mNeedsRelease(false) { mNeedsRelease = (mMutex != NULL && mMutex->Lock()); }
|
||||
// in this case the mutex can be null
|
||||
~Locker() { if(mNeedsRelease) { mMutex->Unlock(); } }
|
||||
|
||||
|
||||
private:
|
||||
Locker(const Locker&);
|
||||
Locker& operator=(const Locker&);
|
||||
|
||||
// Implementation
|
||||
private:
|
||||
CAMutex* mMutex;
|
||||
bool mNeedsRelease;
|
||||
|
||||
};
|
||||
|
||||
// Unlocker
|
||||
class Unlocker
|
||||
{
|
||||
public:
|
||||
Unlocker(CAMutex& inMutex);
|
||||
~Unlocker();
|
||||
|
||||
private:
|
||||
CAMutex& mMutex;
|
||||
bool mNeedsLock;
|
||||
|
||||
// Hidden definitions of copy ctor, assignment operator
|
||||
Unlocker(const Unlocker& copy); // Not implemented
|
||||
Unlocker& operator=(const Unlocker& copy); // Not implemented
|
||||
};
|
||||
|
||||
// you can use this with Try - if you take the lock in try, pass in the outWasLocked var
|
||||
class Tryer {
|
||||
|
||||
// Construction/Destruction
|
||||
public:
|
||||
Tryer (CAMutex &mutex) : mMutex(mutex), mNeedsRelease(false), mHasLock(false) { mHasLock = mMutex.Try (mNeedsRelease); }
|
||||
~Tryer () { if (mNeedsRelease) mMutex.Unlock(); }
|
||||
|
||||
bool HasLock () const { return mHasLock; }
|
||||
|
||||
private:
|
||||
Tryer(const Tryer&);
|
||||
Tryer& operator=(const Tryer&);
|
||||
|
||||
// Implementation
|
||||
private:
|
||||
CAMutex & mMutex;
|
||||
bool mNeedsRelease;
|
||||
bool mHasLock;
|
||||
};
|
||||
};
|
||||
|
||||
|
||||
#endif // __CAMutex_h__
|
||||
/*
|
||||
File: CAMutex.h
|
||||
Abstract: Part of CoreAudio Utility Classes
|
||||
Version: 1.1
|
||||
|
||||
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.
|
||||
|
||||
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.
|
||||
|
||||
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.
|
||||
|
||||
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.
|
||||
|
||||
Copyright (C) 2014 Apple Inc. All Rights Reserved.
|
||||
|
||||
*/
|
||||
#ifndef __CAMutex_h__
|
||||
#define __CAMutex_h__
|
||||
|
||||
//==================================================================================================
|
||||
// Includes
|
||||
//==================================================================================================
|
||||
|
||||
// System Includes
|
||||
#if !defined(__COREAUDIO_USE_FLAT_INCLUDES__)
|
||||
#include <CoreAudio/CoreAudioTypes.h>
|
||||
#else
|
||||
#include <CoreAudioTypes.h>
|
||||
#endif
|
||||
|
||||
#if TARGET_OS_MAC
|
||||
#include <pthread.h>
|
||||
#elif TARGET_OS_WIN32
|
||||
#include <windows.h>
|
||||
#else
|
||||
#error Unsupported operating system
|
||||
#endif
|
||||
|
||||
//==================================================================================================
|
||||
// A recursive mutex.
|
||||
//==================================================================================================
|
||||
|
||||
class CAMutex
|
||||
{
|
||||
// Construction/Destruction
|
||||
public:
|
||||
CAMutex(const char* inName);
|
||||
virtual ~CAMutex();
|
||||
|
||||
// Actions
|
||||
public:
|
||||
virtual bool Lock();
|
||||
virtual void Unlock();
|
||||
virtual bool Try(bool& outWasLocked); // returns true if lock is free, false if not
|
||||
|
||||
virtual bool IsFree() const;
|
||||
virtual bool IsOwnedByCurrentThread() const;
|
||||
|
||||
// Implementation
|
||||
protected:
|
||||
const char* mName;
|
||||
#if TARGET_OS_MAC
|
||||
pthread_t mOwner;
|
||||
pthread_mutex_t mMutex;
|
||||
#elif TARGET_OS_WIN32
|
||||
UInt32 mOwner;
|
||||
HANDLE mMutex;
|
||||
#endif
|
||||
|
||||
// Helper class to manage taking and releasing recursively
|
||||
public:
|
||||
class Locker
|
||||
{
|
||||
|
||||
// Construction/Destruction
|
||||
public:
|
||||
Locker(CAMutex& inMutex) : mMutex(&inMutex), mNeedsRelease(false) { mNeedsRelease = mMutex->Lock(); }
|
||||
Locker(CAMutex* inMutex) : mMutex(inMutex), mNeedsRelease(false) { mNeedsRelease = (mMutex != NULL && mMutex->Lock()); }
|
||||
// in this case the mutex can be null
|
||||
~Locker() { if(mNeedsRelease) { mMutex->Unlock(); } }
|
||||
|
||||
|
||||
private:
|
||||
Locker(const Locker&);
|
||||
Locker& operator=(const Locker&);
|
||||
|
||||
// Implementation
|
||||
private:
|
||||
CAMutex* mMutex;
|
||||
bool mNeedsRelease;
|
||||
|
||||
};
|
||||
|
||||
// Unlocker
|
||||
class Unlocker
|
||||
{
|
||||
public:
|
||||
Unlocker(CAMutex& inMutex);
|
||||
~Unlocker();
|
||||
|
||||
private:
|
||||
CAMutex& mMutex;
|
||||
bool mNeedsLock;
|
||||
|
||||
// Hidden definitions of copy ctor, assignment operator
|
||||
Unlocker(const Unlocker& copy); // Not implemented
|
||||
Unlocker& operator=(const Unlocker& copy); // Not implemented
|
||||
};
|
||||
|
||||
// you can use this with Try - if you take the lock in try, pass in the outWasLocked var
|
||||
class Tryer {
|
||||
|
||||
// Construction/Destruction
|
||||
public:
|
||||
Tryer (CAMutex &mutex) : mMutex(mutex), mNeedsRelease(false), mHasLock(false) { mHasLock = mMutex.Try (mNeedsRelease); }
|
||||
~Tryer () { if (mNeedsRelease) mMutex.Unlock(); }
|
||||
|
||||
bool HasLock () const { return mHasLock; }
|
||||
|
||||
private:
|
||||
Tryer(const Tryer&);
|
||||
Tryer& operator=(const Tryer&);
|
||||
|
||||
// Implementation
|
||||
private:
|
||||
CAMutex & mMutex;
|
||||
bool mNeedsRelease;
|
||||
bool mHasLock;
|
||||
};
|
||||
};
|
||||
|
||||
|
||||
#endif // __CAMutex_h__
|
||||
|
||||
@@ -1,97 +1,97 @@
|
||||
/*
|
||||
File: CAReferenceCounted.h
|
||||
Abstract: Part of CoreAudio Utility Classes
|
||||
Version: 1.1
|
||||
|
||||
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.
|
||||
|
||||
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.
|
||||
|
||||
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.
|
||||
|
||||
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.
|
||||
|
||||
Copyright (C) 2014 Apple Inc. All Rights Reserved.
|
||||
|
||||
*/
|
||||
#ifndef __CAReferenceCounted_h__
|
||||
#define __CAReferenceCounted_h__
|
||||
|
||||
#include "CAAtomic.h"
|
||||
|
||||
// base class for reference-counted objects
|
||||
class CAReferenceCounted {
|
||||
public:
|
||||
CAReferenceCounted() : mRefCount(1) {}
|
||||
|
||||
void retain() { CAAtomicIncrement32(&mRefCount); }
|
||||
|
||||
void release()
|
||||
{
|
||||
SInt32 rc = CAAtomicDecrement32(&mRefCount);
|
||||
if (rc == 0) {
|
||||
releaseObject();
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
class Retainer {
|
||||
public:
|
||||
Retainer(CAReferenceCounted *obj) : mObject(obj) { mObject->retain(); }
|
||||
~Retainer() { mObject->release(); }
|
||||
|
||||
private:
|
||||
CAReferenceCounted * mObject;
|
||||
};
|
||||
|
||||
protected:
|
||||
virtual ~CAReferenceCounted() { }
|
||||
|
||||
virtual void releaseObject ()
|
||||
{
|
||||
delete this;
|
||||
}
|
||||
|
||||
#if DEBUG
|
||||
public:
|
||||
#endif
|
||||
SInt32 GetReferenceCount() const { return mRefCount; }
|
||||
private:
|
||||
SInt32 mRefCount;
|
||||
|
||||
CAReferenceCounted(const CAReferenceCounted &a);
|
||||
CAReferenceCounted &operator=(const CAReferenceCounted &a);
|
||||
};
|
||||
|
||||
|
||||
#endif // __CAReferenceCounted_h__
|
||||
/*
|
||||
File: CAReferenceCounted.h
|
||||
Abstract: Part of CoreAudio Utility Classes
|
||||
Version: 1.1
|
||||
|
||||
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.
|
||||
|
||||
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.
|
||||
|
||||
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.
|
||||
|
||||
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.
|
||||
|
||||
Copyright (C) 2014 Apple Inc. All Rights Reserved.
|
||||
|
||||
*/
|
||||
#ifndef __CAReferenceCounted_h__
|
||||
#define __CAReferenceCounted_h__
|
||||
|
||||
#include "CAAtomic.h"
|
||||
|
||||
// base class for reference-counted objects
|
||||
class CAReferenceCounted {
|
||||
public:
|
||||
CAReferenceCounted() : mRefCount(1) {}
|
||||
|
||||
void retain() { CAAtomicIncrement32(&mRefCount); }
|
||||
|
||||
void release()
|
||||
{
|
||||
SInt32 rc = CAAtomicDecrement32(&mRefCount);
|
||||
if (rc == 0) {
|
||||
releaseObject();
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
class Retainer {
|
||||
public:
|
||||
Retainer(CAReferenceCounted *obj) : mObject(obj) { mObject->retain(); }
|
||||
~Retainer() { mObject->release(); }
|
||||
|
||||
private:
|
||||
CAReferenceCounted * mObject;
|
||||
};
|
||||
|
||||
protected:
|
||||
virtual ~CAReferenceCounted() { }
|
||||
|
||||
virtual void releaseObject ()
|
||||
{
|
||||
delete this;
|
||||
}
|
||||
|
||||
#if DEBUG
|
||||
public:
|
||||
#endif
|
||||
SInt32 GetReferenceCount() const { return mRefCount; }
|
||||
private:
|
||||
SInt32 mRefCount;
|
||||
|
||||
CAReferenceCounted(const CAReferenceCounted &a);
|
||||
CAReferenceCounted &operator=(const CAReferenceCounted &a);
|
||||
};
|
||||
|
||||
|
||||
#endif // __CAReferenceCounted_h__
|
||||
|
||||
File diff suppressed because it is too large
Load Diff
@@ -1,424 +1,424 @@
|
||||
/*
|
||||
File: CAStreamBasicDescription.h
|
||||
Abstract: Part of CoreAudio Utility Classes
|
||||
Version: 1.1
|
||||
|
||||
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.
|
||||
|
||||
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.
|
||||
|
||||
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.
|
||||
|
||||
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.
|
||||
|
||||
Copyright (C) 2014 Apple Inc. All Rights Reserved.
|
||||
|
||||
*/
|
||||
#ifndef __CAStreamBasicDescription_h__
|
||||
#define __CAStreamBasicDescription_h__
|
||||
|
||||
#if !defined(__COREAUDIO_USE_FLAT_INCLUDES__)
|
||||
#include <CoreAudio/CoreAudioTypes.h>
|
||||
#include <CoreFoundation/CoreFoundation.h>
|
||||
#else
|
||||
#include "CoreAudioTypes.h"
|
||||
#include "CoreFoundation.h"
|
||||
#endif
|
||||
|
||||
#include "CADebugMacros.h"
|
||||
#include <string.h> // for memset, memcpy
|
||||
#include <stdio.h> // for FILE *
|
||||
|
||||
#pragma mark This file needs to compile on more earlier versions of the OS, so please keep that in mind when editing it
|
||||
|
||||
extern char *CAStringForOSType (OSType t, char *writeLocation, size_t bufsize);
|
||||
|
||||
// define Leopard specific symbols for backward compatibility if applicable
|
||||
#if COREAUDIOTYPES_VERSION < 1050
|
||||
typedef Float32 AudioSampleType;
|
||||
enum { kAudioFormatFlagsCanonical = kAudioFormatFlagIsFloat | kAudioFormatFlagsNativeEndian | kAudioFormatFlagIsPacked };
|
||||
#endif
|
||||
#if COREAUDIOTYPES_VERSION < 1051
|
||||
typedef Float32 AudioUnitSampleType;
|
||||
enum {
|
||||
kLinearPCMFormatFlagsSampleFractionShift = 7,
|
||||
kLinearPCMFormatFlagsSampleFractionMask = (0x3F << kLinearPCMFormatFlagsSampleFractionShift),
|
||||
};
|
||||
#endif
|
||||
|
||||
// define the IsMixable format flag for all versions of the system
|
||||
#if (MAC_OS_X_VERSION_MAX_ALLOWED >= MAC_OS_X_VERSION_10_3)
|
||||
enum { kIsNonMixableFlag = kAudioFormatFlagIsNonMixable };
|
||||
#else
|
||||
enum { kIsNonMixableFlag = (1L << 6) };
|
||||
#endif
|
||||
|
||||
//=============================================================================
|
||||
// CAStreamBasicDescription
|
||||
//
|
||||
// This is a wrapper class for the AudioStreamBasicDescription struct.
|
||||
// It adds a number of convenience routines, but otherwise adds nothing
|
||||
// to the footprint of the original struct.
|
||||
//=============================================================================
|
||||
class CAStreamBasicDescription :
|
||||
public AudioStreamBasicDescription
|
||||
{
|
||||
|
||||
// Constants
|
||||
public:
|
||||
static const AudioStreamBasicDescription sEmpty;
|
||||
|
||||
enum CommonPCMFormat {
|
||||
kPCMFormatOther = 0,
|
||||
kPCMFormatFloat32 = 1,
|
||||
kPCMFormatInt16 = 2,
|
||||
kPCMFormatFixed824 = 3,
|
||||
kPCMFormatFloat64 = 4
|
||||
};
|
||||
|
||||
// Construction/Destruction
|
||||
public:
|
||||
CAStreamBasicDescription();
|
||||
|
||||
CAStreamBasicDescription(const AudioStreamBasicDescription &desc);
|
||||
|
||||
CAStreamBasicDescription( double inSampleRate, UInt32 inFormatID,
|
||||
UInt32 inBytesPerPacket, UInt32 inFramesPerPacket,
|
||||
UInt32 inBytesPerFrame, UInt32 inChannelsPerFrame,
|
||||
UInt32 inBitsPerChannel, UInt32 inFormatFlags);
|
||||
|
||||
CAStreamBasicDescription( double inSampleRate, UInt32 inNumChannels, CommonPCMFormat pcmf, bool inIsInterleaved) {
|
||||
unsigned wordsize;
|
||||
|
||||
mSampleRate = inSampleRate;
|
||||
mFormatID = kAudioFormatLinearPCM;
|
||||
mFormatFlags = kAudioFormatFlagsNativeEndian | kAudioFormatFlagIsPacked;
|
||||
mFramesPerPacket = 1;
|
||||
mChannelsPerFrame = inNumChannels;
|
||||
mBytesPerFrame = mBytesPerPacket = 0;
|
||||
mReserved = 0;
|
||||
|
||||
switch (pcmf) {
|
||||
default:
|
||||
return;
|
||||
case kPCMFormatFloat32:
|
||||
wordsize = 4;
|
||||
mFormatFlags |= kAudioFormatFlagIsFloat;
|
||||
break;
|
||||
case kPCMFormatFloat64:
|
||||
wordsize = 8;
|
||||
mFormatFlags |= kAudioFormatFlagIsFloat;
|
||||
break;
|
||||
case kPCMFormatInt16:
|
||||
wordsize = 2;
|
||||
mFormatFlags |= kAudioFormatFlagIsSignedInteger;
|
||||
break;
|
||||
case kPCMFormatFixed824:
|
||||
wordsize = 4;
|
||||
mFormatFlags |= kAudioFormatFlagIsSignedInteger | (24 << kLinearPCMFormatFlagsSampleFractionShift);
|
||||
break;
|
||||
}
|
||||
mBitsPerChannel = wordsize * 8;
|
||||
if (inIsInterleaved)
|
||||
mBytesPerFrame = mBytesPerPacket = wordsize * inNumChannels;
|
||||
else {
|
||||
mFormatFlags |= kAudioFormatFlagIsNonInterleaved;
|
||||
mBytesPerFrame = mBytesPerPacket = wordsize;
|
||||
}
|
||||
}
|
||||
|
||||
// Assignment
|
||||
CAStreamBasicDescription& operator=(const AudioStreamBasicDescription& v) { SetFrom(v); return *this; }
|
||||
|
||||
void SetFrom(const AudioStreamBasicDescription &desc)
|
||||
{
|
||||
memcpy(this, &desc, sizeof(AudioStreamBasicDescription));
|
||||
}
|
||||
|
||||
bool FromText(const char *inTextDesc) { return FromText(inTextDesc, *this); }
|
||||
static bool FromText(const char *inTextDesc, AudioStreamBasicDescription &outDesc);
|
||||
// return true if parsing was successful
|
||||
|
||||
static const char *sTextParsingUsageString;
|
||||
|
||||
// _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _
|
||||
//
|
||||
// interrogation
|
||||
|
||||
bool IsPCM() const { return mFormatID == kAudioFormatLinearPCM; }
|
||||
|
||||
bool PackednessIsSignificant() const
|
||||
{
|
||||
Assert(IsPCM(), "PackednessIsSignificant only applies for PCM");
|
||||
return (SampleWordSize() << 3) != mBitsPerChannel;
|
||||
}
|
||||
|
||||
bool AlignmentIsSignificant() const
|
||||
{
|
||||
return PackednessIsSignificant() || (mBitsPerChannel & 7) != 0;
|
||||
}
|
||||
|
||||
bool IsInterleaved() const
|
||||
{
|
||||
return !(mFormatFlags & kAudioFormatFlagIsNonInterleaved);
|
||||
}
|
||||
|
||||
bool IsSignedInteger() const
|
||||
{
|
||||
return IsPCM() && (mFormatFlags & kAudioFormatFlagIsSignedInteger);
|
||||
}
|
||||
|
||||
bool IsFloat() const
|
||||
{
|
||||
return IsPCM() && (mFormatFlags & kAudioFormatFlagIsFloat);
|
||||
}
|
||||
|
||||
bool IsNativeEndian() const
|
||||
{
|
||||
return (mFormatFlags & kAudioFormatFlagIsBigEndian) == kAudioFormatFlagsNativeEndian;
|
||||
}
|
||||
|
||||
// for sanity with interleaved/deinterleaved possibilities, never access mChannelsPerFrame, use these:
|
||||
UInt32 NumberInterleavedChannels() const { return IsInterleaved() ? mChannelsPerFrame : 1; }
|
||||
UInt32 NumberChannelStreams() const { return IsInterleaved() ? 1 : mChannelsPerFrame; }
|
||||
UInt32 NumberChannels() const { return mChannelsPerFrame; }
|
||||
UInt32 SampleWordSize() const {
|
||||
return (mBytesPerFrame > 0 && NumberInterleavedChannels()) ? mBytesPerFrame / NumberInterleavedChannels() : 0;
|
||||
}
|
||||
|
||||
UInt32 FramesToBytes(UInt32 nframes) const { return nframes * mBytesPerFrame; }
|
||||
UInt32 BytesToFrames(UInt32 nbytes) const {
|
||||
Assert(mBytesPerFrame > 0, "bytesPerFrame must be > 0 in BytesToFrames");
|
||||
return nbytes / mBytesPerFrame;
|
||||
}
|
||||
|
||||
bool SameChannelsAndInterleaving(const CAStreamBasicDescription &a) const
|
||||
{
|
||||
return this->NumberChannels() == a.NumberChannels() && this->IsInterleaved() == a.IsInterleaved();
|
||||
}
|
||||
|
||||
bool IdentifyCommonPCMFormat(CommonPCMFormat &outFormat, bool *outIsInterleaved=NULL) const
|
||||
{ // return true if it's a valid PCM format.
|
||||
|
||||
outFormat = kPCMFormatOther;
|
||||
// trap out patently invalid formats.
|
||||
if (mFormatID != kAudioFormatLinearPCM || mFramesPerPacket != 1 || mBytesPerFrame != mBytesPerPacket || mBitsPerChannel/8 > mBytesPerFrame || mChannelsPerFrame == 0)
|
||||
return false;
|
||||
bool interleaved = (mFormatFlags & kAudioFormatFlagIsNonInterleaved) == 0;
|
||||
if (outIsInterleaved != NULL) *outIsInterleaved = interleaved;
|
||||
unsigned wordsize = mBytesPerFrame;
|
||||
if (interleaved) {
|
||||
if (wordsize % mChannelsPerFrame != 0) return false;
|
||||
wordsize /= mChannelsPerFrame;
|
||||
}
|
||||
|
||||
if ((mFormatFlags & kAudioFormatFlagIsBigEndian) == kAudioFormatFlagsNativeEndian
|
||||
&& wordsize * 8 == mBitsPerChannel) {
|
||||
// packed and native endian, good
|
||||
if (mFormatFlags & kLinearPCMFormatFlagIsFloat) {
|
||||
// float: reject nonsense bits
|
||||
if (mFormatFlags & (kLinearPCMFormatFlagIsSignedInteger | kLinearPCMFormatFlagsSampleFractionMask))
|
||||
return false;
|
||||
if (wordsize == 4)
|
||||
outFormat = kPCMFormatFloat32;
|
||||
if (wordsize == 8)
|
||||
outFormat = kPCMFormatFloat64;
|
||||
} else if (mFormatFlags & kLinearPCMFormatFlagIsSignedInteger) {
|
||||
// signed int
|
||||
unsigned fracbits = (mFormatFlags & kLinearPCMFormatFlagsSampleFractionMask) >> kLinearPCMFormatFlagsSampleFractionShift;
|
||||
if (wordsize == 4 && fracbits == 24)
|
||||
outFormat = kPCMFormatFixed824;
|
||||
else if (wordsize == 2 && fracbits == 0)
|
||||
outFormat = kPCMFormatInt16;
|
||||
}
|
||||
}
|
||||
return true;
|
||||
}
|
||||
|
||||
bool IsCommonFloat32(bool *outIsInterleaved=NULL) const {
|
||||
CommonPCMFormat fmt;
|
||||
return IdentifyCommonPCMFormat(fmt, outIsInterleaved) && fmt == kPCMFormatFloat32;
|
||||
}
|
||||
bool IsCommonFloat64(bool *outIsInterleaved=NULL) const {
|
||||
CommonPCMFormat fmt;
|
||||
return IdentifyCommonPCMFormat(fmt, outIsInterleaved) && fmt == kPCMFormatFloat64;
|
||||
}
|
||||
bool IsCommonFixed824(bool *outIsInterleaved=NULL) const {
|
||||
CommonPCMFormat fmt;
|
||||
return IdentifyCommonPCMFormat(fmt, outIsInterleaved) && fmt == kPCMFormatFixed824;
|
||||
}
|
||||
bool IsCommonInt16(bool *outIsInterleaved=NULL) const {
|
||||
CommonPCMFormat fmt;
|
||||
return IdentifyCommonPCMFormat(fmt, outIsInterleaved) && fmt == kPCMFormatInt16;
|
||||
}
|
||||
|
||||
// _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _
|
||||
//
|
||||
// manipulation
|
||||
|
||||
void SetCanonical(UInt32 nChannels, bool interleaved)
|
||||
// note: leaves sample rate untouched
|
||||
{
|
||||
mFormatID = kAudioFormatLinearPCM;
|
||||
UInt32 sampleSize = SizeOf32(AudioSampleType);
|
||||
mFormatFlags = kAudioFormatFlagsCanonical;
|
||||
mBitsPerChannel = 8 * sampleSize;
|
||||
mChannelsPerFrame = nChannels;
|
||||
mFramesPerPacket = 1;
|
||||
if (interleaved)
|
||||
mBytesPerPacket = mBytesPerFrame = nChannels * sampleSize;
|
||||
else {
|
||||
mBytesPerPacket = mBytesPerFrame = sampleSize;
|
||||
mFormatFlags |= kAudioFormatFlagIsNonInterleaved;
|
||||
}
|
||||
}
|
||||
|
||||
bool IsCanonical() const
|
||||
{
|
||||
if (mFormatID != kAudioFormatLinearPCM) return false;
|
||||
UInt32 reqFormatFlags;
|
||||
UInt32 flagsMask = (kLinearPCMFormatFlagIsFloat | kLinearPCMFormatFlagIsBigEndian | kLinearPCMFormatFlagIsSignedInteger | kLinearPCMFormatFlagIsPacked | kLinearPCMFormatFlagsSampleFractionMask);
|
||||
bool interleaved = (mFormatFlags & kAudioFormatFlagIsNonInterleaved) == 0;
|
||||
unsigned sampleSize = SizeOf32(AudioSampleType);
|
||||
reqFormatFlags = kAudioFormatFlagsCanonical;
|
||||
UInt32 reqFrameSize = interleaved ? (mChannelsPerFrame * sampleSize) : sampleSize;
|
||||
|
||||
return ((mFormatFlags & flagsMask) == reqFormatFlags
|
||||
&& mBitsPerChannel == 8 * sampleSize
|
||||
&& mFramesPerPacket == 1
|
||||
&& mBytesPerFrame == reqFrameSize
|
||||
&& mBytesPerPacket == reqFrameSize);
|
||||
}
|
||||
|
||||
void SetAUCanonical(UInt32 nChannels, bool interleaved)
|
||||
{
|
||||
mFormatID = kAudioFormatLinearPCM;
|
||||
#if CA_PREFER_FIXED_POINT
|
||||
mFormatFlags = kAudioFormatFlagsCanonical | (kAudioUnitSampleFractionBits << kLinearPCMFormatFlagsSampleFractionShift);
|
||||
#else
|
||||
mFormatFlags = kAudioFormatFlagsCanonical;
|
||||
#endif
|
||||
mChannelsPerFrame = nChannels;
|
||||
mFramesPerPacket = 1;
|
||||
mBitsPerChannel = 8 * SizeOf32(AudioUnitSampleType);
|
||||
if (interleaved)
|
||||
mBytesPerPacket = mBytesPerFrame = nChannels * SizeOf32(AudioUnitSampleType);
|
||||
else {
|
||||
mBytesPerPacket = mBytesPerFrame = SizeOf32(AudioUnitSampleType);
|
||||
mFormatFlags |= kAudioFormatFlagIsNonInterleaved;
|
||||
}
|
||||
}
|
||||
|
||||
void ChangeNumberChannels(UInt32 nChannels, bool interleaved)
|
||||
// alter an existing format
|
||||
{
|
||||
Assert(IsPCM(), "ChangeNumberChannels only works for PCM formats");
|
||||
UInt32 wordSize = SampleWordSize(); // get this before changing ANYTHING
|
||||
if (wordSize == 0)
|
||||
wordSize = (mBitsPerChannel + 7) / 8;
|
||||
mChannelsPerFrame = nChannels;
|
||||
mFramesPerPacket = 1;
|
||||
if (interleaved) {
|
||||
mBytesPerPacket = mBytesPerFrame = nChannels * wordSize;
|
||||
mFormatFlags &= ~static_cast<UInt32>(kAudioFormatFlagIsNonInterleaved);
|
||||
} else {
|
||||
mBytesPerPacket = mBytesPerFrame = wordSize;
|
||||
mFormatFlags |= kAudioFormatFlagIsNonInterleaved;
|
||||
}
|
||||
}
|
||||
|
||||
// _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _
|
||||
//
|
||||
// other
|
||||
|
||||
bool IsEqual(const AudioStreamBasicDescription &other, bool interpretingWildcards=true) const;
|
||||
static bool FlagIndependentEquivalence(const AudioStreamBasicDescription &x, const AudioStreamBasicDescription &y);
|
||||
static bool IsFunctionallyEquivalent(const AudioStreamBasicDescription &x, const AudioStreamBasicDescription &y);
|
||||
|
||||
void Print() const {
|
||||
Print (stdout);
|
||||
}
|
||||
|
||||
void Print(FILE* file) const {
|
||||
PrintFormat (file, "", "AudioStreamBasicDescription:");
|
||||
}
|
||||
|
||||
void PrintFormat(FILE *f, const char *indent, const char *name) const {
|
||||
char buf[256];
|
||||
fprintf(f, "%s%s %s\n", indent, name, AsString(buf, sizeof(buf)));
|
||||
}
|
||||
|
||||
void PrintFormat2(FILE *f, const char *indent, const char *name) const { // no trailing newline
|
||||
char buf[256];
|
||||
fprintf(f, "%s%s %s", indent, name, AsString(buf, sizeof(buf)));
|
||||
}
|
||||
|
||||
char * AsString(char *buf, size_t bufsize, bool brief=false) const;
|
||||
|
||||
static void Print (const AudioStreamBasicDescription &inDesc)
|
||||
{
|
||||
CAStreamBasicDescription desc(inDesc);
|
||||
desc.Print ();
|
||||
}
|
||||
|
||||
OSStatus Save(CFPropertyListRef *outData) const;
|
||||
|
||||
OSStatus Restore(CFPropertyListRef &inData);
|
||||
|
||||
// Operations
|
||||
static bool IsMixable(const AudioStreamBasicDescription& inDescription) { return (inDescription.mFormatID == kAudioFormatLinearPCM) && ((inDescription.mFormatFlags & kIsNonMixableFlag) == 0); }
|
||||
static void NormalizeLinearPCMFormat(AudioStreamBasicDescription& ioDescription);
|
||||
static void NormalizeLinearPCMFormat(bool inNativeEndian, AudioStreamBasicDescription& ioDescription);
|
||||
static void ResetFormat(AudioStreamBasicDescription& ioDescription);
|
||||
static void FillOutFormat(AudioStreamBasicDescription& ioDescription, const AudioStreamBasicDescription& inTemplateDescription);
|
||||
static void GetSimpleName(const AudioStreamBasicDescription& inDescription, char* outName, UInt32 inMaxNameLength, bool inAbbreviate, bool inIncludeSampleRate = false);
|
||||
static void ModifyFormatFlagsForMatching(const AudioStreamBasicDescription& x, const AudioStreamBasicDescription& y, UInt32& xFlags, UInt32& yFlags, bool converterOnly);
|
||||
|
||||
#if CoreAudio_Debug
|
||||
static void PrintToLog(const AudioStreamBasicDescription& inDesc);
|
||||
#endif
|
||||
};
|
||||
|
||||
bool operator<(const AudioStreamBasicDescription& x, const AudioStreamBasicDescription& y);
|
||||
bool operator==(const AudioStreamBasicDescription& x, const AudioStreamBasicDescription& y);
|
||||
#if TARGET_OS_MAC || (TARGET_OS_WIN32 && (_MSC_VER > 600))
|
||||
inline bool operator!=(const AudioStreamBasicDescription& x, const AudioStreamBasicDescription& y) { return !(x == y); }
|
||||
inline bool operator<=(const AudioStreamBasicDescription& x, const AudioStreamBasicDescription& y) { return (x < y) || (x == y); }
|
||||
inline bool operator>=(const AudioStreamBasicDescription& x, const AudioStreamBasicDescription& y) { return !(x < y); }
|
||||
inline bool operator>(const AudioStreamBasicDescription& x, const AudioStreamBasicDescription& y) { return !((x < y) || (x == y)); }
|
||||
#endif
|
||||
|
||||
bool SanityCheck(const AudioStreamBasicDescription& x);
|
||||
|
||||
|
||||
#endif // __CAStreamBasicDescription_h__
|
||||
/*
|
||||
File: CAStreamBasicDescription.h
|
||||
Abstract: Part of CoreAudio Utility Classes
|
||||
Version: 1.1
|
||||
|
||||
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.
|
||||
|
||||
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.
|
||||
|
||||
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.
|
||||
|
||||
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.
|
||||
|
||||
Copyright (C) 2014 Apple Inc. All Rights Reserved.
|
||||
|
||||
*/
|
||||
#ifndef __CAStreamBasicDescription_h__
|
||||
#define __CAStreamBasicDescription_h__
|
||||
|
||||
#if !defined(__COREAUDIO_USE_FLAT_INCLUDES__)
|
||||
#include <CoreAudio/CoreAudioTypes.h>
|
||||
#include <CoreFoundation/CoreFoundation.h>
|
||||
#else
|
||||
#include "CoreAudioTypes.h"
|
||||
#include "CoreFoundation.h"
|
||||
#endif
|
||||
|
||||
#include "CADebugMacros.h"
|
||||
#include <string.h> // for memset, memcpy
|
||||
#include <stdio.h> // for FILE *
|
||||
|
||||
#pragma mark This file needs to compile on more earlier versions of the OS, so please keep that in mind when editing it
|
||||
|
||||
extern char *CAStringForOSType (OSType t, char *writeLocation, size_t bufsize);
|
||||
|
||||
// define Leopard specific symbols for backward compatibility if applicable
|
||||
#if COREAUDIOTYPES_VERSION < 1050
|
||||
typedef Float32 AudioSampleType;
|
||||
enum { kAudioFormatFlagsCanonical = kAudioFormatFlagIsFloat | kAudioFormatFlagsNativeEndian | kAudioFormatFlagIsPacked };
|
||||
#endif
|
||||
#if COREAUDIOTYPES_VERSION < 1051
|
||||
typedef Float32 AudioUnitSampleType;
|
||||
enum {
|
||||
kLinearPCMFormatFlagsSampleFractionShift = 7,
|
||||
kLinearPCMFormatFlagsSampleFractionMask = (0x3F << kLinearPCMFormatFlagsSampleFractionShift),
|
||||
};
|
||||
#endif
|
||||
|
||||
// define the IsMixable format flag for all versions of the system
|
||||
#if (MAC_OS_X_VERSION_MAX_ALLOWED >= MAC_OS_X_VERSION_10_3)
|
||||
enum { kIsNonMixableFlag = kAudioFormatFlagIsNonMixable };
|
||||
#else
|
||||
enum { kIsNonMixableFlag = (1L << 6) };
|
||||
#endif
|
||||
|
||||
//=============================================================================
|
||||
// CAStreamBasicDescription
|
||||
//
|
||||
// This is a wrapper class for the AudioStreamBasicDescription struct.
|
||||
// It adds a number of convenience routines, but otherwise adds nothing
|
||||
// to the footprint of the original struct.
|
||||
//=============================================================================
|
||||
class CAStreamBasicDescription :
|
||||
public AudioStreamBasicDescription
|
||||
{
|
||||
|
||||
// Constants
|
||||
public:
|
||||
static const AudioStreamBasicDescription sEmpty;
|
||||
|
||||
enum CommonPCMFormat {
|
||||
kPCMFormatOther = 0,
|
||||
kPCMFormatFloat32 = 1,
|
||||
kPCMFormatInt16 = 2,
|
||||
kPCMFormatFixed824 = 3,
|
||||
kPCMFormatFloat64 = 4
|
||||
};
|
||||
|
||||
// Construction/Destruction
|
||||
public:
|
||||
CAStreamBasicDescription();
|
||||
|
||||
CAStreamBasicDescription(const AudioStreamBasicDescription &desc);
|
||||
|
||||
CAStreamBasicDescription( double inSampleRate, UInt32 inFormatID,
|
||||
UInt32 inBytesPerPacket, UInt32 inFramesPerPacket,
|
||||
UInt32 inBytesPerFrame, UInt32 inChannelsPerFrame,
|
||||
UInt32 inBitsPerChannel, UInt32 inFormatFlags);
|
||||
|
||||
CAStreamBasicDescription( double inSampleRate, UInt32 inNumChannels, CommonPCMFormat pcmf, bool inIsInterleaved) {
|
||||
unsigned wordsize;
|
||||
|
||||
mSampleRate = inSampleRate;
|
||||
mFormatID = kAudioFormatLinearPCM;
|
||||
mFormatFlags = kAudioFormatFlagsNativeEndian | kAudioFormatFlagIsPacked;
|
||||
mFramesPerPacket = 1;
|
||||
mChannelsPerFrame = inNumChannels;
|
||||
mBytesPerFrame = mBytesPerPacket = 0;
|
||||
mReserved = 0;
|
||||
|
||||
switch (pcmf) {
|
||||
default:
|
||||
return;
|
||||
case kPCMFormatFloat32:
|
||||
wordsize = 4;
|
||||
mFormatFlags |= kAudioFormatFlagIsFloat;
|
||||
break;
|
||||
case kPCMFormatFloat64:
|
||||
wordsize = 8;
|
||||
mFormatFlags |= kAudioFormatFlagIsFloat;
|
||||
break;
|
||||
case kPCMFormatInt16:
|
||||
wordsize = 2;
|
||||
mFormatFlags |= kAudioFormatFlagIsSignedInteger;
|
||||
break;
|
||||
case kPCMFormatFixed824:
|
||||
wordsize = 4;
|
||||
mFormatFlags |= kAudioFormatFlagIsSignedInteger | (24 << kLinearPCMFormatFlagsSampleFractionShift);
|
||||
break;
|
||||
}
|
||||
mBitsPerChannel = wordsize * 8;
|
||||
if (inIsInterleaved)
|
||||
mBytesPerFrame = mBytesPerPacket = wordsize * inNumChannels;
|
||||
else {
|
||||
mFormatFlags |= kAudioFormatFlagIsNonInterleaved;
|
||||
mBytesPerFrame = mBytesPerPacket = wordsize;
|
||||
}
|
||||
}
|
||||
|
||||
// Assignment
|
||||
CAStreamBasicDescription& operator=(const AudioStreamBasicDescription& v) { SetFrom(v); return *this; }
|
||||
|
||||
void SetFrom(const AudioStreamBasicDescription &desc)
|
||||
{
|
||||
memcpy(this, &desc, sizeof(AudioStreamBasicDescription));
|
||||
}
|
||||
|
||||
bool FromText(const char *inTextDesc) { return FromText(inTextDesc, *this); }
|
||||
static bool FromText(const char *inTextDesc, AudioStreamBasicDescription &outDesc);
|
||||
// return true if parsing was successful
|
||||
|
||||
static const char *sTextParsingUsageString;
|
||||
|
||||
// _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _
|
||||
//
|
||||
// interrogation
|
||||
|
||||
bool IsPCM() const { return mFormatID == kAudioFormatLinearPCM; }
|
||||
|
||||
bool PackednessIsSignificant() const
|
||||
{
|
||||
Assert(IsPCM(), "PackednessIsSignificant only applies for PCM");
|
||||
return (SampleWordSize() << 3) != mBitsPerChannel;
|
||||
}
|
||||
|
||||
bool AlignmentIsSignificant() const
|
||||
{
|
||||
return PackednessIsSignificant() || (mBitsPerChannel & 7) != 0;
|
||||
}
|
||||
|
||||
bool IsInterleaved() const
|
||||
{
|
||||
return !(mFormatFlags & kAudioFormatFlagIsNonInterleaved);
|
||||
}
|
||||
|
||||
bool IsSignedInteger() const
|
||||
{
|
||||
return IsPCM() && (mFormatFlags & kAudioFormatFlagIsSignedInteger);
|
||||
}
|
||||
|
||||
bool IsFloat() const
|
||||
{
|
||||
return IsPCM() && (mFormatFlags & kAudioFormatFlagIsFloat);
|
||||
}
|
||||
|
||||
bool IsNativeEndian() const
|
||||
{
|
||||
return (mFormatFlags & kAudioFormatFlagIsBigEndian) == kAudioFormatFlagsNativeEndian;
|
||||
}
|
||||
|
||||
// for sanity with interleaved/deinterleaved possibilities, never access mChannelsPerFrame, use these:
|
||||
UInt32 NumberInterleavedChannels() const { return IsInterleaved() ? mChannelsPerFrame : 1; }
|
||||
UInt32 NumberChannelStreams() const { return IsInterleaved() ? 1 : mChannelsPerFrame; }
|
||||
UInt32 NumberChannels() const { return mChannelsPerFrame; }
|
||||
UInt32 SampleWordSize() const {
|
||||
return (mBytesPerFrame > 0 && NumberInterleavedChannels()) ? mBytesPerFrame / NumberInterleavedChannels() : 0;
|
||||
}
|
||||
|
||||
UInt32 FramesToBytes(UInt32 nframes) const { return nframes * mBytesPerFrame; }
|
||||
UInt32 BytesToFrames(UInt32 nbytes) const {
|
||||
Assert(mBytesPerFrame > 0, "bytesPerFrame must be > 0 in BytesToFrames");
|
||||
return nbytes / mBytesPerFrame;
|
||||
}
|
||||
|
||||
bool SameChannelsAndInterleaving(const CAStreamBasicDescription &a) const
|
||||
{
|
||||
return this->NumberChannels() == a.NumberChannels() && this->IsInterleaved() == a.IsInterleaved();
|
||||
}
|
||||
|
||||
bool IdentifyCommonPCMFormat(CommonPCMFormat &outFormat, bool *outIsInterleaved=NULL) const
|
||||
{ // return true if it's a valid PCM format.
|
||||
|
||||
outFormat = kPCMFormatOther;
|
||||
// trap out patently invalid formats.
|
||||
if (mFormatID != kAudioFormatLinearPCM || mFramesPerPacket != 1 || mBytesPerFrame != mBytesPerPacket || mBitsPerChannel/8 > mBytesPerFrame || mChannelsPerFrame == 0)
|
||||
return false;
|
||||
bool interleaved = (mFormatFlags & kAudioFormatFlagIsNonInterleaved) == 0;
|
||||
if (outIsInterleaved != NULL) *outIsInterleaved = interleaved;
|
||||
unsigned wordsize = mBytesPerFrame;
|
||||
if (interleaved) {
|
||||
if (wordsize % mChannelsPerFrame != 0) return false;
|
||||
wordsize /= mChannelsPerFrame;
|
||||
}
|
||||
|
||||
if ((mFormatFlags & kAudioFormatFlagIsBigEndian) == kAudioFormatFlagsNativeEndian
|
||||
&& wordsize * 8 == mBitsPerChannel) {
|
||||
// packed and native endian, good
|
||||
if (mFormatFlags & kLinearPCMFormatFlagIsFloat) {
|
||||
// float: reject nonsense bits
|
||||
if (mFormatFlags & (kLinearPCMFormatFlagIsSignedInteger | kLinearPCMFormatFlagsSampleFractionMask))
|
||||
return false;
|
||||
if (wordsize == 4)
|
||||
outFormat = kPCMFormatFloat32;
|
||||
if (wordsize == 8)
|
||||
outFormat = kPCMFormatFloat64;
|
||||
} else if (mFormatFlags & kLinearPCMFormatFlagIsSignedInteger) {
|
||||
// signed int
|
||||
unsigned fracbits = (mFormatFlags & kLinearPCMFormatFlagsSampleFractionMask) >> kLinearPCMFormatFlagsSampleFractionShift;
|
||||
if (wordsize == 4 && fracbits == 24)
|
||||
outFormat = kPCMFormatFixed824;
|
||||
else if (wordsize == 2 && fracbits == 0)
|
||||
outFormat = kPCMFormatInt16;
|
||||
}
|
||||
}
|
||||
return true;
|
||||
}
|
||||
|
||||
bool IsCommonFloat32(bool *outIsInterleaved=NULL) const {
|
||||
CommonPCMFormat fmt;
|
||||
return IdentifyCommonPCMFormat(fmt, outIsInterleaved) && fmt == kPCMFormatFloat32;
|
||||
}
|
||||
bool IsCommonFloat64(bool *outIsInterleaved=NULL) const {
|
||||
CommonPCMFormat fmt;
|
||||
return IdentifyCommonPCMFormat(fmt, outIsInterleaved) && fmt == kPCMFormatFloat64;
|
||||
}
|
||||
bool IsCommonFixed824(bool *outIsInterleaved=NULL) const {
|
||||
CommonPCMFormat fmt;
|
||||
return IdentifyCommonPCMFormat(fmt, outIsInterleaved) && fmt == kPCMFormatFixed824;
|
||||
}
|
||||
bool IsCommonInt16(bool *outIsInterleaved=NULL) const {
|
||||
CommonPCMFormat fmt;
|
||||
return IdentifyCommonPCMFormat(fmt, outIsInterleaved) && fmt == kPCMFormatInt16;
|
||||
}
|
||||
|
||||
// _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _
|
||||
//
|
||||
// manipulation
|
||||
|
||||
void SetCanonical(UInt32 nChannels, bool interleaved)
|
||||
// note: leaves sample rate untouched
|
||||
{
|
||||
mFormatID = kAudioFormatLinearPCM;
|
||||
UInt32 sampleSize = SizeOf32(AudioSampleType);
|
||||
mFormatFlags = kAudioFormatFlagsCanonical;
|
||||
mBitsPerChannel = 8 * sampleSize;
|
||||
mChannelsPerFrame = nChannels;
|
||||
mFramesPerPacket = 1;
|
||||
if (interleaved)
|
||||
mBytesPerPacket = mBytesPerFrame = nChannels * sampleSize;
|
||||
else {
|
||||
mBytesPerPacket = mBytesPerFrame = sampleSize;
|
||||
mFormatFlags |= kAudioFormatFlagIsNonInterleaved;
|
||||
}
|
||||
}
|
||||
|
||||
bool IsCanonical() const
|
||||
{
|
||||
if (mFormatID != kAudioFormatLinearPCM) return false;
|
||||
UInt32 reqFormatFlags;
|
||||
UInt32 flagsMask = (kLinearPCMFormatFlagIsFloat | kLinearPCMFormatFlagIsBigEndian | kLinearPCMFormatFlagIsSignedInteger | kLinearPCMFormatFlagIsPacked | kLinearPCMFormatFlagsSampleFractionMask);
|
||||
bool interleaved = (mFormatFlags & kAudioFormatFlagIsNonInterleaved) == 0;
|
||||
unsigned sampleSize = SizeOf32(AudioSampleType);
|
||||
reqFormatFlags = kAudioFormatFlagsCanonical;
|
||||
UInt32 reqFrameSize = interleaved ? (mChannelsPerFrame * sampleSize) : sampleSize;
|
||||
|
||||
return ((mFormatFlags & flagsMask) == reqFormatFlags
|
||||
&& mBitsPerChannel == 8 * sampleSize
|
||||
&& mFramesPerPacket == 1
|
||||
&& mBytesPerFrame == reqFrameSize
|
||||
&& mBytesPerPacket == reqFrameSize);
|
||||
}
|
||||
|
||||
void SetAUCanonical(UInt32 nChannels, bool interleaved)
|
||||
{
|
||||
mFormatID = kAudioFormatLinearPCM;
|
||||
#if CA_PREFER_FIXED_POINT
|
||||
mFormatFlags = kAudioFormatFlagsCanonical | (kAudioUnitSampleFractionBits << kLinearPCMFormatFlagsSampleFractionShift);
|
||||
#else
|
||||
mFormatFlags = kAudioFormatFlagsCanonical;
|
||||
#endif
|
||||
mChannelsPerFrame = nChannels;
|
||||
mFramesPerPacket = 1;
|
||||
mBitsPerChannel = 8 * SizeOf32(AudioUnitSampleType);
|
||||
if (interleaved)
|
||||
mBytesPerPacket = mBytesPerFrame = nChannels * SizeOf32(AudioUnitSampleType);
|
||||
else {
|
||||
mBytesPerPacket = mBytesPerFrame = SizeOf32(AudioUnitSampleType);
|
||||
mFormatFlags |= kAudioFormatFlagIsNonInterleaved;
|
||||
}
|
||||
}
|
||||
|
||||
void ChangeNumberChannels(UInt32 nChannels, bool interleaved)
|
||||
// alter an existing format
|
||||
{
|
||||
Assert(IsPCM(), "ChangeNumberChannels only works for PCM formats");
|
||||
UInt32 wordSize = SampleWordSize(); // get this before changing ANYTHING
|
||||
if (wordSize == 0)
|
||||
wordSize = (mBitsPerChannel + 7) / 8;
|
||||
mChannelsPerFrame = nChannels;
|
||||
mFramesPerPacket = 1;
|
||||
if (interleaved) {
|
||||
mBytesPerPacket = mBytesPerFrame = nChannels * wordSize;
|
||||
mFormatFlags &= ~static_cast<UInt32>(kAudioFormatFlagIsNonInterleaved);
|
||||
} else {
|
||||
mBytesPerPacket = mBytesPerFrame = wordSize;
|
||||
mFormatFlags |= kAudioFormatFlagIsNonInterleaved;
|
||||
}
|
||||
}
|
||||
|
||||
// _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _
|
||||
//
|
||||
// other
|
||||
|
||||
bool IsEqual(const AudioStreamBasicDescription &other, bool interpretingWildcards=true) const;
|
||||
static bool FlagIndependentEquivalence(const AudioStreamBasicDescription &x, const AudioStreamBasicDescription &y);
|
||||
static bool IsFunctionallyEquivalent(const AudioStreamBasicDescription &x, const AudioStreamBasicDescription &y);
|
||||
|
||||
void Print() const {
|
||||
Print (stdout);
|
||||
}
|
||||
|
||||
void Print(FILE* file) const {
|
||||
PrintFormat (file, "", "AudioStreamBasicDescription:");
|
||||
}
|
||||
|
||||
void PrintFormat(FILE *f, const char *indent, const char *name) const {
|
||||
char buf[256];
|
||||
fprintf(f, "%s%s %s\n", indent, name, AsString(buf, sizeof(buf)));
|
||||
}
|
||||
|
||||
void PrintFormat2(FILE *f, const char *indent, const char *name) const { // no trailing newline
|
||||
char buf[256];
|
||||
fprintf(f, "%s%s %s", indent, name, AsString(buf, sizeof(buf)));
|
||||
}
|
||||
|
||||
char * AsString(char *buf, size_t bufsize, bool brief=false) const;
|
||||
|
||||
static void Print (const AudioStreamBasicDescription &inDesc)
|
||||
{
|
||||
CAStreamBasicDescription desc(inDesc);
|
||||
desc.Print ();
|
||||
}
|
||||
|
||||
OSStatus Save(CFPropertyListRef *outData) const;
|
||||
|
||||
OSStatus Restore(CFPropertyListRef &inData);
|
||||
|
||||
// Operations
|
||||
static bool IsMixable(const AudioStreamBasicDescription& inDescription) { return (inDescription.mFormatID == kAudioFormatLinearPCM) && ((inDescription.mFormatFlags & kIsNonMixableFlag) == 0); }
|
||||
static void NormalizeLinearPCMFormat(AudioStreamBasicDescription& ioDescription);
|
||||
static void NormalizeLinearPCMFormat(bool inNativeEndian, AudioStreamBasicDescription& ioDescription);
|
||||
static void ResetFormat(AudioStreamBasicDescription& ioDescription);
|
||||
static void FillOutFormat(AudioStreamBasicDescription& ioDescription, const AudioStreamBasicDescription& inTemplateDescription);
|
||||
static void GetSimpleName(const AudioStreamBasicDescription& inDescription, char* outName, UInt32 inMaxNameLength, bool inAbbreviate, bool inIncludeSampleRate = false);
|
||||
static void ModifyFormatFlagsForMatching(const AudioStreamBasicDescription& x, const AudioStreamBasicDescription& y, UInt32& xFlags, UInt32& yFlags, bool converterOnly);
|
||||
|
||||
#if CoreAudio_Debug
|
||||
static void PrintToLog(const AudioStreamBasicDescription& inDesc);
|
||||
#endif
|
||||
};
|
||||
|
||||
bool operator<(const AudioStreamBasicDescription& x, const AudioStreamBasicDescription& y);
|
||||
bool operator==(const AudioStreamBasicDescription& x, const AudioStreamBasicDescription& y);
|
||||
#if TARGET_OS_MAC || (TARGET_OS_WIN32 && (_MSC_VER > 600))
|
||||
inline bool operator!=(const AudioStreamBasicDescription& x, const AudioStreamBasicDescription& y) { return !(x == y); }
|
||||
inline bool operator<=(const AudioStreamBasicDescription& x, const AudioStreamBasicDescription& y) { return (x < y) || (x == y); }
|
||||
inline bool operator>=(const AudioStreamBasicDescription& x, const AudioStreamBasicDescription& y) { return !(x < y); }
|
||||
inline bool operator>(const AudioStreamBasicDescription& x, const AudioStreamBasicDescription& y) { return !((x < y) || (x == y)); }
|
||||
#endif
|
||||
|
||||
bool SanityCheck(const AudioStreamBasicDescription& x);
|
||||
|
||||
|
||||
#endif // __CAStreamBasicDescription_h__
|
||||
|
||||
@@ -1,233 +1,233 @@
|
||||
/*
|
||||
File: CAThreadSafeList.h
|
||||
Abstract: Part of CoreAudio Utility Classes
|
||||
Version: 1.1
|
||||
|
||||
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.
|
||||
|
||||
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.
|
||||
|
||||
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.
|
||||
|
||||
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.
|
||||
|
||||
Copyright (C) 2014 Apple Inc. All Rights Reserved.
|
||||
|
||||
*/
|
||||
#ifndef __CAThreadSafeList_h__
|
||||
#define __CAThreadSafeList_h__
|
||||
|
||||
#include "CAAtomicStack.h"
|
||||
|
||||
// linked list of T's
|
||||
// T must define operator ==
|
||||
template <class T>
|
||||
class TThreadSafeList {
|
||||
private:
|
||||
enum EEventType { kAdd, kRemove, kClear };
|
||||
class Node {
|
||||
public:
|
||||
Node * mNext;
|
||||
EEventType mEventType;
|
||||
T mObject;
|
||||
|
||||
Node *& next() { return mNext; }
|
||||
};
|
||||
|
||||
public:
|
||||
class iterator {
|
||||
public:
|
||||
iterator() { }
|
||||
iterator(Node *n) : mNode(n) { }
|
||||
|
||||
bool operator == (const iterator &other) const { return this->mNode == other.mNode; }
|
||||
bool operator != (const iterator &other) const { return this->mNode != other.mNode; }
|
||||
|
||||
T & operator * () const { return mNode->mObject; }
|
||||
|
||||
iterator & operator ++ () { mNode = mNode->next(); return *this; } // preincrement
|
||||
iterator operator ++ (int) { iterator tmp = *this; mNode = mNode->next(); return tmp; } // postincrement
|
||||
|
||||
private:
|
||||
Node * mNode;
|
||||
};
|
||||
|
||||
TThreadSafeList() { }
|
||||
~TThreadSafeList()
|
||||
{
|
||||
mActiveList.free_all();
|
||||
mPendingList.free_all();
|
||||
mFreeList.free_all();
|
||||
}
|
||||
|
||||
// These may be called on any thread
|
||||
|
||||
void deferred_add(const T &obj) // can be called on any thread
|
||||
{
|
||||
Node *node = AllocNode();
|
||||
node->mEventType = kAdd;
|
||||
node->mObject = obj;
|
||||
mPendingList.push_atomic(node);
|
||||
//mPendingList.dump("pending after add");
|
||||
}
|
||||
|
||||
void deferred_remove(const T &obj) // can be called on any thread
|
||||
{
|
||||
Node *node = AllocNode();
|
||||
node->mEventType = kRemove;
|
||||
node->mObject = obj;
|
||||
mPendingList.push_atomic(node);
|
||||
//mPendingList.dump("pending after remove");
|
||||
}
|
||||
|
||||
void deferred_clear() // can be called on any thread
|
||||
{
|
||||
Node *node = AllocNode();
|
||||
node->mEventType = kClear;
|
||||
mPendingList.push_atomic(node);
|
||||
}
|
||||
|
||||
// These must be called from only one thread
|
||||
|
||||
void update() // must only be called from one thread
|
||||
{
|
||||
NodeStack reversed;
|
||||
Node *event, *node, *next;
|
||||
bool workDone = false;
|
||||
|
||||
// reverse the events so they are in order
|
||||
event = mPendingList.pop_all();
|
||||
while (event != NULL) {
|
||||
next = event->mNext;
|
||||
reversed.push_NA(event);
|
||||
event = next;
|
||||
workDone = true;
|
||||
}
|
||||
if (workDone) {
|
||||
//reversed.dump("pending popped");
|
||||
//mActiveList.dump("active before update");
|
||||
|
||||
// now process them
|
||||
while ((event = reversed.pop_NA()) != NULL) {
|
||||
switch (event->mEventType) {
|
||||
case kAdd:
|
||||
{
|
||||
Node **pnode;
|
||||
bool needToInsert = true;
|
||||
for (pnode = mActiveList.phead(); *pnode != NULL; pnode = &node->mNext) {
|
||||
node = *pnode;
|
||||
if (node->mObject == event->mObject) {
|
||||
//printf("already active!!!\n");
|
||||
FreeNode(event);
|
||||
needToInsert = false;
|
||||
break;
|
||||
}
|
||||
}
|
||||
if (needToInsert) {
|
||||
// link the new event in at the end of the active list
|
||||
*pnode = event;
|
||||
event->mNext = NULL;
|
||||
}
|
||||
}
|
||||
break;
|
||||
case kRemove:
|
||||
// find matching node in the active list, remove it
|
||||
for (Node **pnode = mActiveList.phead(); *pnode != NULL; ) {
|
||||
node = *pnode;
|
||||
if (node->mObject == event->mObject) {
|
||||
*pnode = node->mNext; // remove from linked list
|
||||
FreeNode(node);
|
||||
break;
|
||||
}
|
||||
pnode = &node->mNext;
|
||||
}
|
||||
// dispose the request node
|
||||
FreeNode(event);
|
||||
break;
|
||||
case kClear:
|
||||
for (node = mActiveList.head(); node != NULL; ) {
|
||||
next = node->mNext;
|
||||
FreeNode(node);
|
||||
node = next;
|
||||
}
|
||||
FreeNode(event);
|
||||
break;
|
||||
default:
|
||||
//printf("invalid node type %d!\n", event->mEventType);
|
||||
break;
|
||||
}
|
||||
}
|
||||
//mActiveList.dump("active after update");
|
||||
}
|
||||
}
|
||||
|
||||
iterator begin() const {
|
||||
//mActiveList.dump("active at begin");
|
||||
return iterator(mActiveList.head());
|
||||
}
|
||||
iterator end() const { return iterator(NULL); }
|
||||
|
||||
|
||||
private:
|
||||
Node * AllocNode()
|
||||
{
|
||||
Node *node = mFreeList.pop_atomic();
|
||||
if (node == NULL)
|
||||
node = (Node *)CA_malloc(sizeof(Node));
|
||||
return node;
|
||||
}
|
||||
|
||||
void FreeNode(Node *node)
|
||||
{
|
||||
mFreeList.push_atomic(node);
|
||||
}
|
||||
|
||||
private:
|
||||
class NodeStack : public TAtomicStack<Node> {
|
||||
public:
|
||||
void free_all() {
|
||||
Node *node;
|
||||
while ((node = this->pop_NA()) != NULL)
|
||||
free(node);
|
||||
}
|
||||
|
||||
Node ** phead() { return &this->mHead; }
|
||||
Node * head() const { return this->mHead; }
|
||||
};
|
||||
|
||||
NodeStack mActiveList; // what's actually in the container - only accessed on one thread
|
||||
NodeStack mPendingList; // add or remove requests - threadsafe
|
||||
NodeStack mFreeList; // free nodes for reuse - threadsafe
|
||||
};
|
||||
|
||||
#endif // __CAThreadSafeList_h__
|
||||
/*
|
||||
File: CAThreadSafeList.h
|
||||
Abstract: Part of CoreAudio Utility Classes
|
||||
Version: 1.1
|
||||
|
||||
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.
|
||||
|
||||
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.
|
||||
|
||||
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.
|
||||
|
||||
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.
|
||||
|
||||
Copyright (C) 2014 Apple Inc. All Rights Reserved.
|
||||
|
||||
*/
|
||||
#ifndef __CAThreadSafeList_h__
|
||||
#define __CAThreadSafeList_h__
|
||||
|
||||
#include "CAAtomicStack.h"
|
||||
|
||||
// linked list of T's
|
||||
// T must define operator ==
|
||||
template <class T>
|
||||
class TThreadSafeList {
|
||||
private:
|
||||
enum EEventType { kAdd, kRemove, kClear };
|
||||
class Node {
|
||||
public:
|
||||
Node * mNext;
|
||||
EEventType mEventType;
|
||||
T mObject;
|
||||
|
||||
Node *& next() { return mNext; }
|
||||
};
|
||||
|
||||
public:
|
||||
class iterator {
|
||||
public:
|
||||
iterator() { }
|
||||
iterator(Node *n) : mNode(n) { }
|
||||
|
||||
bool operator == (const iterator &other) const { return this->mNode == other.mNode; }
|
||||
bool operator != (const iterator &other) const { return this->mNode != other.mNode; }
|
||||
|
||||
T & operator * () const { return mNode->mObject; }
|
||||
|
||||
iterator & operator ++ () { mNode = mNode->next(); return *this; } // preincrement
|
||||
iterator operator ++ (int) { iterator tmp = *this; mNode = mNode->next(); return tmp; } // postincrement
|
||||
|
||||
private:
|
||||
Node * mNode;
|
||||
};
|
||||
|
||||
TThreadSafeList() { }
|
||||
~TThreadSafeList()
|
||||
{
|
||||
mActiveList.free_all();
|
||||
mPendingList.free_all();
|
||||
mFreeList.free_all();
|
||||
}
|
||||
|
||||
// These may be called on any thread
|
||||
|
||||
void deferred_add(const T &obj) // can be called on any thread
|
||||
{
|
||||
Node *node = AllocNode();
|
||||
node->mEventType = kAdd;
|
||||
node->mObject = obj;
|
||||
mPendingList.push_atomic(node);
|
||||
//mPendingList.dump("pending after add");
|
||||
}
|
||||
|
||||
void deferred_remove(const T &obj) // can be called on any thread
|
||||
{
|
||||
Node *node = AllocNode();
|
||||
node->mEventType = kRemove;
|
||||
node->mObject = obj;
|
||||
mPendingList.push_atomic(node);
|
||||
//mPendingList.dump("pending after remove");
|
||||
}
|
||||
|
||||
void deferred_clear() // can be called on any thread
|
||||
{
|
||||
Node *node = AllocNode();
|
||||
node->mEventType = kClear;
|
||||
mPendingList.push_atomic(node);
|
||||
}
|
||||
|
||||
// These must be called from only one thread
|
||||
|
||||
void update() // must only be called from one thread
|
||||
{
|
||||
NodeStack reversed;
|
||||
Node *event, *node, *next;
|
||||
bool workDone = false;
|
||||
|
||||
// reverse the events so they are in order
|
||||
event = mPendingList.pop_all();
|
||||
while (event != NULL) {
|
||||
next = event->mNext;
|
||||
reversed.push_NA(event);
|
||||
event = next;
|
||||
workDone = true;
|
||||
}
|
||||
if (workDone) {
|
||||
//reversed.dump("pending popped");
|
||||
//mActiveList.dump("active before update");
|
||||
|
||||
// now process them
|
||||
while ((event = reversed.pop_NA()) != NULL) {
|
||||
switch (event->mEventType) {
|
||||
case kAdd:
|
||||
{
|
||||
Node **pnode;
|
||||
bool needToInsert = true;
|
||||
for (pnode = mActiveList.phead(); *pnode != NULL; pnode = &node->mNext) {
|
||||
node = *pnode;
|
||||
if (node->mObject == event->mObject) {
|
||||
//printf("already active!!!\n");
|
||||
FreeNode(event);
|
||||
needToInsert = false;
|
||||
break;
|
||||
}
|
||||
}
|
||||
if (needToInsert) {
|
||||
// link the new event in at the end of the active list
|
||||
*pnode = event;
|
||||
event->mNext = NULL;
|
||||
}
|
||||
}
|
||||
break;
|
||||
case kRemove:
|
||||
// find matching node in the active list, remove it
|
||||
for (Node **pnode = mActiveList.phead(); *pnode != NULL; ) {
|
||||
node = *pnode;
|
||||
if (node->mObject == event->mObject) {
|
||||
*pnode = node->mNext; // remove from linked list
|
||||
FreeNode(node);
|
||||
break;
|
||||
}
|
||||
pnode = &node->mNext;
|
||||
}
|
||||
// dispose the request node
|
||||
FreeNode(event);
|
||||
break;
|
||||
case kClear:
|
||||
for (node = mActiveList.head(); node != NULL; ) {
|
||||
next = node->mNext;
|
||||
FreeNode(node);
|
||||
node = next;
|
||||
}
|
||||
FreeNode(event);
|
||||
break;
|
||||
default:
|
||||
//printf("invalid node type %d!\n", event->mEventType);
|
||||
break;
|
||||
}
|
||||
}
|
||||
//mActiveList.dump("active after update");
|
||||
}
|
||||
}
|
||||
|
||||
iterator begin() const {
|
||||
//mActiveList.dump("active at begin");
|
||||
return iterator(mActiveList.head());
|
||||
}
|
||||
iterator end() const { return iterator(NULL); }
|
||||
|
||||
|
||||
private:
|
||||
Node * AllocNode()
|
||||
{
|
||||
Node *node = mFreeList.pop_atomic();
|
||||
if (node == NULL)
|
||||
node = (Node *)CA_malloc(sizeof(Node));
|
||||
return node;
|
||||
}
|
||||
|
||||
void FreeNode(Node *node)
|
||||
{
|
||||
mFreeList.push_atomic(node);
|
||||
}
|
||||
|
||||
private:
|
||||
class NodeStack : public TAtomicStack<Node> {
|
||||
public:
|
||||
void free_all() {
|
||||
Node *node;
|
||||
while ((node = this->pop_NA()) != NULL)
|
||||
free(node);
|
||||
}
|
||||
|
||||
Node ** phead() { return &this->mHead; }
|
||||
Node * head() const { return this->mHead; }
|
||||
};
|
||||
|
||||
NodeStack mActiveList; // what's actually in the container - only accessed on one thread
|
||||
NodeStack mPendingList; // add or remove requests - threadsafe
|
||||
NodeStack mFreeList; // free nodes for reuse - threadsafe
|
||||
};
|
||||
|
||||
#endif // __CAThreadSafeList_h__
|
||||
|
||||
@@ -1,194 +1,194 @@
|
||||
/*
|
||||
File: CAVectorUnit.cpp
|
||||
Abstract: CAVectorUnit.h
|
||||
Version: 1.1
|
||||
|
||||
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.
|
||||
|
||||
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.
|
||||
|
||||
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.
|
||||
|
||||
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.
|
||||
|
||||
Copyright (C) 2014 Apple Inc. All Rights Reserved.
|
||||
|
||||
*/
|
||||
#include "CAVectorUnit.h"
|
||||
|
||||
#if !TARGET_OS_WIN32
|
||||
#include <sys/sysctl.h>
|
||||
#elif HAS_IPP
|
||||
#include "ippdefs.h"
|
||||
#include "ippcore.h"
|
||||
#endif
|
||||
|
||||
int gCAVectorUnitType = kVecUninitialized;
|
||||
|
||||
#if TARGET_OS_WIN32
|
||||
// Use cpuid to check if SSE2 is available.
|
||||
// Before calling this function make sure cpuid is available
|
||||
static SInt32 IsSSE2Available()
|
||||
{
|
||||
int return_value;
|
||||
|
||||
{
|
||||
int r_edx;
|
||||
_asm
|
||||
{
|
||||
mov eax, 0x01
|
||||
cpuid
|
||||
mov r_edx, edx
|
||||
}
|
||||
return_value = (r_edx >> 26) & 0x1;
|
||||
}
|
||||
return return_value;
|
||||
}
|
||||
|
||||
// Use cpuid to check if SSE3 is available.
|
||||
// Before calling this function make sure cpuid is available
|
||||
static SInt32 IsSSE3Available()
|
||||
{
|
||||
SInt32 return_value;
|
||||
|
||||
{
|
||||
SInt32 r_ecx;
|
||||
_asm
|
||||
{
|
||||
mov eax, 0x01
|
||||
cpuid
|
||||
mov r_ecx, ecx
|
||||
}
|
||||
return_value = r_ecx & 0x1;
|
||||
}
|
||||
return return_value;
|
||||
}
|
||||
|
||||
// Return true if the cpuid instruction is available.
|
||||
// The cpuid instruction is available if bit 21 in the EFLAGS register can be changed
|
||||
// This function may not work on Intel CPUs prior to Pentium (didn't test)
|
||||
static bool IsCpuidAvailable()
|
||||
{
|
||||
SInt32 return_value = 0x0;
|
||||
_asm{
|
||||
pushfd ; //push original EFLAGS
|
||||
pop eax ; //get original EFLAGS
|
||||
mov ecx, eax ; //save original EFLAGS
|
||||
xor eax, 200000h ; //flip ID bit in EFLAGS
|
||||
push eax ; //save new EFLAGS value on stack
|
||||
popfd ; //replace current EFLAGS value
|
||||
pushfd ; //get new EFLAGS
|
||||
pop eax ; //store new EFLAGS in EAX
|
||||
xor eax, ecx ;
|
||||
je end_cpuid_identify ; //can't toggle ID bit
|
||||
mov return_value, 0x1;
|
||||
end_cpuid_identify:
|
||||
nop;
|
||||
}
|
||||
return return_value;
|
||||
}
|
||||
|
||||
#endif
|
||||
|
||||
SInt32 CAVectorUnit_Examine()
|
||||
{
|
||||
int result = kVecNone;
|
||||
|
||||
#if TARGET_OS_WIN32
|
||||
#if HAS_IPP
|
||||
// Initialize the static IPP library! This needs to be done before
|
||||
// any IPP function calls, otherwise we may have a performance penalty
|
||||
int status = ippStaticInit();
|
||||
if ( status == ippStsNonIntelCpu )
|
||||
{
|
||||
IppCpuType cpuType = ippGetCpuType();
|
||||
if ( cpuType >= ippCpuSSE || cpuType <= ippCpuSSE42 )
|
||||
ippStaticInitCpu( cpuType );
|
||||
}
|
||||
#endif
|
||||
{
|
||||
// On Windows we use cpuid to detect the vector unit because it works on Intel and AMD.
|
||||
// The IPP library does not detect SSE on AMD processors.
|
||||
if (IsCpuidAvailable())
|
||||
{
|
||||
if(IsSSE3Available())
|
||||
{
|
||||
result = kVecSSE3;
|
||||
}
|
||||
else if(IsSSE2Available())
|
||||
{
|
||||
result = kVecSSE2;
|
||||
}
|
||||
}
|
||||
}
|
||||
#elif TARGET_OS_MAC
|
||||
#if DEBUG
|
||||
if (getenv("CA_NoVector")) {
|
||||
fprintf(stderr, "CA_NoVector set; Vector unit optimized routines will be bypassed\n");
|
||||
return result;
|
||||
}
|
||||
else
|
||||
#endif
|
||||
{
|
||||
#if (TARGET_CPU_PPC || TARGET_CPU_PPC64)
|
||||
int sels[2] = { CTL_HW, HW_VECTORUNIT };
|
||||
int vType = 0; //0 == scalar only
|
||||
size_t length = sizeof(vType);
|
||||
int error = sysctl(sels, 2, &vType, &length, NULL, 0);
|
||||
if (!error && vType > 0)
|
||||
result = kVecAltivec;
|
||||
#elif (TARGET_CPU_X86 || TARGET_CPU_X86_64)
|
||||
static const struct { const char* kName; const int kVectype; } kStringVectypes[] = {
|
||||
{ "hw.optional.avx1_0", kVecAVX1 }, { "hw.optional.sse3", kVecSSE3 }, { "hw.optional.sse2", kVecSSE2 }
|
||||
};
|
||||
static const size_t kNumStringVectypes = sizeof(kStringVectypes)/sizeof(kStringVectypes[0]);
|
||||
int i = 0, answer = 0;
|
||||
while(i != kNumStringVectypes)
|
||||
{
|
||||
size_t length = sizeof(answer);
|
||||
int error = sysctlbyname(kStringVectypes[i].kName, &answer, &length, NULL, 0);
|
||||
if (!error && answer)
|
||||
{
|
||||
result = kStringVectypes[i].kVectype;
|
||||
break;
|
||||
}
|
||||
++i;
|
||||
};
|
||||
#elif CA_ARM_NEON
|
||||
result = kVecNeon;
|
||||
#endif
|
||||
}
|
||||
#endif
|
||||
gCAVectorUnitType = result;
|
||||
return result;
|
||||
}
|
||||
/*
|
||||
File: CAVectorUnit.cpp
|
||||
Abstract: CAVectorUnit.h
|
||||
Version: 1.1
|
||||
|
||||
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.
|
||||
|
||||
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.
|
||||
|
||||
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.
|
||||
|
||||
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.
|
||||
|
||||
Copyright (C) 2014 Apple Inc. All Rights Reserved.
|
||||
|
||||
*/
|
||||
#include "CAVectorUnit.h"
|
||||
|
||||
#if !TARGET_OS_WIN32
|
||||
#include <sys/sysctl.h>
|
||||
#elif HAS_IPP
|
||||
#include "ippdefs.h"
|
||||
#include "ippcore.h"
|
||||
#endif
|
||||
|
||||
int gCAVectorUnitType = kVecUninitialized;
|
||||
|
||||
#if TARGET_OS_WIN32
|
||||
// Use cpuid to check if SSE2 is available.
|
||||
// Before calling this function make sure cpuid is available
|
||||
static SInt32 IsSSE2Available()
|
||||
{
|
||||
int return_value;
|
||||
|
||||
{
|
||||
int r_edx;
|
||||
_asm
|
||||
{
|
||||
mov eax, 0x01
|
||||
cpuid
|
||||
mov r_edx, edx
|
||||
}
|
||||
return_value = (r_edx >> 26) & 0x1;
|
||||
}
|
||||
return return_value;
|
||||
}
|
||||
|
||||
// Use cpuid to check if SSE3 is available.
|
||||
// Before calling this function make sure cpuid is available
|
||||
static SInt32 IsSSE3Available()
|
||||
{
|
||||
SInt32 return_value;
|
||||
|
||||
{
|
||||
SInt32 r_ecx;
|
||||
_asm
|
||||
{
|
||||
mov eax, 0x01
|
||||
cpuid
|
||||
mov r_ecx, ecx
|
||||
}
|
||||
return_value = r_ecx & 0x1;
|
||||
}
|
||||
return return_value;
|
||||
}
|
||||
|
||||
// Return true if the cpuid instruction is available.
|
||||
// The cpuid instruction is available if bit 21 in the EFLAGS register can be changed
|
||||
// This function may not work on Intel CPUs prior to Pentium (didn't test)
|
||||
static bool IsCpuidAvailable()
|
||||
{
|
||||
SInt32 return_value = 0x0;
|
||||
_asm{
|
||||
pushfd ; //push original EFLAGS
|
||||
pop eax ; //get original EFLAGS
|
||||
mov ecx, eax ; //save original EFLAGS
|
||||
xor eax, 200000h ; //flip ID bit in EFLAGS
|
||||
push eax ; //save new EFLAGS value on stack
|
||||
popfd ; //replace current EFLAGS value
|
||||
pushfd ; //get new EFLAGS
|
||||
pop eax ; //store new EFLAGS in EAX
|
||||
xor eax, ecx ;
|
||||
je end_cpuid_identify ; //can't toggle ID bit
|
||||
mov return_value, 0x1;
|
||||
end_cpuid_identify:
|
||||
nop;
|
||||
}
|
||||
return return_value;
|
||||
}
|
||||
|
||||
#endif
|
||||
|
||||
SInt32 CAVectorUnit_Examine()
|
||||
{
|
||||
int result = kVecNone;
|
||||
|
||||
#if TARGET_OS_WIN32
|
||||
#if HAS_IPP
|
||||
// Initialize the static IPP library! This needs to be done before
|
||||
// any IPP function calls, otherwise we may have a performance penalty
|
||||
int status = ippStaticInit();
|
||||
if ( status == ippStsNonIntelCpu )
|
||||
{
|
||||
IppCpuType cpuType = ippGetCpuType();
|
||||
if ( cpuType >= ippCpuSSE || cpuType <= ippCpuSSE42 )
|
||||
ippStaticInitCpu( cpuType );
|
||||
}
|
||||
#endif
|
||||
{
|
||||
// On Windows we use cpuid to detect the vector unit because it works on Intel and AMD.
|
||||
// The IPP library does not detect SSE on AMD processors.
|
||||
if (IsCpuidAvailable())
|
||||
{
|
||||
if(IsSSE3Available())
|
||||
{
|
||||
result = kVecSSE3;
|
||||
}
|
||||
else if(IsSSE2Available())
|
||||
{
|
||||
result = kVecSSE2;
|
||||
}
|
||||
}
|
||||
}
|
||||
#elif TARGET_OS_MAC
|
||||
#if DEBUG
|
||||
if (getenv("CA_NoVector")) {
|
||||
fprintf(stderr, "CA_NoVector set; Vector unit optimized routines will be bypassed\n");
|
||||
return result;
|
||||
}
|
||||
else
|
||||
#endif
|
||||
{
|
||||
#if (TARGET_CPU_PPC || TARGET_CPU_PPC64)
|
||||
int sels[2] = { CTL_HW, HW_VECTORUNIT };
|
||||
int vType = 0; //0 == scalar only
|
||||
size_t length = sizeof(vType);
|
||||
int error = sysctl(sels, 2, &vType, &length, NULL, 0);
|
||||
if (!error && vType > 0)
|
||||
result = kVecAltivec;
|
||||
#elif (TARGET_CPU_X86 || TARGET_CPU_X86_64)
|
||||
static const struct { const char* kName; const int kVectype; } kStringVectypes[] = {
|
||||
{ "hw.optional.avx1_0", kVecAVX1 }, { "hw.optional.sse3", kVecSSE3 }, { "hw.optional.sse2", kVecSSE2 }
|
||||
};
|
||||
static const size_t kNumStringVectypes = sizeof(kStringVectypes)/sizeof(kStringVectypes[0]);
|
||||
int i = 0, answer = 0;
|
||||
while(i != kNumStringVectypes)
|
||||
{
|
||||
size_t length = sizeof(answer);
|
||||
int error = sysctlbyname(kStringVectypes[i].kName, &answer, &length, NULL, 0);
|
||||
if (!error && answer)
|
||||
{
|
||||
result = kStringVectypes[i].kVectype;
|
||||
break;
|
||||
}
|
||||
++i;
|
||||
};
|
||||
#elif CA_ARM_NEON
|
||||
result = kVecNeon;
|
||||
#endif
|
||||
}
|
||||
#endif
|
||||
gCAVectorUnitType = result;
|
||||
return result;
|
||||
}
|
||||
|
||||
@@ -1,101 +1,101 @@
|
||||
/*
|
||||
File: CAVectorUnit.h
|
||||
Abstract: Part of CoreAudio Utility Classes
|
||||
Version: 1.1
|
||||
|
||||
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.
|
||||
|
||||
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.
|
||||
|
||||
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.
|
||||
|
||||
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.
|
||||
|
||||
Copyright (C) 2014 Apple Inc. All Rights Reserved.
|
||||
|
||||
*/
|
||||
#ifndef __CAVectorUnit_h__
|
||||
#define __CAVectorUnit_h__
|
||||
|
||||
#include <TargetConditionals.h>
|
||||
#include "CAVectorUnitTypes.h"
|
||||
#include <stdlib.h>
|
||||
#include <stdio.h>
|
||||
|
||||
#if !defined(__COREAUDIO_USE_FLAT_INCLUDES__)
|
||||
#include <CoreFoundation/CFBase.h>
|
||||
#else
|
||||
#include "CFBase.h"
|
||||
#endif
|
||||
|
||||
// Unify checks for vector units.
|
||||
// Allow setting an environment variable "CA_NoVector" to turn off vectorized code at runtime (very useful for performance testing).
|
||||
|
||||
extern int gCAVectorUnitType;
|
||||
|
||||
#ifdef __cplusplus
|
||||
extern "C" {
|
||||
#endif
|
||||
|
||||
extern SInt32 CAVectorUnit_Examine(); // expensive. use GetType() for lazy initialization and caching.
|
||||
|
||||
static inline SInt32 CAVectorUnit_GetType()
|
||||
{
|
||||
int x = gCAVectorUnitType;
|
||||
return (x != kVecUninitialized) ? x : CAVectorUnit_Examine();
|
||||
}
|
||||
|
||||
static inline Boolean CAVectorUnit_HasVectorUnit()
|
||||
{
|
||||
return CAVectorUnit_GetType() > kVecNone;
|
||||
}
|
||||
|
||||
#ifdef __cplusplus
|
||||
}
|
||||
#endif
|
||||
|
||||
|
||||
#ifdef __cplusplus
|
||||
class CAVectorUnit {
|
||||
public:
|
||||
static SInt32 GetVectorUnitType() { return CAVectorUnit_GetType(); }
|
||||
static bool HasVectorUnit() { return GetVectorUnitType() > kVecNone; }
|
||||
static bool HasAltivec() { return GetVectorUnitType() == kVecAltivec; }
|
||||
static bool HasSSE2() { return GetVectorUnitType() >= kVecSSE2; }
|
||||
static bool HasSSE3() { return GetVectorUnitType() >= kVecSSE3; }
|
||||
static bool HasAVX1() { return GetVectorUnitType() >= kVecAVX1; }
|
||||
static bool HasNeon() { return GetVectorUnitType() == kVecNeon; }
|
||||
};
|
||||
#endif
|
||||
|
||||
#endif // __CAVectorUnit_h__
|
||||
/*
|
||||
File: CAVectorUnit.h
|
||||
Abstract: Part of CoreAudio Utility Classes
|
||||
Version: 1.1
|
||||
|
||||
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.
|
||||
|
||||
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.
|
||||
|
||||
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.
|
||||
|
||||
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.
|
||||
|
||||
Copyright (C) 2014 Apple Inc. All Rights Reserved.
|
||||
|
||||
*/
|
||||
#ifndef __CAVectorUnit_h__
|
||||
#define __CAVectorUnit_h__
|
||||
|
||||
#include <TargetConditionals.h>
|
||||
#include "CAVectorUnitTypes.h"
|
||||
#include <stdlib.h>
|
||||
#include <stdio.h>
|
||||
|
||||
#if !defined(__COREAUDIO_USE_FLAT_INCLUDES__)
|
||||
#include <CoreFoundation/CFBase.h>
|
||||
#else
|
||||
#include "CFBase.h"
|
||||
#endif
|
||||
|
||||
// Unify checks for vector units.
|
||||
// Allow setting an environment variable "CA_NoVector" to turn off vectorized code at runtime (very useful for performance testing).
|
||||
|
||||
extern int gCAVectorUnitType;
|
||||
|
||||
#ifdef __cplusplus
|
||||
extern "C" {
|
||||
#endif
|
||||
|
||||
extern SInt32 CAVectorUnit_Examine(); // expensive. use GetType() for lazy initialization and caching.
|
||||
|
||||
static inline SInt32 CAVectorUnit_GetType()
|
||||
{
|
||||
int x = gCAVectorUnitType;
|
||||
return (x != kVecUninitialized) ? x : CAVectorUnit_Examine();
|
||||
}
|
||||
|
||||
static inline Boolean CAVectorUnit_HasVectorUnit()
|
||||
{
|
||||
return CAVectorUnit_GetType() > kVecNone;
|
||||
}
|
||||
|
||||
#ifdef __cplusplus
|
||||
}
|
||||
#endif
|
||||
|
||||
|
||||
#ifdef __cplusplus
|
||||
class CAVectorUnit {
|
||||
public:
|
||||
static SInt32 GetVectorUnitType() { return CAVectorUnit_GetType(); }
|
||||
static bool HasVectorUnit() { return GetVectorUnitType() > kVecNone; }
|
||||
static bool HasAltivec() { return GetVectorUnitType() == kVecAltivec; }
|
||||
static bool HasSSE2() { return GetVectorUnitType() >= kVecSSE2; }
|
||||
static bool HasSSE3() { return GetVectorUnitType() >= kVecSSE3; }
|
||||
static bool HasAVX1() { return GetVectorUnitType() >= kVecAVX1; }
|
||||
static bool HasNeon() { return GetVectorUnitType() == kVecNeon; }
|
||||
};
|
||||
#endif
|
||||
|
||||
#endif // __CAVectorUnit_h__
|
||||
|
||||
@@ -1,60 +1,60 @@
|
||||
/*
|
||||
File: CAVectorUnitTypes.h
|
||||
Abstract: Part of CoreAudio Utility Classes
|
||||
Version: 1.1
|
||||
|
||||
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.
|
||||
|
||||
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.
|
||||
|
||||
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.
|
||||
|
||||
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.
|
||||
|
||||
Copyright (C) 2014 Apple Inc. All Rights Reserved.
|
||||
|
||||
*/
|
||||
#ifndef __CAVectorUnitTypes_h__
|
||||
#define __CAVectorUnitTypes_h__
|
||||
|
||||
enum {
|
||||
kVecUninitialized = -1,
|
||||
kVecNone = 0,
|
||||
kVecAltivec = 1,
|
||||
kVecSSE2 = 100,
|
||||
kVecSSE3 = 101,
|
||||
kVecAVX1 = 110,
|
||||
kVecNeon = 200
|
||||
};
|
||||
|
||||
#endif
|
||||
/*
|
||||
File: CAVectorUnitTypes.h
|
||||
Abstract: Part of CoreAudio Utility Classes
|
||||
Version: 1.1
|
||||
|
||||
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.
|
||||
|
||||
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.
|
||||
|
||||
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.
|
||||
|
||||
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.
|
||||
|
||||
Copyright (C) 2014 Apple Inc. All Rights Reserved.
|
||||
|
||||
*/
|
||||
#ifndef __CAVectorUnitTypes_h__
|
||||
#define __CAVectorUnitTypes_h__
|
||||
|
||||
enum {
|
||||
kVecUninitialized = -1,
|
||||
kVecNone = 0,
|
||||
kVecAltivec = 1,
|
||||
kVecSSE2 = 100,
|
||||
kVecSSE3 = 101,
|
||||
kVecAVX1 = 110,
|
||||
kVecNeon = 200
|
||||
};
|
||||
|
||||
#endif
|
||||
|
||||
@@ -1,361 +1,361 @@
|
||||
/*
|
||||
File: CAXException.h
|
||||
Abstract: Part of CoreAudio Utility Classes
|
||||
Version: 1.1
|
||||
|
||||
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.
|
||||
|
||||
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.
|
||||
|
||||
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.
|
||||
|
||||
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.
|
||||
|
||||
Copyright (C) 2014 Apple Inc. All Rights Reserved.
|
||||
|
||||
*/
|
||||
#ifndef __CAXException_h__
|
||||
#define __CAXException_h__
|
||||
|
||||
#if !defined(__COREAUDIO_USE_FLAT_INCLUDES__)
|
||||
#include <CoreFoundation/CoreFoundation.h>
|
||||
#else
|
||||
#include <ConditionalMacros.h>
|
||||
#include <CoreFoundation.h>
|
||||
#endif
|
||||
#include "CADebugMacros.h"
|
||||
#include <ctype.h>
|
||||
//#include <stdio.h>
|
||||
#include <string.h>
|
||||
|
||||
|
||||
class CAX4CCString {
|
||||
public:
|
||||
CAX4CCString(OSStatus error) {
|
||||
// see if it appears to be a 4-char-code
|
||||
UInt32 beErr = CFSwapInt32HostToBig(error);
|
||||
char *str = mStr;
|
||||
memcpy(str + 1, &beErr, 4);
|
||||
if (isprint(str[1]) && isprint(str[2]) && isprint(str[3]) && isprint(str[4])) {
|
||||
str[0] = str[5] = '\'';
|
||||
str[6] = '\0';
|
||||
} else if (error > -200000 && error < 200000)
|
||||
// no, format it as an integer
|
||||
snprintf(str, sizeof(mStr), "%d", (int)error);
|
||||
else
|
||||
snprintf(str, sizeof(mStr), "0x%x", (int)error);
|
||||
}
|
||||
const char *get() const { return mStr; }
|
||||
operator const char *() const { return mStr; }
|
||||
private:
|
||||
char mStr[16];
|
||||
};
|
||||
|
||||
class CAX4CCStringNoQuote {
|
||||
public:
|
||||
CAX4CCStringNoQuote(OSStatus error) {
|
||||
// see if it appears to be a 4-char-code
|
||||
UInt32 beErr = CFSwapInt32HostToBig(error);
|
||||
char *str = mStr;
|
||||
memcpy(str, &beErr, 4);
|
||||
if (isprint(str[0]) && isprint(str[1]) && isprint(str[2]) && isprint(str[3])) {
|
||||
str[4] = '\0';
|
||||
} else if (error > -200000 && error < 200000)
|
||||
// no, format it as an integer
|
||||
snprintf(str, sizeof(mStr), "%d", (int)error);
|
||||
else
|
||||
snprintf(str, sizeof(mStr), "0x%x", (int)error);
|
||||
}
|
||||
const char *get() const { return mStr; }
|
||||
operator const char *() const { return mStr; }
|
||||
private:
|
||||
char mStr[16];
|
||||
};
|
||||
|
||||
|
||||
// An extended exception class that includes the name of the failed operation
|
||||
class CAXException {
|
||||
public:
|
||||
CAXException(const char *operation, OSStatus err) :
|
||||
mError(err)
|
||||
{
|
||||
if (operation == NULL)
|
||||
mOperation[0] = '\0';
|
||||
else if (strlen(operation) >= sizeof(mOperation)) {
|
||||
memcpy(mOperation, operation, sizeof(mOperation) - 1);
|
||||
mOperation[sizeof(mOperation) - 1] = '\0';
|
||||
} else
|
||||
|
||||
strlcpy(mOperation, operation, sizeof(mOperation));
|
||||
}
|
||||
|
||||
char *FormatError(char *str, size_t strsize) const
|
||||
{
|
||||
return FormatError(str, strsize, mError);
|
||||
}
|
||||
|
||||
char mOperation[256];
|
||||
const OSStatus mError;
|
||||
|
||||
// -------------------------------------------------
|
||||
|
||||
typedef void (*WarningHandler)(const char *msg, OSStatus err);
|
||||
|
||||
static char *FormatError(char *str, size_t strsize, OSStatus error)
|
||||
{
|
||||
strlcpy(str, CAX4CCString(error), strsize);
|
||||
return str;
|
||||
}
|
||||
|
||||
static void Warning(const char *s, OSStatus error)
|
||||
{
|
||||
if (sWarningHandler)
|
||||
(*sWarningHandler)(s, error);
|
||||
}
|
||||
|
||||
static void SetWarningHandler(WarningHandler f) { sWarningHandler = f; }
|
||||
private:
|
||||
static WarningHandler sWarningHandler;
|
||||
};
|
||||
|
||||
#if DEBUG || CoreAudio_Debug
|
||||
#define XThrowIfError(error, operation) \
|
||||
do { \
|
||||
OSStatus __err = error; \
|
||||
if (__err) { \
|
||||
DebugMessageN4("%s:%d: about to throw %s: %s", __FILE__, __LINE__, CAX4CCString(__err).get(), operation);\
|
||||
__THROW_STOP; \
|
||||
throw CAXException(operation, __err); \
|
||||
} \
|
||||
} while (0)
|
||||
|
||||
#define XThrowIf(condition, error, operation) \
|
||||
do { \
|
||||
if (condition) { \
|
||||
OSStatus __err = error; \
|
||||
DebugMessageN4("%s:%d: about to throw %s: %s", __FILE__, __LINE__, CAX4CCString(__err).get(), operation);\
|
||||
__THROW_STOP; \
|
||||
throw CAXException(operation, __err); \
|
||||
} \
|
||||
} while (0)
|
||||
|
||||
#define XRequireNoError(error, label) \
|
||||
do { \
|
||||
OSStatus __err = error; \
|
||||
if (__err) { \
|
||||
DebugMessageN4("%s:%d: about to throw %s: %s", __FILE__, __LINE__, CAX4CCString(__err).get(), #error);\
|
||||
STOP; \
|
||||
goto label; \
|
||||
} \
|
||||
} while (0)
|
||||
|
||||
#define XAssert(assertion) \
|
||||
do { \
|
||||
if (!(assertion)) { \
|
||||
DebugMessageN3("%s:%d: error: failed assertion: %s", __FILE__, __LINE__, #assertion); \
|
||||
__ASSERT_STOP; \
|
||||
} \
|
||||
} while (0)
|
||||
|
||||
#define XAssertNoError(error) \
|
||||
do { \
|
||||
OSStatus __err = error; \
|
||||
if (__err) { \
|
||||
DebugMessageN4("%s:%d: error %s: %s", __FILE__, __LINE__, CAX4CCString(__err).get(), #error);\
|
||||
STOP; \
|
||||
} \
|
||||
} while (0)
|
||||
|
||||
#define ca_require_noerr(errorCode, exceptionLabel) \
|
||||
do \
|
||||
{ \
|
||||
int evalOnceErrorCode = (errorCode); \
|
||||
if ( __builtin_expect(0 != evalOnceErrorCode, 0) ) \
|
||||
{ \
|
||||
DebugMessageN5("ca_require_noerr: [%s, %d] (goto %s;) %s:%d", \
|
||||
#errorCode, evalOnceErrorCode, \
|
||||
#exceptionLabel, \
|
||||
__FILE__, \
|
||||
__LINE__); \
|
||||
goto exceptionLabel; \
|
||||
} \
|
||||
} while ( 0 )
|
||||
|
||||
#define ca_verify_noerr(errorCode) \
|
||||
do \
|
||||
{ \
|
||||
int evalOnceErrorCode = (errorCode); \
|
||||
if ( __builtin_expect(0 != evalOnceErrorCode, 0) ) \
|
||||
{ \
|
||||
DebugMessageN4("ca_verify_noerr: [%s, %d] %s:%d", \
|
||||
#errorCode, evalOnceErrorCode, \
|
||||
__FILE__, \
|
||||
__LINE__); \
|
||||
} \
|
||||
} while ( 0 )
|
||||
|
||||
#define ca_debug_string(message) \
|
||||
do \
|
||||
{ \
|
||||
DebugMessageN3("ca_debug_string: %s %s:%d", \
|
||||
message, \
|
||||
__FILE__, \
|
||||
__LINE__); \
|
||||
} while ( 0 )
|
||||
|
||||
|
||||
#define ca_verify(assertion) \
|
||||
do \
|
||||
{ \
|
||||
if ( __builtin_expect(!(assertion), 0) ) \
|
||||
{ \
|
||||
DebugMessageN3("ca_verify: %s %s:%d", \
|
||||
#assertion, \
|
||||
__FILE__, \
|
||||
__LINE__); \
|
||||
} \
|
||||
} while ( 0 )
|
||||
|
||||
#define ca_require(assertion, exceptionLabel) \
|
||||
do \
|
||||
{ \
|
||||
if ( __builtin_expect(!(assertion), 0) ) \
|
||||
{ \
|
||||
DebugMessageN4("ca_require: %s %s %s:%d", \
|
||||
#assertion, \
|
||||
#exceptionLabel, \
|
||||
__FILE__, \
|
||||
__LINE__); \
|
||||
goto exceptionLabel; \
|
||||
} \
|
||||
} while ( 0 )
|
||||
|
||||
#define ca_check(assertion) \
|
||||
do \
|
||||
{ \
|
||||
if ( __builtin_expect(!(assertion), 0) ) \
|
||||
{ \
|
||||
DebugMessageN3("ca_check: %s %s:%d", \
|
||||
#assertion, \
|
||||
__FILE__, \
|
||||
__LINE__); \
|
||||
} \
|
||||
} while ( 0 )
|
||||
|
||||
#else
|
||||
#define XThrowIfError(error, operation) \
|
||||
do { \
|
||||
OSStatus __err = error; \
|
||||
if (__err) { \
|
||||
throw CAXException(operation, __err); \
|
||||
} \
|
||||
} while (0)
|
||||
|
||||
#define XThrowIf(condition, error, operation) \
|
||||
do { \
|
||||
if (condition) { \
|
||||
OSStatus __err = error; \
|
||||
throw CAXException(operation, __err); \
|
||||
} \
|
||||
} while (0)
|
||||
|
||||
#define XRequireNoError(error, label) \
|
||||
do { \
|
||||
OSStatus __err = error; \
|
||||
if (__err) { \
|
||||
goto label; \
|
||||
} \
|
||||
} while (0)
|
||||
|
||||
#define XAssert(assertion) \
|
||||
do { \
|
||||
if (!(assertion)) { \
|
||||
} \
|
||||
} while (0)
|
||||
|
||||
#define XAssertNoError(error) \
|
||||
do { \
|
||||
/*OSStatus __err =*/ error; \
|
||||
} while (0)
|
||||
|
||||
#define ca_require_noerr(errorCode, exceptionLabel) \
|
||||
do \
|
||||
{ \
|
||||
if ( __builtin_expect(0 != (errorCode), 0) ) \
|
||||
{ \
|
||||
goto exceptionLabel; \
|
||||
} \
|
||||
} while ( 0 )
|
||||
|
||||
#define ca_verify_noerr(errorCode) \
|
||||
do \
|
||||
{ \
|
||||
if ( 0 != (errorCode) ) \
|
||||
{ \
|
||||
} \
|
||||
} while ( 0 )
|
||||
|
||||
#define ca_debug_string(message)
|
||||
|
||||
#define ca_verify(assertion) \
|
||||
do \
|
||||
{ \
|
||||
if ( !(assertion) ) \
|
||||
{ \
|
||||
} \
|
||||
} while ( 0 )
|
||||
|
||||
#define ca_require(assertion, exceptionLabel) \
|
||||
do \
|
||||
{ \
|
||||
if ( __builtin_expect(!(assertion), 0) ) \
|
||||
{ \
|
||||
goto exceptionLabel; \
|
||||
} \
|
||||
} while ( 0 )
|
||||
|
||||
#define ca_check(assertion) \
|
||||
do \
|
||||
{ \
|
||||
if ( !(assertion) ) \
|
||||
{ \
|
||||
} \
|
||||
} while ( 0 )
|
||||
|
||||
|
||||
#endif
|
||||
|
||||
#define XThrow(error, operation) XThrowIf(true, error, operation)
|
||||
#define XThrowIfErr(error) XThrowIfError(error, #error)
|
||||
|
||||
#endif // __CAXException_h__
|
||||
/*
|
||||
File: CAXException.h
|
||||
Abstract: Part of CoreAudio Utility Classes
|
||||
Version: 1.1
|
||||
|
||||
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.
|
||||
|
||||
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.
|
||||
|
||||
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.
|
||||
|
||||
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.
|
||||
|
||||
Copyright (C) 2014 Apple Inc. All Rights Reserved.
|
||||
|
||||
*/
|
||||
#ifndef __CAXException_h__
|
||||
#define __CAXException_h__
|
||||
|
||||
#if !defined(__COREAUDIO_USE_FLAT_INCLUDES__)
|
||||
#include <CoreFoundation/CoreFoundation.h>
|
||||
#else
|
||||
#include <ConditionalMacros.h>
|
||||
#include <CoreFoundation.h>
|
||||
#endif
|
||||
#include "CADebugMacros.h"
|
||||
#include <ctype.h>
|
||||
//#include <stdio.h>
|
||||
#include <string.h>
|
||||
|
||||
|
||||
class CAX4CCString {
|
||||
public:
|
||||
CAX4CCString(OSStatus error) {
|
||||
// see if it appears to be a 4-char-code
|
||||
UInt32 beErr = CFSwapInt32HostToBig(error);
|
||||
char *str = mStr;
|
||||
memcpy(str + 1, &beErr, 4);
|
||||
if (isprint(str[1]) && isprint(str[2]) && isprint(str[3]) && isprint(str[4])) {
|
||||
str[0] = str[5] = '\'';
|
||||
str[6] = '\0';
|
||||
} else if (error > -200000 && error < 200000)
|
||||
// no, format it as an integer
|
||||
snprintf(str, sizeof(mStr), "%d", (int)error);
|
||||
else
|
||||
snprintf(str, sizeof(mStr), "0x%x", (int)error);
|
||||
}
|
||||
const char *get() const { return mStr; }
|
||||
operator const char *() const { return mStr; }
|
||||
private:
|
||||
char mStr[16];
|
||||
};
|
||||
|
||||
class CAX4CCStringNoQuote {
|
||||
public:
|
||||
CAX4CCStringNoQuote(OSStatus error) {
|
||||
// see if it appears to be a 4-char-code
|
||||
UInt32 beErr = CFSwapInt32HostToBig(error);
|
||||
char *str = mStr;
|
||||
memcpy(str, &beErr, 4);
|
||||
if (isprint(str[0]) && isprint(str[1]) && isprint(str[2]) && isprint(str[3])) {
|
||||
str[4] = '\0';
|
||||
} else if (error > -200000 && error < 200000)
|
||||
// no, format it as an integer
|
||||
snprintf(str, sizeof(mStr), "%d", (int)error);
|
||||
else
|
||||
snprintf(str, sizeof(mStr), "0x%x", (int)error);
|
||||
}
|
||||
const char *get() const { return mStr; }
|
||||
operator const char *() const { return mStr; }
|
||||
private:
|
||||
char mStr[16];
|
||||
};
|
||||
|
||||
|
||||
// An extended exception class that includes the name of the failed operation
|
||||
class CAXException {
|
||||
public:
|
||||
CAXException(const char *operation, OSStatus err) :
|
||||
mError(err)
|
||||
{
|
||||
if (operation == NULL)
|
||||
mOperation[0] = '\0';
|
||||
else if (strlen(operation) >= sizeof(mOperation)) {
|
||||
memcpy(mOperation, operation, sizeof(mOperation) - 1);
|
||||
mOperation[sizeof(mOperation) - 1] = '\0';
|
||||
} else
|
||||
|
||||
strlcpy(mOperation, operation, sizeof(mOperation));
|
||||
}
|
||||
|
||||
char *FormatError(char *str, size_t strsize) const
|
||||
{
|
||||
return FormatError(str, strsize, mError);
|
||||
}
|
||||
|
||||
char mOperation[256];
|
||||
const OSStatus mError;
|
||||
|
||||
// -------------------------------------------------
|
||||
|
||||
typedef void (*WarningHandler)(const char *msg, OSStatus err);
|
||||
|
||||
static char *FormatError(char *str, size_t strsize, OSStatus error)
|
||||
{
|
||||
strlcpy(str, CAX4CCString(error), strsize);
|
||||
return str;
|
||||
}
|
||||
|
||||
static void Warning(const char *s, OSStatus error)
|
||||
{
|
||||
if (sWarningHandler)
|
||||
(*sWarningHandler)(s, error);
|
||||
}
|
||||
|
||||
static void SetWarningHandler(WarningHandler f) { sWarningHandler = f; }
|
||||
private:
|
||||
static WarningHandler sWarningHandler;
|
||||
};
|
||||
|
||||
#if DEBUG || CoreAudio_Debug
|
||||
#define XThrowIfError(error, operation) \
|
||||
do { \
|
||||
OSStatus __err = error; \
|
||||
if (__err) { \
|
||||
DebugMessageN4("%s:%d: about to throw %s: %s", __FILE__, __LINE__, CAX4CCString(__err).get(), operation);\
|
||||
__THROW_STOP; \
|
||||
throw CAXException(operation, __err); \
|
||||
} \
|
||||
} while (0)
|
||||
|
||||
#define XThrowIf(condition, error, operation) \
|
||||
do { \
|
||||
if (condition) { \
|
||||
OSStatus __err = error; \
|
||||
DebugMessageN4("%s:%d: about to throw %s: %s", __FILE__, __LINE__, CAX4CCString(__err).get(), operation);\
|
||||
__THROW_STOP; \
|
||||
throw CAXException(operation, __err); \
|
||||
} \
|
||||
} while (0)
|
||||
|
||||
#define XRequireNoError(error, label) \
|
||||
do { \
|
||||
OSStatus __err = error; \
|
||||
if (__err) { \
|
||||
DebugMessageN4("%s:%d: about to throw %s: %s", __FILE__, __LINE__, CAX4CCString(__err).get(), #error);\
|
||||
STOP; \
|
||||
goto label; \
|
||||
} \
|
||||
} while (0)
|
||||
|
||||
#define XAssert(assertion) \
|
||||
do { \
|
||||
if (!(assertion)) { \
|
||||
DebugMessageN3("%s:%d: error: failed assertion: %s", __FILE__, __LINE__, #assertion); \
|
||||
__ASSERT_STOP; \
|
||||
} \
|
||||
} while (0)
|
||||
|
||||
#define XAssertNoError(error) \
|
||||
do { \
|
||||
OSStatus __err = error; \
|
||||
if (__err) { \
|
||||
DebugMessageN4("%s:%d: error %s: %s", __FILE__, __LINE__, CAX4CCString(__err).get(), #error);\
|
||||
STOP; \
|
||||
} \
|
||||
} while (0)
|
||||
|
||||
#define ca_require_noerr(errorCode, exceptionLabel) \
|
||||
do \
|
||||
{ \
|
||||
int evalOnceErrorCode = (errorCode); \
|
||||
if ( __builtin_expect(0 != evalOnceErrorCode, 0) ) \
|
||||
{ \
|
||||
DebugMessageN5("ca_require_noerr: [%s, %d] (goto %s;) %s:%d", \
|
||||
#errorCode, evalOnceErrorCode, \
|
||||
#exceptionLabel, \
|
||||
__FILE__, \
|
||||
__LINE__); \
|
||||
goto exceptionLabel; \
|
||||
} \
|
||||
} while ( 0 )
|
||||
|
||||
#define ca_verify_noerr(errorCode) \
|
||||
do \
|
||||
{ \
|
||||
int evalOnceErrorCode = (errorCode); \
|
||||
if ( __builtin_expect(0 != evalOnceErrorCode, 0) ) \
|
||||
{ \
|
||||
DebugMessageN4("ca_verify_noerr: [%s, %d] %s:%d", \
|
||||
#errorCode, evalOnceErrorCode, \
|
||||
__FILE__, \
|
||||
__LINE__); \
|
||||
} \
|
||||
} while ( 0 )
|
||||
|
||||
#define ca_debug_string(message) \
|
||||
do \
|
||||
{ \
|
||||
DebugMessageN3("ca_debug_string: %s %s:%d", \
|
||||
message, \
|
||||
__FILE__, \
|
||||
__LINE__); \
|
||||
} while ( 0 )
|
||||
|
||||
|
||||
#define ca_verify(assertion) \
|
||||
do \
|
||||
{ \
|
||||
if ( __builtin_expect(!(assertion), 0) ) \
|
||||
{ \
|
||||
DebugMessageN3("ca_verify: %s %s:%d", \
|
||||
#assertion, \
|
||||
__FILE__, \
|
||||
__LINE__); \
|
||||
} \
|
||||
} while ( 0 )
|
||||
|
||||
#define ca_require(assertion, exceptionLabel) \
|
||||
do \
|
||||
{ \
|
||||
if ( __builtin_expect(!(assertion), 0) ) \
|
||||
{ \
|
||||
DebugMessageN4("ca_require: %s %s %s:%d", \
|
||||
#assertion, \
|
||||
#exceptionLabel, \
|
||||
__FILE__, \
|
||||
__LINE__); \
|
||||
goto exceptionLabel; \
|
||||
} \
|
||||
} while ( 0 )
|
||||
|
||||
#define ca_check(assertion) \
|
||||
do \
|
||||
{ \
|
||||
if ( __builtin_expect(!(assertion), 0) ) \
|
||||
{ \
|
||||
DebugMessageN3("ca_check: %s %s:%d", \
|
||||
#assertion, \
|
||||
__FILE__, \
|
||||
__LINE__); \
|
||||
} \
|
||||
} while ( 0 )
|
||||
|
||||
#else
|
||||
#define XThrowIfError(error, operation) \
|
||||
do { \
|
||||
OSStatus __err = error; \
|
||||
if (__err) { \
|
||||
throw CAXException(operation, __err); \
|
||||
} \
|
||||
} while (0)
|
||||
|
||||
#define XThrowIf(condition, error, operation) \
|
||||
do { \
|
||||
if (condition) { \
|
||||
OSStatus __err = error; \
|
||||
throw CAXException(operation, __err); \
|
||||
} \
|
||||
} while (0)
|
||||
|
||||
#define XRequireNoError(error, label) \
|
||||
do { \
|
||||
OSStatus __err = error; \
|
||||
if (__err) { \
|
||||
goto label; \
|
||||
} \
|
||||
} while (0)
|
||||
|
||||
#define XAssert(assertion) \
|
||||
do { \
|
||||
if (!(assertion)) { \
|
||||
} \
|
||||
} while (0)
|
||||
|
||||
#define XAssertNoError(error) \
|
||||
do { \
|
||||
/*OSStatus __err =*/ error; \
|
||||
} while (0)
|
||||
|
||||
#define ca_require_noerr(errorCode, exceptionLabel) \
|
||||
do \
|
||||
{ \
|
||||
if ( __builtin_expect(0 != (errorCode), 0) ) \
|
||||
{ \
|
||||
goto exceptionLabel; \
|
||||
} \
|
||||
} while ( 0 )
|
||||
|
||||
#define ca_verify_noerr(errorCode) \
|
||||
do \
|
||||
{ \
|
||||
if ( 0 != (errorCode) ) \
|
||||
{ \
|
||||
} \
|
||||
} while ( 0 )
|
||||
|
||||
#define ca_debug_string(message)
|
||||
|
||||
#define ca_verify(assertion) \
|
||||
do \
|
||||
{ \
|
||||
if ( !(assertion) ) \
|
||||
{ \
|
||||
} \
|
||||
} while ( 0 )
|
||||
|
||||
#define ca_require(assertion, exceptionLabel) \
|
||||
do \
|
||||
{ \
|
||||
if ( __builtin_expect(!(assertion), 0) ) \
|
||||
{ \
|
||||
goto exceptionLabel; \
|
||||
} \
|
||||
} while ( 0 )
|
||||
|
||||
#define ca_check(assertion) \
|
||||
do \
|
||||
{ \
|
||||
if ( !(assertion) ) \
|
||||
{ \
|
||||
} \
|
||||
} while ( 0 )
|
||||
|
||||
|
||||
#endif
|
||||
|
||||
#define XThrow(error, operation) XThrowIf(true, error, operation)
|
||||
#define XThrowIfErr(error) XThrowIfError(error, #error)
|
||||
|
||||
#endif // __CAXException_h__
|
||||
|
||||
@@ -1,91 +0,0 @@
|
||||
/*
|
||||
File: CarbonEventHandler.cpp
|
||||
Abstract: CarbonEventHandler.h
|
||||
Version: 1.1
|
||||
|
||||
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.
|
||||
|
||||
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.
|
||||
|
||||
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.
|
||||
|
||||
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.
|
||||
|
||||
Copyright (C) 2014 Apple Inc. All Rights Reserved.
|
||||
|
||||
*/
|
||||
|
||||
#include "CarbonEventHandler.h"
|
||||
|
||||
static pascal OSStatus TheEventHandler(EventHandlerCallRef inHandlerRef, EventRef inEvent, void *inUserData)
|
||||
{
|
||||
CarbonEventHandler *handler = (CarbonEventHandler *)inUserData;
|
||||
if (handler->HandleEvent(inHandlerRef, inEvent))
|
||||
return noErr;
|
||||
else return eventNotHandledErr;
|
||||
}
|
||||
|
||||
CarbonEventHandler::CarbonEventHandler() :
|
||||
mHandlers(NULL)
|
||||
{
|
||||
}
|
||||
|
||||
CarbonEventHandler::~CarbonEventHandler()
|
||||
{
|
||||
if (mHandlers != NULL) {
|
||||
int count = static_cast<int>(CFDictionaryGetCount(mHandlers));
|
||||
EventHandlerRef *theHandlers = (EventHandlerRef*) malloc(count * sizeof(EventHandlerRef));
|
||||
CFDictionaryGetKeysAndValues(mHandlers, NULL, (const void **)theHandlers);
|
||||
|
||||
for (int i = 0; i < count; i++)
|
||||
RemoveEventHandler(theHandlers[i]);
|
||||
CFDictionaryRemoveAllValues(mHandlers);
|
||||
CFRelease (mHandlers);
|
||||
free(theHandlers);
|
||||
}
|
||||
}
|
||||
|
||||
void CarbonEventHandler::WantEventTypes(EventTargetRef target, UInt32 inNumTypes, const EventTypeSpec *inList)
|
||||
{
|
||||
if (mHandlers == NULL)
|
||||
mHandlers = CFDictionaryCreateMutable(NULL, 0, NULL, NULL);
|
||||
|
||||
EventHandlerRef handler;
|
||||
|
||||
if (CFDictionaryGetValueIfPresent (mHandlers, target, (const void **)&handler)) // if there is already a handler for the target, add the type
|
||||
verify_noerr(AddEventTypesToHandler(handler, inNumTypes, inList));
|
||||
else {
|
||||
verify_noerr(InstallEventHandler(target, TheEventHandler, inNumTypes, inList, this, &handler));
|
||||
CFDictionaryAddValue(mHandlers, target, handler);
|
||||
}
|
||||
}
|
||||
@@ -1,71 +0,0 @@
|
||||
/*
|
||||
File: CarbonEventHandler.h
|
||||
Abstract: Part of CoreAudio Utility Classes
|
||||
Version: 1.1
|
||||
|
||||
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.
|
||||
|
||||
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.
|
||||
|
||||
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.
|
||||
|
||||
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.
|
||||
|
||||
Copyright (C) 2014 Apple Inc. All Rights Reserved.
|
||||
|
||||
*/
|
||||
#ifndef __CarbonEventHandler_h__
|
||||
#define __CarbonEventHandler_h__
|
||||
|
||||
#include <Carbon/Carbon.h>
|
||||
|
||||
/*! @class CarbonEventHandler */
|
||||
class CarbonEventHandler {
|
||||
public:
|
||||
/*! @ctor CarbonEventHandler */
|
||||
CarbonEventHandler();
|
||||
/*! @dtor ~CarbonEventHandler */
|
||||
virtual ~CarbonEventHandler();
|
||||
|
||||
/*! @method WantEventTypes */
|
||||
virtual void WantEventTypes(EventTargetRef target, UInt32 inNumTypes, const EventTypeSpec *inList);
|
||||
|
||||
/*! @method HandleEvent */
|
||||
virtual bool HandleEvent(EventHandlerCallRef inHandlerRef, EventRef event) = 0;
|
||||
|
||||
protected:
|
||||
/*! @var mHandlers */
|
||||
CFMutableDictionaryRef mHandlers;
|
||||
};
|
||||
|
||||
#endif // __CarbonEventHandler_h__
|
||||
@@ -1,369 +1,369 @@
|
||||
/*
|
||||
File: ComponentBase.cpp
|
||||
Abstract: ComponentBase.h
|
||||
Version: 1.1
|
||||
|
||||
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.
|
||||
|
||||
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.
|
||||
|
||||
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.
|
||||
|
||||
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.
|
||||
|
||||
Copyright (C) 2014 Apple Inc. All Rights Reserved.
|
||||
|
||||
*/
|
||||
#include "ComponentBase.h"
|
||||
#include "CAXException.h"
|
||||
|
||||
#if TARGET_OS_MAC
|
||||
pthread_mutex_t ComponentInitLocker::sComponentOpenMutex = PTHREAD_MUTEX_INITIALIZER;
|
||||
pthread_once_t ComponentInitLocker::sOnce = PTHREAD_ONCE_INIT;
|
||||
|
||||
void ComponentInitLocker::InitComponentInitLocker()
|
||||
{
|
||||
// have to do this because OS X lacks PTHREAD_MUTEX_RECURSIVE_INITIALIZER_NP
|
||||
pthread_mutexattr_t attr;
|
||||
pthread_mutexattr_init(&attr);
|
||||
pthread_mutexattr_settype(&attr, PTHREAD_MUTEX_RECURSIVE);
|
||||
pthread_mutex_init(&sComponentOpenMutex, &attr);
|
||||
pthread_mutexattr_destroy(&attr);
|
||||
}
|
||||
|
||||
#elif TARGET_OS_WIN32
|
||||
CAGuard ComponentInitLocker::sComponentOpenGuard("sComponentOpenGuard");
|
||||
#endif
|
||||
|
||||
ComponentBase::EInstanceType ComponentBase::sNewInstanceType;
|
||||
|
||||
static OSStatus CB_GetComponentDescription (const AudioComponentInstance inInstance, AudioComponentDescription * outDesc);
|
||||
#if !CA_USE_AUDIO_PLUGIN_ONLY && !TARGET_OS_WIN32
|
||||
static OSStatus CMgr_GetComponentDescription (const AudioComponentInstance inInstance, AudioComponentDescription * outDesc);
|
||||
#endif
|
||||
|
||||
ComponentBase::ComponentBase(AudioComponentInstance inInstance)
|
||||
: mComponentInstance(inInstance),
|
||||
mInstanceType(sNewInstanceType)
|
||||
{
|
||||
GetComponentDescription();
|
||||
}
|
||||
|
||||
ComponentBase::~ComponentBase()
|
||||
{
|
||||
}
|
||||
|
||||
void ComponentBase::PostConstructor()
|
||||
{
|
||||
}
|
||||
|
||||
void ComponentBase::PreDestructor()
|
||||
{
|
||||
}
|
||||
|
||||
#define ACPI ((AudioComponentPlugInInstance *)self)
|
||||
#define ACImp ((ComponentBase *)&ACPI->mInstanceStorage)
|
||||
|
||||
OSStatus ComponentBase::AP_Open(void *self, AudioUnit compInstance)
|
||||
{
|
||||
OSStatus result = noErr;
|
||||
try {
|
||||
ComponentInitLocker lock;
|
||||
|
||||
ComponentBase::sNewInstanceType = ComponentBase::kAudioComponentInstance;
|
||||
ComponentBase *cb = (ComponentBase *)(*ACPI->mConstruct)(&ACPI->mInstanceStorage, compInstance);
|
||||
cb->PostConstructor(); // allows base class to do additional initialization
|
||||
// once the derived class is fully constructed
|
||||
result = noErr;
|
||||
}
|
||||
COMPONENT_CATCH
|
||||
if (result)
|
||||
delete ACPI;
|
||||
return result;
|
||||
}
|
||||
|
||||
OSStatus ComponentBase::AP_Close(void *self)
|
||||
{
|
||||
OSStatus result = noErr;
|
||||
try {
|
||||
if (ACImp) {
|
||||
ACImp->PreDestructor();
|
||||
(*ACPI->mDestruct)(&ACPI->mInstanceStorage);
|
||||
free(self);
|
||||
}
|
||||
}
|
||||
COMPONENT_CATCH
|
||||
return result;
|
||||
}
|
||||
|
||||
#if !CA_USE_AUDIO_PLUGIN_ONLY
|
||||
OSStatus ComponentBase::Version()
|
||||
{
|
||||
return 0x00000001;
|
||||
}
|
||||
|
||||
OSStatus ComponentBase::ComponentEntryDispatch(ComponentParameters *p, ComponentBase *This)
|
||||
{
|
||||
if (This == NULL) return kAudio_ParamError;
|
||||
|
||||
OSStatus result = noErr;
|
||||
|
||||
switch (p->what) {
|
||||
case kComponentCloseSelect:
|
||||
This->PreDestructor();
|
||||
delete This;
|
||||
break;
|
||||
|
||||
case kComponentVersionSelect:
|
||||
result = This->Version();
|
||||
break;
|
||||
|
||||
case kComponentCanDoSelect:
|
||||
switch (GetSelectorForCanDo(p)) {
|
||||
case kComponentOpenSelect:
|
||||
case kComponentCloseSelect:
|
||||
case kComponentVersionSelect:
|
||||
case kComponentCanDoSelect:
|
||||
return 1;
|
||||
default:
|
||||
return 0;
|
||||
}
|
||||
|
||||
default:
|
||||
result = badComponentSelector;
|
||||
break;
|
||||
}
|
||||
return result;
|
||||
}
|
||||
|
||||
SInt16 ComponentBase::GetSelectorForCanDo(ComponentParameters *params)
|
||||
{
|
||||
if (params->what != kComponentCanDoSelect) return 0;
|
||||
|
||||
#if TARGET_CPU_X86
|
||||
SInt16 sel = params->params[0];
|
||||
#elif TARGET_CPU_X86_64
|
||||
SInt16 sel = params->params[1];
|
||||
#elif TARGET_CPU_PPC
|
||||
SInt16 sel = (params->params[0] >> 16);
|
||||
#else
|
||||
SInt16 sel = params->params[0];
|
||||
#endif
|
||||
|
||||
return sel;
|
||||
/*
|
||||
printf ("flags:%d, paramSize: %d, what: %d\n\t", params->flags, params->paramSize, params->what);
|
||||
for (int i = 0; i < params->paramSize; ++i) {
|
||||
printf ("[%d]:%d(0x%x), ", i, params->params[i], params->params[i]);
|
||||
}
|
||||
printf("\n\tsel:%d\n", sel);
|
||||
*/
|
||||
}
|
||||
|
||||
#endif
|
||||
|
||||
#if CA_DO_NOT_USE_AUDIO_COMPONENT
|
||||
static OSStatus ComponentBase_GetComponentDescription (const AudioComponentInstance & inInstance, AudioComponentDescription &outDesc);
|
||||
#endif
|
||||
|
||||
AudioComponentDescription ComponentBase::GetComponentDescription() const
|
||||
{
|
||||
AudioComponentDescription desc;
|
||||
OSStatus result = 1;
|
||||
|
||||
if (IsPluginObject()) {
|
||||
ca_require_noerr(result = CB_GetComponentDescription (mComponentInstance, &desc), home);
|
||||
}
|
||||
#if !CA_USE_AUDIO_PLUGIN_ONLY
|
||||
else {
|
||||
ca_require_noerr(result = CMgr_GetComponentDescription (mComponentInstance, &desc), home);
|
||||
}
|
||||
#endif
|
||||
|
||||
home:
|
||||
if (result)
|
||||
memset (&desc, 0, sizeof(AudioComponentDescription));
|
||||
|
||||
return desc;
|
||||
}
|
||||
|
||||
#if CA_USE_AUDIO_PLUGIN_ONLY
|
||||
// everything we need is there and we should be linking against it
|
||||
static OSStatus CB_GetComponentDescription (const AudioComponentInstance inInstance, AudioComponentDescription * outDesc)
|
||||
{
|
||||
AudioComponent comp = AudioComponentInstanceGetComponent(inInstance);
|
||||
if (comp)
|
||||
return AudioComponentGetDescription(comp, outDesc);
|
||||
|
||||
return kAudio_ParamError;
|
||||
}
|
||||
|
||||
#elif !TARGET_OS_WIN32
|
||||
// these are the direct dependencies on ComponentMgr calls that an AU
|
||||
// that is a component mgr is dependent on
|
||||
|
||||
// these are dynamically loaded so that these calls will work on Leopard
|
||||
#include <dlfcn.h>
|
||||
|
||||
static OSStatus CB_GetComponentDescription (const AudioComponentInstance inInstance, AudioComponentDescription * outDesc)
|
||||
{
|
||||
typedef AudioComponent (*AudioComponentInstanceGetComponentProc) (AudioComponentInstance);
|
||||
static AudioComponentInstanceGetComponentProc aciGCProc = NULL;
|
||||
|
||||
typedef OSStatus (*AudioComponentGetDescriptionProc)(AudioComponent, AudioComponentDescription *);
|
||||
static AudioComponentGetDescriptionProc acGDProc = NULL;
|
||||
|
||||
static int doneInit = 0;
|
||||
if (doneInit == 0) {
|
||||
doneInit = 1;
|
||||
void* theImage = dlopen("/System/Library/Frameworks/AudioUnit.framework/AudioUnit", RTLD_LAZY);
|
||||
if (theImage != NULL)
|
||||
{
|
||||
aciGCProc = (AudioComponentInstanceGetComponentProc)dlsym (theImage, "AudioComponentInstanceGetComponent");
|
||||
if (aciGCProc) {
|
||||
acGDProc = (AudioComponentGetDescriptionProc)dlsym (theImage, "AudioComponentGetDescription");
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
OSStatus result = kAudio_UnimplementedError;
|
||||
if (acGDProc && aciGCProc) {
|
||||
AudioComponent comp = (*aciGCProc)(inInstance);
|
||||
if (comp)
|
||||
result = (*acGDProc)(comp, outDesc);
|
||||
}
|
||||
#if !CA_USE_AUDIO_PLUGIN_ONLY
|
||||
else {
|
||||
result = CMgr_GetComponentDescription (inInstance, outDesc);
|
||||
}
|
||||
#endif
|
||||
|
||||
return result;
|
||||
}
|
||||
|
||||
#if !CA_USE_AUDIO_PLUGIN_ONLY
|
||||
// these are the direct dependencies on ComponentMgr calls that an AU
|
||||
// that is a component mgr is dependent on
|
||||
|
||||
// these are dynamically loaded
|
||||
|
||||
#include <CoreServices/CoreServices.h>
|
||||
#include <AudioUnit/AudioUnit.h>
|
||||
#include "CAXException.h"
|
||||
#include "ComponentBase.h"
|
||||
|
||||
//~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
|
||||
// Component Manager
|
||||
// Used for fast dispatch with audio units
|
||||
typedef Handle (*GetComponentInstanceStorageProc)(ComponentInstance aComponentInstance);
|
||||
static GetComponentInstanceStorageProc sGetComponentInstanceStorageProc = NULL;
|
||||
|
||||
typedef OSErr (*GetComponentInfoProc)(Component, ComponentDescription *, void*, void*, void*);
|
||||
static GetComponentInfoProc sGetComponentInfoProc = NULL;
|
||||
|
||||
typedef void (*SetComponentInstanceStorageProc)(ComponentInstance, Handle);
|
||||
static SetComponentInstanceStorageProc sSetComponentInstanceStorageProc = NULL;
|
||||
|
||||
//~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
|
||||
|
||||
static void CSInitOnce(void* /*unused*/)
|
||||
{
|
||||
void *theImage = dlopen("/System/Library/Frameworks/CoreServices.framework/CoreServices", RTLD_LAZY);
|
||||
if (!theImage) return;
|
||||
|
||||
sGetComponentInstanceStorageProc = (GetComponentInstanceStorageProc) dlsym(theImage, "GetComponentInstanceStorage");
|
||||
sGetComponentInfoProc = (GetComponentInfoProc)dlsym (theImage, "GetComponentInfo");
|
||||
sSetComponentInstanceStorageProc = (SetComponentInstanceStorageProc) dlsym(theImage, "SetComponentInstanceStorage");
|
||||
}
|
||||
|
||||
#if TARGET_OS_MAC
|
||||
|
||||
#include <dispatch/dispatch.h>
|
||||
|
||||
static dispatch_once_t sCSInitOnce = 0;
|
||||
|
||||
static void CSInit ()
|
||||
{
|
||||
dispatch_once_f(&sCSInitOnce, NULL, CSInitOnce);
|
||||
}
|
||||
|
||||
#else
|
||||
|
||||
static void CSInit ()
|
||||
{
|
||||
static int sDoCSLoad = 1;
|
||||
if (sDoCSLoad) {
|
||||
sDoCSLoad = 0;
|
||||
CSInitOnce(NULL);
|
||||
}
|
||||
}
|
||||
|
||||
#endif
|
||||
|
||||
OSStatus CMgr_GetComponentDescription (const AudioComponentInstance inInstance, AudioComponentDescription * outDesc)
|
||||
{
|
||||
CSInit();
|
||||
if (sGetComponentInfoProc)
|
||||
return (*sGetComponentInfoProc)((Component)inInstance, (ComponentDescription*)outDesc, NULL, NULL, NULL);
|
||||
return kAudio_UnimplementedError;
|
||||
}
|
||||
|
||||
Handle CMgr_GetComponentInstanceStorage(ComponentInstance aComponentInstance)
|
||||
{
|
||||
CSInit();
|
||||
if (sGetComponentInstanceStorageProc)
|
||||
return (*sGetComponentInstanceStorageProc)(aComponentInstance);
|
||||
return NULL;
|
||||
}
|
||||
|
||||
void CMgr_SetComponentInstanceStorage(ComponentInstance aComponentInstance, Handle theStorage)
|
||||
{
|
||||
CSInit();
|
||||
if (sSetComponentInstanceStorageProc)
|
||||
(*sSetComponentInstanceStorageProc)(aComponentInstance, theStorage);
|
||||
}
|
||||
#endif // !CA_USE_AUDIO_PLUGIN_ONLY
|
||||
|
||||
#else
|
||||
//#include "ComponentManagerDependenciesWin.h"
|
||||
// everything we need is there and we should be linking against it
|
||||
static OSStatus CB_GetComponentDescription (const AudioComponentInstance inInstance, AudioComponentDescription * outDesc)
|
||||
{
|
||||
AudioComponent comp = AudioComponentInstanceGetComponent(inInstance);
|
||||
if (comp)
|
||||
return AudioComponentGetDescription(comp, outDesc);
|
||||
|
||||
return kAudio_ParamError;
|
||||
}
|
||||
|
||||
#endif
|
||||
/*
|
||||
File: ComponentBase.cpp
|
||||
Abstract: ComponentBase.h
|
||||
Version: 1.1
|
||||
|
||||
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.
|
||||
|
||||
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.
|
||||
|
||||
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.
|
||||
|
||||
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.
|
||||
|
||||
Copyright (C) 2014 Apple Inc. All Rights Reserved.
|
||||
|
||||
*/
|
||||
#include "ComponentBase.h"
|
||||
#include "CAXException.h"
|
||||
|
||||
#if TARGET_OS_MAC
|
||||
pthread_mutex_t ComponentInitLocker::sComponentOpenMutex = PTHREAD_MUTEX_INITIALIZER;
|
||||
pthread_once_t ComponentInitLocker::sOnce = PTHREAD_ONCE_INIT;
|
||||
|
||||
void ComponentInitLocker::InitComponentInitLocker()
|
||||
{
|
||||
// have to do this because OS X lacks PTHREAD_MUTEX_RECURSIVE_INITIALIZER_NP
|
||||
pthread_mutexattr_t attr;
|
||||
pthread_mutexattr_init(&attr);
|
||||
pthread_mutexattr_settype(&attr, PTHREAD_MUTEX_RECURSIVE);
|
||||
pthread_mutex_init(&sComponentOpenMutex, &attr);
|
||||
pthread_mutexattr_destroy(&attr);
|
||||
}
|
||||
|
||||
#elif TARGET_OS_WIN32
|
||||
CAGuard ComponentInitLocker::sComponentOpenGuard("sComponentOpenGuard");
|
||||
#endif
|
||||
|
||||
ComponentBase::EInstanceType ComponentBase::sNewInstanceType;
|
||||
|
||||
static OSStatus CB_GetComponentDescription (const AudioComponentInstance inInstance, AudioComponentDescription * outDesc);
|
||||
#if !CA_USE_AUDIO_PLUGIN_ONLY && !TARGET_OS_WIN32
|
||||
static OSStatus CMgr_GetComponentDescription (const AudioComponentInstance inInstance, AudioComponentDescription * outDesc);
|
||||
#endif
|
||||
|
||||
ComponentBase::ComponentBase(AudioComponentInstance inInstance)
|
||||
: mComponentInstance(inInstance),
|
||||
mInstanceType(sNewInstanceType)
|
||||
{
|
||||
GetComponentDescription();
|
||||
}
|
||||
|
||||
ComponentBase::~ComponentBase()
|
||||
{
|
||||
}
|
||||
|
||||
void ComponentBase::PostConstructor()
|
||||
{
|
||||
}
|
||||
|
||||
void ComponentBase::PreDestructor()
|
||||
{
|
||||
}
|
||||
|
||||
#define ACPI ((AudioComponentPlugInInstance *)self)
|
||||
#define ACImp ((ComponentBase *)&ACPI->mInstanceStorage)
|
||||
|
||||
OSStatus ComponentBase::AP_Open(void *self, AudioUnit compInstance)
|
||||
{
|
||||
OSStatus result = noErr;
|
||||
try {
|
||||
ComponentInitLocker lock;
|
||||
|
||||
ComponentBase::sNewInstanceType = ComponentBase::kAudioComponentInstance;
|
||||
ComponentBase *cb = (ComponentBase *)(*ACPI->mConstruct)(&ACPI->mInstanceStorage, compInstance);
|
||||
cb->PostConstructor(); // allows base class to do additional initialization
|
||||
// once the derived class is fully constructed
|
||||
result = noErr;
|
||||
}
|
||||
COMPONENT_CATCH
|
||||
if (result)
|
||||
delete ACPI;
|
||||
return result;
|
||||
}
|
||||
|
||||
OSStatus ComponentBase::AP_Close(void *self)
|
||||
{
|
||||
OSStatus result = noErr;
|
||||
try {
|
||||
if (ACImp) {
|
||||
ACImp->PreDestructor();
|
||||
(*ACPI->mDestruct)(&ACPI->mInstanceStorage);
|
||||
free(self);
|
||||
}
|
||||
}
|
||||
COMPONENT_CATCH
|
||||
return result;
|
||||
}
|
||||
|
||||
#if !CA_USE_AUDIO_PLUGIN_ONLY
|
||||
OSStatus ComponentBase::Version()
|
||||
{
|
||||
return 0x00000001;
|
||||
}
|
||||
|
||||
OSStatus ComponentBase::ComponentEntryDispatch(ComponentParameters *p, ComponentBase *This)
|
||||
{
|
||||
if (This == NULL) return kAudio_ParamError;
|
||||
|
||||
OSStatus result = noErr;
|
||||
|
||||
switch (p->what) {
|
||||
case kComponentCloseSelect:
|
||||
This->PreDestructor();
|
||||
delete This;
|
||||
break;
|
||||
|
||||
case kComponentVersionSelect:
|
||||
result = This->Version();
|
||||
break;
|
||||
|
||||
case kComponentCanDoSelect:
|
||||
switch (GetSelectorForCanDo(p)) {
|
||||
case kComponentOpenSelect:
|
||||
case kComponentCloseSelect:
|
||||
case kComponentVersionSelect:
|
||||
case kComponentCanDoSelect:
|
||||
return 1;
|
||||
default:
|
||||
return 0;
|
||||
}
|
||||
|
||||
default:
|
||||
result = badComponentSelector;
|
||||
break;
|
||||
}
|
||||
return result;
|
||||
}
|
||||
|
||||
SInt16 ComponentBase::GetSelectorForCanDo(ComponentParameters *params)
|
||||
{
|
||||
if (params->what != kComponentCanDoSelect) return 0;
|
||||
|
||||
#if TARGET_CPU_X86
|
||||
SInt16 sel = params->params[0];
|
||||
#elif TARGET_CPU_X86_64
|
||||
SInt16 sel = params->params[1];
|
||||
#elif TARGET_CPU_PPC
|
||||
SInt16 sel = (params->params[0] >> 16);
|
||||
#else
|
||||
SInt16 sel = params->params[0];
|
||||
#endif
|
||||
|
||||
return sel;
|
||||
/*
|
||||
printf ("flags:%d, paramSize: %d, what: %d\n\t", params->flags, params->paramSize, params->what);
|
||||
for (int i = 0; i < params->paramSize; ++i) {
|
||||
printf ("[%d]:%d(0x%x), ", i, params->params[i], params->params[i]);
|
||||
}
|
||||
printf("\n\tsel:%d\n", sel);
|
||||
*/
|
||||
}
|
||||
|
||||
#endif
|
||||
|
||||
#if CA_DO_NOT_USE_AUDIO_COMPONENT
|
||||
static OSStatus ComponentBase_GetComponentDescription (const AudioComponentInstance & inInstance, AudioComponentDescription &outDesc);
|
||||
#endif
|
||||
|
||||
AudioComponentDescription ComponentBase::GetComponentDescription() const
|
||||
{
|
||||
AudioComponentDescription desc;
|
||||
OSStatus result = 1;
|
||||
|
||||
if (IsPluginObject()) {
|
||||
ca_require_noerr(result = CB_GetComponentDescription (mComponentInstance, &desc), home);
|
||||
}
|
||||
#if !CA_USE_AUDIO_PLUGIN_ONLY
|
||||
else {
|
||||
ca_require_noerr(result = CMgr_GetComponentDescription (mComponentInstance, &desc), home);
|
||||
}
|
||||
#endif
|
||||
|
||||
home:
|
||||
if (result)
|
||||
memset (&desc, 0, sizeof(AudioComponentDescription));
|
||||
|
||||
return desc;
|
||||
}
|
||||
|
||||
#if CA_USE_AUDIO_PLUGIN_ONLY
|
||||
// everything we need is there and we should be linking against it
|
||||
static OSStatus CB_GetComponentDescription (const AudioComponentInstance inInstance, AudioComponentDescription * outDesc)
|
||||
{
|
||||
AudioComponent comp = AudioComponentInstanceGetComponent(inInstance);
|
||||
if (comp)
|
||||
return AudioComponentGetDescription(comp, outDesc);
|
||||
|
||||
return kAudio_ParamError;
|
||||
}
|
||||
|
||||
#elif !TARGET_OS_WIN32
|
||||
// these are the direct dependencies on ComponentMgr calls that an AU
|
||||
// that is a component mgr is dependent on
|
||||
|
||||
// these are dynamically loaded so that these calls will work on Leopard
|
||||
#include <dlfcn.h>
|
||||
|
||||
static OSStatus CB_GetComponentDescription (const AudioComponentInstance inInstance, AudioComponentDescription * outDesc)
|
||||
{
|
||||
typedef AudioComponent (*AudioComponentInstanceGetComponentProc) (AudioComponentInstance);
|
||||
static AudioComponentInstanceGetComponentProc aciGCProc = NULL;
|
||||
|
||||
typedef OSStatus (*AudioComponentGetDescriptionProc)(AudioComponent, AudioComponentDescription *);
|
||||
static AudioComponentGetDescriptionProc acGDProc = NULL;
|
||||
|
||||
static int doneInit = 0;
|
||||
if (doneInit == 0) {
|
||||
doneInit = 1;
|
||||
void* theImage = dlopen("/System/Library/Frameworks/AudioUnit.framework/AudioUnit", RTLD_LAZY);
|
||||
if (theImage != NULL)
|
||||
{
|
||||
aciGCProc = (AudioComponentInstanceGetComponentProc)dlsym (theImage, "AudioComponentInstanceGetComponent");
|
||||
if (aciGCProc) {
|
||||
acGDProc = (AudioComponentGetDescriptionProc)dlsym (theImage, "AudioComponentGetDescription");
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
OSStatus result = kAudio_UnimplementedError;
|
||||
if (acGDProc && aciGCProc) {
|
||||
AudioComponent comp = (*aciGCProc)(inInstance);
|
||||
if (comp)
|
||||
result = (*acGDProc)(comp, outDesc);
|
||||
}
|
||||
#if !CA_USE_AUDIO_PLUGIN_ONLY
|
||||
else {
|
||||
result = CMgr_GetComponentDescription (inInstance, outDesc);
|
||||
}
|
||||
#endif
|
||||
|
||||
return result;
|
||||
}
|
||||
|
||||
#if !CA_USE_AUDIO_PLUGIN_ONLY
|
||||
// these are the direct dependencies on ComponentMgr calls that an AU
|
||||
// that is a component mgr is dependent on
|
||||
|
||||
// these are dynamically loaded
|
||||
|
||||
#include <CoreServices/CoreServices.h>
|
||||
#include <AudioUnit/AudioUnit.h>
|
||||
#include "CAXException.h"
|
||||
#include "ComponentBase.h"
|
||||
|
||||
//~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
|
||||
// Component Manager
|
||||
// Used for fast dispatch with audio units
|
||||
typedef Handle (*GetComponentInstanceStorageProc)(ComponentInstance aComponentInstance);
|
||||
static GetComponentInstanceStorageProc sGetComponentInstanceStorageProc = NULL;
|
||||
|
||||
typedef OSErr (*GetComponentInfoProc)(Component, ComponentDescription *, void*, void*, void*);
|
||||
static GetComponentInfoProc sGetComponentInfoProc = NULL;
|
||||
|
||||
typedef void (*SetComponentInstanceStorageProc)(ComponentInstance, Handle);
|
||||
static SetComponentInstanceStorageProc sSetComponentInstanceStorageProc = NULL;
|
||||
|
||||
//~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
|
||||
|
||||
static void CSInitOnce(void* /*unused*/)
|
||||
{
|
||||
void *theImage = dlopen("/System/Library/Frameworks/CoreServices.framework/CoreServices", RTLD_LAZY);
|
||||
if (!theImage) return;
|
||||
|
||||
sGetComponentInstanceStorageProc = (GetComponentInstanceStorageProc) dlsym(theImage, "GetComponentInstanceStorage");
|
||||
sGetComponentInfoProc = (GetComponentInfoProc)dlsym (theImage, "GetComponentInfo");
|
||||
sSetComponentInstanceStorageProc = (SetComponentInstanceStorageProc) dlsym(theImage, "SetComponentInstanceStorage");
|
||||
}
|
||||
|
||||
#if TARGET_OS_MAC
|
||||
|
||||
#include <dispatch/dispatch.h>
|
||||
|
||||
static dispatch_once_t sCSInitOnce = 0;
|
||||
|
||||
static void CSInit ()
|
||||
{
|
||||
dispatch_once_f(&sCSInitOnce, NULL, CSInitOnce);
|
||||
}
|
||||
|
||||
#else
|
||||
|
||||
static void CSInit ()
|
||||
{
|
||||
static int sDoCSLoad = 1;
|
||||
if (sDoCSLoad) {
|
||||
sDoCSLoad = 0;
|
||||
CSInitOnce(NULL);
|
||||
}
|
||||
}
|
||||
|
||||
#endif
|
||||
|
||||
OSStatus CMgr_GetComponentDescription (const AudioComponentInstance inInstance, AudioComponentDescription * outDesc)
|
||||
{
|
||||
CSInit();
|
||||
if (sGetComponentInfoProc)
|
||||
return (*sGetComponentInfoProc)((Component)inInstance, (ComponentDescription*)outDesc, NULL, NULL, NULL);
|
||||
return kAudio_UnimplementedError;
|
||||
}
|
||||
|
||||
Handle CMgr_GetComponentInstanceStorage(ComponentInstance aComponentInstance)
|
||||
{
|
||||
CSInit();
|
||||
if (sGetComponentInstanceStorageProc)
|
||||
return (*sGetComponentInstanceStorageProc)(aComponentInstance);
|
||||
return NULL;
|
||||
}
|
||||
|
||||
void CMgr_SetComponentInstanceStorage(ComponentInstance aComponentInstance, Handle theStorage)
|
||||
{
|
||||
CSInit();
|
||||
if (sSetComponentInstanceStorageProc)
|
||||
(*sSetComponentInstanceStorageProc)(aComponentInstance, theStorage);
|
||||
}
|
||||
#endif // !CA_USE_AUDIO_PLUGIN_ONLY
|
||||
|
||||
#else
|
||||
//#include "ComponentManagerDependenciesWin.h"
|
||||
// everything we need is there and we should be linking against it
|
||||
static OSStatus CB_GetComponentDescription (const AudioComponentInstance inInstance, AudioComponentDescription * outDesc)
|
||||
{
|
||||
AudioComponent comp = AudioComponentInstanceGetComponent(inInstance);
|
||||
if (comp)
|
||||
return AudioComponentGetDescription(comp, outDesc);
|
||||
|
||||
return kAudio_ParamError;
|
||||
}
|
||||
|
||||
#endif
|
||||
|
||||
@@ -1,353 +1,353 @@
|
||||
/*
|
||||
File: ComponentBase.h
|
||||
Abstract: Part of CoreAudio Utility Classes
|
||||
Version: 1.1
|
||||
|
||||
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.
|
||||
|
||||
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.
|
||||
|
||||
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.
|
||||
|
||||
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.
|
||||
|
||||
Copyright (C) 2014 Apple Inc. All Rights Reserved.
|
||||
|
||||
*/
|
||||
#ifndef __ComponentBase_h__
|
||||
#define __ComponentBase_h__
|
||||
|
||||
#include <new>
|
||||
#include "CADebugMacros.h"
|
||||
#include "CAXException.h"
|
||||
|
||||
#if !defined(__COREAUDIO_USE_FLAT_INCLUDES__)
|
||||
#include <CoreAudio/CoreAudioTypes.h>
|
||||
#include <AudioUnit/AudioUnit.h>
|
||||
|
||||
#if !CA_USE_AUDIO_PLUGIN_ONLY
|
||||
#include <CoreServices/../Frameworks/CarbonCore.framework/Headers/Components.h>
|
||||
|
||||
#if (MAC_OS_X_VERSION_MAX_ALLOWED <= MAC_OS_X_VERSION_10_5)
|
||||
#define AudioComponentInstance ComponentInstance
|
||||
#define AudioComponentDescription ComponentDescription
|
||||
#define AudioComponent Component
|
||||
#endif
|
||||
Handle CMgr_GetComponentInstanceStorage(ComponentInstance aComponentInstance);
|
||||
void CMgr_SetComponentInstanceStorage(ComponentInstance aComponentInstance, Handle theStorage);
|
||||
#endif
|
||||
|
||||
#if MAC_OS_X_VERSION_MAX_ALLOWED <= MAC_OS_X_VERSION_10_4
|
||||
typedef Float32 AudioUnitParameterValue;
|
||||
#endif
|
||||
#if COREAUDIOTYPES_VERSION < 1051
|
||||
typedef Float32 AudioUnitSampleType;
|
||||
#endif
|
||||
|
||||
#if !TARGET_OS_WIN32
|
||||
#include <pthread.h>
|
||||
#endif
|
||||
|
||||
#if TARGET_OS_WIN32
|
||||
#include "CAGuard.h"
|
||||
#endif
|
||||
#else
|
||||
#include "CoreAudioTypes.h"
|
||||
#if !CA_USE_AUDIO_PLUGIN_ONLY
|
||||
#include "ComponentManagerDependenciesWin.h"
|
||||
#endif
|
||||
#include "AudioUnit.h"
|
||||
#include "CAGuard.h"
|
||||
#endif
|
||||
|
||||
#ifndef COMPONENT_THROW
|
||||
#if VERBOSE_COMPONENT_THROW
|
||||
#define COMPONENT_THROW(throw_err) \
|
||||
do { DebugMessage(#throw_err); throw static_cast<OSStatus>(throw_err); } while (0)
|
||||
#else
|
||||
#define COMPONENT_THROW(throw_err) \
|
||||
throw static_cast<OSStatus>(throw_err)
|
||||
#endif
|
||||
#endif
|
||||
|
||||
#define COMPONENT_CATCH \
|
||||
catch (const CAXException &ex) { result = ex.mError; } \
|
||||
catch (std::bad_alloc &) { result = kAudio_MemFullError; } \
|
||||
catch (OSStatus catch_err) { result = catch_err; } \
|
||||
catch (OSErr catch_err) { result = catch_err; } \
|
||||
catch (...) { result = -1; }
|
||||
|
||||
/*! @class ComponentBase */
|
||||
class ComponentBase {
|
||||
public:
|
||||
// classic MacErrors
|
||||
enum { noErr = 0};
|
||||
|
||||
/*! @ctor ComponentBase */
|
||||
ComponentBase(AudioComponentInstance inInstance);
|
||||
|
||||
/*! @dtor ~ComponentBase */
|
||||
virtual ~ComponentBase();
|
||||
|
||||
/*! @method PostConstructor */
|
||||
virtual void PostConstructor();
|
||||
|
||||
/*! @method PreDestructor */
|
||||
virtual void PreDestructor();
|
||||
|
||||
#if !CA_USE_AUDIO_PLUGIN_ONLY
|
||||
/*! @method Version */
|
||||
virtual OSStatus Version();
|
||||
|
||||
/*! @method ComponentEntryDispatch */
|
||||
static OSStatus ComponentEntryDispatch(ComponentParameters *p, ComponentBase *This);
|
||||
|
||||
/*! GetSelectorForCanDo */
|
||||
static SInt16 GetSelectorForCanDo(ComponentParameters *params);
|
||||
#endif
|
||||
|
||||
/*! @method GetComponentInstance */
|
||||
AudioComponentInstance GetComponentInstance() const { return mComponentInstance; }
|
||||
|
||||
/*! @method GetComponentDescription */
|
||||
AudioComponentDescription GetComponentDescription() const;
|
||||
|
||||
// This global variable is so that new instances know how they were instantiated: via the Component Manager,
|
||||
// or as AudioComponents. It's ugly, but preferable to altering the constructor of every class in the hierarchy.
|
||||
// It's safe because construction is protected by ComponentInitLocker.
|
||||
enum EInstanceType { kComponentMgrInstance, kAudioComponentInstance };
|
||||
static EInstanceType sNewInstanceType;
|
||||
|
||||
/*! @method IsPluginObject */
|
||||
bool IsPluginObject () const { return mInstanceType == kAudioComponentInstance; }
|
||||
/*! @method IsCMgrObject */
|
||||
bool IsCMgrObject () const { return mInstanceType == kComponentMgrInstance; }
|
||||
|
||||
/*! @method AP_Open */
|
||||
static OSStatus AP_Open(void *self, AudioUnit compInstance);
|
||||
|
||||
/*! @method AP_Close */
|
||||
static OSStatus AP_Close(void *self);
|
||||
|
||||
protected:
|
||||
/*! @var mComponentInstance */
|
||||
AudioComponentInstance mComponentInstance;
|
||||
EInstanceType mInstanceType;
|
||||
};
|
||||
|
||||
class ComponentInitLocker
|
||||
{
|
||||
#if TARGET_OS_MAC
|
||||
public:
|
||||
ComponentInitLocker()
|
||||
{
|
||||
pthread_once(&sOnce, InitComponentInitLocker);
|
||||
pthread_mutex_lock(&sComponentOpenMutex);
|
||||
mPreviousNewInstanceType = ComponentBase::sNewInstanceType;
|
||||
}
|
||||
~ComponentInitLocker()
|
||||
{
|
||||
ComponentBase::sNewInstanceType = mPreviousNewInstanceType;
|
||||
pthread_mutex_unlock(&sComponentOpenMutex);
|
||||
}
|
||||
|
||||
// There are situations (11844772) where we need to be able to release the lock early.
|
||||
class Unlocker {
|
||||
public:
|
||||
Unlocker()
|
||||
{
|
||||
pthread_mutex_unlock(&sComponentOpenMutex);
|
||||
}
|
||||
~Unlocker()
|
||||
{
|
||||
pthread_mutex_lock(&sComponentOpenMutex);
|
||||
}
|
||||
};
|
||||
|
||||
private:
|
||||
static pthread_mutex_t sComponentOpenMutex;
|
||||
static pthread_once_t sOnce;
|
||||
static void InitComponentInitLocker();
|
||||
|
||||
#elif TARGET_OS_WIN32
|
||||
public:
|
||||
bool sNeedsUnlocking;
|
||||
ComponentInitLocker() { sNeedsUnlocking = sComponentOpenGuard.Lock(); }
|
||||
~ComponentInitLocker() { if(sNeedsUnlocking) { sComponentOpenGuard.Unlock(); } }
|
||||
private:
|
||||
static CAGuard sComponentOpenGuard;
|
||||
#endif
|
||||
|
||||
private:
|
||||
ComponentBase::EInstanceType mPreviousNewInstanceType;
|
||||
};
|
||||
|
||||
/*! @class AudioComponentPlugInInstance */
|
||||
struct AudioComponentPlugInInstance {
|
||||
AudioComponentPlugInInterface mPlugInInterface;
|
||||
void * (*mConstruct)(void *memory, AudioComponentInstance ci);
|
||||
void (*mDestruct)(void *memory);
|
||||
void * mPad[2]; // pad to a 16-byte boundary (in either 32 or 64 bit mode)
|
||||
UInt32 mInstanceStorage; // the ACI implementation object is constructed into this memory
|
||||
// this member is just a placeholder. it is aligned to a 16byte boundary
|
||||
};
|
||||
|
||||
/*! @class APFactory */
|
||||
template <class APMethodLookup, class Implementor>
|
||||
class APFactory {
|
||||
public:
|
||||
static void *Construct(void *memory, AudioComponentInstance compInstance)
|
||||
{
|
||||
return new(memory) Implementor(compInstance);
|
||||
}
|
||||
|
||||
static void Destruct(void *memory)
|
||||
{
|
||||
((Implementor *)memory)->~Implementor();
|
||||
}
|
||||
|
||||
// This is the AudioComponentFactoryFunction. It returns an AudioComponentPlugInInstance.
|
||||
// The actual implementation object is not created until Open().
|
||||
static AudioComponentPlugInInterface *Factory(const AudioComponentDescription * /* inDesc */)
|
||||
{
|
||||
AudioComponentPlugInInstance *acpi =
|
||||
(AudioComponentPlugInInstance *)malloc( offsetof(AudioComponentPlugInInstance, mInstanceStorage) + sizeof(Implementor) );
|
||||
acpi->mPlugInInterface.Open = ComponentBase::AP_Open;
|
||||
acpi->mPlugInInterface.Close = ComponentBase::AP_Close;
|
||||
acpi->mPlugInInterface.Lookup = APMethodLookup::Lookup;
|
||||
acpi->mPlugInInterface.reserved = NULL;
|
||||
acpi->mConstruct = Construct;
|
||||
acpi->mDestruct = Destruct;
|
||||
acpi->mPad[0] = NULL;
|
||||
acpi->mPad[1] = NULL;
|
||||
return (AudioComponentPlugInInterface*)acpi;
|
||||
}
|
||||
|
||||
// This is for runtime registration (not for plug-ins loaded from bundles).
|
||||
static AudioComponent Register(UInt32 type, UInt32 subtype, UInt32 manuf, CFStringRef name, UInt32 vers, UInt32 flags=0)
|
||||
{
|
||||
AudioComponentDescription desc = { type, subtype, manuf, flags, 0 };
|
||||
return AudioComponentRegister(&desc, name, vers, Factory);
|
||||
}
|
||||
};
|
||||
|
||||
#if !CA_USE_AUDIO_PLUGIN_ONLY
|
||||
/*! @class ComponentEntryPoint
|
||||
* @discussion This is only used for a component manager version
|
||||
*/
|
||||
template <class Class>
|
||||
class ComponentEntryPoint {
|
||||
public:
|
||||
/*! @method Dispatch */
|
||||
static OSStatus Dispatch(ComponentParameters *params, Class *obj)
|
||||
{
|
||||
OSStatus result = noErr;
|
||||
|
||||
try {
|
||||
if (params->what == kComponentOpenSelect) {
|
||||
// solve a host of initialization thread safety issues.
|
||||
ComponentInitLocker lock;
|
||||
|
||||
ComponentBase::sNewInstanceType = ComponentBase::kComponentMgrInstance;
|
||||
ComponentInstance ci = (ComponentInstance)(params->params[0]);
|
||||
Class *This = new Class((AudioComponentInstance)ci);
|
||||
This->PostConstructor(); // allows base class to do additional initialization
|
||||
// once the derived class is fully constructed
|
||||
|
||||
CMgr_SetComponentInstanceStorage(ci, (Handle)This);
|
||||
} else
|
||||
result = Class::ComponentEntryDispatch(params, obj);
|
||||
}
|
||||
COMPONENT_CATCH
|
||||
|
||||
return result;
|
||||
}
|
||||
|
||||
/*! @method Register */
|
||||
static Component Register(OSType compType, OSType subType, OSType manufacturer)
|
||||
{
|
||||
ComponentDescription description = {compType, subType, manufacturer, 0, 0};
|
||||
Component component = RegisterComponent(&description, (ComponentRoutineUPP) Dispatch, registerComponentGlobal, NULL, NULL, NULL);
|
||||
if (component != NULL) {
|
||||
SetDefaultComponent(component, defaultComponentAnyFlagsAnyManufacturerAnySubType);
|
||||
}
|
||||
return component;
|
||||
}
|
||||
};
|
||||
|
||||
// NOTE: Component Mgr is deprecated in ML.
|
||||
// this macro should not be used with new audio components
|
||||
// it is only for backwards compatibility with Lion and SL.
|
||||
// this macro registers both a plugin and a component mgr version.
|
||||
#define AUDIOCOMPONENT_ENTRY(FactoryType, Class) \
|
||||
extern "C" OSStatus Class##Entry(ComponentParameters *params, Class *obj); \
|
||||
extern "C" OSStatus Class##Entry(ComponentParameters *params, Class *obj) { \
|
||||
return ComponentEntryPoint<Class>::Dispatch(params, obj); \
|
||||
} \
|
||||
extern "C" void * Class##Factory(const AudioComponentDescription *inDesc); \
|
||||
extern "C" void * Class##Factory(const AudioComponentDescription *inDesc) { \
|
||||
return FactoryType<Class>::Factory(inDesc); \
|
||||
}
|
||||
// the only component we still support are the carbon based view components
|
||||
// you should be using this macro now to exclusively register those types
|
||||
#define VIEW_COMPONENT_ENTRY(Class) \
|
||||
extern "C" OSStatus Class##Entry(ComponentParameters *params, Class *obj); \
|
||||
extern "C" OSStatus Class##Entry(ComponentParameters *params, Class *obj) { \
|
||||
return ComponentEntryPoint<Class>::Dispatch(params, obj); \
|
||||
}
|
||||
|
||||
/*! @class ComponentRegistrar */
|
||||
template <class Class, OSType Type, OSType Subtype, OSType Manufacturer>
|
||||
class ComponentRegistrar {
|
||||
public:
|
||||
/*! @ctor ComponentRegistrar */
|
||||
ComponentRegistrar() { ComponentEntryPoint<Class>::Register(Type, Subtype, Manufacturer); }
|
||||
};
|
||||
|
||||
#define COMPONENT_REGISTER(Class,Type,Subtype,Manufacturer) \
|
||||
static ComponentRegistrar<Class, Type, Subtype, Manufacturer> gRegistrar##Class
|
||||
#else
|
||||
#define COMPONENT_ENTRY(Class)
|
||||
#define COMPONENT_REGISTER(Class)
|
||||
// this macro is used to generate the Entry Point for a given Audio Plugin
|
||||
// you should be using this macro now with audio components
|
||||
#define AUDIOCOMPONENT_ENTRY(FactoryType, Class) \
|
||||
extern "C" void * Class##Factory(const AudioComponentDescription *inDesc); \
|
||||
extern "C" void * Class##Factory(const AudioComponentDescription *inDesc) { \
|
||||
return FactoryType<Class>::Factory(inDesc); \
|
||||
}
|
||||
|
||||
#endif // !CA_USE_AUDIO_PLUGIN_ONLY
|
||||
|
||||
|
||||
#endif // __ComponentBase_h__
|
||||
/*
|
||||
File: ComponentBase.h
|
||||
Abstract: Part of CoreAudio Utility Classes
|
||||
Version: 1.1
|
||||
|
||||
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.
|
||||
|
||||
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.
|
||||
|
||||
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.
|
||||
|
||||
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.
|
||||
|
||||
Copyright (C) 2014 Apple Inc. All Rights Reserved.
|
||||
|
||||
*/
|
||||
#ifndef __ComponentBase_h__
|
||||
#define __ComponentBase_h__
|
||||
|
||||
#include <new>
|
||||
#include "CADebugMacros.h"
|
||||
#include "CAXException.h"
|
||||
|
||||
#if !defined(__COREAUDIO_USE_FLAT_INCLUDES__)
|
||||
#include <CoreAudio/CoreAudioTypes.h>
|
||||
#include <AudioUnit/AudioUnit.h>
|
||||
|
||||
#if !CA_USE_AUDIO_PLUGIN_ONLY
|
||||
#include <CoreServices/../Frameworks/CarbonCore.framework/Headers/Components.h>
|
||||
|
||||
#if (MAC_OS_X_VERSION_MAX_ALLOWED <= MAC_OS_X_VERSION_10_5)
|
||||
#define AudioComponentInstance ComponentInstance
|
||||
#define AudioComponentDescription ComponentDescription
|
||||
#define AudioComponent Component
|
||||
#endif
|
||||
Handle CMgr_GetComponentInstanceStorage(ComponentInstance aComponentInstance);
|
||||
void CMgr_SetComponentInstanceStorage(ComponentInstance aComponentInstance, Handle theStorage);
|
||||
#endif
|
||||
|
||||
#if MAC_OS_X_VERSION_MAX_ALLOWED <= MAC_OS_X_VERSION_10_4
|
||||
typedef Float32 AudioUnitParameterValue;
|
||||
#endif
|
||||
#if COREAUDIOTYPES_VERSION < 1051
|
||||
typedef Float32 AudioUnitSampleType;
|
||||
#endif
|
||||
|
||||
#if !TARGET_OS_WIN32
|
||||
#include <pthread.h>
|
||||
#endif
|
||||
|
||||
#if TARGET_OS_WIN32
|
||||
#include "CAGuard.h"
|
||||
#endif
|
||||
#else
|
||||
#include "CoreAudioTypes.h"
|
||||
#if !CA_USE_AUDIO_PLUGIN_ONLY
|
||||
#include "ComponentManagerDependenciesWin.h"
|
||||
#endif
|
||||
#include "AudioUnit.h"
|
||||
#include "CAGuard.h"
|
||||
#endif
|
||||
|
||||
#ifndef COMPONENT_THROW
|
||||
#if VERBOSE_COMPONENT_THROW
|
||||
#define COMPONENT_THROW(throw_err) \
|
||||
do { DebugMessage(#throw_err); throw static_cast<OSStatus>(throw_err); } while (0)
|
||||
#else
|
||||
#define COMPONENT_THROW(throw_err) \
|
||||
throw static_cast<OSStatus>(throw_err)
|
||||
#endif
|
||||
#endif
|
||||
|
||||
#define COMPONENT_CATCH \
|
||||
catch (const CAXException &ex) { result = ex.mError; } \
|
||||
catch (std::bad_alloc &) { result = kAudio_MemFullError; } \
|
||||
catch (OSStatus catch_err) { result = catch_err; } \
|
||||
catch (OSErr catch_err) { result = catch_err; } \
|
||||
catch (...) { result = -1; }
|
||||
|
||||
/*! @class ComponentBase */
|
||||
class ComponentBase {
|
||||
public:
|
||||
// classic MacErrors
|
||||
enum { noErr = 0};
|
||||
|
||||
/*! @ctor ComponentBase */
|
||||
ComponentBase(AudioComponentInstance inInstance);
|
||||
|
||||
/*! @dtor ~ComponentBase */
|
||||
virtual ~ComponentBase();
|
||||
|
||||
/*! @method PostConstructor */
|
||||
virtual void PostConstructor();
|
||||
|
||||
/*! @method PreDestructor */
|
||||
virtual void PreDestructor();
|
||||
|
||||
#if !CA_USE_AUDIO_PLUGIN_ONLY
|
||||
/*! @method Version */
|
||||
virtual OSStatus Version();
|
||||
|
||||
/*! @method ComponentEntryDispatch */
|
||||
static OSStatus ComponentEntryDispatch(ComponentParameters *p, ComponentBase *This);
|
||||
|
||||
/*! GetSelectorForCanDo */
|
||||
static SInt16 GetSelectorForCanDo(ComponentParameters *params);
|
||||
#endif
|
||||
|
||||
/*! @method GetComponentInstance */
|
||||
AudioComponentInstance GetComponentInstance() const { return mComponentInstance; }
|
||||
|
||||
/*! @method GetComponentDescription */
|
||||
AudioComponentDescription GetComponentDescription() const;
|
||||
|
||||
// This global variable is so that new instances know how they were instantiated: via the Component Manager,
|
||||
// or as AudioComponents. It's ugly, but preferable to altering the constructor of every class in the hierarchy.
|
||||
// It's safe because construction is protected by ComponentInitLocker.
|
||||
enum EInstanceType { kComponentMgrInstance, kAudioComponentInstance };
|
||||
static EInstanceType sNewInstanceType;
|
||||
|
||||
/*! @method IsPluginObject */
|
||||
bool IsPluginObject () const { return mInstanceType == kAudioComponentInstance; }
|
||||
/*! @method IsCMgrObject */
|
||||
bool IsCMgrObject () const { return mInstanceType == kComponentMgrInstance; }
|
||||
|
||||
/*! @method AP_Open */
|
||||
static OSStatus AP_Open(void *self, AudioUnit compInstance);
|
||||
|
||||
/*! @method AP_Close */
|
||||
static OSStatus AP_Close(void *self);
|
||||
|
||||
protected:
|
||||
/*! @var mComponentInstance */
|
||||
AudioComponentInstance mComponentInstance;
|
||||
EInstanceType mInstanceType;
|
||||
};
|
||||
|
||||
class ComponentInitLocker
|
||||
{
|
||||
#if TARGET_OS_MAC
|
||||
public:
|
||||
ComponentInitLocker()
|
||||
{
|
||||
pthread_once(&sOnce, InitComponentInitLocker);
|
||||
pthread_mutex_lock(&sComponentOpenMutex);
|
||||
mPreviousNewInstanceType = ComponentBase::sNewInstanceType;
|
||||
}
|
||||
~ComponentInitLocker()
|
||||
{
|
||||
ComponentBase::sNewInstanceType = mPreviousNewInstanceType;
|
||||
pthread_mutex_unlock(&sComponentOpenMutex);
|
||||
}
|
||||
|
||||
// There are situations (11844772) where we need to be able to release the lock early.
|
||||
class Unlocker {
|
||||
public:
|
||||
Unlocker()
|
||||
{
|
||||
pthread_mutex_unlock(&sComponentOpenMutex);
|
||||
}
|
||||
~Unlocker()
|
||||
{
|
||||
pthread_mutex_lock(&sComponentOpenMutex);
|
||||
}
|
||||
};
|
||||
|
||||
private:
|
||||
static pthread_mutex_t sComponentOpenMutex;
|
||||
static pthread_once_t sOnce;
|
||||
static void InitComponentInitLocker();
|
||||
|
||||
#elif TARGET_OS_WIN32
|
||||
public:
|
||||
bool sNeedsUnlocking;
|
||||
ComponentInitLocker() { sNeedsUnlocking = sComponentOpenGuard.Lock(); }
|
||||
~ComponentInitLocker() { if(sNeedsUnlocking) { sComponentOpenGuard.Unlock(); } }
|
||||
private:
|
||||
static CAGuard sComponentOpenGuard;
|
||||
#endif
|
||||
|
||||
private:
|
||||
ComponentBase::EInstanceType mPreviousNewInstanceType;
|
||||
};
|
||||
|
||||
/*! @class AudioComponentPlugInInstance */
|
||||
struct AudioComponentPlugInInstance {
|
||||
AudioComponentPlugInInterface mPlugInInterface;
|
||||
void * (*mConstruct)(void *memory, AudioComponentInstance ci);
|
||||
void (*mDestruct)(void *memory);
|
||||
void * mPad[2]; // pad to a 16-byte boundary (in either 32 or 64 bit mode)
|
||||
UInt32 mInstanceStorage; // the ACI implementation object is constructed into this memory
|
||||
// this member is just a placeholder. it is aligned to a 16byte boundary
|
||||
};
|
||||
|
||||
/*! @class APFactory */
|
||||
template <class APMethodLookup, class Implementor>
|
||||
class APFactory {
|
||||
public:
|
||||
static void *Construct(void *memory, AudioComponentInstance compInstance)
|
||||
{
|
||||
return new(memory) Implementor(compInstance);
|
||||
}
|
||||
|
||||
static void Destruct(void *memory)
|
||||
{
|
||||
((Implementor *)memory)->~Implementor();
|
||||
}
|
||||
|
||||
// This is the AudioComponentFactoryFunction. It returns an AudioComponentPlugInInstance.
|
||||
// The actual implementation object is not created until Open().
|
||||
static AudioComponentPlugInInterface *Factory(const AudioComponentDescription * /* inDesc */)
|
||||
{
|
||||
AudioComponentPlugInInstance *acpi =
|
||||
(AudioComponentPlugInInstance *)malloc( offsetof(AudioComponentPlugInInstance, mInstanceStorage) + sizeof(Implementor) );
|
||||
acpi->mPlugInInterface.Open = ComponentBase::AP_Open;
|
||||
acpi->mPlugInInterface.Close = ComponentBase::AP_Close;
|
||||
acpi->mPlugInInterface.Lookup = APMethodLookup::Lookup;
|
||||
acpi->mPlugInInterface.reserved = NULL;
|
||||
acpi->mConstruct = Construct;
|
||||
acpi->mDestruct = Destruct;
|
||||
acpi->mPad[0] = NULL;
|
||||
acpi->mPad[1] = NULL;
|
||||
return (AudioComponentPlugInInterface*)acpi;
|
||||
}
|
||||
|
||||
// This is for runtime registration (not for plug-ins loaded from bundles).
|
||||
static AudioComponent Register(UInt32 type, UInt32 subtype, UInt32 manuf, CFStringRef name, UInt32 vers, UInt32 flags=0)
|
||||
{
|
||||
AudioComponentDescription desc = { type, subtype, manuf, flags, 0 };
|
||||
return AudioComponentRegister(&desc, name, vers, Factory);
|
||||
}
|
||||
};
|
||||
|
||||
#if !CA_USE_AUDIO_PLUGIN_ONLY
|
||||
/*! @class ComponentEntryPoint
|
||||
* @discussion This is only used for a component manager version
|
||||
*/
|
||||
template <class Class>
|
||||
class ComponentEntryPoint {
|
||||
public:
|
||||
/*! @method Dispatch */
|
||||
static OSStatus Dispatch(ComponentParameters *params, Class *obj)
|
||||
{
|
||||
OSStatus result = noErr;
|
||||
|
||||
try {
|
||||
if (params->what == kComponentOpenSelect) {
|
||||
// solve a host of initialization thread safety issues.
|
||||
ComponentInitLocker lock;
|
||||
|
||||
ComponentBase::sNewInstanceType = ComponentBase::kComponentMgrInstance;
|
||||
ComponentInstance ci = (ComponentInstance)(params->params[0]);
|
||||
Class *This = new Class((AudioComponentInstance)ci);
|
||||
This->PostConstructor(); // allows base class to do additional initialization
|
||||
// once the derived class is fully constructed
|
||||
|
||||
CMgr_SetComponentInstanceStorage(ci, (Handle)This);
|
||||
} else
|
||||
result = Class::ComponentEntryDispatch(params, obj);
|
||||
}
|
||||
COMPONENT_CATCH
|
||||
|
||||
return result;
|
||||
}
|
||||
|
||||
/*! @method Register */
|
||||
static Component Register(OSType compType, OSType subType, OSType manufacturer)
|
||||
{
|
||||
ComponentDescription description = {compType, subType, manufacturer, 0, 0};
|
||||
Component component = RegisterComponent(&description, (ComponentRoutineUPP) Dispatch, registerComponentGlobal, NULL, NULL, NULL);
|
||||
if (component != NULL) {
|
||||
SetDefaultComponent(component, defaultComponentAnyFlagsAnyManufacturerAnySubType);
|
||||
}
|
||||
return component;
|
||||
}
|
||||
};
|
||||
|
||||
// NOTE: Component Mgr is deprecated in ML.
|
||||
// this macro should not be used with new audio components
|
||||
// it is only for backwards compatibility with Lion and SL.
|
||||
// this macro registers both a plugin and a component mgr version.
|
||||
#define AUDIOCOMPONENT_ENTRY(FactoryType, Class) \
|
||||
extern "C" OSStatus Class##Entry(ComponentParameters *params, Class *obj); \
|
||||
extern "C" OSStatus Class##Entry(ComponentParameters *params, Class *obj) { \
|
||||
return ComponentEntryPoint<Class>::Dispatch(params, obj); \
|
||||
} \
|
||||
extern "C" void * Class##Factory(const AudioComponentDescription *inDesc); \
|
||||
extern "C" void * Class##Factory(const AudioComponentDescription *inDesc) { \
|
||||
return FactoryType<Class>::Factory(inDesc); \
|
||||
}
|
||||
// the only component we still support are the carbon based view components
|
||||
// you should be using this macro now to exclusively register those types
|
||||
#define VIEW_COMPONENT_ENTRY(Class) \
|
||||
extern "C" OSStatus Class##Entry(ComponentParameters *params, Class *obj); \
|
||||
extern "C" OSStatus Class##Entry(ComponentParameters *params, Class *obj) { \
|
||||
return ComponentEntryPoint<Class>::Dispatch(params, obj); \
|
||||
}
|
||||
|
||||
/*! @class ComponentRegistrar */
|
||||
template <class Class, OSType Type, OSType Subtype, OSType Manufacturer>
|
||||
class ComponentRegistrar {
|
||||
public:
|
||||
/*! @ctor ComponentRegistrar */
|
||||
ComponentRegistrar() { ComponentEntryPoint<Class>::Register(Type, Subtype, Manufacturer); }
|
||||
};
|
||||
|
||||
#define COMPONENT_REGISTER(Class,Type,Subtype,Manufacturer) \
|
||||
static ComponentRegistrar<Class, Type, Subtype, Manufacturer> gRegistrar##Class
|
||||
#else
|
||||
#define COMPONENT_ENTRY(Class)
|
||||
#define COMPONENT_REGISTER(Class)
|
||||
// this macro is used to generate the Entry Point for a given Audio Plugin
|
||||
// you should be using this macro now with audio components
|
||||
#define AUDIOCOMPONENT_ENTRY(FactoryType, Class) \
|
||||
extern "C" void * Class##Factory(const AudioComponentDescription *inDesc); \
|
||||
extern "C" void * Class##Factory(const AudioComponentDescription *inDesc) { \
|
||||
return FactoryType<Class>::Factory(inDesc); \
|
||||
}
|
||||
|
||||
#endif // !CA_USE_AUDIO_PLUGIN_ONLY
|
||||
|
||||
|
||||
#endif // __ComponentBase_h__
|
||||
|
||||
@@ -1,354 +1,354 @@
|
||||
/*
|
||||
File: MusicDeviceBase.cpp
|
||||
Abstract: MusicDeviceBase.h
|
||||
Version: 1.1
|
||||
|
||||
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.
|
||||
|
||||
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.
|
||||
|
||||
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.
|
||||
|
||||
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.
|
||||
|
||||
Copyright (C) 2014 Apple Inc. All Rights Reserved.
|
||||
|
||||
*/
|
||||
#include "MusicDeviceBase.h"
|
||||
|
||||
// compatibility with older OS SDK releases
|
||||
typedef OSStatus
|
||||
(*TEMP_MusicDeviceMIDIEventProc)( void * inComponentStorage,
|
||||
UInt32 inStatus,
|
||||
UInt32 inData1,
|
||||
UInt32 inData2,
|
||||
UInt32 inOffsetSampleFrame);
|
||||
|
||||
typedef OSStatus
|
||||
(*TEMP_MusicDeviceStartNoteProc)( void * inComponentStorage,
|
||||
MusicDeviceInstrumentID inInstrument,
|
||||
MusicDeviceGroupID inGroupID,
|
||||
NoteInstanceID * outNoteInstanceID,
|
||||
UInt32 inOffsetSampleFrame,
|
||||
const MusicDeviceNoteParams * inParams);
|
||||
|
||||
typedef OSStatus
|
||||
(*TEMP_MusicDeviceStopNoteProc)(void * inComponentStorage,
|
||||
MusicDeviceGroupID inGroupID,
|
||||
NoteInstanceID inNoteInstanceID,
|
||||
UInt32 inOffsetSampleFrame);
|
||||
|
||||
#if !CA_USE_AUDIO_PLUGIN_ONLY
|
||||
|
||||
static OSStatus MusicDeviceBaseMIDIEvent(void * inComponentStorage,
|
||||
UInt32 inStatus,
|
||||
UInt32 inData1,
|
||||
UInt32 inData2,
|
||||
UInt32 inOffsetSampleFrame);
|
||||
|
||||
static OSStatus MusicDeviceBaseStartNote( void * inComponentStorage,
|
||||
MusicDeviceInstrumentID inInstrument,
|
||||
MusicDeviceGroupID inGroupID,
|
||||
NoteInstanceID * outNoteInstanceID,
|
||||
UInt32 inOffsetSampleFrame,
|
||||
const MusicDeviceNoteParams * inParams);
|
||||
|
||||
static OSStatus MusicDeviceBaseStopNote(void * inComponentStorage,
|
||||
MusicDeviceGroupID inGroupID,
|
||||
NoteInstanceID inNoteInstanceID,
|
||||
UInt32 inOffsetSampleFrame);
|
||||
|
||||
#endif
|
||||
|
||||
MusicDeviceBase::MusicDeviceBase(AudioComponentInstance inInstance,
|
||||
UInt32 numInputs,
|
||||
UInt32 numOutputs,
|
||||
UInt32 numGroups)
|
||||
: AUBase(inInstance, numInputs, numOutputs, numGroups),
|
||||
AUMIDIBase(this)
|
||||
{
|
||||
}
|
||||
|
||||
OSStatus MusicDeviceBase::GetPropertyInfo(AudioUnitPropertyID inID,
|
||||
AudioUnitScope inScope,
|
||||
AudioUnitElement inElement,
|
||||
UInt32 & outDataSize,
|
||||
Boolean & outWritable)
|
||||
{
|
||||
OSStatus result;
|
||||
|
||||
switch (inID)
|
||||
{
|
||||
#if !TARGET_OS_IPHONE
|
||||
case kMusicDeviceProperty_InstrumentCount:
|
||||
if (inScope != kAudioUnitScope_Global) return kAudioUnitErr_InvalidScope;
|
||||
outDataSize = sizeof(UInt32);
|
||||
outWritable = false;
|
||||
result = noErr;
|
||||
break;
|
||||
#endif
|
||||
default:
|
||||
result = AUBase::GetPropertyInfo (inID, inScope, inElement, outDataSize, outWritable);
|
||||
|
||||
if (result == kAudioUnitErr_InvalidProperty)
|
||||
result = AUMIDIBase::DelegateGetPropertyInfo (inID, inScope, inElement, outDataSize, outWritable);
|
||||
break;
|
||||
}
|
||||
return result;
|
||||
}
|
||||
|
||||
OSStatus MusicDeviceBase::GetProperty( AudioUnitPropertyID inID,
|
||||
AudioUnitScope inScope,
|
||||
AudioUnitElement inElement,
|
||||
void * outData)
|
||||
{
|
||||
OSStatus result;
|
||||
|
||||
switch (inID)
|
||||
{
|
||||
#if !CA_USE_AUDIO_PLUGIN_ONLY
|
||||
case kAudioUnitProperty_FastDispatch:
|
||||
if (!IsCMgrObject()) return kAudioUnitErr_InvalidProperty;
|
||||
if (inElement == kMusicDeviceMIDIEventSelect) {
|
||||
*(TEMP_MusicDeviceMIDIEventProc *)outData = MusicDeviceBaseMIDIEvent;
|
||||
return noErr;
|
||||
}
|
||||
else if (inElement == kMusicDeviceStartNoteSelect) {
|
||||
*(TEMP_MusicDeviceStartNoteProc *)outData = MusicDeviceBaseStartNote;
|
||||
return noErr;
|
||||
}
|
||||
else if (inElement == kMusicDeviceStopNoteSelect) {
|
||||
*(TEMP_MusicDeviceStopNoteProc *)outData = MusicDeviceBaseStopNote;
|
||||
return noErr;
|
||||
}
|
||||
return kAudioUnitErr_InvalidElement;
|
||||
#endif
|
||||
|
||||
#if !TARGET_OS_IPHONE
|
||||
case kMusicDeviceProperty_InstrumentCount:
|
||||
if (inScope != kAudioUnitScope_Global) return kAudioUnitErr_InvalidScope;
|
||||
return GetInstrumentCount (*(UInt32*)outData);
|
||||
#endif
|
||||
default:
|
||||
result = AUBase::GetProperty (inID, inScope, inElement, outData);
|
||||
|
||||
if (result == kAudioUnitErr_InvalidProperty)
|
||||
result = AUMIDIBase::DelegateGetProperty (inID, inScope, inElement, outData);
|
||||
}
|
||||
|
||||
return result;
|
||||
}
|
||||
|
||||
|
||||
OSStatus MusicDeviceBase::SetProperty( AudioUnitPropertyID inID,
|
||||
AudioUnitScope inScope,
|
||||
AudioUnitElement inElement,
|
||||
const void * inData,
|
||||
UInt32 inDataSize)
|
||||
|
||||
{
|
||||
|
||||
OSStatus result = AUBase::SetProperty (inID, inScope, inElement, inData, inDataSize);
|
||||
|
||||
if (result == kAudioUnitErr_InvalidProperty)
|
||||
result = AUMIDIBase::DelegateSetProperty (inID, inScope, inElement, inData, inDataSize);
|
||||
|
||||
return result;
|
||||
}
|
||||
|
||||
// For a MusicDevice that doesn't support separate instruments (ie. is mono-timbral)
|
||||
// then this call should return an instrument count of zero and noErr
|
||||
OSStatus MusicDeviceBase::GetInstrumentCount (UInt32 &outInstCount) const
|
||||
{
|
||||
outInstCount = 0;
|
||||
return noErr;
|
||||
}
|
||||
|
||||
OSStatus MusicDeviceBase::HandleNoteOn( UInt8 inChannel,
|
||||
UInt8 inNoteNumber,
|
||||
UInt8 inVelocity,
|
||||
UInt32 inStartFrame)
|
||||
{
|
||||
MusicDeviceNoteParams params;
|
||||
params.argCount = 2;
|
||||
params.mPitch = inNoteNumber;
|
||||
params.mVelocity = inVelocity;
|
||||
return StartNote (kMusicNoteEvent_UseGroupInstrument, inChannel, NULL, inStartFrame, params);
|
||||
}
|
||||
|
||||
OSStatus MusicDeviceBase::HandleNoteOff( UInt8 inChannel,
|
||||
UInt8 inNoteNumber,
|
||||
UInt8 inVelocity,
|
||||
UInt32 inStartFrame)
|
||||
{
|
||||
return StopNote (inChannel, inNoteNumber, inStartFrame);
|
||||
}
|
||||
|
||||
OSStatus
|
||||
MusicDeviceBase::HandleStartNoteMessage (MusicDeviceInstrumentID inInstrument,
|
||||
MusicDeviceGroupID inGroupID,
|
||||
NoteInstanceID * outNoteInstanceID,
|
||||
UInt32 inOffsetSampleFrame,
|
||||
const MusicDeviceNoteParams * inParams)
|
||||
{
|
||||
if (inParams == NULL || outNoteInstanceID == NULL) return kAudio_ParamError;
|
||||
|
||||
if (!IsInitialized()) return kAudioUnitErr_Uninitialized;
|
||||
|
||||
return StartNote (inInstrument, inGroupID, outNoteInstanceID, inOffsetSampleFrame, *inParams);
|
||||
}
|
||||
|
||||
#if TARGET_OS_MAC
|
||||
#if __LP64__
|
||||
// comp instance, parameters in forward order
|
||||
#define PARAM(_typ, _name, _index, _nparams) \
|
||||
_typ _name = *(_typ *)¶ms->params[_index + 1];
|
||||
#else
|
||||
// parameters in reverse order, then comp instance
|
||||
#define PARAM(_typ, _name, _index, _nparams) \
|
||||
_typ _name = *(_typ *)¶ms->params[_nparams - 1 - _index];
|
||||
#endif
|
||||
#elif TARGET_OS_WIN32
|
||||
// (no comp instance), parameters in forward order
|
||||
#define PARAM(_typ, _name, _index, _nparams) \
|
||||
_typ _name = *(_typ *)¶ms->params[_index];
|
||||
#endif
|
||||
|
||||
#if !CA_USE_AUDIO_PLUGIN_ONLY
|
||||
OSStatus MusicDeviceBase::ComponentEntryDispatch( ComponentParameters * params,
|
||||
MusicDeviceBase * This)
|
||||
{
|
||||
if (This == NULL) return kAudio_ParamError;
|
||||
|
||||
OSStatus result;
|
||||
|
||||
switch (params->what) {
|
||||
case kMusicDeviceMIDIEventSelect:
|
||||
case kMusicDeviceSysExSelect:
|
||||
{
|
||||
result = AUMIDIBase::ComponentEntryDispatch (params, This);
|
||||
}
|
||||
break;
|
||||
case kMusicDevicePrepareInstrumentSelect:
|
||||
{
|
||||
PARAM(MusicDeviceInstrumentID, inInstrument, 0, 1);
|
||||
result = This->PrepareInstrument(inInstrument);
|
||||
}
|
||||
break;
|
||||
case kMusicDeviceReleaseInstrumentSelect:
|
||||
{
|
||||
PARAM(MusicDeviceInstrumentID, inInstrument, 0, 1);
|
||||
result = This->ReleaseInstrument(inInstrument);
|
||||
}
|
||||
break;
|
||||
case kMusicDeviceStartNoteSelect:
|
||||
{
|
||||
PARAM(MusicDeviceInstrumentID, pbinInstrument, 0, 5);
|
||||
PARAM(MusicDeviceGroupID, pbinGroupID, 1, 5);
|
||||
PARAM(NoteInstanceID *, pboutNoteInstanceID, 2, 5);
|
||||
PARAM(UInt32, pbinOffsetSampleFrame, 3, 5);
|
||||
PARAM(const MusicDeviceNoteParams *, pbinParams, 4, 5);
|
||||
result = This->HandleStartNoteMessage(pbinInstrument, pbinGroupID, pboutNoteInstanceID, pbinOffsetSampleFrame, pbinParams);
|
||||
}
|
||||
break;
|
||||
case kMusicDeviceStopNoteSelect:
|
||||
{
|
||||
PARAM(MusicDeviceGroupID, pbinGroupID, 0, 3);
|
||||
PARAM(NoteInstanceID, pbinNoteInstanceID, 1, 3);
|
||||
PARAM(UInt32, pbinOffsetSampleFrame, 2, 3);
|
||||
result = This->StopNote(pbinGroupID, pbinNoteInstanceID, pbinOffsetSampleFrame);
|
||||
}
|
||||
break;
|
||||
|
||||
default:
|
||||
result = AUBase::ComponentEntryDispatch(params, This);
|
||||
break;
|
||||
}
|
||||
|
||||
return result;
|
||||
}
|
||||
#endif
|
||||
|
||||
#if !CA_USE_AUDIO_PLUGIN_ONLY
|
||||
|
||||
// fast dispatch
|
||||
static OSStatus MusicDeviceBaseMIDIEvent(void * inComponentStorage,
|
||||
UInt32 inStatus,
|
||||
UInt32 inData1,
|
||||
UInt32 inData2,
|
||||
UInt32 inOffsetSampleFrame)
|
||||
{
|
||||
OSStatus result = noErr;
|
||||
try {
|
||||
MusicDeviceBase *This = static_cast<MusicDeviceBase *>(inComponentStorage);
|
||||
if (This == NULL) return kAudio_ParamError;
|
||||
result = This->MIDIEvent(inStatus, inData1, inData2, inOffsetSampleFrame);
|
||||
}
|
||||
COMPONENT_CATCH
|
||||
return result;
|
||||
}
|
||||
|
||||
OSStatus MusicDeviceBaseStartNote( void * inComponentStorage,
|
||||
MusicDeviceInstrumentID inInstrument,
|
||||
MusicDeviceGroupID inGroupID,
|
||||
NoteInstanceID * outNoteInstanceID,
|
||||
UInt32 inOffsetSampleFrame,
|
||||
const MusicDeviceNoteParams * inParams)
|
||||
{
|
||||
OSStatus result = noErr;
|
||||
try {
|
||||
if (inParams == NULL || outNoteInstanceID == NULL) return kAudio_ParamError;
|
||||
MusicDeviceBase *This = static_cast<MusicDeviceBase *>(inComponentStorage);
|
||||
if (This == NULL) return kAudio_ParamError;
|
||||
result = This->StartNote(inInstrument, inGroupID, outNoteInstanceID, inOffsetSampleFrame, *inParams);
|
||||
}
|
||||
COMPONENT_CATCH
|
||||
return result;
|
||||
}
|
||||
|
||||
OSStatus MusicDeviceBaseStopNote(void * inComponentStorage,
|
||||
MusicDeviceGroupID inGroupID,
|
||||
NoteInstanceID inNoteInstanceID,
|
||||
UInt32 inOffsetSampleFrame)
|
||||
{
|
||||
OSStatus result = noErr;
|
||||
try {
|
||||
MusicDeviceBase *This = static_cast<MusicDeviceBase *>(inComponentStorage);
|
||||
if (This == NULL) return kAudio_ParamError;
|
||||
result = This->StopNote(inGroupID, inNoteInstanceID, inOffsetSampleFrame);
|
||||
}
|
||||
COMPONENT_CATCH
|
||||
return result;
|
||||
}
|
||||
|
||||
#endif
|
||||
/*
|
||||
File: MusicDeviceBase.cpp
|
||||
Abstract: MusicDeviceBase.h
|
||||
Version: 1.1
|
||||
|
||||
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.
|
||||
|
||||
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.
|
||||
|
||||
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.
|
||||
|
||||
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.
|
||||
|
||||
Copyright (C) 2014 Apple Inc. All Rights Reserved.
|
||||
|
||||
*/
|
||||
#include "MusicDeviceBase.h"
|
||||
|
||||
// compatibility with older OS SDK releases
|
||||
typedef OSStatus
|
||||
(*TEMP_MusicDeviceMIDIEventProc)( void * inComponentStorage,
|
||||
UInt32 inStatus,
|
||||
UInt32 inData1,
|
||||
UInt32 inData2,
|
||||
UInt32 inOffsetSampleFrame);
|
||||
|
||||
typedef OSStatus
|
||||
(*TEMP_MusicDeviceStartNoteProc)( void * inComponentStorage,
|
||||
MusicDeviceInstrumentID inInstrument,
|
||||
MusicDeviceGroupID inGroupID,
|
||||
NoteInstanceID * outNoteInstanceID,
|
||||
UInt32 inOffsetSampleFrame,
|
||||
const MusicDeviceNoteParams * inParams);
|
||||
|
||||
typedef OSStatus
|
||||
(*TEMP_MusicDeviceStopNoteProc)(void * inComponentStorage,
|
||||
MusicDeviceGroupID inGroupID,
|
||||
NoteInstanceID inNoteInstanceID,
|
||||
UInt32 inOffsetSampleFrame);
|
||||
|
||||
#if !CA_USE_AUDIO_PLUGIN_ONLY
|
||||
|
||||
static OSStatus MusicDeviceBaseMIDIEvent(void * inComponentStorage,
|
||||
UInt32 inStatus,
|
||||
UInt32 inData1,
|
||||
UInt32 inData2,
|
||||
UInt32 inOffsetSampleFrame);
|
||||
|
||||
static OSStatus MusicDeviceBaseStartNote( void * inComponentStorage,
|
||||
MusicDeviceInstrumentID inInstrument,
|
||||
MusicDeviceGroupID inGroupID,
|
||||
NoteInstanceID * outNoteInstanceID,
|
||||
UInt32 inOffsetSampleFrame,
|
||||
const MusicDeviceNoteParams * inParams);
|
||||
|
||||
static OSStatus MusicDeviceBaseStopNote(void * inComponentStorage,
|
||||
MusicDeviceGroupID inGroupID,
|
||||
NoteInstanceID inNoteInstanceID,
|
||||
UInt32 inOffsetSampleFrame);
|
||||
|
||||
#endif
|
||||
|
||||
MusicDeviceBase::MusicDeviceBase(AudioComponentInstance inInstance,
|
||||
UInt32 numInputs,
|
||||
UInt32 numOutputs,
|
||||
UInt32 numGroups)
|
||||
: AUBase(inInstance, numInputs, numOutputs, numGroups),
|
||||
AUMIDIBase(this)
|
||||
{
|
||||
}
|
||||
|
||||
OSStatus MusicDeviceBase::GetPropertyInfo(AudioUnitPropertyID inID,
|
||||
AudioUnitScope inScope,
|
||||
AudioUnitElement inElement,
|
||||
UInt32 & outDataSize,
|
||||
Boolean & outWritable)
|
||||
{
|
||||
OSStatus result;
|
||||
|
||||
switch (inID)
|
||||
{
|
||||
#if !TARGET_OS_IPHONE
|
||||
case kMusicDeviceProperty_InstrumentCount:
|
||||
if (inScope != kAudioUnitScope_Global) return kAudioUnitErr_InvalidScope;
|
||||
outDataSize = sizeof(UInt32);
|
||||
outWritable = false;
|
||||
result = noErr;
|
||||
break;
|
||||
#endif
|
||||
default:
|
||||
result = AUBase::GetPropertyInfo (inID, inScope, inElement, outDataSize, outWritable);
|
||||
|
||||
if (result == kAudioUnitErr_InvalidProperty)
|
||||
result = AUMIDIBase::DelegateGetPropertyInfo (inID, inScope, inElement, outDataSize, outWritable);
|
||||
break;
|
||||
}
|
||||
return result;
|
||||
}
|
||||
|
||||
OSStatus MusicDeviceBase::GetProperty( AudioUnitPropertyID inID,
|
||||
AudioUnitScope inScope,
|
||||
AudioUnitElement inElement,
|
||||
void * outData)
|
||||
{
|
||||
OSStatus result;
|
||||
|
||||
switch (inID)
|
||||
{
|
||||
#if !CA_USE_AUDIO_PLUGIN_ONLY
|
||||
case kAudioUnitProperty_FastDispatch:
|
||||
if (!IsCMgrObject()) return kAudioUnitErr_InvalidProperty;
|
||||
if (inElement == kMusicDeviceMIDIEventSelect) {
|
||||
*(TEMP_MusicDeviceMIDIEventProc *)outData = MusicDeviceBaseMIDIEvent;
|
||||
return noErr;
|
||||
}
|
||||
else if (inElement == kMusicDeviceStartNoteSelect) {
|
||||
*(TEMP_MusicDeviceStartNoteProc *)outData = MusicDeviceBaseStartNote;
|
||||
return noErr;
|
||||
}
|
||||
else if (inElement == kMusicDeviceStopNoteSelect) {
|
||||
*(TEMP_MusicDeviceStopNoteProc *)outData = MusicDeviceBaseStopNote;
|
||||
return noErr;
|
||||
}
|
||||
return kAudioUnitErr_InvalidElement;
|
||||
#endif
|
||||
|
||||
#if !TARGET_OS_IPHONE
|
||||
case kMusicDeviceProperty_InstrumentCount:
|
||||
if (inScope != kAudioUnitScope_Global) return kAudioUnitErr_InvalidScope;
|
||||
return GetInstrumentCount (*(UInt32*)outData);
|
||||
#endif
|
||||
default:
|
||||
result = AUBase::GetProperty (inID, inScope, inElement, outData);
|
||||
|
||||
if (result == kAudioUnitErr_InvalidProperty)
|
||||
result = AUMIDIBase::DelegateGetProperty (inID, inScope, inElement, outData);
|
||||
}
|
||||
|
||||
return result;
|
||||
}
|
||||
|
||||
|
||||
OSStatus MusicDeviceBase::SetProperty( AudioUnitPropertyID inID,
|
||||
AudioUnitScope inScope,
|
||||
AudioUnitElement inElement,
|
||||
const void * inData,
|
||||
UInt32 inDataSize)
|
||||
|
||||
{
|
||||
|
||||
OSStatus result = AUBase::SetProperty (inID, inScope, inElement, inData, inDataSize);
|
||||
|
||||
if (result == kAudioUnitErr_InvalidProperty)
|
||||
result = AUMIDIBase::DelegateSetProperty (inID, inScope, inElement, inData, inDataSize);
|
||||
|
||||
return result;
|
||||
}
|
||||
|
||||
// For a MusicDevice that doesn't support separate instruments (ie. is mono-timbral)
|
||||
// then this call should return an instrument count of zero and noErr
|
||||
OSStatus MusicDeviceBase::GetInstrumentCount (UInt32 &outInstCount) const
|
||||
{
|
||||
outInstCount = 0;
|
||||
return noErr;
|
||||
}
|
||||
|
||||
OSStatus MusicDeviceBase::HandleNoteOn( UInt8 inChannel,
|
||||
UInt8 inNoteNumber,
|
||||
UInt8 inVelocity,
|
||||
UInt32 inStartFrame)
|
||||
{
|
||||
MusicDeviceNoteParams params;
|
||||
params.argCount = 2;
|
||||
params.mPitch = inNoteNumber;
|
||||
params.mVelocity = inVelocity;
|
||||
return StartNote (kMusicNoteEvent_UseGroupInstrument, inChannel, NULL, inStartFrame, params);
|
||||
}
|
||||
|
||||
OSStatus MusicDeviceBase::HandleNoteOff( UInt8 inChannel,
|
||||
UInt8 inNoteNumber,
|
||||
UInt8 inVelocity,
|
||||
UInt32 inStartFrame)
|
||||
{
|
||||
return StopNote (inChannel, inNoteNumber, inStartFrame);
|
||||
}
|
||||
|
||||
OSStatus
|
||||
MusicDeviceBase::HandleStartNoteMessage (MusicDeviceInstrumentID inInstrument,
|
||||
MusicDeviceGroupID inGroupID,
|
||||
NoteInstanceID * outNoteInstanceID,
|
||||
UInt32 inOffsetSampleFrame,
|
||||
const MusicDeviceNoteParams * inParams)
|
||||
{
|
||||
if (inParams == NULL || outNoteInstanceID == NULL) return kAudio_ParamError;
|
||||
|
||||
if (!IsInitialized()) return kAudioUnitErr_Uninitialized;
|
||||
|
||||
return StartNote (inInstrument, inGroupID, outNoteInstanceID, inOffsetSampleFrame, *inParams);
|
||||
}
|
||||
|
||||
#if TARGET_OS_MAC
|
||||
#if __LP64__
|
||||
// comp instance, parameters in forward order
|
||||
#define PARAM(_typ, _name, _index, _nparams) \
|
||||
_typ _name = *(_typ *)¶ms->params[_index + 1];
|
||||
#else
|
||||
// parameters in reverse order, then comp instance
|
||||
#define PARAM(_typ, _name, _index, _nparams) \
|
||||
_typ _name = *(_typ *)¶ms->params[_nparams - 1 - _index];
|
||||
#endif
|
||||
#elif TARGET_OS_WIN32
|
||||
// (no comp instance), parameters in forward order
|
||||
#define PARAM(_typ, _name, _index, _nparams) \
|
||||
_typ _name = *(_typ *)¶ms->params[_index];
|
||||
#endif
|
||||
|
||||
#if !CA_USE_AUDIO_PLUGIN_ONLY
|
||||
OSStatus MusicDeviceBase::ComponentEntryDispatch( ComponentParameters * params,
|
||||
MusicDeviceBase * This)
|
||||
{
|
||||
if (This == NULL) return kAudio_ParamError;
|
||||
|
||||
OSStatus result;
|
||||
|
||||
switch (params->what) {
|
||||
case kMusicDeviceMIDIEventSelect:
|
||||
case kMusicDeviceSysExSelect:
|
||||
{
|
||||
result = AUMIDIBase::ComponentEntryDispatch (params, This);
|
||||
}
|
||||
break;
|
||||
case kMusicDevicePrepareInstrumentSelect:
|
||||
{
|
||||
PARAM(MusicDeviceInstrumentID, inInstrument, 0, 1);
|
||||
result = This->PrepareInstrument(inInstrument);
|
||||
}
|
||||
break;
|
||||
case kMusicDeviceReleaseInstrumentSelect:
|
||||
{
|
||||
PARAM(MusicDeviceInstrumentID, inInstrument, 0, 1);
|
||||
result = This->ReleaseInstrument(inInstrument);
|
||||
}
|
||||
break;
|
||||
case kMusicDeviceStartNoteSelect:
|
||||
{
|
||||
PARAM(MusicDeviceInstrumentID, pbinInstrument, 0, 5);
|
||||
PARAM(MusicDeviceGroupID, pbinGroupID, 1, 5);
|
||||
PARAM(NoteInstanceID *, pboutNoteInstanceID, 2, 5);
|
||||
PARAM(UInt32, pbinOffsetSampleFrame, 3, 5);
|
||||
PARAM(const MusicDeviceNoteParams *, pbinParams, 4, 5);
|
||||
result = This->HandleStartNoteMessage(pbinInstrument, pbinGroupID, pboutNoteInstanceID, pbinOffsetSampleFrame, pbinParams);
|
||||
}
|
||||
break;
|
||||
case kMusicDeviceStopNoteSelect:
|
||||
{
|
||||
PARAM(MusicDeviceGroupID, pbinGroupID, 0, 3);
|
||||
PARAM(NoteInstanceID, pbinNoteInstanceID, 1, 3);
|
||||
PARAM(UInt32, pbinOffsetSampleFrame, 2, 3);
|
||||
result = This->StopNote(pbinGroupID, pbinNoteInstanceID, pbinOffsetSampleFrame);
|
||||
}
|
||||
break;
|
||||
|
||||
default:
|
||||
result = AUBase::ComponentEntryDispatch(params, This);
|
||||
break;
|
||||
}
|
||||
|
||||
return result;
|
||||
}
|
||||
#endif
|
||||
|
||||
#if !CA_USE_AUDIO_PLUGIN_ONLY
|
||||
|
||||
// fast dispatch
|
||||
static OSStatus MusicDeviceBaseMIDIEvent(void * inComponentStorage,
|
||||
UInt32 inStatus,
|
||||
UInt32 inData1,
|
||||
UInt32 inData2,
|
||||
UInt32 inOffsetSampleFrame)
|
||||
{
|
||||
OSStatus result = noErr;
|
||||
try {
|
||||
MusicDeviceBase *This = static_cast<MusicDeviceBase *>(inComponentStorage);
|
||||
if (This == NULL) return kAudio_ParamError;
|
||||
result = This->MIDIEvent(inStatus, inData1, inData2, inOffsetSampleFrame);
|
||||
}
|
||||
COMPONENT_CATCH
|
||||
return result;
|
||||
}
|
||||
|
||||
OSStatus MusicDeviceBaseStartNote( void * inComponentStorage,
|
||||
MusicDeviceInstrumentID inInstrument,
|
||||
MusicDeviceGroupID inGroupID,
|
||||
NoteInstanceID * outNoteInstanceID,
|
||||
UInt32 inOffsetSampleFrame,
|
||||
const MusicDeviceNoteParams * inParams)
|
||||
{
|
||||
OSStatus result = noErr;
|
||||
try {
|
||||
if (inParams == NULL || outNoteInstanceID == NULL) return kAudio_ParamError;
|
||||
MusicDeviceBase *This = static_cast<MusicDeviceBase *>(inComponentStorage);
|
||||
if (This == NULL) return kAudio_ParamError;
|
||||
result = This->StartNote(inInstrument, inGroupID, outNoteInstanceID, inOffsetSampleFrame, *inParams);
|
||||
}
|
||||
COMPONENT_CATCH
|
||||
return result;
|
||||
}
|
||||
|
||||
OSStatus MusicDeviceBaseStopNote(void * inComponentStorage,
|
||||
MusicDeviceGroupID inGroupID,
|
||||
NoteInstanceID inNoteInstanceID,
|
||||
UInt32 inOffsetSampleFrame)
|
||||
{
|
||||
OSStatus result = noErr;
|
||||
try {
|
||||
MusicDeviceBase *This = static_cast<MusicDeviceBase *>(inComponentStorage);
|
||||
if (This == NULL) return kAudio_ParamError;
|
||||
result = This->StopNote(inGroupID, inNoteInstanceID, inOffsetSampleFrame);
|
||||
}
|
||||
COMPONENT_CATCH
|
||||
return result;
|
||||
}
|
||||
|
||||
#endif
|
||||
|
||||
@@ -1,126 +1,126 @@
|
||||
/*
|
||||
File: MusicDeviceBase.h
|
||||
Abstract: Part of CoreAudio Utility Classes
|
||||
Version: 1.1
|
||||
|
||||
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.
|
||||
|
||||
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.
|
||||
|
||||
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.
|
||||
|
||||
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.
|
||||
|
||||
Copyright (C) 2014 Apple Inc. All Rights Reserved.
|
||||
|
||||
*/
|
||||
#ifndef __MusicDeviceBase_h__
|
||||
#define __MusicDeviceBase_h__
|
||||
|
||||
#include "AUMIDIBase.h"
|
||||
|
||||
// ________________________________________________________________________
|
||||
// MusicDeviceBase
|
||||
//
|
||||
|
||||
/*! @class MusicDeviceBase */
|
||||
class MusicDeviceBase : public AUBase, public AUMIDIBase {
|
||||
public:
|
||||
/*! @ctor MusicDeviceBase */
|
||||
MusicDeviceBase( AudioComponentInstance inInstance,
|
||||
UInt32 numInputs,
|
||||
UInt32 numOutputs,
|
||||
UInt32 numGroups = 0);
|
||||
|
||||
|
||||
virtual OSStatus MIDIEvent( UInt32 inStatus,
|
||||
UInt32 inData1,
|
||||
UInt32 inData2,
|
||||
UInt32 inOffsetSampleFrame)
|
||||
{
|
||||
return AUMIDIBase::MIDIEvent (inStatus, inData1, inData2, inOffsetSampleFrame);
|
||||
}
|
||||
|
||||
/*! @method SysEx */
|
||||
virtual OSStatus SysEx( const UInt8 * inData,
|
||||
UInt32 inLength)
|
||||
{
|
||||
return AUMIDIBase::SysEx (inData, inLength);
|
||||
}
|
||||
|
||||
/*! @method GetPropertyInfo */
|
||||
virtual OSStatus GetPropertyInfo(AudioUnitPropertyID inID,
|
||||
AudioUnitScope inScope,
|
||||
AudioUnitElement inElement,
|
||||
UInt32 & outDataSize,
|
||||
Boolean & outWritable);
|
||||
|
||||
/*! @method GetProperty */
|
||||
virtual OSStatus GetProperty( AudioUnitPropertyID inID,
|
||||
AudioUnitScope inScope,
|
||||
AudioUnitElement inElement,
|
||||
void * outData);
|
||||
|
||||
/*! @method SetProperty */
|
||||
virtual OSStatus SetProperty( AudioUnitPropertyID inID,
|
||||
AudioUnitScope inScope,
|
||||
AudioUnitElement inElement,
|
||||
const void * inData,
|
||||
UInt32 inDataSize);
|
||||
|
||||
/*! @method HandleNoteOn */
|
||||
virtual OSStatus HandleNoteOn( UInt8 inChannel,
|
||||
UInt8 inNoteNumber,
|
||||
UInt8 inVelocity,
|
||||
UInt32 inStartFrame);
|
||||
|
||||
/*! @method HandleNoteOff */
|
||||
virtual OSStatus HandleNoteOff( UInt8 inChannel,
|
||||
UInt8 inNoteNumber,
|
||||
UInt8 inVelocity,
|
||||
UInt32 inStartFrame);
|
||||
|
||||
/*! @method GetInstrumentCount */
|
||||
virtual OSStatus GetInstrumentCount ( UInt32 &outInstCount) const;
|
||||
|
||||
#if !CA_USE_AUDIO_PLUGIN_ONLY
|
||||
// component dispatcher
|
||||
/*! @method ComponentEntryDispatch */
|
||||
static OSStatus ComponentEntryDispatch( ComponentParameters * params,
|
||||
MusicDeviceBase * This);
|
||||
#endif
|
||||
private:
|
||||
OSStatus HandleStartNoteMessage (MusicDeviceInstrumentID inInstrument, MusicDeviceGroupID inGroupID, NoteInstanceID *outNoteInstanceID, UInt32 inOffsetSampleFrame, const MusicDeviceNoteParams *inParams);
|
||||
};
|
||||
|
||||
#endif // __MusicDeviceBase_h__
|
||||
/*
|
||||
File: MusicDeviceBase.h
|
||||
Abstract: Part of CoreAudio Utility Classes
|
||||
Version: 1.1
|
||||
|
||||
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.
|
||||
|
||||
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.
|
||||
|
||||
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.
|
||||
|
||||
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.
|
||||
|
||||
Copyright (C) 2014 Apple Inc. All Rights Reserved.
|
||||
|
||||
*/
|
||||
#ifndef __MusicDeviceBase_h__
|
||||
#define __MusicDeviceBase_h__
|
||||
|
||||
#include "AUMIDIBase.h"
|
||||
|
||||
// ________________________________________________________________________
|
||||
// MusicDeviceBase
|
||||
//
|
||||
|
||||
/*! @class MusicDeviceBase */
|
||||
class MusicDeviceBase : public AUBase, public AUMIDIBase {
|
||||
public:
|
||||
/*! @ctor MusicDeviceBase */
|
||||
MusicDeviceBase( AudioComponentInstance inInstance,
|
||||
UInt32 numInputs,
|
||||
UInt32 numOutputs,
|
||||
UInt32 numGroups = 0);
|
||||
|
||||
|
||||
virtual OSStatus MIDIEvent( UInt32 inStatus,
|
||||
UInt32 inData1,
|
||||
UInt32 inData2,
|
||||
UInt32 inOffsetSampleFrame)
|
||||
{
|
||||
return AUMIDIBase::MIDIEvent (inStatus, inData1, inData2, inOffsetSampleFrame);
|
||||
}
|
||||
|
||||
/*! @method SysEx */
|
||||
virtual OSStatus SysEx( const UInt8 * inData,
|
||||
UInt32 inLength)
|
||||
{
|
||||
return AUMIDIBase::SysEx (inData, inLength);
|
||||
}
|
||||
|
||||
/*! @method GetPropertyInfo */
|
||||
virtual OSStatus GetPropertyInfo(AudioUnitPropertyID inID,
|
||||
AudioUnitScope inScope,
|
||||
AudioUnitElement inElement,
|
||||
UInt32 & outDataSize,
|
||||
Boolean & outWritable);
|
||||
|
||||
/*! @method GetProperty */
|
||||
virtual OSStatus GetProperty( AudioUnitPropertyID inID,
|
||||
AudioUnitScope inScope,
|
||||
AudioUnitElement inElement,
|
||||
void * outData);
|
||||
|
||||
/*! @method SetProperty */
|
||||
virtual OSStatus SetProperty( AudioUnitPropertyID inID,
|
||||
AudioUnitScope inScope,
|
||||
AudioUnitElement inElement,
|
||||
const void * inData,
|
||||
UInt32 inDataSize);
|
||||
|
||||
/*! @method HandleNoteOn */
|
||||
virtual OSStatus HandleNoteOn( UInt8 inChannel,
|
||||
UInt8 inNoteNumber,
|
||||
UInt8 inVelocity,
|
||||
UInt32 inStartFrame);
|
||||
|
||||
/*! @method HandleNoteOff */
|
||||
virtual OSStatus HandleNoteOff( UInt8 inChannel,
|
||||
UInt8 inNoteNumber,
|
||||
UInt8 inVelocity,
|
||||
UInt32 inStartFrame);
|
||||
|
||||
/*! @method GetInstrumentCount */
|
||||
virtual OSStatus GetInstrumentCount ( UInt32 &outInstCount) const;
|
||||
|
||||
#if !CA_USE_AUDIO_PLUGIN_ONLY
|
||||
// component dispatcher
|
||||
/*! @method ComponentEntryDispatch */
|
||||
static OSStatus ComponentEntryDispatch( ComponentParameters * params,
|
||||
MusicDeviceBase * This);
|
||||
#endif
|
||||
private:
|
||||
OSStatus HandleStartNoteMessage (MusicDeviceInstrumentID inInstrument, MusicDeviceGroupID inGroupID, NoteInstanceID *outNoteInstanceID, UInt32 inOffsetSampleFrame, const MusicDeviceNoteParams *inParams);
|
||||
};
|
||||
|
||||
#endif // __MusicDeviceBase_h__
|
||||
|
||||
@@ -2,15 +2,15 @@
|
||||
==============================================================================
|
||||
|
||||
This file is part of the JUCE library.
|
||||
Copyright (c) 2020 - Raw Material Software Limited
|
||||
Copyright (c) 2022 - Raw Material Software Limited
|
||||
|
||||
JUCE is an open source library subject to commercial or open-source
|
||||
licensing.
|
||||
|
||||
By using JUCE, you agree to the terms of both the JUCE 6 End-User License
|
||||
Agreement and JUCE Privacy Policy (both effective as of the 16th June 2020).
|
||||
By using JUCE, you agree to the terms of both the JUCE 7 End-User License
|
||||
Agreement and JUCE Privacy Policy.
|
||||
|
||||
End User License Agreement: www.juce.com/juce-6-licence
|
||||
End User License Agreement: www.juce.com/juce-7-licence
|
||||
Privacy Policy: www.juce.com/juce-privacy-policy
|
||||
|
||||
Or: You may also use this code under the terms of the GPL v3 (see
|
||||
@@ -29,11 +29,6 @@
|
||||
|
||||
#if JucePlugin_Build_AU
|
||||
|
||||
#if __LP64__
|
||||
#undef JUCE_SUPPORT_CARBON
|
||||
#define JUCE_SUPPORT_CARBON 0
|
||||
#endif
|
||||
|
||||
JUCE_BEGIN_IGNORE_WARNINGS_GCC_LIKE ("-Wshorten-64-to-32",
|
||||
"-Wunused-parameter",
|
||||
"-Wdeprecated-declarations",
|
||||
@@ -59,35 +54,25 @@ JUCE_BEGIN_IGNORE_WARNINGS_GCC_LIKE ("-Wshorten-64-to-32",
|
||||
#include <QuartzCore/QuartzCore.h>
|
||||
#include "CoreAudioUtilityClasses/MusicDeviceBase.h"
|
||||
|
||||
/** The BUILD_AU_CARBON_UI flag lets you specify whether old-school carbon hosts are supported as
|
||||
well as ones that can open a cocoa view. If this is enabled, you'll need to also add the AUCarbonBase
|
||||
files to your project.
|
||||
*/
|
||||
#if ! (defined (BUILD_AU_CARBON_UI) || JUCE_64BIT)
|
||||
#define BUILD_AU_CARBON_UI 1
|
||||
#endif
|
||||
|
||||
#ifdef __LP64__
|
||||
#undef BUILD_AU_CARBON_UI // (not possible in a 64-bit build)
|
||||
#endif
|
||||
|
||||
#if BUILD_AU_CARBON_UI
|
||||
#include "CoreAudioUtilityClasses/AUCarbonViewBase.h"
|
||||
#endif
|
||||
|
||||
JUCE_END_IGNORE_WARNINGS_GCC_LIKE
|
||||
|
||||
#define JUCE_MAC_WINDOW_VISIBITY_BODGE 1
|
||||
#define JUCE_CORE_INCLUDE_OBJC_HELPERS 1
|
||||
|
||||
#include "../utility/juce_IncludeModuleHeaders.h"
|
||||
#include "../utility/juce_FakeMouseMoveGenerator.h"
|
||||
#include "../utility/juce_CarbonVisibility.h"
|
||||
|
||||
#include <juce_audio_basics/native/juce_mac_CoreAudioLayouts.h>
|
||||
#include <juce_audio_basics/native/juce_mac_CoreAudioTimeConversions.h>
|
||||
#include <juce_audio_processors/format_types/juce_LegacyAudioParameter.cpp>
|
||||
#include <juce_audio_processors/format_types/juce_AU_Shared.h>
|
||||
|
||||
#if JucePlugin_Enable_ARA
|
||||
#include <juce_audio_processors/utilities/ARA/juce_AudioProcessor_ARAExtensions.h>
|
||||
#include <ARA_API/ARAAudioUnit.h>
|
||||
#if ARA_SUPPORT_VERSION_1
|
||||
#error "Unsupported ARA version - only ARA version 2 and onward are supported by the current JUCE ARA implementation"
|
||||
#endif
|
||||
#endif
|
||||
|
||||
//==============================================================================
|
||||
using namespace juce;
|
||||
|
||||
@@ -103,13 +88,7 @@ struct AudioProcessorHolder
|
||||
AudioProcessorHolder (bool initialiseGUI)
|
||||
{
|
||||
if (initialiseGUI)
|
||||
{
|
||||
#if BUILD_AU_CARBON_UI
|
||||
NSApplicationLoad();
|
||||
#endif
|
||||
|
||||
initialiseJuce_GUI();
|
||||
}
|
||||
|
||||
juceFilter.reset (createPluginFilterOfType (AudioProcessor::wrapperType_AudioUnit));
|
||||
|
||||
@@ -124,7 +103,6 @@ struct AudioProcessorHolder
|
||||
class JuceAU : public AudioProcessorHolder,
|
||||
public MusicDeviceBase,
|
||||
public AudioProcessorListener,
|
||||
public AudioPlayHead,
|
||||
public AudioProcessorParameter::Listener
|
||||
{
|
||||
public:
|
||||
@@ -132,8 +110,7 @@ public:
|
||||
: AudioProcessorHolder (activePlugins.size() + activeUIs.size() == 0),
|
||||
MusicDeviceBase (component,
|
||||
(UInt32) AudioUnitHelpers::getBusCountForWrapper (*juceFilter, true),
|
||||
(UInt32) AudioUnitHelpers::getBusCountForWrapper (*juceFilter, false)),
|
||||
mapper (*juceFilter)
|
||||
(UInt32) AudioUnitHelpers::getBusCountForWrapper (*juceFilter, false))
|
||||
{
|
||||
inParameterChangedCallback = false;
|
||||
|
||||
@@ -162,7 +139,6 @@ public:
|
||||
totalInChannels = juceFilter->getTotalNumInputChannels();
|
||||
totalOutChannels = juceFilter->getTotalNumOutputChannels();
|
||||
|
||||
juceFilter->setPlayHead (this);
|
||||
juceFilter->addListener (this);
|
||||
|
||||
addParameters();
|
||||
@@ -209,7 +185,7 @@ public:
|
||||
if ((err = MusicDeviceBase::Initialize()) != noErr)
|
||||
return err;
|
||||
|
||||
mapper.alloc();
|
||||
mapper.alloc (*juceFilter);
|
||||
pulledSucceeded.calloc (static_cast<size_t> (AudioUnitHelpers::getBusCountForWrapper (*juceFilter, true)));
|
||||
|
||||
prepareToPlay();
|
||||
@@ -251,7 +227,7 @@ public:
|
||||
{
|
||||
juceFilter->setRateAndBufferSizeDetails (getSampleRate(), (int) GetMaxFramesPerSlice());
|
||||
|
||||
audioBuffer.prepare (totalInChannels, totalOutChannels, (int) GetMaxFramesPerSlice() + 32);
|
||||
audioBuffer.prepare (AudioUnitHelpers::getBusesLayout (juceFilter.get()), (int) GetMaxFramesPerSlice() + 32);
|
||||
juceFilter->prepareToPlay (getSampleRate(), (int) GetMaxFramesPerSlice());
|
||||
|
||||
midiEvents.ensureSize (2048);
|
||||
@@ -462,6 +438,17 @@ public:
|
||||
outWritable = false;
|
||||
return noErr;
|
||||
|
||||
#if JucePlugin_Enable_ARA
|
||||
case ARA::kAudioUnitProperty_ARAFactory:
|
||||
outWritable = false;
|
||||
outDataSize = sizeof (ARA::ARAAudioUnitFactory);
|
||||
return noErr;
|
||||
case ARA::kAudioUnitProperty_ARAPlugInExtensionBindingWithRoles:
|
||||
outWritable = false;
|
||||
outDataSize = sizeof (ARA::ARAAudioUnitPlugInExtensionBinding);
|
||||
return noErr;
|
||||
#endif
|
||||
|
||||
default: break;
|
||||
}
|
||||
}
|
||||
@@ -503,6 +490,33 @@ public:
|
||||
jassertfalse;
|
||||
break;
|
||||
|
||||
//==============================================================================
|
||||
#if JucePlugin_Enable_ARA
|
||||
case ARA::kAudioUnitProperty_ARAFactory:
|
||||
{
|
||||
auto auFactory = static_cast<ARA::ARAAudioUnitFactory*> (outData);
|
||||
if (auFactory->inOutMagicNumber != ARA::kARAAudioUnitMagic)
|
||||
return kAudioUnitErr_InvalidProperty; // if the magic value isn't found, the property ID is re-used outside the ARA context with different, unsupported sematics
|
||||
|
||||
auFactory->outFactory = createARAFactory();
|
||||
return noErr;
|
||||
}
|
||||
|
||||
case ARA::kAudioUnitProperty_ARAPlugInExtensionBindingWithRoles:
|
||||
{
|
||||
auto binding = static_cast<ARA::ARAAudioUnitPlugInExtensionBinding*> (outData);
|
||||
if (binding->inOutMagicNumber != ARA::kARAAudioUnitMagic)
|
||||
return kAudioUnitErr_InvalidProperty; // if the magic value isn't found, the property ID is re-used outside the ARA context with different, unsupported sematics
|
||||
|
||||
AudioProcessorARAExtension* araAudioProcessorExtension = dynamic_cast<AudioProcessorARAExtension*> (juceFilter.get());
|
||||
binding->outPlugInExtension = araAudioProcessorExtension->bindToARA (binding->inDocumentControllerRef, binding->knownRoles, binding->assignedRoles);
|
||||
if (binding->outPlugInExtension == nullptr)
|
||||
return kAudioUnitErr_CannotDoInCurrentContext; // bindToARA() returns null if binding is already established
|
||||
|
||||
return noErr;
|
||||
}
|
||||
#endif
|
||||
|
||||
case juceFilterObjectPropertyID:
|
||||
((void**) outData)[0] = (void*) static_cast<AudioProcessor*> (juceFilter.get());
|
||||
((void**) outData)[1] = (void*) this;
|
||||
@@ -670,14 +684,15 @@ public:
|
||||
const ScopedLock sl (juceFilter->getCallbackLock());
|
||||
|
||||
juceFilter->setNonRealtime (shouldBeOffline);
|
||||
juceFilter->prepareToPlay (getSampleRate(), (int) GetMaxFramesPerSlice());
|
||||
|
||||
if (prepared)
|
||||
juceFilter->prepareToPlay (getSampleRate(), (int) GetMaxFramesPerSlice());
|
||||
}
|
||||
}
|
||||
|
||||
return noErr;
|
||||
}
|
||||
|
||||
#if defined (MAC_OS_X_VERSION_10_12)
|
||||
case kAudioUnitProperty_AUHostIdentifier:
|
||||
{
|
||||
if (inDataSize < sizeof (AUHostVersionIdentifier))
|
||||
@@ -688,7 +703,6 @@ public:
|
||||
|
||||
return noErr;
|
||||
}
|
||||
#endif
|
||||
|
||||
default: break;
|
||||
}
|
||||
@@ -732,6 +746,8 @@ public:
|
||||
|
||||
ComponentResult RestoreState (CFPropertyListRef inData) override
|
||||
{
|
||||
const ScopedValueSetter<bool> scope { restoringState, true };
|
||||
|
||||
{
|
||||
// Remove the data entry from the state to prevent the superclass loading the parameters
|
||||
CFUniquePtr<CFMutableDictionaryRef> copyWithoutData (CFDictionaryCreateMutableCopy (nullptr, 0, (CFDictionaryRef) inData));
|
||||
@@ -1063,97 +1079,114 @@ public:
|
||||
{
|
||||
const double rate = getSampleRate();
|
||||
jassert (rate > 0);
|
||||
#if JucePlugin_Enable_ARA
|
||||
jassert (juceFilter->getLatencySamples() == 0 || ! dynamic_cast<AudioProcessorARAExtension*> (juceFilter.get())->isBoundToARA());
|
||||
#endif
|
||||
return rate > 0 ? juceFilter->getLatencySamples() / rate : 0;
|
||||
}
|
||||
|
||||
//==============================================================================
|
||||
#if BUILD_AU_CARBON_UI
|
||||
int GetNumCustomUIComponents() override
|
||||
class ScopedPlayHead : private AudioPlayHead
|
||||
{
|
||||
return getHostType().isDigitalPerformer() ? 0 : 1;
|
||||
}
|
||||
public:
|
||||
explicit ScopedPlayHead (JuceAU& juceAudioUnit)
|
||||
: audioUnit (juceAudioUnit)
|
||||
{
|
||||
audioUnit.juceFilter->setPlayHead (this);
|
||||
}
|
||||
|
||||
void GetUIComponentDescs (ComponentDescription* inDescArray) override
|
||||
{
|
||||
inDescArray[0].componentType = kAudioUnitCarbonViewComponentType;
|
||||
inDescArray[0].componentSubType = JucePlugin_AUSubType;
|
||||
inDescArray[0].componentManufacturer = JucePlugin_AUManufacturerCode;
|
||||
inDescArray[0].componentFlags = 0;
|
||||
inDescArray[0].componentFlagsMask = 0;
|
||||
}
|
||||
#endif
|
||||
~ScopedPlayHead() override
|
||||
{
|
||||
audioUnit.juceFilter->setPlayHead (nullptr);
|
||||
}
|
||||
|
||||
private:
|
||||
Optional<PositionInfo> getPosition() const override
|
||||
{
|
||||
PositionInfo info;
|
||||
|
||||
info.setFrameRate ([this]() -> Optional<FrameRate>
|
||||
{
|
||||
switch (audioUnit.lastTimeStamp.mSMPTETime.mType)
|
||||
{
|
||||
case kSMPTETimeType2398: return FrameRate().withBaseRate (24).withPullDown();
|
||||
case kSMPTETimeType24: return FrameRate().withBaseRate (24);
|
||||
case kSMPTETimeType25: return FrameRate().withBaseRate (25);
|
||||
case kSMPTETimeType30Drop: return FrameRate().withBaseRate (30).withDrop();
|
||||
case kSMPTETimeType30: return FrameRate().withBaseRate (30);
|
||||
case kSMPTETimeType2997: return FrameRate().withBaseRate (30).withPullDown();
|
||||
case kSMPTETimeType2997Drop: return FrameRate().withBaseRate (30).withPullDown().withDrop();
|
||||
case kSMPTETimeType60: return FrameRate().withBaseRate (60);
|
||||
case kSMPTETimeType60Drop: return FrameRate().withBaseRate (60).withDrop();
|
||||
case kSMPTETimeType5994: return FrameRate().withBaseRate (60).withPullDown();
|
||||
case kSMPTETimeType5994Drop: return FrameRate().withBaseRate (60).withPullDown().withDrop();
|
||||
case kSMPTETimeType50: return FrameRate().withBaseRate (50);
|
||||
default: break;
|
||||
}
|
||||
|
||||
return {};
|
||||
}());
|
||||
|
||||
double ppqPosition = 0.0;
|
||||
double bpm = 0.0;
|
||||
|
||||
if (audioUnit.CallHostBeatAndTempo (&ppqPosition, &bpm) == noErr)
|
||||
{
|
||||
info.setPpqPosition (ppqPosition);
|
||||
info.setBpm (bpm);
|
||||
}
|
||||
|
||||
UInt32 outDeltaSampleOffsetToNextBeat;
|
||||
double outCurrentMeasureDownBeat;
|
||||
float num;
|
||||
UInt32 den;
|
||||
|
||||
if (audioUnit.CallHostMusicalTimeLocation (&outDeltaSampleOffsetToNextBeat,
|
||||
&num,
|
||||
&den,
|
||||
&outCurrentMeasureDownBeat) == noErr)
|
||||
{
|
||||
info.setTimeSignature (TimeSignature { (int) num, (int) den });
|
||||
info.setPpqPositionOfLastBarStart (outCurrentMeasureDownBeat);
|
||||
}
|
||||
|
||||
double outCurrentSampleInTimeLine = 0, outCycleStartBeat = 0, outCycleEndBeat = 0;
|
||||
Boolean playing = false, looping = false, playchanged;
|
||||
|
||||
if (audioUnit.CallHostTransportState (&playing,
|
||||
&playchanged,
|
||||
&outCurrentSampleInTimeLine,
|
||||
&looping,
|
||||
&outCycleStartBeat,
|
||||
&outCycleEndBeat) == noErr)
|
||||
{
|
||||
info.setIsPlaying (playing);
|
||||
info.setTimeInSamples ((int64) (outCurrentSampleInTimeLine + 0.5));
|
||||
info.setTimeInSeconds (*info.getTimeInSamples() / audioUnit.getSampleRate());
|
||||
info.setIsLooping (looping);
|
||||
info.setLoopPoints (LoopPoints { outCycleStartBeat, outCycleEndBeat });
|
||||
}
|
||||
else
|
||||
{
|
||||
// If the host doesn't support this callback, then use the sample time from lastTimeStamp:
|
||||
outCurrentSampleInTimeLine = audioUnit.lastTimeStamp.mSampleTime;
|
||||
}
|
||||
|
||||
info.setHostTimeNs ((audioUnit.lastTimeStamp.mFlags & kAudioTimeStampHostTimeValid) != 0
|
||||
? makeOptional (audioUnit.timeConversions.hostTimeToNanos (audioUnit.lastTimeStamp.mHostTime))
|
||||
: nullopt);
|
||||
|
||||
return info;
|
||||
}
|
||||
|
||||
JuceAU& audioUnit;
|
||||
};
|
||||
|
||||
//==============================================================================
|
||||
bool getCurrentPosition (AudioPlayHead::CurrentPositionInfo& info) override
|
||||
{
|
||||
info.timeSigNumerator = 0;
|
||||
info.timeSigDenominator = 0;
|
||||
info.editOriginTime = 0;
|
||||
info.ppqPositionOfLastBarStart = 0;
|
||||
info.isRecording = false;
|
||||
|
||||
switch (lastTimeStamp.mSMPTETime.mType)
|
||||
{
|
||||
case kSMPTETimeType2398: info.frameRate = AudioPlayHead::fps23976; break;
|
||||
case kSMPTETimeType24: info.frameRate = AudioPlayHead::fps24; break;
|
||||
case kSMPTETimeType25: info.frameRate = AudioPlayHead::fps25; break;
|
||||
case kSMPTETimeType30Drop: info.frameRate = AudioPlayHead::fps30drop; break;
|
||||
case kSMPTETimeType30: info.frameRate = AudioPlayHead::fps30; break;
|
||||
case kSMPTETimeType2997: info.frameRate = AudioPlayHead::fps2997; break;
|
||||
case kSMPTETimeType2997Drop: info.frameRate = AudioPlayHead::fps2997drop; break;
|
||||
case kSMPTETimeType60: info.frameRate = AudioPlayHead::fps60; break;
|
||||
case kSMPTETimeType60Drop: info.frameRate = AudioPlayHead::fps60drop; break;
|
||||
case kSMPTETimeType5994:
|
||||
case kSMPTETimeType5994Drop:
|
||||
case kSMPTETimeType50:
|
||||
default: info.frameRate = AudioPlayHead::fpsUnknown; break;
|
||||
}
|
||||
|
||||
if (CallHostBeatAndTempo (&info.ppqPosition, &info.bpm) != noErr)
|
||||
{
|
||||
info.ppqPosition = 0;
|
||||
info.bpm = 0;
|
||||
}
|
||||
|
||||
UInt32 outDeltaSampleOffsetToNextBeat;
|
||||
double outCurrentMeasureDownBeat;
|
||||
float num;
|
||||
UInt32 den;
|
||||
|
||||
if (CallHostMusicalTimeLocation (&outDeltaSampleOffsetToNextBeat, &num, &den,
|
||||
&outCurrentMeasureDownBeat) == noErr)
|
||||
{
|
||||
info.timeSigNumerator = (int) num;
|
||||
info.timeSigDenominator = (int) den;
|
||||
info.ppqPositionOfLastBarStart = outCurrentMeasureDownBeat;
|
||||
}
|
||||
|
||||
double outCurrentSampleInTimeLine, outCycleStartBeat = 0, outCycleEndBeat = 0;
|
||||
Boolean playing = false, looping = false, playchanged;
|
||||
|
||||
if (CallHostTransportState (&playing,
|
||||
&playchanged,
|
||||
&outCurrentSampleInTimeLine,
|
||||
&looping,
|
||||
&outCycleStartBeat,
|
||||
&outCycleEndBeat) != noErr)
|
||||
{
|
||||
// If the host doesn't support this callback, then use the sample time from lastTimeStamp:
|
||||
outCurrentSampleInTimeLine = lastTimeStamp.mSampleTime;
|
||||
}
|
||||
|
||||
info.isPlaying = playing;
|
||||
info.timeInSamples = (int64) (outCurrentSampleInTimeLine + 0.5);
|
||||
info.timeInSeconds = info.timeInSamples / getSampleRate();
|
||||
info.isLooping = looping;
|
||||
info.ppqLoopStart = outCycleStartBeat;
|
||||
info.ppqLoopEnd = outCycleEndBeat;
|
||||
|
||||
return true;
|
||||
}
|
||||
|
||||
void sendAUEvent (const AudioUnitEventType type, const int juceParamIndex)
|
||||
{
|
||||
if (restoringState)
|
||||
return;
|
||||
|
||||
auEvent.mEventType = type;
|
||||
auEvent.mArgument.mParameter.mParameterID = getAUParameterIDForIndex (juceParamIndex);
|
||||
AUEventListenerNotify (nullptr, nullptr, &auEvent);
|
||||
@@ -1189,7 +1222,8 @@ public:
|
||||
// this will only ever be called by the bypass parameter
|
||||
void parameterValueChanged (int, float) override
|
||||
{
|
||||
PropertyChanged (kAudioUnitProperty_BypassEffect, kAudioUnitScope_Global, 0);
|
||||
if (! restoringState)
|
||||
PropertyChanged (kAudioUnitProperty_BypassEffect, kAudioUnitScope_Global, 0);
|
||||
}
|
||||
|
||||
void parameterGestureChanged (int, bool) override {}
|
||||
@@ -1341,21 +1375,12 @@ public:
|
||||
for (int busIdx = 0; busIdx < numInputBuses; ++busIdx)
|
||||
{
|
||||
if (pulledSucceeded[busIdx])
|
||||
{
|
||||
audioBuffer.push (GetInput ((UInt32) busIdx)->GetBufferList(), mapper.get (true, busIdx));
|
||||
}
|
||||
audioBuffer.set (busIdx, GetInput ((UInt32) busIdx)->GetBufferList(), mapper.get (true, busIdx));
|
||||
else
|
||||
{
|
||||
const int n = juceFilter->getChannelCountOfBus (true, busIdx);
|
||||
|
||||
for (int ch = 0; ch < n; ++ch)
|
||||
zeromem (audioBuffer.push(), sizeof (float) * nFrames);
|
||||
}
|
||||
audioBuffer.clearInputBus (busIdx, (int) nFrames);
|
||||
}
|
||||
|
||||
// clear remaining channels
|
||||
for (int i = totalInChannels; i < totalOutChannels; ++i)
|
||||
zeromem (audioBuffer.push(), sizeof (float) * nFrames);
|
||||
audioBuffer.clearUnusedChannels ((int) nFrames);
|
||||
}
|
||||
|
||||
// swap midi buffers
|
||||
@@ -1371,7 +1396,7 @@ public:
|
||||
// copy back
|
||||
{
|
||||
for (int busIdx = 0; busIdx < numOutputBuses; ++busIdx)
|
||||
audioBuffer.pop (GetOutput ((UInt32) busIdx)->GetBufferList(), mapper.get (false, busIdx));
|
||||
audioBuffer.get (busIdx, GetOutput ((UInt32) busIdx)->GetBufferList(), mapper.get (false, busIdx));
|
||||
}
|
||||
|
||||
// process midi output
|
||||
@@ -1482,7 +1507,6 @@ public:
|
||||
setWantsKeyboardFocus (true);
|
||||
#endif
|
||||
|
||||
ignoreUnused (fakeMouseGenerator);
|
||||
setBounds (getSizeToContainChild());
|
||||
|
||||
lastBounds = getBounds();
|
||||
@@ -1594,7 +1618,6 @@ public:
|
||||
}
|
||||
|
||||
private:
|
||||
FakeMouseMoveGenerator fakeMouseGenerator;
|
||||
Rectangle<int> lastBounds;
|
||||
|
||||
JUCE_DECLARE_NON_COPYABLE (EditorCompHolder)
|
||||
@@ -1620,10 +1643,10 @@ public:
|
||||
addIvar<JuceAU*> ("au");
|
||||
addIvar<EditorCompHolder*> ("editor");
|
||||
|
||||
addMethod (@selector (dealloc), dealloc, "v@:");
|
||||
addMethod (@selector (applicationWillTerminate:), applicationWillTerminate, "v@:@");
|
||||
addMethod (@selector (viewDidMoveToWindow), viewDidMoveToWindow, "v@:");
|
||||
addMethod (@selector (mouseDownCanMoveWindow), mouseDownCanMoveWindow, "c@:");
|
||||
addMethod (@selector (dealloc), dealloc);
|
||||
addMethod (@selector (applicationWillTerminate:), applicationWillTerminate);
|
||||
addMethod (@selector (viewDidMoveToWindow), viewDidMoveToWindow);
|
||||
addMethod (@selector (mouseDownCanMoveWindow), mouseDownCanMoveWindow);
|
||||
|
||||
registerClass();
|
||||
}
|
||||
@@ -1707,9 +1730,9 @@ public:
|
||||
{
|
||||
JuceUICreationClass() : ObjCClass<NSObject> ("JUCE_AUCocoaViewClass_")
|
||||
{
|
||||
addMethod (@selector (interfaceVersion), interfaceVersion, @encode (unsigned int), "@:");
|
||||
addMethod (@selector (description), description, @encode (NSString*), "@:");
|
||||
addMethod (@selector (uiViewForAudioUnit:withSize:), uiViewForAudioUnit, @encode (NSView*), "@:", @encode (AudioUnit), @encode (NSSize));
|
||||
addMethod (@selector (interfaceVersion), interfaceVersion);
|
||||
addMethod (@selector (description), description);
|
||||
addMethod (@selector (uiViewForAudioUnit:withSize:), uiViewForAudioUnit);
|
||||
|
||||
addProtocol (@protocol (AUCocoaUIBase));
|
||||
|
||||
@@ -1734,7 +1757,14 @@ public:
|
||||
{
|
||||
if (AudioProcessor* filter = static_cast<AudioProcessor*> (pointers[0]))
|
||||
if (AudioProcessorEditor* editorComp = filter->createEditorIfNeeded())
|
||||
{
|
||||
#if JucePlugin_Enable_ARA
|
||||
jassert (dynamic_cast<AudioProcessorEditorARAExtension*> (editorComp) != nullptr);
|
||||
// for proper view embedding, ARA plug-ins must be resizable
|
||||
jassert (editorComp->isResizable());
|
||||
#endif
|
||||
return EditorCompHolder::createViewFor (filter, static_cast<JuceAU*> (pointers[1]), editorComp);
|
||||
}
|
||||
}
|
||||
|
||||
return nil;
|
||||
@@ -1809,7 +1839,7 @@ private:
|
||||
//==============================================================================
|
||||
AudioUnitHelpers::CoreAudioBufferList audioBuffer;
|
||||
MidiBuffer midiEvents, incomingEvents;
|
||||
bool prepared = false, isBypassed = false;
|
||||
bool prepared = false, isBypassed = false, restoringState = false;
|
||||
|
||||
//==============================================================================
|
||||
#if JUCE_FORCE_USE_LEGACY_PARAM_IDS
|
||||
@@ -1820,14 +1850,18 @@ private:
|
||||
|
||||
//==============================================================================
|
||||
LegacyAudioParametersWrapper juceParameters;
|
||||
HashMap<int32, AudioProcessorParameter*> paramMap;
|
||||
std::unordered_map<int32, AudioProcessorParameter*> paramMap;
|
||||
Array<AudioUnitParameterID> auParamIDs;
|
||||
Array<const AudioProcessorParameterGroup*> parameterGroups;
|
||||
|
||||
// Stores the parameter IDs in the order that they will be reported to the host.
|
||||
std::vector<AudioUnitParameterID> cachedParameterList;
|
||||
|
||||
//==============================================================================
|
||||
// According to the docs, this is the maximum size of a MIDIPacketList.
|
||||
static constexpr UInt32 packetListBytes = 65536;
|
||||
|
||||
CoreAudioTimeConversions timeConversions;
|
||||
AudioUnitEvent auEvent;
|
||||
mutable Array<AUPreset> presetsArray;
|
||||
CriticalSection incomingMidiLock;
|
||||
@@ -1921,6 +1955,7 @@ private:
|
||||
void processBlock (juce::AudioBuffer<float>& buffer, MidiBuffer& midiBuffer) noexcept
|
||||
{
|
||||
const ScopedLock sl (juceFilter->getCallbackLock());
|
||||
const ScopedPlayHead playhead { *this };
|
||||
|
||||
if (juceFilter->isSuspended())
|
||||
{
|
||||
@@ -2045,6 +2080,40 @@ private:
|
||||
return { {}, {}, {}, kAudioUnitErr_InvalidElement };
|
||||
}
|
||||
|
||||
OSStatus GetParameterList (AudioUnitScope inScope, AudioUnitParameterID* outParameterList, UInt32& outNumParameters) override
|
||||
{
|
||||
if (forceUseLegacyParamIDs || inScope != kAudioUnitScope_Global)
|
||||
return MusicDeviceBase::GetParameterList (inScope, outParameterList, outNumParameters);
|
||||
|
||||
outNumParameters = (UInt32) juceParameters.size();
|
||||
|
||||
if (outParameterList == nullptr)
|
||||
return noErr;
|
||||
|
||||
if (cachedParameterList.empty())
|
||||
{
|
||||
struct ParamInfo
|
||||
{
|
||||
AudioUnitParameterID identifier;
|
||||
int versionHint;
|
||||
};
|
||||
|
||||
std::vector<ParamInfo> vec;
|
||||
vec.reserve (juceParameters.size());
|
||||
|
||||
for (const auto* param : juceParameters)
|
||||
vec.push_back ({ generateAUParameterID (*param), param->getVersionHint() });
|
||||
|
||||
std::sort (vec.begin(), vec.end(), [] (auto a, auto b) { return a.identifier < b.identifier; });
|
||||
std::stable_sort (vec.begin(), vec.end(), [] (auto a, auto b) { return a.versionHint < b.versionHint; });
|
||||
std::transform (vec.begin(), vec.end(), std::back_inserter (cachedParameterList), [] (auto x) { return x.identifier; });
|
||||
}
|
||||
|
||||
std::copy (cachedParameterList.begin(), cachedParameterList.end(), outParameterList);
|
||||
|
||||
return noErr;
|
||||
}
|
||||
|
||||
//==============================================================================
|
||||
void addParameters()
|
||||
{
|
||||
@@ -2061,14 +2130,14 @@ private:
|
||||
{
|
||||
for (auto* param : juceParameters)
|
||||
{
|
||||
const AudioUnitParameterID auParamID = generateAUParameterID (param);
|
||||
const AudioUnitParameterID auParamID = generateAUParameterID (*param);
|
||||
|
||||
// Consider yourself very unlucky if you hit this assertion. The hash codes of your
|
||||
// parameter ids are not unique.
|
||||
jassert (! paramMap.contains (static_cast<int32> (auParamID)));
|
||||
jassert (paramMap.find (static_cast<int32> (auParamID)) == paramMap.end());
|
||||
|
||||
auParamIDs.add (auParamID);
|
||||
paramMap.set (static_cast<int32> (auParamID), param);
|
||||
paramMap.emplace (static_cast<int32> (auParamID), param);
|
||||
Globals()->SetParameter (auParamID, param->getValue());
|
||||
}
|
||||
}
|
||||
@@ -2127,9 +2196,9 @@ private:
|
||||
}
|
||||
|
||||
//==============================================================================
|
||||
AudioUnitParameterID generateAUParameterID (AudioProcessorParameter* param) const
|
||||
static AudioUnitParameterID generateAUParameterID (const AudioProcessorParameter& param)
|
||||
{
|
||||
const String& juceParamID = LegacyAudioParameter::getParamID (param, forceUseLegacyParamIDs);
|
||||
const String& juceParamID = LegacyAudioParameter::getParamID (¶m, forceUseLegacyParamIDs);
|
||||
AudioUnitParameterID paramHash = static_cast<AudioUnitParameterID> (juceParamID.hashCode());
|
||||
|
||||
#if JUCE_USE_STUDIO_ONE_COMPATIBLE_PARAMETERS
|
||||
@@ -2149,9 +2218,13 @@ private:
|
||||
|
||||
AudioProcessorParameter* getParameterForAUParameterID (AudioUnitParameterID address) const noexcept
|
||||
{
|
||||
auto index = static_cast<int32> (address);
|
||||
return forceUseLegacyParamIDs ? juceParameters.getParamForIndex (index)
|
||||
: paramMap[index];
|
||||
const auto index = static_cast<int32> (address);
|
||||
|
||||
if (forceUseLegacyParamIDs)
|
||||
return juceParameters.getParamForIndex (index);
|
||||
|
||||
const auto iter = paramMap.find (index);
|
||||
return iter != paramMap.end() ? iter->second : nullptr;
|
||||
}
|
||||
|
||||
//==============================================================================
|
||||
@@ -2370,244 +2443,6 @@ private:
|
||||
JUCE_DECLARE_NON_COPYABLE (JuceAU)
|
||||
};
|
||||
|
||||
//==============================================================================
|
||||
#if BUILD_AU_CARBON_UI
|
||||
|
||||
class JuceAUView : public AUCarbonViewBase
|
||||
{
|
||||
public:
|
||||
JuceAUView (AudioUnitCarbonView auview)
|
||||
: AUCarbonViewBase (auview),
|
||||
juceFilter (nullptr)
|
||||
{
|
||||
}
|
||||
|
||||
~JuceAUView()
|
||||
{
|
||||
deleteUI();
|
||||
}
|
||||
|
||||
ComponentResult CreateUI (Float32 /*inXOffset*/, Float32 /*inYOffset*/) override
|
||||
{
|
||||
JUCE_AUTORELEASEPOOL
|
||||
{
|
||||
if (juceFilter == nullptr)
|
||||
{
|
||||
void* pointers[2];
|
||||
UInt32 propertySize = sizeof (pointers);
|
||||
|
||||
AudioUnitGetProperty (GetEditAudioUnit(),
|
||||
juceFilterObjectPropertyID,
|
||||
kAudioUnitScope_Global,
|
||||
0,
|
||||
pointers,
|
||||
&propertySize);
|
||||
|
||||
juceFilter = (AudioProcessor*) pointers[0];
|
||||
}
|
||||
|
||||
if (juceFilter != nullptr)
|
||||
{
|
||||
deleteUI();
|
||||
|
||||
if (AudioProcessorEditor* editorComp = juceFilter->createEditorIfNeeded())
|
||||
{
|
||||
editorComp->setOpaque (true);
|
||||
windowComp.reset (new ComponentInHIView (editorComp, mCarbonPane));
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
jassertfalse; // can't get a pointer to our effect
|
||||
}
|
||||
}
|
||||
|
||||
return noErr;
|
||||
}
|
||||
|
||||
AudioUnitCarbonViewEventListener getEventListener() const { return mEventListener; }
|
||||
void* getEventListenerUserData() const { return mEventListenerUserData; }
|
||||
|
||||
private:
|
||||
//==============================================================================
|
||||
AudioProcessor* juceFilter;
|
||||
std::unique_ptr<Component> windowComp;
|
||||
FakeMouseMoveGenerator fakeMouseGenerator;
|
||||
|
||||
void deleteUI()
|
||||
{
|
||||
if (windowComp != nullptr)
|
||||
{
|
||||
PopupMenu::dismissAllActiveMenus();
|
||||
|
||||
/* This assertion is triggered when there's some kind of modal component active, and the
|
||||
host is trying to delete our plugin.
|
||||
If you must use modal components, always use them in a non-blocking way, by never
|
||||
calling runModalLoop(), but instead using enterModalState() with a callback that
|
||||
will be performed on completion. (Note that this assertion could actually trigger
|
||||
a false alarm even if you're doing it correctly, but is here to catch people who
|
||||
aren't so careful) */
|
||||
jassert (Component::getCurrentlyModalComponent() == nullptr);
|
||||
|
||||
if (JuceAU::EditorCompHolder* editorCompHolder = dynamic_cast<JuceAU::EditorCompHolder*> (windowComp->getChildComponent(0)))
|
||||
if (AudioProcessorEditor* audioProcessEditor = dynamic_cast<AudioProcessorEditor*> (editorCompHolder->getChildComponent(0)))
|
||||
juceFilter->editorBeingDeleted (audioProcessEditor);
|
||||
|
||||
windowComp = nullptr;
|
||||
}
|
||||
}
|
||||
|
||||
//==============================================================================
|
||||
// Uses a child NSWindow to sit in front of a HIView and display our component
|
||||
class ComponentInHIView : public Component
|
||||
{
|
||||
public:
|
||||
ComponentInHIView (AudioProcessorEditor* ed, HIViewRef parentHIView)
|
||||
: parentView (parentHIView),
|
||||
editor (ed),
|
||||
recursive (false)
|
||||
{
|
||||
JUCE_AUTORELEASEPOOL
|
||||
{
|
||||
jassert (ed != nullptr);
|
||||
addAndMakeVisible (editor);
|
||||
setOpaque (true);
|
||||
setVisible (true);
|
||||
setBroughtToFrontOnMouseClick (true);
|
||||
|
||||
setSize (editor.getWidth(), editor.getHeight());
|
||||
SizeControl (parentHIView, (SInt16) editor.getWidth(), (SInt16) editor.getHeight());
|
||||
|
||||
WindowRef windowRef = HIViewGetWindow (parentHIView);
|
||||
hostWindow = [[NSWindow alloc] initWithWindowRef: windowRef];
|
||||
|
||||
// not really sure why this is needed in older OS X versions
|
||||
// but JUCE plug-ins crash without it
|
||||
if ((SystemStats::getOperatingSystemType() & 0xff) < 12)
|
||||
[hostWindow retain];
|
||||
|
||||
[hostWindow setCanHide: YES];
|
||||
[hostWindow setReleasedWhenClosed: YES];
|
||||
|
||||
updateWindowPos();
|
||||
|
||||
#if ! JucePlugin_EditorRequiresKeyboardFocus
|
||||
addToDesktop (ComponentPeer::windowIsTemporary | ComponentPeer::windowIgnoresKeyPresses);
|
||||
setWantsKeyboardFocus (false);
|
||||
#else
|
||||
addToDesktop (ComponentPeer::windowIsTemporary);
|
||||
setWantsKeyboardFocus (true);
|
||||
#endif
|
||||
|
||||
setVisible (true);
|
||||
toFront (false);
|
||||
|
||||
addSubWindow();
|
||||
|
||||
NSWindow* pluginWindow = [((NSView*) getWindowHandle()) window];
|
||||
[pluginWindow setNextResponder: hostWindow];
|
||||
|
||||
attachWindowHidingHooks (this, (WindowRef) windowRef, hostWindow);
|
||||
}
|
||||
}
|
||||
|
||||
~ComponentInHIView()
|
||||
{
|
||||
JUCE_AUTORELEASEPOOL
|
||||
{
|
||||
removeWindowHidingHooks (this);
|
||||
|
||||
NSWindow* pluginWindow = [((NSView*) getWindowHandle()) window];
|
||||
[hostWindow removeChildWindow: pluginWindow];
|
||||
removeFromDesktop();
|
||||
|
||||
[hostWindow release];
|
||||
hostWindow = nil;
|
||||
}
|
||||
}
|
||||
|
||||
void updateWindowPos()
|
||||
{
|
||||
HIPoint f;
|
||||
f.x = f.y = 0;
|
||||
HIPointConvert (&f, kHICoordSpaceView, parentView, kHICoordSpaceScreenPixel, 0);
|
||||
setTopLeftPosition ((int) f.x, (int) f.y);
|
||||
}
|
||||
|
||||
void addSubWindow()
|
||||
{
|
||||
NSWindow* pluginWindow = [((NSView*) getWindowHandle()) window];
|
||||
[pluginWindow setExcludedFromWindowsMenu: YES];
|
||||
[pluginWindow setCanHide: YES];
|
||||
|
||||
[hostWindow addChildWindow: pluginWindow
|
||||
ordered: NSWindowAbove];
|
||||
[hostWindow orderFront: nil];
|
||||
[pluginWindow orderFront: nil];
|
||||
}
|
||||
|
||||
void resized() override
|
||||
{
|
||||
if (Component* const child = getChildComponent (0))
|
||||
child->setBounds (getLocalBounds());
|
||||
}
|
||||
|
||||
void paint (Graphics&) override {}
|
||||
|
||||
void childBoundsChanged (Component*) override
|
||||
{
|
||||
if (! recursive)
|
||||
{
|
||||
recursive = true;
|
||||
|
||||
const int w = jmax (32, editor.getWidth());
|
||||
const int h = jmax (32, editor.getHeight());
|
||||
|
||||
SizeControl (parentView, (SInt16) w, (SInt16) h);
|
||||
|
||||
if (getWidth() != w || getHeight() != h)
|
||||
setSize (w, h);
|
||||
|
||||
editor.repaint();
|
||||
|
||||
updateWindowPos();
|
||||
addSubWindow(); // (need this for AULab)
|
||||
|
||||
recursive = false;
|
||||
}
|
||||
}
|
||||
|
||||
bool keyPressed (const KeyPress& kp) override
|
||||
{
|
||||
if (! kp.getModifiers().isCommandDown())
|
||||
{
|
||||
// If we have an unused keypress, move the key-focus to a host window
|
||||
// and re-inject the event..
|
||||
static NSTimeInterval lastEventTime = 0; // check we're not recursively sending the same event
|
||||
NSTimeInterval eventTime = [[NSApp currentEvent] timestamp];
|
||||
|
||||
if (lastEventTime != eventTime)
|
||||
{
|
||||
lastEventTime = eventTime;
|
||||
|
||||
[[hostWindow parentWindow] makeKeyWindow];
|
||||
repostCurrentNSEvent();
|
||||
}
|
||||
}
|
||||
|
||||
return false;
|
||||
}
|
||||
|
||||
private:
|
||||
HIViewRef parentView;
|
||||
NSWindow* hostWindow;
|
||||
JuceAU::EditorCompHolder editor;
|
||||
bool recursive;
|
||||
};
|
||||
};
|
||||
|
||||
#endif
|
||||
|
||||
//==============================================================================
|
||||
#define JUCE_COMPONENT_ENTRYX(Class, Name, Suffix) \
|
||||
extern "C" __attribute__((visibility("default"))) ComponentResult Name ## Suffix (ComponentParameters* params, Class* obj); \
|
||||
@@ -2645,10 +2480,6 @@ JUCE_COMPONENT_ENTRY (JuceAU, JucePlugin_AUExportPrefix, Entry)
|
||||
JUCE_FACTORY_ENTRY (JuceAU, JucePlugin_AUExportPrefix)
|
||||
#endif
|
||||
|
||||
#if BUILD_AU_CARBON_UI
|
||||
JUCE_COMPONENT_ENTRY (JuceAUView, JucePlugin_AUExportPrefix, ViewEntry)
|
||||
#endif
|
||||
|
||||
#if ! JUCE_DISABLE_AU_FACTORY_ENTRY
|
||||
JUCE_BEGIN_IGNORE_WARNINGS_GCC_LIKE ("-Wcast-align", "-Wzero-as-null-pointer-constant")
|
||||
|
||||
|
||||
@@ -2,15 +2,15 @@
|
||||
==============================================================================
|
||||
|
||||
This file is part of the JUCE library.
|
||||
Copyright (c) 2020 - Raw Material Software Limited
|
||||
Copyright (c) 2022 - Raw Material Software Limited
|
||||
|
||||
JUCE is an open source library subject to commercial or open-source
|
||||
licensing.
|
||||
|
||||
By using JUCE, you agree to the terms of both the JUCE 6 End-User License
|
||||
Agreement and JUCE Privacy Policy (both effective as of the 16th June 2020).
|
||||
By using JUCE, you agree to the terms of both the JUCE 7 End-User License
|
||||
Agreement and JUCE Privacy Policy.
|
||||
|
||||
End User License Agreement: www.juce.com/juce-6-licence
|
||||
End User License Agreement: www.juce.com/juce-7-licence
|
||||
Privacy Policy: www.juce.com/juce-privacy-policy
|
||||
|
||||
Or: You may also use this code under the terms of the GPL v3 (see
|
||||
@@ -28,27 +28,13 @@
|
||||
|
||||
#if JucePlugin_Build_AUv3
|
||||
|
||||
#if JUCE_MAC
|
||||
#if (! defined MAC_OS_X_VERSION_MIN_REQUIRED) || (! defined MAC_OS_X_VERSION_10_11) || (MAC_OS_X_VERSION_MIN_REQUIRED < MAC_OS_X_VERSION_10_11)
|
||||
#error AUv3 needs Deployment Target OS X 10.11 or higher to compile
|
||||
#endif
|
||||
#if (defined MAC_OS_X_VERSION_10_13) && (MAC_OS_X_VERSION_MIN_REQUIRED >= MAC_OS_X_VERSION_10_13)
|
||||
#define JUCE_AUV3_MIDI_OUTPUT_SUPPORTED 1
|
||||
#define JUCE_AUV3_VIEW_CONFIG_SUPPORTED 1
|
||||
#endif
|
||||
#if defined (MAC_OS_VERSION_12_0)
|
||||
#define JUCE_AUV3_MIDI_EVENT_LIST_SUPPORTED 1
|
||||
#endif
|
||||
#if JUCE_MAC && ! (defined (MAC_OS_X_VERSION_10_11) && MAC_OS_X_VERSION_MIN_REQUIRED >= MAC_OS_X_VERSION_10_11)
|
||||
#error AUv3 needs Deployment Target OS X 10.11 or higher to compile
|
||||
#endif
|
||||
|
||||
#if JUCE_IOS
|
||||
#if (defined __IPHONE_11_0) && (__IPHONE_OS_VERSION_MIN_REQUIRED >= __IPHONE_11_0)
|
||||
#define JUCE_AUV3_MIDI_OUTPUT_SUPPORTED 1
|
||||
#define JUCE_AUV3_VIEW_CONFIG_SUPPORTED 1
|
||||
#endif
|
||||
#if (defined __IPHONE_15_0)
|
||||
#define JUCE_AUV3_MIDI_EVENT_LIST_SUPPORTED 1
|
||||
#endif
|
||||
#if (JUCE_IOS && defined (__IPHONE_15_0) && __IPHONE_OS_VERSION_MAX_ALLOWED >= __IPHONE_15_0) \
|
||||
|| (JUCE_MAC && defined (MAC_OS_VERSION_12_0) && MAC_OS_X_VERSION_MAX_ALLOWED >= MAC_OS_VERSION_12_0)
|
||||
#define JUCE_AUV3_MIDI_EVENT_LIST_SUPPORTED 1
|
||||
#endif
|
||||
|
||||
#ifndef __OBJC2__
|
||||
@@ -66,6 +52,7 @@
|
||||
|
||||
#include <juce_graphics/native/juce_mac_CoreGraphicsHelpers.h>
|
||||
#include <juce_audio_basics/native/juce_mac_CoreAudioLayouts.h>
|
||||
#include <juce_audio_basics/native/juce_mac_CoreAudioTimeConversions.h>
|
||||
#include <juce_audio_processors/format_types/juce_LegacyAudioParameter.cpp>
|
||||
#include <juce_audio_processors/format_types/juce_AU_Shared.h>
|
||||
|
||||
@@ -147,7 +134,7 @@ public:
|
||||
|
||||
//==============================================================================
|
||||
virtual AUAudioUnitPreset* getCurrentPreset() = 0;
|
||||
virtual void setCurrentPreset(AUAudioUnitPreset*) = 0;
|
||||
virtual void setCurrentPreset (AUAudioUnitPreset*) = 0;
|
||||
virtual NSArray<AUAudioUnitPreset*>* getFactoryPresets() = 0;
|
||||
|
||||
virtual NSDictionary<NSString*, id>* getFullState()
|
||||
@@ -209,10 +196,11 @@ public:
|
||||
}
|
||||
|
||||
//==============================================================================
|
||||
#if JUCE_AUV3_VIEW_CONFIG_SUPPORTED
|
||||
API_AVAILABLE (macos (10.13), ios (11.0))
|
||||
virtual NSIndexSet* getSupportedViewConfigurations (NSArray<AUAudioUnitViewConfiguration*>*) = 0;
|
||||
virtual void selectViewConfiguration (AUAudioUnitViewConfiguration*) = 0;
|
||||
#endif
|
||||
|
||||
API_AVAILABLE (macos (10.13), ios (11.0))
|
||||
virtual void selectViewConfiguration (AUAudioUnitViewConfiguration*) = 0;
|
||||
|
||||
private:
|
||||
struct Class : public ObjCClass<AUAudioUnit>
|
||||
@@ -222,71 +210,65 @@ private:
|
||||
addIvar<JuceAudioUnitv3Base*> ("cppObject");
|
||||
|
||||
JUCE_BEGIN_IGNORE_WARNINGS_GCC_LIKE ("-Wundeclared-selector")
|
||||
addMethod (@selector (initWithComponentDescription:options:error:juceClass:),
|
||||
initWithComponentDescriptionAndJuceClass, "@@:",
|
||||
@encode (AudioComponentDescription),
|
||||
@encode (AudioComponentInstantiationOptions), "^@@");
|
||||
addMethod (@selector (initWithComponentDescription:options:error:juceClass:), initWithComponentDescriptionAndJuceClass);
|
||||
JUCE_END_IGNORE_WARNINGS_GCC_LIKE
|
||||
|
||||
addMethod (@selector (initWithComponentDescription:options:error:),
|
||||
initWithComponentDescription, "@@:",
|
||||
@encode (AudioComponentDescription),
|
||||
@encode (AudioComponentInstantiationOptions), "^@");
|
||||
addMethod (@selector (initWithComponentDescription:options:error:), initWithComponentDescription);
|
||||
|
||||
addMethod (@selector (dealloc), dealloc, "v@:");
|
||||
addMethod (@selector (dealloc), dealloc);
|
||||
|
||||
//==============================================================================
|
||||
addMethod (@selector (reset), reset, "v@:");
|
||||
addMethod (@selector (reset), reset);
|
||||
|
||||
//==============================================================================
|
||||
addMethod (@selector (currentPreset), getCurrentPreset, "@@:");
|
||||
addMethod (@selector (setCurrentPreset:), setCurrentPreset, "v@:@");
|
||||
addMethod (@selector (factoryPresets), getFactoryPresets, "@@:");
|
||||
addMethod (@selector (fullState), getFullState, "@@:");
|
||||
addMethod (@selector (setFullState:), setFullState, "v@:@");
|
||||
addMethod (@selector (parameterTree), getParameterTree, "@@:");
|
||||
addMethod (@selector (parametersForOverviewWithCount:), parametersForOverviewWithCount, "@@:", @encode (NSInteger));
|
||||
addMethod (@selector (currentPreset), getCurrentPreset);
|
||||
addMethod (@selector (setCurrentPreset:), setCurrentPreset);
|
||||
addMethod (@selector (factoryPresets), getFactoryPresets);
|
||||
addMethod (@selector (fullState), getFullState);
|
||||
addMethod (@selector (setFullState:), setFullState);
|
||||
addMethod (@selector (parameterTree), getParameterTree);
|
||||
addMethod (@selector (parametersForOverviewWithCount:), parametersForOverviewWithCount);
|
||||
|
||||
//==============================================================================
|
||||
addMethod (@selector (latency), getLatency, @encode (NSTimeInterval), "@:");
|
||||
addMethod (@selector (tailTime), getTailTime, @encode (NSTimeInterval), "@:");
|
||||
addMethod (@selector (latency), getLatency);
|
||||
addMethod (@selector (tailTime), getTailTime);
|
||||
|
||||
//==============================================================================
|
||||
addMethod (@selector (inputBusses), getInputBusses, "@@:");
|
||||
addMethod (@selector (outputBusses), getOutputBusses, "@@:");
|
||||
addMethod (@selector (channelCapabilities), getChannelCapabilities, "@@:");
|
||||
addMethod (@selector (shouldChangeToFormat:forBus:), shouldChangeToFormat, "c@:@@");
|
||||
addMethod (@selector (inputBusses), getInputBusses);
|
||||
addMethod (@selector (outputBusses), getOutputBusses);
|
||||
addMethod (@selector (channelCapabilities), getChannelCapabilities);
|
||||
addMethod (@selector (shouldChangeToFormat:forBus:), shouldChangeToFormat);
|
||||
|
||||
//==============================================================================
|
||||
addMethod (@selector (virtualMIDICableCount), getVirtualMIDICableCount, @encode (NSInteger), "@:");
|
||||
addMethod (@selector (virtualMIDICableCount), getVirtualMIDICableCount);
|
||||
|
||||
JUCE_BEGIN_IGNORE_WARNINGS_GCC_LIKE ("-Wundeclared-selector")
|
||||
addMethod (@selector (supportsMPE), getSupportsMPE, @encode (BOOL), "@:");
|
||||
addMethod (@selector (supportsMPE), getSupportsMPE);
|
||||
JUCE_END_IGNORE_WARNINGS_GCC_LIKE
|
||||
|
||||
#if JUCE_AUV3_MIDI_OUTPUT_SUPPORTED
|
||||
addMethod (@selector (MIDIOutputNames), getMIDIOutputNames, "@@:");
|
||||
#endif
|
||||
if (@available (macOS 10.13, iOS 11.0, *))
|
||||
addMethod (@selector (MIDIOutputNames), getMIDIOutputNames);
|
||||
|
||||
//==============================================================================
|
||||
addMethod (@selector (internalRenderBlock), getInternalRenderBlock, @encode (AUInternalRenderBlock), "@:");
|
||||
addMethod (@selector (canProcessInPlace), getCanProcessInPlace, @encode (BOOL), "@:");
|
||||
addMethod (@selector (isRenderingOffline), getRenderingOffline, @encode (BOOL), "@:");
|
||||
addMethod (@selector (setRenderingOffline:), setRenderingOffline, "v@:", @encode (BOOL));
|
||||
addMethod (@selector (shouldBypassEffect), getShouldBypassEffect, @encode (BOOL), "@:");
|
||||
addMethod (@selector (setShouldBypassEffect:), setShouldBypassEffect, "v@:", @encode (BOOL));
|
||||
addMethod (@selector (allocateRenderResourcesAndReturnError:), allocateRenderResourcesAndReturnError, "c@:^@");
|
||||
addMethod (@selector (deallocateRenderResources), deallocateRenderResources, "v@:");
|
||||
addMethod (@selector (internalRenderBlock), getInternalRenderBlock);
|
||||
addMethod (@selector (canProcessInPlace), getCanProcessInPlace);
|
||||
addMethod (@selector (isRenderingOffline), getRenderingOffline);
|
||||
addMethod (@selector (setRenderingOffline:), setRenderingOffline);
|
||||
addMethod (@selector (shouldBypassEffect), getShouldBypassEffect);
|
||||
addMethod (@selector (setShouldBypassEffect:), setShouldBypassEffect);
|
||||
addMethod (@selector (allocateRenderResourcesAndReturnError:), allocateRenderResourcesAndReturnError);
|
||||
addMethod (@selector (deallocateRenderResources), deallocateRenderResources);
|
||||
|
||||
//==============================================================================
|
||||
addMethod (@selector (contextName), getContextName, "@@:");
|
||||
addMethod (@selector (setContextName:), setContextName, "v@:@");
|
||||
addMethod (@selector (contextName), getContextName);
|
||||
addMethod (@selector (setContextName:), setContextName);
|
||||
|
||||
//==============================================================================
|
||||
#if JUCE_AUV3_VIEW_CONFIG_SUPPORTED
|
||||
addMethod (@selector (supportedViewConfigurations:), getSupportedViewConfigurations, "@@:@");
|
||||
addMethod (@selector (selectViewConfiguration:), selectViewConfiguration, "v@:@");
|
||||
#endif
|
||||
if (@available (macOS 10.13, iOS 11.0, *))
|
||||
{
|
||||
addMethod (@selector (supportedViewConfigurations:), getSupportedViewConfigurations);
|
||||
addMethod (@selector (selectViewConfiguration:), selectViewConfiguration);
|
||||
}
|
||||
|
||||
registerClass();
|
||||
}
|
||||
@@ -395,10 +377,11 @@ private:
|
||||
static void setContextName (id self, SEL, NSString* str) { return _this (self)->setContextName (str); }
|
||||
|
||||
//==============================================================================
|
||||
#if JUCE_AUV3_VIEW_CONFIG_SUPPORTED
|
||||
API_AVAILABLE (macos (10.13), ios (11.0))
|
||||
static NSIndexSet* getSupportedViewConfigurations (id self, SEL, NSArray<AUAudioUnitViewConfiguration*>* configs) { return _this (self)->getSupportedViewConfigurations (configs); }
|
||||
static void selectViewConfiguration (id self, SEL, AUAudioUnitViewConfiguration* config) { _this (self)->selectViewConfiguration (config); }
|
||||
#endif
|
||||
|
||||
API_AVAILABLE (macos (10.13), ios (11.0))
|
||||
static void selectViewConfiguration (id self, SEL, AUAudioUnitViewConfiguration* config) { _this (self)->selectViewConfiguration (config); }
|
||||
};
|
||||
|
||||
static JuceAudioUnitv3Base* create (AUAudioUnit*, AudioComponentDescription, AudioComponentInstantiationOptions, NSError**);
|
||||
@@ -427,16 +410,14 @@ public:
|
||||
AudioComponentInstantiationOptions options,
|
||||
NSError** error)
|
||||
: JuceAudioUnitv3Base (descr, options, error),
|
||||
processorHolder (processor),
|
||||
mapper (*processorHolder->get())
|
||||
processorHolder (processor)
|
||||
{
|
||||
init();
|
||||
}
|
||||
|
||||
JuceAudioUnitv3 (AUAudioUnit* audioUnit, AudioComponentDescription, AudioComponentInstantiationOptions, NSError**)
|
||||
: JuceAudioUnitv3Base (audioUnit),
|
||||
processorHolder (new AudioProcessorHolder (createPluginFilterOfType (AudioProcessor::wrapperType_AudioUnitv3))),
|
||||
mapper (*processorHolder->get())
|
||||
processorHolder (new AudioProcessorHolder (createPluginFilterOfType (AudioProcessor::wrapperType_AudioUnitv3)))
|
||||
{
|
||||
init();
|
||||
}
|
||||
@@ -526,27 +507,18 @@ public:
|
||||
{
|
||||
midiMessages.clear();
|
||||
lastTimeStamp.mSampleTime = std::numeric_limits<Float64>::max();
|
||||
lastTimeStamp.mFlags = 0;
|
||||
}
|
||||
|
||||
//==============================================================================
|
||||
AUAudioUnitPreset* getCurrentPreset() override
|
||||
{
|
||||
const int n = static_cast<int> ([factoryPresets.get() count]);
|
||||
const int idx = static_cast<int> (getAudioProcessor().getCurrentProgram());
|
||||
|
||||
if (idx < n)
|
||||
return [factoryPresets.get() objectAtIndex:static_cast<unsigned int> (idx)];
|
||||
|
||||
return nullptr;
|
||||
return factoryPresets.getAtIndex (getAudioProcessor().getCurrentProgram());
|
||||
}
|
||||
|
||||
void setCurrentPreset (AUAudioUnitPreset* preset) override
|
||||
{
|
||||
const int n = static_cast<int> ([factoryPresets.get() count]);
|
||||
const int idx = static_cast<int> ([preset number]);
|
||||
|
||||
if (isPositiveAndBelow (idx, n))
|
||||
getAudioProcessor().setCurrentProgram (idx);
|
||||
getAudioProcessor().setCurrentProgram (static_cast<int> ([preset number]));
|
||||
}
|
||||
|
||||
NSArray<AUAudioUnitPreset*>* getFactoryPresets() override
|
||||
@@ -850,9 +822,9 @@ public:
|
||||
allocateBusBuffer (true);
|
||||
allocateBusBuffer (false);
|
||||
|
||||
mapper.alloc();
|
||||
mapper.alloc (processor);
|
||||
|
||||
audioBuffer.prepare (totalInChannels, totalOutChannels, static_cast<int> (maxFrames));
|
||||
audioBuffer.prepare (AudioUnitHelpers::getBusesLayout (&processor), static_cast<int> (maxFrames));
|
||||
|
||||
auto sampleRate = [&]
|
||||
{
|
||||
@@ -869,10 +841,12 @@ public:
|
||||
midiMessages.ensureSize (2048);
|
||||
midiMessages.clear();
|
||||
|
||||
zeromem (&lastAudioHead, sizeof (lastAudioHead));
|
||||
hostMusicalContextCallback = [getAudioUnit() musicalContextBlock];
|
||||
hostTransportStateCallback = [getAudioUnit() transportStateBlock];
|
||||
|
||||
if (@available (macOS 10.13, iOS 11.0, *))
|
||||
midiOutputEventBlock = [au MIDIOutputEventBlock];
|
||||
|
||||
reset();
|
||||
|
||||
return true;
|
||||
@@ -880,6 +854,8 @@ public:
|
||||
|
||||
void deallocateRenderResources() override
|
||||
{
|
||||
midiOutputEventBlock = nullptr;
|
||||
|
||||
hostMusicalContextCallback = nullptr;
|
||||
hostTransportStateCallback = nullptr;
|
||||
|
||||
@@ -895,7 +871,7 @@ public:
|
||||
}
|
||||
|
||||
//==============================================================================
|
||||
#if JUCE_AUV3_VIEW_CONFIG_SUPPORTED
|
||||
API_AVAILABLE (macos (10.13), ios (11.0))
|
||||
NSIndexSet* getSupportedViewConfigurations (NSArray<AUAudioUnitViewConfiguration*>* configs) override
|
||||
{
|
||||
auto supportedViewIndecies = [[NSMutableIndexSet alloc] init];
|
||||
@@ -928,11 +904,11 @@ public:
|
||||
return [supportedViewIndecies autorelease];
|
||||
}
|
||||
|
||||
API_AVAILABLE (macos (10.13), ios (11.0))
|
||||
void selectViewConfiguration (AUAudioUnitViewConfiguration* config) override
|
||||
{
|
||||
processorHolder->viewConfiguration.reset (new AudioProcessorHolder::ViewConfig { [config width], [config height], [config hostHasController] == YES });
|
||||
}
|
||||
#endif
|
||||
|
||||
struct ScopedKeyChange
|
||||
{
|
||||
@@ -969,7 +945,7 @@ public:
|
||||
}
|
||||
}
|
||||
|
||||
void audioProcessorParameterChanged (AudioProcessor*, int idx, float newValue) override
|
||||
void sendParameterEvent (int idx, const float* newValue, AUParameterAutomationEventType type)
|
||||
{
|
||||
if (inParameterChangedCallback.get())
|
||||
{
|
||||
@@ -979,44 +955,68 @@ public:
|
||||
|
||||
if (auto* juceParam = juceParameters.getParamForIndex (idx))
|
||||
{
|
||||
if (AUParameter* param = [paramTree.get() parameterWithAddress: getAUParameterAddressForIndex (idx)])
|
||||
if (auto* param = [paramTree.get() parameterWithAddress: getAUParameterAddressForIndex (idx)])
|
||||
{
|
||||
newValue *= getMaximumParameterValue (juceParam);
|
||||
const auto value = (newValue != nullptr ? *newValue : juceParam->getValue()) * getMaximumParameterValue (juceParam);
|
||||
|
||||
if (editorObserverToken != nullptr)
|
||||
[param setValue: newValue originator: editorObserverToken];
|
||||
else
|
||||
[param setValue: newValue];
|
||||
if (@available (macOS 10.12, iOS 10.0, *))
|
||||
{
|
||||
[param setValue: value
|
||||
originator: editorObserverToken
|
||||
atHostTime: lastTimeStamp.mHostTime
|
||||
eventType: type];
|
||||
}
|
||||
else if (type == AUParameterAutomationEventTypeValue)
|
||||
{
|
||||
[param setValue: value originator: editorObserverToken];
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
//==============================================================================
|
||||
bool getCurrentPosition (CurrentPositionInfo& info) override
|
||||
void audioProcessorParameterChanged (AudioProcessor*, int idx, float newValue) override
|
||||
{
|
||||
bool musicContextCallSucceeded = false;
|
||||
bool transportStateCallSucceeded = false;
|
||||
sendParameterEvent (idx, &newValue, AUParameterAutomationEventTypeValue);
|
||||
}
|
||||
|
||||
info = lastAudioHead;
|
||||
info.timeInSamples = (int64) (lastTimeStamp.mSampleTime + 0.5);
|
||||
info.timeInSeconds = info.timeInSamples / getAudioProcessor().getSampleRate();
|
||||
void audioProcessorParameterChangeGestureBegin (AudioProcessor*, int idx) override
|
||||
{
|
||||
sendParameterEvent (idx, nullptr, AUParameterAutomationEventTypeTouch);
|
||||
}
|
||||
|
||||
switch (lastTimeStamp.mSMPTETime.mType)
|
||||
void audioProcessorParameterChangeGestureEnd (AudioProcessor*, int idx) override
|
||||
{
|
||||
sendParameterEvent (idx, nullptr, AUParameterAutomationEventTypeRelease);
|
||||
}
|
||||
|
||||
//==============================================================================
|
||||
Optional<PositionInfo> getPosition() const override
|
||||
{
|
||||
PositionInfo info;
|
||||
info.setTimeInSamples ((int64) (lastTimeStamp.mSampleTime + 0.5));
|
||||
info.setTimeInSeconds (*info.getTimeInSamples() / getAudioProcessor().getSampleRate());
|
||||
|
||||
info.setFrameRate ([this]
|
||||
{
|
||||
case kSMPTETimeType2398: info.frameRate = AudioPlayHead::fps23976; break;
|
||||
case kSMPTETimeType24: info.frameRate = AudioPlayHead::fps24; break;
|
||||
case kSMPTETimeType25: info.frameRate = AudioPlayHead::fps25; break;
|
||||
case kSMPTETimeType2997: info.frameRate = AudioPlayHead::fps2997; break;
|
||||
case kSMPTETimeType2997Drop: info.frameRate = AudioPlayHead::fps2997drop; break;
|
||||
case kSMPTETimeType30Drop: info.frameRate = AudioPlayHead::fps30drop; break;
|
||||
case kSMPTETimeType30: info.frameRate = AudioPlayHead::fps30; break;
|
||||
case kSMPTETimeType60Drop: info.frameRate = AudioPlayHead::fps60drop; break;
|
||||
case kSMPTETimeType60: info.frameRate = AudioPlayHead::fps60; break;
|
||||
case kSMPTETimeType5994:
|
||||
case kSMPTETimeType5994Drop:
|
||||
case kSMPTETimeType50:
|
||||
default: info.frameRate = AudioPlayHead::fpsUnknown; break;
|
||||
}
|
||||
switch (lastTimeStamp.mSMPTETime.mType)
|
||||
{
|
||||
case kSMPTETimeType2398: return FrameRate().withBaseRate (24).withPullDown();
|
||||
case kSMPTETimeType24: return FrameRate().withBaseRate (24);
|
||||
case kSMPTETimeType25: return FrameRate().withBaseRate (25);
|
||||
case kSMPTETimeType30Drop: return FrameRate().withBaseRate (30).withDrop();
|
||||
case kSMPTETimeType30: return FrameRate().withBaseRate (30);
|
||||
case kSMPTETimeType2997: return FrameRate().withBaseRate (30).withPullDown();
|
||||
case kSMPTETimeType2997Drop: return FrameRate().withBaseRate (30).withPullDown().withDrop();
|
||||
case kSMPTETimeType60: return FrameRate().withBaseRate (60);
|
||||
case kSMPTETimeType60Drop: return FrameRate().withBaseRate (60).withDrop();
|
||||
case kSMPTETimeType5994: return FrameRate().withBaseRate (60).withPullDown();
|
||||
case kSMPTETimeType5994Drop: return FrameRate().withBaseRate (60).withPullDown().withDrop();
|
||||
case kSMPTETimeType50: return FrameRate().withBaseRate (50);
|
||||
default: break;
|
||||
}
|
||||
|
||||
return FrameRate();
|
||||
}());
|
||||
|
||||
double num;
|
||||
NSInteger den;
|
||||
@@ -1030,17 +1030,14 @@ public:
|
||||
|
||||
if (musicalContextCallback (&bpm, &num, &den, &ppqPosition, &outDeltaSampleOffsetToNextBeat, &outCurrentMeasureDownBeat))
|
||||
{
|
||||
musicContextCallSucceeded = true;
|
||||
|
||||
info.timeSigNumerator = (int) num;
|
||||
info.timeSigDenominator = (int) den;
|
||||
info.ppqPositionOfLastBarStart = outCurrentMeasureDownBeat;
|
||||
info.bpm = bpm;
|
||||
info.ppqPosition = ppqPosition;
|
||||
info.setTimeSignature (TimeSignature { (int) num, (int) den });
|
||||
info.setPpqPositionOfLastBarStart (outCurrentMeasureDownBeat);
|
||||
info.setBpm (bpm);
|
||||
info.setPpqPosition (ppqPosition);
|
||||
}
|
||||
}
|
||||
|
||||
double outCurrentSampleInTimeLine, outCycleStartBeat = 0, outCycleEndBeat = 0;
|
||||
double outCurrentSampleInTimeLine = 0, outCycleStartBeat = 0, outCycleEndBeat = 0;
|
||||
AUHostTransportStateFlags flags;
|
||||
|
||||
if (hostTransportStateCallback != nullptr)
|
||||
@@ -1049,22 +1046,19 @@ public:
|
||||
|
||||
if (transportStateCallback (&flags, &outCurrentSampleInTimeLine, &outCycleStartBeat, &outCycleEndBeat))
|
||||
{
|
||||
transportStateCallSucceeded = true;
|
||||
|
||||
info.timeInSamples = (int64) (outCurrentSampleInTimeLine + 0.5);
|
||||
info.timeInSeconds = info.timeInSamples / getAudioProcessor().getSampleRate();
|
||||
info.isPlaying = ((flags & AUHostTransportStateMoving) != 0);
|
||||
info.isLooping = ((flags & AUHostTransportStateCycling) != 0);
|
||||
info.isRecording = ((flags & AUHostTransportStateRecording) != 0);
|
||||
info.ppqLoopStart = outCycleStartBeat;
|
||||
info.ppqLoopEnd = outCycleEndBeat;
|
||||
info.setTimeInSamples ((int64) (outCurrentSampleInTimeLine + 0.5));
|
||||
info.setTimeInSeconds (*info.getTimeInSamples() / getAudioProcessor().getSampleRate());
|
||||
info.setIsPlaying ((flags & AUHostTransportStateMoving) != 0);
|
||||
info.setIsLooping ((flags & AUHostTransportStateCycling) != 0);
|
||||
info.setIsRecording ((flags & AUHostTransportStateRecording) != 0);
|
||||
info.setLoopPoints (LoopPoints { outCycleStartBeat, outCycleEndBeat });
|
||||
}
|
||||
}
|
||||
|
||||
if (musicContextCallSucceeded && transportStateCallSucceeded)
|
||||
lastAudioHead = info;
|
||||
if ((lastTimeStamp.mFlags & kAudioTimeStampHostTimeValid) != 0)
|
||||
info.setHostTimeNs (timeConversions.hostTimeToNanos (lastTimeStamp.mHostTime));
|
||||
|
||||
return true;
|
||||
return info;
|
||||
}
|
||||
|
||||
//==============================================================================
|
||||
@@ -1165,6 +1159,38 @@ private:
|
||||
juce::AudioBuffer<float> scratchBuffer;
|
||||
};
|
||||
|
||||
class FactoryPresets
|
||||
{
|
||||
public:
|
||||
using Presets = std::unique_ptr<NSMutableArray<AUAudioUnitPreset*>, NSObjectDeleter>;
|
||||
|
||||
void set (Presets newPresets)
|
||||
{
|
||||
std::lock_guard<std::mutex> lock (mutex);
|
||||
std::swap (presets, newPresets);
|
||||
}
|
||||
|
||||
NSArray* get() const
|
||||
{
|
||||
std::lock_guard<std::mutex> lock (mutex);
|
||||
return presets.get();
|
||||
}
|
||||
|
||||
AUAudioUnitPreset* getAtIndex (int index) const
|
||||
{
|
||||
std::lock_guard<std::mutex> lock (mutex);
|
||||
|
||||
if (index < (int) [presets.get() count])
|
||||
return [presets.get() objectAtIndex: (unsigned int) index];
|
||||
|
||||
return nullptr;
|
||||
}
|
||||
|
||||
private:
|
||||
Presets presets;
|
||||
mutable std::mutex mutex;
|
||||
};
|
||||
|
||||
//==============================================================================
|
||||
void addAudioUnitBusses (bool isInput)
|
||||
{
|
||||
@@ -1408,7 +1434,7 @@ private:
|
||||
|
||||
void addPresets()
|
||||
{
|
||||
factoryPresets.reset ([[NSMutableArray<AUAudioUnitPreset*> alloc] init]);
|
||||
FactoryPresets::Presets newPresets { [[NSMutableArray<AUAudioUnitPreset*> alloc] init] };
|
||||
|
||||
const int n = getAudioProcessor().getNumPrograms();
|
||||
|
||||
@@ -1420,8 +1446,10 @@ private:
|
||||
[preset.get() setName: juceStringToNS (name)];
|
||||
[preset.get() setNumber: static_cast<NSInteger> (idx)];
|
||||
|
||||
[factoryPresets.get() addObject: preset.get()];
|
||||
[newPresets.get() addObject: preset.get()];
|
||||
}
|
||||
|
||||
factoryPresets.set (std::move (newPresets));
|
||||
}
|
||||
|
||||
//==============================================================================
|
||||
@@ -1500,11 +1528,14 @@ private:
|
||||
auto& processor = getAudioProcessor();
|
||||
jassert (static_cast<int> (frameCount) <= getAudioProcessor().getBlockSize());
|
||||
|
||||
// process params
|
||||
const int numParams = juceParameters.getNumParameters();
|
||||
const auto numProcessorBusesOut = AudioUnitHelpers::getBusCount (processor, false);
|
||||
|
||||
if (lastTimeStamp.mSampleTime != timestamp->mSampleTime)
|
||||
{
|
||||
// process params and incoming midi (only once for a given timestamp)
|
||||
midiMessages.clear();
|
||||
|
||||
const int numParams = juceParameters.getNumParameters();
|
||||
processEvents (realtimeEventListHead, numParams, static_cast<AUEventSampleTime> (timestamp->mSampleTime));
|
||||
|
||||
lastTimeStamp = *timestamp;
|
||||
@@ -1512,7 +1543,6 @@ private:
|
||||
const auto numWrapperBusesIn = AudioUnitHelpers::getBusCountForWrapper (processor, true);
|
||||
const auto numWrapperBusesOut = AudioUnitHelpers::getBusCountForWrapper (processor, false);
|
||||
const auto numProcessorBusesIn = AudioUnitHelpers::getBusCount (processor, true);
|
||||
const auto numProcessorBusesOut = AudioUnitHelpers::getBusCount (processor, false);
|
||||
|
||||
// prepare buffers
|
||||
{
|
||||
@@ -1580,45 +1610,39 @@ private:
|
||||
AudioBufferList* buffer = busBuffer.get();
|
||||
|
||||
const int* inLayoutMap = mapper.get (true, busIdx);
|
||||
audioBuffer.setBuffer (chIdx++, busBuffer.interleaved() ? nullptr : static_cast<float*> (buffer->mBuffers[inLayoutMap[channelOffset]].mData));
|
||||
audioBuffer.setBuffer (chIdx++, busBuffer.interleaved() ? nullptr : static_cast<float*> (buffer->mBuffers[inLayoutMap[channelOffset]].mData));
|
||||
}
|
||||
}
|
||||
|
||||
// copy input
|
||||
{
|
||||
for (int busIdx = 0; busIdx < numProcessorBusesIn; ++busIdx)
|
||||
audioBuffer.push (*inBusBuffers[busIdx]->get(), mapper.get (true, busIdx));
|
||||
audioBuffer.set (busIdx, *inBusBuffers[busIdx]->get(), mapper.get (true, busIdx));
|
||||
|
||||
// clear remaining channels
|
||||
for (int i = totalInChannels; i < totalOutChannels; ++i)
|
||||
zeromem (audioBuffer.push(), sizeof (float) * frameCount);
|
||||
audioBuffer.clearUnusedChannels ((int) frameCount);
|
||||
}
|
||||
|
||||
// process audio
|
||||
processBlock (audioBuffer.getBuffer (frameCount), midiMessages);
|
||||
|
||||
// send MIDI
|
||||
#if JucePlugin_ProducesMidiOutput && JUCE_AUV3_MIDI_OUTPUT_SUPPORTED
|
||||
if (auto midiOut = [au MIDIOutputEventBlock])
|
||||
#if JucePlugin_ProducesMidiOutput
|
||||
if (@available (macOS 10.13, iOS 11.0, *))
|
||||
{
|
||||
for (const auto metadata : midiMessages)
|
||||
midiOut (metadata.samplePosition, 0, metadata.numBytes, metadata.data);
|
||||
if (auto midiOut = midiOutputEventBlock)
|
||||
for (const auto metadata : midiMessages)
|
||||
if (isPositiveAndBelow (metadata.samplePosition, frameCount))
|
||||
midiOut ((int64_t) metadata.samplePosition + (int64_t) (timestamp->mSampleTime + 0.5),
|
||||
0,
|
||||
metadata.numBytes,
|
||||
metadata.data);
|
||||
}
|
||||
#endif
|
||||
|
||||
midiMessages.clear();
|
||||
|
||||
// copy back
|
||||
if (outputBusNumber < numProcessorBusesOut)
|
||||
audioBuffer.pop (*outBusBuffers[(int) outputBusNumber]->get(),
|
||||
mapper.get (false, (int) outputBusNumber));
|
||||
}
|
||||
else {
|
||||
// now copy the next bus data to the other output buffer
|
||||
audioBuffer.pop (*outputData,
|
||||
mapper.get (false, (int) outputBusNumber));
|
||||
}
|
||||
|
||||
// copy back
|
||||
if (outputBusNumber < numProcessorBusesOut && outputData != nullptr)
|
||||
audioBuffer.get ((int) outputBusNumber, *outputData, mapper.get (false, (int) outputBusNumber));
|
||||
|
||||
return noErr;
|
||||
}
|
||||
@@ -1630,7 +1654,7 @@ private:
|
||||
|
||||
if (processor.isSuspended())
|
||||
buffer.clear();
|
||||
else if (bypassParam != nullptr && [au shouldBypassEffect])
|
||||
else if (bypassParam == nullptr && [au shouldBypassEffect])
|
||||
processor.processBlockBypassed (buffer, midiBuffer);
|
||||
else
|
||||
processor.processBlock (buffer, midiBuffer);
|
||||
@@ -1749,6 +1773,7 @@ private:
|
||||
|
||||
int totalInChannels, totalOutChannels;
|
||||
|
||||
CoreAudioTimeConversions timeConversions;
|
||||
std::unique_ptr<AUAudioUnitBusArray, NSObjectDeleter> inputBusses, outputBusses;
|
||||
|
||||
ObjCBlock<AUImplementorValueObserver> paramObserver;
|
||||
@@ -1770,7 +1795,7 @@ private:
|
||||
std::unique_ptr<AUParameterTree, NSObjectDeleter> paramTree;
|
||||
std::unique_ptr<NSMutableArray<NSNumber*>, NSObjectDeleter> overviewParams, channelCapabilities;
|
||||
|
||||
std::unique_ptr<NSMutableArray<AUAudioUnitPreset*>, NSObjectDeleter> factoryPresets;
|
||||
FactoryPresets factoryPresets;
|
||||
|
||||
ObjCBlock<AUInternalRenderBlock> internalRenderBlock;
|
||||
|
||||
@@ -1779,6 +1804,7 @@ private:
|
||||
|
||||
OwnedArray<BusBuffer> inBusBuffers, outBusBuffers;
|
||||
MidiBuffer midiMessages;
|
||||
AUMIDIOutputEventBlock midiOutputEventBlock = nullptr;
|
||||
|
||||
#if JUCE_AUV3_MIDI_EVENT_LIST_SUPPORTED
|
||||
ump::ToBytestreamDispatcher converter { 2048 };
|
||||
@@ -1788,7 +1814,6 @@ private:
|
||||
ObjCBlock<AUHostTransportStateBlock> hostTransportStateCallback;
|
||||
|
||||
AudioTimeStamp lastTimeStamp;
|
||||
CurrentPositionInfo lastAudioHead;
|
||||
|
||||
String contextName;
|
||||
|
||||
@@ -1946,7 +1971,7 @@ public:
|
||||
if (holder == nullptr)
|
||||
return nullptr;
|
||||
|
||||
return (new JuceAudioUnitv3 (holder, descr, 0, error))->getAudioUnit();
|
||||
return [(new JuceAudioUnitv3 (holder, descr, 0, error))->getAudioUnit() autorelease];
|
||||
}
|
||||
|
||||
private:
|
||||
@@ -2030,9 +2055,13 @@ private:
|
||||
|
||||
//==============================================================================
|
||||
#if JUCE_IOS
|
||||
JUCE_BEGIN_IGNORE_WARNINGS_GCC_LIKE ("-Wmissing-prototypes")
|
||||
|
||||
bool JUCE_CALLTYPE juce_isInterAppAudioConnected() { return false; }
|
||||
void JUCE_CALLTYPE juce_switchToHostApplication() {}
|
||||
Image JUCE_CALLTYPE juce_getIAAHostIcon (int) { return {}; }
|
||||
|
||||
JUCE_END_IGNORE_WARNINGS_GCC_LIKE
|
||||
#endif
|
||||
|
||||
JUCE_END_IGNORE_WARNINGS_GCC_LIKE
|
||||
|
||||
29
deps/juce/modules/juce_audio_plugin_client/CMakeLists.txt
vendored
Normal file
29
deps/juce/modules/juce_audio_plugin_client/CMakeLists.txt
vendored
Normal file
@@ -0,0 +1,29 @@
|
||||
# ==============================================================================
|
||||
#
|
||||
# This file is part of the JUCE library.
|
||||
# Copyright (c) 2022 - Raw Material Software Limited
|
||||
#
|
||||
# JUCE is an open source library subject to commercial or open-source
|
||||
# licensing.
|
||||
#
|
||||
# By using JUCE, you agree to the terms of both the JUCE 7 End-User License
|
||||
# Agreement and JUCE Privacy Policy.
|
||||
#
|
||||
# End User License Agreement: www.juce.com/juce-7-licence
|
||||
# Privacy Policy: www.juce.com/juce-privacy-policy
|
||||
#
|
||||
# Or: You may also use this code under the terms of the GPL v3 (see
|
||||
# www.gnu.org/licenses).
|
||||
#
|
||||
# JUCE IS PROVIDED "AS IS" WITHOUT ANY WARRANTY, AND ALL WARRANTIES, WHETHER
|
||||
# EXPRESSED OR IMPLIED, INCLUDING MERCHANTABILITY AND FITNESS FOR PURPOSE, ARE
|
||||
# DISCLAIMED.
|
||||
#
|
||||
# ==============================================================================
|
||||
|
||||
add_executable(juce_lv2_helper LV2/juce_LV2TurtleDumpProgram.cpp)
|
||||
add_executable(juce::juce_lv2_helper ALIAS juce_lv2_helper)
|
||||
target_compile_features(juce_lv2_helper PRIVATE cxx_std_14)
|
||||
set_target_properties(juce_lv2_helper PROPERTIES BUILD_WITH_INSTALL_RPATH ON)
|
||||
target_link_libraries(juce_lv2_helper PRIVATE ${CMAKE_DL_LIBS})
|
||||
install(TARGETS juce_lv2_helper EXPORT LV2_HELPER DESTINATION "bin/JUCE-${JUCE_VERSION}")
|
||||
78
deps/juce/modules/juce_audio_plugin_client/LV2/juce_LV2TurtleDumpProgram.cpp
vendored
Normal file
78
deps/juce/modules/juce_audio_plugin_client/LV2/juce_LV2TurtleDumpProgram.cpp
vendored
Normal file
@@ -0,0 +1,78 @@
|
||||
/*
|
||||
==============================================================================
|
||||
|
||||
This file is part of the JUCE library.
|
||||
Copyright (c) 2022 - Raw Material Software Limited
|
||||
|
||||
JUCE is an open source library subject to commercial or open-source
|
||||
licensing.
|
||||
|
||||
By using JUCE, you agree to the terms of both the JUCE 7 End-User License
|
||||
Agreement and JUCE Privacy Policy.
|
||||
|
||||
End User License Agreement: www.juce.com/juce-7-licence
|
||||
Privacy Policy: www.juce.com/juce-privacy-policy
|
||||
|
||||
Or: You may also use this code under the terms of the GPL v3 (see
|
||||
www.gnu.org/licenses).
|
||||
|
||||
JUCE IS PROVIDED "AS IS" WITHOUT ANY WARRANTY, AND ALL WARRANTIES, WHETHER
|
||||
EXPRESSED OR IMPLIED, INCLUDING MERCHANTABILITY AND FITNESS FOR PURPOSE, ARE
|
||||
DISCLAIMED.
|
||||
|
||||
==============================================================================
|
||||
*/
|
||||
|
||||
#ifdef _WIN32
|
||||
#include <windows.h>
|
||||
HMODULE dlopen (const char* filename, int) { return LoadLibrary (filename); }
|
||||
FARPROC dlsym (HMODULE handle, const char* name) { return GetProcAddress (handle, name); }
|
||||
enum { RTLD_LAZY = 0 };
|
||||
#else
|
||||
#include <dlfcn.h>
|
||||
#endif
|
||||
|
||||
#include <cstdint>
|
||||
|
||||
// Replicating some of the LV2 header here so that we don't have to set up any
|
||||
// custom include paths for this file.
|
||||
// Normally this would be a bad idea, but the LV2 API has to keep these definitions
|
||||
// in order to remain backwards-compatible.
|
||||
|
||||
extern "C"
|
||||
{
|
||||
typedef struct LV2_Descriptor
|
||||
{
|
||||
const void* a;
|
||||
const void* b;
|
||||
const void* c;
|
||||
const void* d;
|
||||
const void* e;
|
||||
const void* f;
|
||||
const void* g;
|
||||
const void* (*extension_data)(const char* uri);
|
||||
} LV2_Descriptor;
|
||||
}
|
||||
|
||||
int main (int argc, const char** argv)
|
||||
{
|
||||
if (argc != 2)
|
||||
return 1;
|
||||
|
||||
const auto* libraryPath = argv[1];
|
||||
|
||||
struct RecallFeature
|
||||
{
|
||||
int (*doRecall) (const char*);
|
||||
};
|
||||
|
||||
if (auto* handle = dlopen (libraryPath, RTLD_LAZY))
|
||||
if (auto* getDescriptor = reinterpret_cast<const LV2_Descriptor* (*) (uint32_t)> (dlsym (handle, "lv2_descriptor")))
|
||||
if (auto* descriptor = getDescriptor (0))
|
||||
if (auto* extensionData = descriptor->extension_data)
|
||||
if (auto* recallFeature = reinterpret_cast<const RecallFeature*> (extensionData ("https://lv2-extensions.juce.com/turtle_recall")))
|
||||
if (auto* doRecall = recallFeature->doRecall)
|
||||
return doRecall (libraryPath);
|
||||
|
||||
return 1;
|
||||
}
|
||||
1778
deps/juce/modules/juce_audio_plugin_client/LV2/juce_LV2_Client.cpp
vendored
Normal file
1778
deps/juce/modules/juce_audio_plugin_client/LV2/juce_LV2_Client.cpp
vendored
Normal file
File diff suppressed because it is too large
Load Diff
@@ -1,73 +0,0 @@
|
||||
/*
|
||||
==============================================================================
|
||||
|
||||
This file is part of the JUCE library.
|
||||
Copyright (c) 2020 - Raw Material Software Limited
|
||||
|
||||
JUCE is an open source library subject to commercial or open-source
|
||||
licensing.
|
||||
|
||||
By using JUCE, you agree to the terms of both the JUCE 6 End-User License
|
||||
Agreement and JUCE Privacy Policy (both effective as of the 16th June 2020).
|
||||
|
||||
End User License Agreement: www.juce.com/juce-6-licence
|
||||
Privacy Policy: www.juce.com/juce-privacy-policy
|
||||
|
||||
Or: You may also use this code under the terms of the GPL v3 (see
|
||||
www.gnu.org/licenses).
|
||||
|
||||
JUCE IS PROVIDED "AS IS" WITHOUT ANY WARRANTY, AND ALL WARRANTIES, WHETHER
|
||||
EXPRESSED OR IMPLIED, INCLUDING MERCHANTABILITY AND FITNESS FOR PURPOSE, ARE
|
||||
DISCLAIMED.
|
||||
|
||||
==============================================================================
|
||||
*/
|
||||
|
||||
#pragma once
|
||||
|
||||
#include <juce_core/system/juce_TargetPlatform.h>
|
||||
#include "../utility/juce_CheckSettingMacros.h"
|
||||
|
||||
#if JucePlugin_Build_RTAS
|
||||
|
||||
#include "juce_RTAS_DigiCode_Header.h"
|
||||
|
||||
/*
|
||||
This file is used to include and build the required digidesign CPP files without your project
|
||||
needing to reference the files directly. Because these files will be found via your include path,
|
||||
this means that the project doesn't have to change to cope with people's SDKs being in different
|
||||
locations.
|
||||
|
||||
Important note on Windows: In your project settings for the three juce_RTAS_DigiCode.cpp files and
|
||||
the juce_RTAS_Wrapper.cpp file, you need to set the calling convention to "__stdcall".
|
||||
If you don't do this, you'll get some unresolved externals and will spend a long time wondering what's
|
||||
going on... All the other files in your project can be set to use the normal __cdecl convention.
|
||||
|
||||
If you get an error building the includes statements below, check your paths - there's a full
|
||||
list of the necessary Digidesign paths in juce_RTAS_Wrapper.cpp
|
||||
*/
|
||||
|
||||
#if WINDOWS_VERSION
|
||||
#undef _UNICODE
|
||||
#undef UNICODE
|
||||
#endif
|
||||
|
||||
JUCE_BEGIN_IGNORE_WARNINGS_GCC_LIKE ("-Wnon-virtual-dtor",
|
||||
"-Wcomment",
|
||||
"-Wreorder",
|
||||
"-Wextra-tokens",
|
||||
"-Wunused-variable",
|
||||
"-Wdeprecated")
|
||||
|
||||
#include <CEffectGroup.cpp>
|
||||
#include <CEffectGroupMIDI.cpp>
|
||||
#include <CEffectMIDIUtils.cpp>
|
||||
#include <CEffectProcess.cpp>
|
||||
#include <CEffectProcessAS.cpp>
|
||||
#include <CEffectType.cpp>
|
||||
#include <CEffectTypeRTAS.cpp>
|
||||
#include <ChunkDataParser.cpp>
|
||||
|
||||
JUCE_END_IGNORE_WARNINGS_GCC_LIKE
|
||||
|
||||
#endif
|
||||
@@ -1,61 +0,0 @@
|
||||
/*
|
||||
==============================================================================
|
||||
|
||||
This file is part of the JUCE library.
|
||||
Copyright (c) 2020 - Raw Material Software Limited
|
||||
|
||||
JUCE is an open source library subject to commercial or open-source
|
||||
licensing.
|
||||
|
||||
By using JUCE, you agree to the terms of both the JUCE 6 End-User License
|
||||
Agreement and JUCE Privacy Policy (both effective as of the 16th June 2020).
|
||||
|
||||
End User License Agreement: www.juce.com/juce-6-licence
|
||||
Privacy Policy: www.juce.com/juce-privacy-policy
|
||||
|
||||
Or: You may also use this code under the terms of the GPL v3 (see
|
||||
www.gnu.org/licenses).
|
||||
|
||||
JUCE IS PROVIDED "AS IS" WITHOUT ANY WARRANTY, AND ALL WARRANTIES, WHETHER
|
||||
EXPRESSED OR IMPLIED, INCLUDING MERCHANTABILITY AND FITNESS FOR PURPOSE, ARE
|
||||
DISCLAIMED.
|
||||
|
||||
==============================================================================
|
||||
*/
|
||||
|
||||
#pragma once
|
||||
|
||||
#include <juce_core/system/juce_TargetPlatform.h>
|
||||
#include "../utility/juce_CheckSettingMacros.h"
|
||||
|
||||
#if JucePlugin_Build_RTAS
|
||||
|
||||
#include "juce_RTAS_DigiCode_Header.h"
|
||||
|
||||
JUCE_BEGIN_IGNORE_WARNINGS_GCC_LIKE ("-Wcomment",
|
||||
"-Wextra-tokens",
|
||||
"-Wnon-virtual-dtor",
|
||||
"-Wreorder",
|
||||
"-Wdeprecated")
|
||||
|
||||
/*
|
||||
This file is used to include and build the required digidesign CPP files without your project
|
||||
needing to reference the files directly. Because these files will be found via your include path,
|
||||
this means that the project doesn't have to change to cope with people's SDKs being in different
|
||||
locations.
|
||||
|
||||
Important note on Windows: In your project settings for the three juce_RTAS_DigiCode.cpp files and
|
||||
the juce_RTAS_Wrapper.cpp file, you need to set the calling convention to "__stdcall".
|
||||
If you don't do this, you'll get some unresolved externals and will spend a long time wondering what's
|
||||
going on... All the other files in your project can be set to use the normal __cdecl convention.
|
||||
|
||||
If you get an error building the includes statements below, check your paths - there's a full
|
||||
list of the necessary Digidesign paths in juce_RTAS_Wrapper.cpp
|
||||
*/
|
||||
|
||||
#include <CEffectProcessMIDI.cpp>
|
||||
#include <PlugInUtils.cpp>
|
||||
|
||||
JUCE_END_IGNORE_WARNINGS_GCC_LIKE
|
||||
|
||||
#endif
|
||||
@@ -1,74 +0,0 @@
|
||||
/*
|
||||
==============================================================================
|
||||
|
||||
This file is part of the JUCE library.
|
||||
Copyright (c) 2020 - Raw Material Software Limited
|
||||
|
||||
JUCE is an open source library subject to commercial or open-source
|
||||
licensing.
|
||||
|
||||
By using JUCE, you agree to the terms of both the JUCE 6 End-User License
|
||||
Agreement and JUCE Privacy Policy (both effective as of the 16th June 2020).
|
||||
|
||||
End User License Agreement: www.juce.com/juce-6-licence
|
||||
Privacy Policy: www.juce.com/juce-privacy-policy
|
||||
|
||||
Or: You may also use this code under the terms of the GPL v3 (see
|
||||
www.gnu.org/licenses).
|
||||
|
||||
JUCE IS PROVIDED "AS IS" WITHOUT ANY WARRANTY, AND ALL WARRANTIES, WHETHER
|
||||
EXPRESSED OR IMPLIED, INCLUDING MERCHANTABILITY AND FITNESS FOR PURPOSE, ARE
|
||||
DISCLAIMED.
|
||||
|
||||
==============================================================================
|
||||
*/
|
||||
|
||||
#pragma once
|
||||
|
||||
#include <juce_core/system/juce_TargetPlatform.h>
|
||||
#include "../utility/juce_CheckSettingMacros.h"
|
||||
|
||||
#if JucePlugin_Build_RTAS
|
||||
|
||||
#include "../utility/juce_IncludeSystemHeaders.h"
|
||||
#include "juce_RTAS_DigiCode_Header.h"
|
||||
|
||||
JUCE_BEGIN_IGNORE_WARNINGS_GCC_LIKE ("-Wnon-virtual-dtor", "-Wextra-tokens", "-Wreorder")
|
||||
|
||||
/*
|
||||
This file is used to include and build the required digidesign CPP files without your project
|
||||
needing to reference the files directly. Because these files will be found via your include path,
|
||||
this means that the project doesn't have to change to cope with people's SDKs being in different
|
||||
locations.
|
||||
|
||||
Important note on Windows: In your project settings for the three juce_RTAS_DigiCode.cpp files and
|
||||
the juce_RTAS_Wrapper.cpp file, you need to set the calling convention to "__stdcall".
|
||||
If you don't do this, you'll get some unresolved externals and will spend a long time wondering what's
|
||||
going on... All the other files in your project can be set to use the normal __cdecl convention.
|
||||
|
||||
If you get an error building the includes statements below, check your paths - there's a full
|
||||
list of the necessary Digidesign paths in juce_RTAS_Wrapper.cpp
|
||||
*/
|
||||
|
||||
#if WINDOWS_VERSION
|
||||
#undef _UNICODE
|
||||
#undef UNICODE
|
||||
#define DllMain DllMainRTAS
|
||||
#include <DLLMain.cpp>
|
||||
#undef DllMain
|
||||
#include <DefaultSwap.cpp>
|
||||
#else
|
||||
#include <PlugInInitialize.cpp>
|
||||
#include <Dispatcher.cpp>
|
||||
#endif
|
||||
|
||||
JUCE_END_IGNORE_WARNINGS_GCC_LIKE
|
||||
|
||||
#else
|
||||
|
||||
#if _MSC_VER
|
||||
short __stdcall NewPlugIn (void*) { return 0; }
|
||||
short __stdcall _PI_GetRoutineDescriptor (long, void*) { return 0; }
|
||||
#endif
|
||||
|
||||
#endif
|
||||
@@ -1,68 +0,0 @@
|
||||
/*
|
||||
==============================================================================
|
||||
|
||||
This file is part of the JUCE library.
|
||||
Copyright (c) 2020 - Raw Material Software Limited
|
||||
|
||||
JUCE is an open source library subject to commercial or open-source
|
||||
licensing.
|
||||
|
||||
By using JUCE, you agree to the terms of both the JUCE 6 End-User License
|
||||
Agreement and JUCE Privacy Policy (both effective as of the 16th June 2020).
|
||||
|
||||
End User License Agreement: www.juce.com/juce-6-licence
|
||||
Privacy Policy: www.juce.com/juce-privacy-policy
|
||||
|
||||
Or: You may also use this code under the terms of the GPL v3 (see
|
||||
www.gnu.org/licenses).
|
||||
|
||||
JUCE IS PROVIDED "AS IS" WITHOUT ANY WARRANTY, AND ALL WARRANTIES, WHETHER
|
||||
EXPRESSED OR IMPLIED, INCLUDING MERCHANTABILITY AND FITNESS FOR PURPOSE, ARE
|
||||
DISCLAIMED.
|
||||
|
||||
==============================================================================
|
||||
*/
|
||||
|
||||
#pragma once
|
||||
|
||||
#if JucePlugin_Build_RTAS
|
||||
#ifdef _MSC_VER
|
||||
|
||||
#define kCompileAsCodeResource 0
|
||||
#define kBuildStandAlone 0
|
||||
#define kNoDSP 0
|
||||
#define kNoDAE 0
|
||||
#define kNoSDS 0
|
||||
#define kNoViews 0
|
||||
#define kUseDSPCodeDecode 0
|
||||
|
||||
#define WIN32 1
|
||||
#define WINDOWS_VERSION 1
|
||||
#define PLUGIN_SDK_BUILD 1
|
||||
#define PLUGIN_SDK_DIRECTMIDI 1
|
||||
#define _STDINT_H 1
|
||||
|
||||
// the Digidesign projects all use a struct alignment of 2..
|
||||
#pragma pack (2)
|
||||
#pragma warning (disable: 4267 4996 4311 4312 4103 4121 4100 4127 4189 4245 4389 4512 4701 4703)
|
||||
|
||||
#include <ForcedInclude.h>
|
||||
|
||||
#else
|
||||
|
||||
#define kCompileAsCodeResource 0
|
||||
#define kNoDSP 1
|
||||
#define kNoDAE 0
|
||||
#define kNoSDS 0
|
||||
#define kNoViews 0
|
||||
#define kUseDSPCodeDecode 0
|
||||
|
||||
#define MAC_VERSION 1
|
||||
#define PLUGIN_SDK_BUILD 1
|
||||
#define PLUGIN_SDK_DIRECTMIDI 1
|
||||
#define DIGI_PASCAL
|
||||
|
||||
#include <MacAlwaysInclude.h>
|
||||
|
||||
#endif
|
||||
#endif
|
||||
@@ -1,169 +0,0 @@
|
||||
/*
|
||||
==============================================================================
|
||||
|
||||
This file is part of the JUCE library.
|
||||
Copyright (c) 2020 - Raw Material Software Limited
|
||||
|
||||
JUCE is an open source library subject to commercial or open-source
|
||||
licensing.
|
||||
|
||||
By using JUCE, you agree to the terms of both the JUCE 6 End-User License
|
||||
Agreement and JUCE Privacy Policy (both effective as of the 16th June 2020).
|
||||
|
||||
End User License Agreement: www.juce.com/juce-6-licence
|
||||
Privacy Policy: www.juce.com/juce-privacy-policy
|
||||
|
||||
Or: You may also use this code under the terms of the GPL v3 (see
|
||||
www.gnu.org/licenses).
|
||||
|
||||
JUCE IS PROVIDED "AS IS" WITHOUT ANY WARRANTY, AND ALL WARRANTIES, WHETHER
|
||||
EXPRESSED OR IMPLIED, INCLUDING MERCHANTABILITY AND FITNESS FOR PURPOSE, ARE
|
||||
DISCLAIMED.
|
||||
|
||||
==============================================================================
|
||||
*/
|
||||
|
||||
#include <juce_core/system/juce_TargetPlatform.h>
|
||||
#include "../utility/juce_CheckSettingMacros.h"
|
||||
|
||||
#if JucePlugin_Build_RTAS
|
||||
|
||||
// Horrible carbon-based fix for a cocoa bug, where an NSWindow that wraps a carbon
|
||||
// window fails to keep its position updated when the user drags the window around..
|
||||
#define WINDOWPOSITION_BODGE 1
|
||||
#define JUCE_MAC_WINDOW_VISIBITY_BODGE 1
|
||||
|
||||
#include "../utility/juce_IncludeSystemHeaders.h"
|
||||
#include "../utility/juce_IncludeModuleHeaders.h"
|
||||
#include "../utility/juce_CarbonVisibility.h"
|
||||
|
||||
using namespace juce;
|
||||
|
||||
//==============================================================================
|
||||
void initialiseMacRTAS();
|
||||
void initialiseMacRTAS()
|
||||
{
|
||||
#if ! JUCE_64BIT
|
||||
NSApplicationLoad();
|
||||
#endif
|
||||
}
|
||||
|
||||
void* attachSubWindow (void*, Component*);
|
||||
void* attachSubWindow (void* hostWindowRef, Component* comp)
|
||||
{
|
||||
JUCE_AUTORELEASEPOOL
|
||||
{
|
||||
#if 0
|
||||
// This was suggested as a way to improve passing keypresses to the host, but
|
||||
// a side-effect seems to be occasional rendering artifacts.
|
||||
HIWindowChangeClass ((WindowRef) hostWindowRef, kFloatingWindowClass);
|
||||
#endif
|
||||
|
||||
NSWindow* hostWindow = [[NSWindow alloc] initWithWindowRef: hostWindowRef];
|
||||
[hostWindow retain];
|
||||
[hostWindow setCanHide: YES];
|
||||
[hostWindow setReleasedWhenClosed: YES];
|
||||
NSRect oldWindowFrame = [hostWindow frame];
|
||||
|
||||
NSView* content = [hostWindow contentView];
|
||||
NSRect f = [content frame];
|
||||
f.size.width = comp->getWidth();
|
||||
f.size.height = comp->getHeight();
|
||||
[content setFrame: f];
|
||||
|
||||
const CGFloat mainScreenHeight = [[[NSScreen screens] objectAtIndex: 0] frame].size.height;
|
||||
|
||||
#if WINDOWPOSITION_BODGE
|
||||
{
|
||||
Rect winBounds;
|
||||
GetWindowBounds ((WindowRef) hostWindowRef, kWindowContentRgn, &winBounds);
|
||||
NSRect w = [hostWindow frame];
|
||||
w.origin.x = winBounds.left;
|
||||
w.origin.y = mainScreenHeight - winBounds.bottom;
|
||||
[hostWindow setFrame: w display: NO animate: NO];
|
||||
}
|
||||
#endif
|
||||
|
||||
NSPoint windowPos = [hostWindow convertBaseToScreen: f.origin];
|
||||
windowPos.x = windowPos.x + jmax (0.0f, (oldWindowFrame.size.width - f.size.width) / 2.0f);
|
||||
windowPos.y = mainScreenHeight - (windowPos.y + f.size.height);
|
||||
|
||||
comp->setTopLeftPosition ((int) windowPos.x, (int) windowPos.y);
|
||||
|
||||
#if ! JucePlugin_EditorRequiresKeyboardFocus
|
||||
comp->addToDesktop (ComponentPeer::windowIsTemporary | ComponentPeer::windowIgnoresKeyPresses);
|
||||
#else
|
||||
comp->addToDesktop (ComponentPeer::windowIsTemporary);
|
||||
#endif
|
||||
|
||||
comp->setVisible (true);
|
||||
|
||||
NSView* pluginView = (NSView*) comp->getWindowHandle();
|
||||
NSWindow* pluginWindow = [pluginView window];
|
||||
|
||||
[hostWindow addChildWindow: pluginWindow
|
||||
ordered: NSWindowAbove];
|
||||
[hostWindow orderFront: nil];
|
||||
[pluginWindow orderFront: nil];
|
||||
|
||||
attachWindowHidingHooks (comp, (WindowRef) hostWindowRef, hostWindow);
|
||||
|
||||
return hostWindow;
|
||||
}
|
||||
}
|
||||
|
||||
void removeSubWindow (void*, Component*);
|
||||
void removeSubWindow (void* nsWindow, Component* comp)
|
||||
{
|
||||
JUCE_AUTORELEASEPOOL
|
||||
{
|
||||
NSView* pluginView = (NSView*) comp->getWindowHandle();
|
||||
NSWindow* hostWindow = (NSWindow*) nsWindow;
|
||||
NSWindow* pluginWindow = [pluginView window];
|
||||
|
||||
removeWindowHidingHooks (comp);
|
||||
[hostWindow removeChildWindow: pluginWindow];
|
||||
comp->removeFromDesktop();
|
||||
[hostWindow release];
|
||||
}
|
||||
}
|
||||
|
||||
namespace
|
||||
{
|
||||
bool isJuceWindow (WindowRef w)
|
||||
{
|
||||
for (int i = ComponentPeer::getNumPeers(); --i >= 0;)
|
||||
{
|
||||
ComponentPeer* peer = ComponentPeer::getPeer(i);
|
||||
NSView* view = (NSView*) peer->getNativeHandle();
|
||||
|
||||
if ([[view window] windowRef] == w)
|
||||
return true;
|
||||
}
|
||||
|
||||
return false;
|
||||
}
|
||||
}
|
||||
|
||||
void forwardCurrentKeyEventToHostWindow();
|
||||
void forwardCurrentKeyEventToHostWindow()
|
||||
{
|
||||
WindowRef w = FrontNonFloatingWindow();
|
||||
WindowRef original = w;
|
||||
|
||||
while (IsValidWindowPtr (w) && isJuceWindow (w))
|
||||
{
|
||||
w = GetNextWindowOfClass (w, kDocumentWindowClass, true);
|
||||
|
||||
if (w == original)
|
||||
break;
|
||||
}
|
||||
|
||||
if (! isJuceWindow (w))
|
||||
{
|
||||
ActivateWindow (w, true);
|
||||
repostCurrentNSEvent();
|
||||
}
|
||||
}
|
||||
|
||||
#endif
|
||||
@@ -1,4 +0,0 @@
|
||||
EXPORTS
|
||||
NewPlugIn @1
|
||||
_PI_GetRoutineDescriptor @2
|
||||
|
||||
Binary file not shown.
|
Before Width: | Height: | Size: 3.1 KiB |
@@ -1,157 +0,0 @@
|
||||
/*
|
||||
==============================================================================
|
||||
|
||||
This file is part of the JUCE library.
|
||||
Copyright (c) 2020 - Raw Material Software Limited
|
||||
|
||||
JUCE is an open source library subject to commercial or open-source
|
||||
licensing.
|
||||
|
||||
By using JUCE, you agree to the terms of both the JUCE 6 End-User License
|
||||
Agreement and JUCE Privacy Policy (both effective as of the 16th June 2020).
|
||||
|
||||
End User License Agreement: www.juce.com/juce-6-licence
|
||||
Privacy Policy: www.juce.com/juce-privacy-policy
|
||||
|
||||
Or: You may also use this code under the terms of the GPL v3 (see
|
||||
www.gnu.org/licenses).
|
||||
|
||||
JUCE IS PROVIDED "AS IS" WITHOUT ANY WARRANTY, AND ALL WARRANTIES, WHETHER
|
||||
EXPRESSED OR IMPLIED, INCLUDING MERCHANTABILITY AND FITNESS FOR PURPOSE, ARE
|
||||
DISCLAIMED.
|
||||
|
||||
==============================================================================
|
||||
*/
|
||||
|
||||
#include <juce_core/system/juce_TargetPlatform.h>
|
||||
#include "../utility/juce_CheckSettingMacros.h"
|
||||
|
||||
#if JucePlugin_Build_RTAS
|
||||
|
||||
// (these functions are in their own file because of problems including windows.h
|
||||
// at the same time as the Digi headers)
|
||||
|
||||
#define _DO_NOT_DECLARE_INTERLOCKED_INTRINSICS_IN_MEMORY // (workaround for a VC build problem)
|
||||
|
||||
#undef _WIN32_WINNT
|
||||
#define _WIN32_WINNT 0x0500
|
||||
#undef STRICT
|
||||
#define STRICT
|
||||
#include <intrin.h>
|
||||
#include <windows.h>
|
||||
|
||||
#pragma pack (push, 8)
|
||||
#include "../utility/juce_IncludeModuleHeaders.h"
|
||||
#pragma pack (pop)
|
||||
|
||||
//==============================================================================
|
||||
void JUCE_CALLTYPE attachSubWindow (void* hostWindow,
|
||||
int& titleW, int& titleH,
|
||||
Component* comp)
|
||||
{
|
||||
using namespace juce;
|
||||
|
||||
RECT clientRect;
|
||||
GetClientRect ((HWND) hostWindow, &clientRect);
|
||||
|
||||
titleW = clientRect.right - clientRect.left;
|
||||
titleH = jmax (0, (int) (clientRect.bottom - clientRect.top) - comp->getHeight());
|
||||
comp->setTopLeftPosition (0, titleH);
|
||||
|
||||
comp->addToDesktop (0);
|
||||
|
||||
HWND plugWnd = (HWND) comp->getWindowHandle();
|
||||
SetParent (plugWnd, (HWND) hostWindow);
|
||||
|
||||
DWORD val = GetWindowLong (plugWnd, GWL_STYLE);
|
||||
val = (val & ~WS_POPUP) | WS_CHILD;
|
||||
SetWindowLong (plugWnd, GWL_STYLE, val);
|
||||
|
||||
val = GetWindowLong ((HWND) hostWindow, GWL_STYLE);
|
||||
SetWindowLong ((HWND) hostWindow, GWL_STYLE, val | WS_CLIPCHILDREN);
|
||||
}
|
||||
|
||||
void JUCE_CALLTYPE resizeHostWindow (void* hostWindow,
|
||||
int& titleW, int& titleH,
|
||||
Component* comp)
|
||||
{
|
||||
using namespace juce;
|
||||
|
||||
RECT clientRect, windowRect;
|
||||
GetClientRect ((HWND) hostWindow, &clientRect);
|
||||
GetWindowRect ((HWND) hostWindow, &windowRect);
|
||||
const int borderW = (windowRect.right - windowRect.left) - (clientRect.right - clientRect.left);
|
||||
const int borderH = (windowRect.bottom - windowRect.top) - (clientRect.bottom - clientRect.top);
|
||||
|
||||
SetWindowPos ((HWND) hostWindow, 0, 0, 0,
|
||||
borderW + jmax (titleW, comp->getWidth()),
|
||||
borderH + comp->getHeight() + titleH,
|
||||
SWP_NOACTIVATE | SWP_NOMOVE | SWP_NOZORDER | SWP_NOOWNERZORDER);
|
||||
}
|
||||
|
||||
extern "C" BOOL WINAPI DllMainRTAS (HINSTANCE, DWORD, LPVOID);
|
||||
|
||||
extern "C" BOOL WINAPI DllMain (HINSTANCE instance, DWORD reason, LPVOID reserved)
|
||||
{
|
||||
if (reason == DLL_PROCESS_ATTACH)
|
||||
juce::Process::setCurrentModuleInstanceHandle (instance);
|
||||
|
||||
if (GetModuleHandleA ("DAE.DLL") != 0)
|
||||
return DllMainRTAS (instance, reason, reserved);
|
||||
|
||||
juce::ignoreUnused (reserved);
|
||||
return TRUE;
|
||||
}
|
||||
|
||||
#if ! JucePlugin_EditorRequiresKeyboardFocus
|
||||
|
||||
namespace
|
||||
{
|
||||
HWND findMDIParentOf (HWND w)
|
||||
{
|
||||
const int frameThickness = GetSystemMetrics (SM_CYFIXEDFRAME);
|
||||
|
||||
while (w != 0)
|
||||
{
|
||||
HWND parent = GetParent (w);
|
||||
|
||||
if (parent == 0)
|
||||
break;
|
||||
|
||||
TCHAR windowType [32] = { 0 };
|
||||
GetClassName (parent, windowType, 31);
|
||||
|
||||
if (juce::String (windowType).equalsIgnoreCase ("MDIClient"))
|
||||
{
|
||||
w = parent;
|
||||
break;
|
||||
}
|
||||
|
||||
RECT windowPos, parentPos;
|
||||
GetWindowRect (w, &windowPos);
|
||||
GetWindowRect (parent, &parentPos);
|
||||
|
||||
int dw = (parentPos.right - parentPos.left) - (windowPos.right - windowPos.left);
|
||||
int dh = (parentPos.bottom - parentPos.top) - (windowPos.bottom - windowPos.top);
|
||||
|
||||
if (dw > 100 || dh > 100)
|
||||
break;
|
||||
|
||||
w = parent;
|
||||
|
||||
if (dw == 2 * frameThickness)
|
||||
break;
|
||||
}
|
||||
|
||||
return w;
|
||||
}
|
||||
}
|
||||
|
||||
void JUCE_CALLTYPE passFocusToHostWindow (void* hostWindow)
|
||||
{
|
||||
SetFocus (findMDIParentOf ((HWND) hostWindow));
|
||||
}
|
||||
|
||||
#endif
|
||||
|
||||
#endif
|
||||
File diff suppressed because it is too large
Load Diff
@@ -1,168 +1,172 @@
|
||||
/*
|
||||
==============================================================================
|
||||
|
||||
This file is part of the JUCE library.
|
||||
Copyright (c) 2020 - Raw Material Software Limited
|
||||
|
||||
JUCE is an open source library subject to commercial or open-source
|
||||
licensing.
|
||||
|
||||
By using JUCE, you agree to the terms of both the JUCE 6 End-User License
|
||||
Agreement and JUCE Privacy Policy (both effective as of the 16th June 2020).
|
||||
|
||||
End User License Agreement: www.juce.com/juce-6-licence
|
||||
Privacy Policy: www.juce.com/juce-privacy-policy
|
||||
|
||||
Or: You may also use this code under the terms of the GPL v3 (see
|
||||
www.gnu.org/licenses).
|
||||
|
||||
JUCE IS PROVIDED "AS IS" WITHOUT ANY WARRANTY, AND ALL WARRANTIES, WHETHER
|
||||
EXPRESSED OR IMPLIED, INCLUDING MERCHANTABILITY AND FITNESS FOR PURPOSE, ARE
|
||||
DISCLAIMED.
|
||||
|
||||
==============================================================================
|
||||
*/
|
||||
|
||||
#include <juce_core/system/juce_TargetPlatform.h>
|
||||
#include "../utility/juce_CheckSettingMacros.h"
|
||||
|
||||
#include "../utility/juce_IncludeSystemHeaders.h"
|
||||
#include "../utility/juce_IncludeModuleHeaders.h"
|
||||
#include "../utility/juce_FakeMouseMoveGenerator.h"
|
||||
#include "../utility/juce_WindowsHooks.h"
|
||||
|
||||
#include <juce_audio_devices/juce_audio_devices.h>
|
||||
#include <juce_gui_extra/juce_gui_extra.h>
|
||||
#include <juce_audio_utils/juce_audio_utils.h>
|
||||
|
||||
// You can set this flag in your build if you need to specify a different
|
||||
// standalone JUCEApplication class for your app to use. If you don't
|
||||
// set it then by default we'll just create a simple one as below.
|
||||
#if ! JUCE_USE_CUSTOM_PLUGIN_STANDALONE_APP
|
||||
|
||||
#include "juce_StandaloneFilterWindow.h"
|
||||
|
||||
namespace juce
|
||||
{
|
||||
|
||||
//==============================================================================
|
||||
class StandaloneFilterApp : public JUCEApplication
|
||||
{
|
||||
public:
|
||||
StandaloneFilterApp()
|
||||
{
|
||||
PluginHostType::jucePlugInClientCurrentWrapperType = AudioProcessor::wrapperType_Standalone;
|
||||
|
||||
PropertiesFile::Options options;
|
||||
|
||||
options.applicationName = getApplicationName();
|
||||
options.filenameSuffix = ".settings";
|
||||
options.osxLibrarySubFolder = "Application Support";
|
||||
#if JUCE_LINUX || JUCE_BSD
|
||||
options.folderName = "~/.config";
|
||||
#else
|
||||
options.folderName = "";
|
||||
#endif
|
||||
|
||||
appProperties.setStorageParameters (options);
|
||||
}
|
||||
|
||||
const String getApplicationName() override { return CharPointer_UTF8 (JucePlugin_Name); }
|
||||
const String getApplicationVersion() override { return JucePlugin_VersionString; }
|
||||
bool moreThanOneInstanceAllowed() override { return true; }
|
||||
void anotherInstanceStarted (const String&) override {}
|
||||
|
||||
virtual StandaloneFilterWindow* createWindow()
|
||||
{
|
||||
#ifdef JucePlugin_PreferredChannelConfigurations
|
||||
StandalonePluginHolder::PluginInOuts channels[] = { JucePlugin_PreferredChannelConfigurations };
|
||||
#endif
|
||||
|
||||
return new StandaloneFilterWindow (getApplicationName(),
|
||||
LookAndFeel::getDefaultLookAndFeel().findColour (ResizableWindow::backgroundColourId),
|
||||
appProperties.getUserSettings(),
|
||||
false, {}, nullptr
|
||||
#ifdef JucePlugin_PreferredChannelConfigurations
|
||||
, juce::Array<StandalonePluginHolder::PluginInOuts> (channels, juce::numElementsInArray (channels))
|
||||
#else
|
||||
, {}
|
||||
#endif
|
||||
#if JUCE_DONT_AUTO_OPEN_MIDI_DEVICES_ON_MOBILE
|
||||
, false
|
||||
#endif
|
||||
);
|
||||
}
|
||||
|
||||
//==============================================================================
|
||||
void initialise (const String&) override
|
||||
{
|
||||
mainWindow.reset (createWindow());
|
||||
|
||||
#if JUCE_STANDALONE_FILTER_WINDOW_USE_KIOSK_MODE
|
||||
Desktop::getInstance().setKioskModeComponent (mainWindow.get(), false);
|
||||
#endif
|
||||
|
||||
mainWindow->setVisible (true);
|
||||
}
|
||||
|
||||
void shutdown() override
|
||||
{
|
||||
mainWindow = nullptr;
|
||||
appProperties.saveIfNeeded();
|
||||
}
|
||||
|
||||
//==============================================================================
|
||||
void systemRequestedQuit() override
|
||||
{
|
||||
if (mainWindow.get() != nullptr)
|
||||
mainWindow->pluginHolder->savePluginState();
|
||||
|
||||
if (ModalComponentManager::getInstance()->cancelAllModalComponents())
|
||||
{
|
||||
Timer::callAfterDelay (100, []()
|
||||
{
|
||||
if (auto app = JUCEApplicationBase::getInstance())
|
||||
app->systemRequestedQuit();
|
||||
});
|
||||
}
|
||||
else
|
||||
{
|
||||
quit();
|
||||
}
|
||||
}
|
||||
|
||||
protected:
|
||||
ApplicationProperties appProperties;
|
||||
std::unique_ptr<StandaloneFilterWindow> mainWindow;
|
||||
};
|
||||
|
||||
} // namespace juce
|
||||
|
||||
#if JucePlugin_Build_Standalone && JUCE_IOS
|
||||
|
||||
using namespace juce;
|
||||
|
||||
bool JUCE_CALLTYPE juce_isInterAppAudioConnected()
|
||||
{
|
||||
if (auto holder = StandalonePluginHolder::getInstance())
|
||||
return holder->isInterAppAudioConnected();
|
||||
|
||||
return false;
|
||||
}
|
||||
|
||||
void JUCE_CALLTYPE juce_switchToHostApplication()
|
||||
{
|
||||
if (auto holder = StandalonePluginHolder::getInstance())
|
||||
holder->switchToHostApplication();
|
||||
}
|
||||
|
||||
Image JUCE_CALLTYPE juce_getIAAHostIcon (int size)
|
||||
{
|
||||
if (auto holder = StandalonePluginHolder::getInstance())
|
||||
return holder->getIAAHostIcon (size);
|
||||
|
||||
return Image();
|
||||
}
|
||||
#endif
|
||||
|
||||
#endif
|
||||
/*
|
||||
==============================================================================
|
||||
|
||||
This file is part of the JUCE library.
|
||||
Copyright (c) 2022 - Raw Material Software Limited
|
||||
|
||||
JUCE is an open source library subject to commercial or open-source
|
||||
licensing.
|
||||
|
||||
By using JUCE, you agree to the terms of both the JUCE 7 End-User License
|
||||
Agreement and JUCE Privacy Policy.
|
||||
|
||||
End User License Agreement: www.juce.com/juce-7-licence
|
||||
Privacy Policy: www.juce.com/juce-privacy-policy
|
||||
|
||||
Or: You may also use this code under the terms of the GPL v3 (see
|
||||
www.gnu.org/licenses).
|
||||
|
||||
JUCE IS PROVIDED "AS IS" WITHOUT ANY WARRANTY, AND ALL WARRANTIES, WHETHER
|
||||
EXPRESSED OR IMPLIED, INCLUDING MERCHANTABILITY AND FITNESS FOR PURPOSE, ARE
|
||||
DISCLAIMED.
|
||||
|
||||
==============================================================================
|
||||
*/
|
||||
|
||||
#include <juce_core/system/juce_TargetPlatform.h>
|
||||
#include "../utility/juce_CheckSettingMacros.h"
|
||||
|
||||
#include "../utility/juce_IncludeSystemHeaders.h"
|
||||
#include "../utility/juce_IncludeModuleHeaders.h"
|
||||
#include "../utility/juce_WindowsHooks.h"
|
||||
|
||||
#include <juce_audio_devices/juce_audio_devices.h>
|
||||
#include <juce_gui_extra/juce_gui_extra.h>
|
||||
#include <juce_audio_utils/juce_audio_utils.h>
|
||||
|
||||
// You can set this flag in your build if you need to specify a different
|
||||
// standalone JUCEApplication class for your app to use. If you don't
|
||||
// set it then by default we'll just create a simple one as below.
|
||||
#if ! JUCE_USE_CUSTOM_PLUGIN_STANDALONE_APP
|
||||
|
||||
#include "juce_StandaloneFilterWindow.h"
|
||||
|
||||
namespace juce
|
||||
{
|
||||
|
||||
//==============================================================================
|
||||
class StandaloneFilterApp : public JUCEApplication
|
||||
{
|
||||
public:
|
||||
StandaloneFilterApp()
|
||||
{
|
||||
PluginHostType::jucePlugInClientCurrentWrapperType = AudioProcessor::wrapperType_Standalone;
|
||||
|
||||
PropertiesFile::Options options;
|
||||
|
||||
options.applicationName = getApplicationName();
|
||||
options.filenameSuffix = ".settings";
|
||||
options.osxLibrarySubFolder = "Application Support";
|
||||
#if JUCE_LINUX || JUCE_BSD
|
||||
options.folderName = "~/.config";
|
||||
#else
|
||||
options.folderName = "";
|
||||
#endif
|
||||
|
||||
appProperties.setStorageParameters (options);
|
||||
}
|
||||
|
||||
const String getApplicationName() override { return CharPointer_UTF8 (JucePlugin_Name); }
|
||||
const String getApplicationVersion() override { return JucePlugin_VersionString; }
|
||||
bool moreThanOneInstanceAllowed() override { return true; }
|
||||
void anotherInstanceStarted (const String&) override {}
|
||||
|
||||
virtual StandaloneFilterWindow* createWindow()
|
||||
{
|
||||
#ifdef JucePlugin_PreferredChannelConfigurations
|
||||
StandalonePluginHolder::PluginInOuts channels[] = { JucePlugin_PreferredChannelConfigurations };
|
||||
#endif
|
||||
|
||||
return new StandaloneFilterWindow (getApplicationName(),
|
||||
LookAndFeel::getDefaultLookAndFeel().findColour (ResizableWindow::backgroundColourId),
|
||||
appProperties.getUserSettings(),
|
||||
false, {}, nullptr
|
||||
#ifdef JucePlugin_PreferredChannelConfigurations
|
||||
, juce::Array<StandalonePluginHolder::PluginInOuts> (channels, juce::numElementsInArray (channels))
|
||||
#else
|
||||
, {}
|
||||
#endif
|
||||
#if JUCE_DONT_AUTO_OPEN_MIDI_DEVICES_ON_MOBILE
|
||||
, false
|
||||
#endif
|
||||
);
|
||||
}
|
||||
|
||||
//==============================================================================
|
||||
void initialise (const String&) override
|
||||
{
|
||||
mainWindow.reset (createWindow());
|
||||
|
||||
#if JUCE_STANDALONE_FILTER_WINDOW_USE_KIOSK_MODE
|
||||
Desktop::getInstance().setKioskModeComponent (mainWindow.get(), false);
|
||||
#endif
|
||||
|
||||
mainWindow->setVisible (true);
|
||||
}
|
||||
|
||||
void shutdown() override
|
||||
{
|
||||
mainWindow = nullptr;
|
||||
appProperties.saveIfNeeded();
|
||||
}
|
||||
|
||||
//==============================================================================
|
||||
void systemRequestedQuit() override
|
||||
{
|
||||
if (mainWindow.get() != nullptr)
|
||||
mainWindow->pluginHolder->savePluginState();
|
||||
|
||||
if (ModalComponentManager::getInstance()->cancelAllModalComponents())
|
||||
{
|
||||
Timer::callAfterDelay (100, []()
|
||||
{
|
||||
if (auto app = JUCEApplicationBase::getInstance())
|
||||
app->systemRequestedQuit();
|
||||
});
|
||||
}
|
||||
else
|
||||
{
|
||||
quit();
|
||||
}
|
||||
}
|
||||
|
||||
protected:
|
||||
ApplicationProperties appProperties;
|
||||
std::unique_ptr<StandaloneFilterWindow> mainWindow;
|
||||
};
|
||||
|
||||
} // namespace juce
|
||||
|
||||
#if JucePlugin_Build_Standalone && JUCE_IOS
|
||||
|
||||
JUCE_BEGIN_IGNORE_WARNINGS_GCC_LIKE ("-Wmissing-prototypes")
|
||||
|
||||
using namespace juce;
|
||||
|
||||
bool JUCE_CALLTYPE juce_isInterAppAudioConnected()
|
||||
{
|
||||
if (auto holder = StandalonePluginHolder::getInstance())
|
||||
return holder->isInterAppAudioConnected();
|
||||
|
||||
return false;
|
||||
}
|
||||
|
||||
void JUCE_CALLTYPE juce_switchToHostApplication()
|
||||
{
|
||||
if (auto holder = StandalonePluginHolder::getInstance())
|
||||
holder->switchToHostApplication();
|
||||
}
|
||||
|
||||
Image JUCE_CALLTYPE juce_getIAAHostIcon (int size)
|
||||
{
|
||||
if (auto holder = StandalonePluginHolder::getInstance())
|
||||
return holder->getIAAHostIcon (size);
|
||||
|
||||
return Image();
|
||||
}
|
||||
|
||||
JUCE_END_IGNORE_WARNINGS_GCC_LIKE
|
||||
|
||||
#endif
|
||||
|
||||
#endif
|
||||
|
||||
File diff suppressed because it is too large
Load Diff
@@ -1,194 +1,194 @@
|
||||
/*
|
||||
==============================================================================
|
||||
|
||||
This file is part of the JUCE library.
|
||||
Copyright (c) 2020 - Raw Material Software Limited
|
||||
|
||||
JUCE is an open source library subject to commercial or open-source
|
||||
licensing.
|
||||
|
||||
By using JUCE, you agree to the terms of both the JUCE 6 End-User License
|
||||
Agreement and JUCE Privacy Policy (both effective as of the 16th June 2020).
|
||||
|
||||
End User License Agreement: www.juce.com/juce-6-licence
|
||||
Privacy Policy: www.juce.com/juce-privacy-policy
|
||||
|
||||
Or: You may also use this code under the terms of the GPL v3 (see
|
||||
www.gnu.org/licenses).
|
||||
|
||||
JUCE IS PROVIDED "AS IS" WITHOUT ANY WARRANTY, AND ALL WARRANTIES, WHETHER
|
||||
EXPRESSED OR IMPLIED, INCLUDING MERCHANTABILITY AND FITNESS FOR PURPOSE, ARE
|
||||
DISCLAIMED.
|
||||
|
||||
==============================================================================
|
||||
*/
|
||||
|
||||
#pragma once
|
||||
|
||||
|
||||
//==============================================================================
|
||||
#define UNITY_AUDIO_PLUGIN_API_VERSION 0x010401
|
||||
|
||||
#if JUCE_MSVC
|
||||
#define UNITY_INTERFACE_API __stdcall
|
||||
#define UNITY_INTERFACE_EXPORT __declspec(dllexport)
|
||||
#else
|
||||
#define UNITY_INTERFACE_API
|
||||
#define UNITY_INTERFACE_EXPORT __attribute__ ((visibility("default")))
|
||||
#endif
|
||||
|
||||
//==============================================================================
|
||||
struct UnityAudioEffectState;
|
||||
|
||||
typedef int (UNITY_INTERFACE_API * createCallback) (UnityAudioEffectState* state);
|
||||
typedef int (UNITY_INTERFACE_API * releaseCallback) (UnityAudioEffectState* state);
|
||||
typedef int (UNITY_INTERFACE_API * resetCallback) (UnityAudioEffectState* state);
|
||||
|
||||
typedef int (UNITY_INTERFACE_API * processCallback) (UnityAudioEffectState* state, float* inBuffer, float* outBuffer, unsigned int bufferSize,
|
||||
int numInChannels, int numOutChannels);
|
||||
|
||||
typedef int (UNITY_INTERFACE_API * setPositionCallback) (UnityAudioEffectState* state, unsigned int pos);
|
||||
|
||||
typedef int (UNITY_INTERFACE_API * setFloatParameterCallback) (UnityAudioEffectState* state, int index, float value);
|
||||
typedef int (UNITY_INTERFACE_API * getFloatParameterCallback) (UnityAudioEffectState* state, int index, float* value, char* valuestr);
|
||||
typedef int (UNITY_INTERFACE_API * getFloatBufferCallback) (UnityAudioEffectState* state, const char* name, float* buffer, int numsamples);
|
||||
|
||||
typedef int (UNITY_INTERFACE_API * distanceAttenuationCallback) (UnityAudioEffectState* state, float distanceIn, float attenuationIn, float* attenuationOut);
|
||||
|
||||
typedef void (UNITY_INTERFACE_API * renderCallback) (int eventId);
|
||||
|
||||
//==============================================================================
|
||||
enum UnityAudioEffectDefinitionFlags
|
||||
{
|
||||
isSideChainTarget = 1,
|
||||
isSpatializer = 2,
|
||||
isAmbisonicDecoder = 4,
|
||||
appliesDistanceAttenuation = 8
|
||||
};
|
||||
|
||||
enum UnityAudioEffectStateFlags
|
||||
{
|
||||
stateIsPlaying = 1,
|
||||
stateIsPaused = 2,
|
||||
stateIsMuted = 8,
|
||||
statIsSideChainTarget = 16
|
||||
};
|
||||
|
||||
enum UnityEventModifiers
|
||||
{
|
||||
shift = 1,
|
||||
control = 2,
|
||||
alt = 4,
|
||||
command = 8,
|
||||
numeric = 16,
|
||||
capsLock = 32,
|
||||
functionKey = 64
|
||||
};
|
||||
|
||||
//==============================================================================
|
||||
#ifndef DOXYGEN
|
||||
|
||||
struct UnityAudioSpatializerData
|
||||
{
|
||||
float listenerMatrix[16];
|
||||
float sourceMatrix[16];
|
||||
float spatialBlend;
|
||||
float reverbZoneMix;
|
||||
float spread;
|
||||
float stereoPan;
|
||||
distanceAttenuationCallback attenuationCallback;
|
||||
float minDistance;
|
||||
float maxDistance;
|
||||
};
|
||||
|
||||
struct UnityAudioAmbisonicData
|
||||
{
|
||||
float listenerMatrix[16];
|
||||
float sourceMatrix[16];
|
||||
float spatialBlend;
|
||||
float reverbZoneMix;
|
||||
float spread;
|
||||
float stereoPan;
|
||||
distanceAttenuationCallback attenuationCallback;
|
||||
int ambisonicOutChannels;
|
||||
float volume;
|
||||
};
|
||||
|
||||
struct UnityAudioEffectState
|
||||
{
|
||||
juce::uint32 structSize;
|
||||
juce::uint32 sampleRate;
|
||||
juce::uint64 dspCurrentTick;
|
||||
juce::uint64 dspPreviousTick;
|
||||
float* sidechainBuffer;
|
||||
void* effectData;
|
||||
juce::uint32 flags;
|
||||
void* internal;
|
||||
|
||||
UnityAudioSpatializerData* spatializerData;
|
||||
juce::uint32 dspBufferSize;
|
||||
juce::uint32 hostAPIVersion;
|
||||
|
||||
UnityAudioAmbisonicData* ambisonicData;
|
||||
|
||||
template <typename T>
|
||||
inline T* getEffectData() const
|
||||
{
|
||||
jassert (effectData != nullptr);
|
||||
jassert (internal != nullptr);
|
||||
|
||||
return (T*) effectData;
|
||||
}
|
||||
};
|
||||
|
||||
struct UnityAudioParameterDefinition
|
||||
{
|
||||
char name[16];
|
||||
char unit[16];
|
||||
const char* description;
|
||||
float min;
|
||||
float max;
|
||||
float defaultVal;
|
||||
float displayScale;
|
||||
float displayExponent;
|
||||
};
|
||||
|
||||
struct UnityAudioEffectDefinition
|
||||
{
|
||||
juce::uint32 structSize;
|
||||
juce::uint32 parameterStructSize;
|
||||
juce::uint32 apiVersion;
|
||||
juce::uint32 pluginVersion;
|
||||
juce::uint32 channels;
|
||||
juce::uint32 numParameters;
|
||||
juce::uint64 flags;
|
||||
char name[32];
|
||||
createCallback create;
|
||||
releaseCallback release;
|
||||
resetCallback reset;
|
||||
processCallback process;
|
||||
setPositionCallback setPosition;
|
||||
UnityAudioParameterDefinition* parameterDefintions;
|
||||
setFloatParameterCallback setFloatParameter;
|
||||
getFloatParameterCallback getFloatParameter;
|
||||
getFloatBufferCallback getFloatBuffer;
|
||||
};
|
||||
|
||||
#endif
|
||||
|
||||
//==============================================================================
|
||||
// Unity callback
|
||||
extern "C" UNITY_INTERFACE_EXPORT int UNITY_INTERFACE_API UnityGetAudioEffectDefinitions (UnityAudioEffectDefinition*** definitionsPtr);
|
||||
|
||||
// GUI script callbacks
|
||||
extern "C" UNITY_INTERFACE_EXPORT renderCallback UNITY_INTERFACE_API getRenderCallback();
|
||||
|
||||
extern "C" UNITY_INTERFACE_EXPORT void UNITY_INTERFACE_API unityInitialiseTexture (int id, void* textureHandle, int w, int h);
|
||||
|
||||
extern "C" UNITY_INTERFACE_EXPORT void UNITY_INTERFACE_API unityMouseDown (int id, float x, float y, UnityEventModifiers mods, int button);
|
||||
extern "C" UNITY_INTERFACE_EXPORT void UNITY_INTERFACE_API unityMouseDrag (int id, float x, float y, UnityEventModifiers mods, int button);
|
||||
extern "C" UNITY_INTERFACE_EXPORT void UNITY_INTERFACE_API unityMouseUp (int id, float x, float y, UnityEventModifiers mods);
|
||||
|
||||
extern "C" UNITY_INTERFACE_EXPORT void UNITY_INTERFACE_API unityKeyEvent (int id, int code, UnityEventModifiers mods, const char* name);
|
||||
|
||||
extern "C" UNITY_INTERFACE_EXPORT void UNITY_INTERFACE_API unitySetScreenBounds (int id, float x, float y, float w, float h);
|
||||
/*
|
||||
==============================================================================
|
||||
|
||||
This file is part of the JUCE library.
|
||||
Copyright (c) 2022 - Raw Material Software Limited
|
||||
|
||||
JUCE is an open source library subject to commercial or open-source
|
||||
licensing.
|
||||
|
||||
By using JUCE, you agree to the terms of both the JUCE 7 End-User License
|
||||
Agreement and JUCE Privacy Policy.
|
||||
|
||||
End User License Agreement: www.juce.com/juce-7-licence
|
||||
Privacy Policy: www.juce.com/juce-privacy-policy
|
||||
|
||||
Or: You may also use this code under the terms of the GPL v3 (see
|
||||
www.gnu.org/licenses).
|
||||
|
||||
JUCE IS PROVIDED "AS IS" WITHOUT ANY WARRANTY, AND ALL WARRANTIES, WHETHER
|
||||
EXPRESSED OR IMPLIED, INCLUDING MERCHANTABILITY AND FITNESS FOR PURPOSE, ARE
|
||||
DISCLAIMED.
|
||||
|
||||
==============================================================================
|
||||
*/
|
||||
|
||||
#pragma once
|
||||
|
||||
|
||||
//==============================================================================
|
||||
#define UNITY_AUDIO_PLUGIN_API_VERSION 0x010401
|
||||
|
||||
#if JUCE_MSVC
|
||||
#define UNITY_INTERFACE_API __stdcall
|
||||
#define UNITY_INTERFACE_EXPORT __declspec(dllexport)
|
||||
#else
|
||||
#define UNITY_INTERFACE_API
|
||||
#define UNITY_INTERFACE_EXPORT __attribute__ ((visibility("default")))
|
||||
#endif
|
||||
|
||||
//==============================================================================
|
||||
struct UnityAudioEffectState;
|
||||
|
||||
typedef int (UNITY_INTERFACE_API * createCallback) (UnityAudioEffectState* state);
|
||||
typedef int (UNITY_INTERFACE_API * releaseCallback) (UnityAudioEffectState* state);
|
||||
typedef int (UNITY_INTERFACE_API * resetCallback) (UnityAudioEffectState* state);
|
||||
|
||||
typedef int (UNITY_INTERFACE_API * processCallback) (UnityAudioEffectState* state, float* inBuffer, float* outBuffer, unsigned int bufferSize,
|
||||
int numInChannels, int numOutChannels);
|
||||
|
||||
typedef int (UNITY_INTERFACE_API * setPositionCallback) (UnityAudioEffectState* state, unsigned int pos);
|
||||
|
||||
typedef int (UNITY_INTERFACE_API * setFloatParameterCallback) (UnityAudioEffectState* state, int index, float value);
|
||||
typedef int (UNITY_INTERFACE_API * getFloatParameterCallback) (UnityAudioEffectState* state, int index, float* value, char* valuestr);
|
||||
typedef int (UNITY_INTERFACE_API * getFloatBufferCallback) (UnityAudioEffectState* state, const char* name, float* buffer, int numsamples);
|
||||
|
||||
typedef int (UNITY_INTERFACE_API * distanceAttenuationCallback) (UnityAudioEffectState* state, float distanceIn, float attenuationIn, float* attenuationOut);
|
||||
|
||||
typedef void (UNITY_INTERFACE_API * renderCallback) (int eventId);
|
||||
|
||||
//==============================================================================
|
||||
enum UnityAudioEffectDefinitionFlags
|
||||
{
|
||||
isSideChainTarget = 1,
|
||||
isSpatializer = 2,
|
||||
isAmbisonicDecoder = 4,
|
||||
appliesDistanceAttenuation = 8
|
||||
};
|
||||
|
||||
enum UnityAudioEffectStateFlags
|
||||
{
|
||||
stateIsPlaying = 1,
|
||||
stateIsPaused = 2,
|
||||
stateIsMuted = 8,
|
||||
statIsSideChainTarget = 16
|
||||
};
|
||||
|
||||
enum UnityEventModifiers
|
||||
{
|
||||
shift = 1,
|
||||
control = 2,
|
||||
alt = 4,
|
||||
command = 8,
|
||||
numeric = 16,
|
||||
capsLock = 32,
|
||||
functionKey = 64
|
||||
};
|
||||
|
||||
//==============================================================================
|
||||
#ifndef DOXYGEN
|
||||
|
||||
struct UnityAudioSpatializerData
|
||||
{
|
||||
float listenerMatrix[16];
|
||||
float sourceMatrix[16];
|
||||
float spatialBlend;
|
||||
float reverbZoneMix;
|
||||
float spread;
|
||||
float stereoPan;
|
||||
distanceAttenuationCallback attenuationCallback;
|
||||
float minDistance;
|
||||
float maxDistance;
|
||||
};
|
||||
|
||||
struct UnityAudioAmbisonicData
|
||||
{
|
||||
float listenerMatrix[16];
|
||||
float sourceMatrix[16];
|
||||
float spatialBlend;
|
||||
float reverbZoneMix;
|
||||
float spread;
|
||||
float stereoPan;
|
||||
distanceAttenuationCallback attenuationCallback;
|
||||
int ambisonicOutChannels;
|
||||
float volume;
|
||||
};
|
||||
|
||||
struct UnityAudioEffectState
|
||||
{
|
||||
juce::uint32 structSize;
|
||||
juce::uint32 sampleRate;
|
||||
juce::uint64 dspCurrentTick;
|
||||
juce::uint64 dspPreviousTick;
|
||||
float* sidechainBuffer;
|
||||
void* effectData;
|
||||
juce::uint32 flags;
|
||||
void* internal;
|
||||
|
||||
UnityAudioSpatializerData* spatializerData;
|
||||
juce::uint32 dspBufferSize;
|
||||
juce::uint32 hostAPIVersion;
|
||||
|
||||
UnityAudioAmbisonicData* ambisonicData;
|
||||
|
||||
template <typename T>
|
||||
inline T* getEffectData() const
|
||||
{
|
||||
jassert (effectData != nullptr);
|
||||
jassert (internal != nullptr);
|
||||
|
||||
return (T*) effectData;
|
||||
}
|
||||
};
|
||||
|
||||
struct UnityAudioParameterDefinition
|
||||
{
|
||||
char name[16];
|
||||
char unit[16];
|
||||
const char* description;
|
||||
float min;
|
||||
float max;
|
||||
float defaultVal;
|
||||
float displayScale;
|
||||
float displayExponent;
|
||||
};
|
||||
|
||||
struct UnityAudioEffectDefinition
|
||||
{
|
||||
juce::uint32 structSize;
|
||||
juce::uint32 parameterStructSize;
|
||||
juce::uint32 apiVersion;
|
||||
juce::uint32 pluginVersion;
|
||||
juce::uint32 channels;
|
||||
juce::uint32 numParameters;
|
||||
juce::uint64 flags;
|
||||
char name[32];
|
||||
createCallback create;
|
||||
releaseCallback release;
|
||||
resetCallback reset;
|
||||
processCallback process;
|
||||
setPositionCallback setPosition;
|
||||
UnityAudioParameterDefinition* parameterDefintions;
|
||||
setFloatParameterCallback setFloatParameter;
|
||||
getFloatParameterCallback getFloatParameter;
|
||||
getFloatBufferCallback getFloatBuffer;
|
||||
};
|
||||
|
||||
#endif
|
||||
|
||||
//==============================================================================
|
||||
// Unity callback
|
||||
extern "C" UNITY_INTERFACE_EXPORT int UNITY_INTERFACE_API UnityGetAudioEffectDefinitions (UnityAudioEffectDefinition*** definitionsPtr);
|
||||
|
||||
// GUI script callbacks
|
||||
extern "C" UNITY_INTERFACE_EXPORT renderCallback UNITY_INTERFACE_API getRenderCallback();
|
||||
|
||||
extern "C" UNITY_INTERFACE_EXPORT void UNITY_INTERFACE_API unityInitialiseTexture (int id, void* textureHandle, int w, int h);
|
||||
|
||||
extern "C" UNITY_INTERFACE_EXPORT void UNITY_INTERFACE_API unityMouseDown (int id, float x, float y, UnityEventModifiers mods, int button);
|
||||
extern "C" UNITY_INTERFACE_EXPORT void UNITY_INTERFACE_API unityMouseDrag (int id, float x, float y, UnityEventModifiers mods, int button);
|
||||
extern "C" UNITY_INTERFACE_EXPORT void UNITY_INTERFACE_API unityMouseUp (int id, float x, float y, UnityEventModifiers mods);
|
||||
|
||||
extern "C" UNITY_INTERFACE_EXPORT void UNITY_INTERFACE_API unityKeyEvent (int id, int code, UnityEventModifiers mods, const char* name);
|
||||
|
||||
extern "C" UNITY_INTERFACE_EXPORT void UNITY_INTERFACE_API unitySetScreenBounds (int id, float x, float y, float w, float h);
|
||||
|
||||
File diff suppressed because it is too large
Load Diff
File diff suppressed because it is too large
Load Diff
@@ -2,15 +2,15 @@
|
||||
==============================================================================
|
||||
|
||||
This file is part of the JUCE library.
|
||||
Copyright (c) 2020 - Raw Material Software Limited
|
||||
Copyright (c) 2022 - Raw Material Software Limited
|
||||
|
||||
JUCE is an open source library subject to commercial or open-source
|
||||
licensing.
|
||||
|
||||
By using JUCE, you agree to the terms of both the JUCE 6 End-User License
|
||||
Agreement and JUCE Privacy Policy (both effective as of the 16th June 2020).
|
||||
By using JUCE, you agree to the terms of both the JUCE 7 End-User License
|
||||
Agreement and JUCE Privacy Policy.
|
||||
|
||||
End User License Agreement: www.juce.com/juce-6-licence
|
||||
End User License Agreement: www.juce.com/juce-7-licence
|
||||
Privacy Policy: www.juce.com/juce-privacy-policy
|
||||
|
||||
Or: You may also use this code under the terms of the GPL v3 (see
|
||||
@@ -31,12 +31,8 @@
|
||||
|
||||
#if JucePlugin_Build_VST || JucePlugin_Build_VST3
|
||||
|
||||
#define JUCE_MAC_WINDOW_VISIBITY_BODGE 1
|
||||
|
||||
#include "../utility/juce_IncludeSystemHeaders.h"
|
||||
#include "../utility/juce_IncludeModuleHeaders.h"
|
||||
#include "../utility/juce_FakeMouseMoveGenerator.h"
|
||||
#include "../utility/juce_CarbonVisibility.h"
|
||||
|
||||
//==============================================================================
|
||||
namespace juce
|
||||
@@ -161,8 +157,6 @@ void* attachComponentToWindowRefVST (Component* comp, void* parentWindowOrView,
|
||||
[hostWindow orderFront: nil];
|
||||
[pluginWindow orderFront: nil];
|
||||
|
||||
attachWindowHidingHooks (comp, (WindowRef) parentWindowOrView, hostWindow);
|
||||
|
||||
return hostWindow;
|
||||
}
|
||||
#endif
|
||||
@@ -200,8 +194,6 @@ void detachComponentFromWindowRefVST (Component* comp, void* window, bool isNSVi
|
||||
comp->getProperties() ["boundsEventRef"].toString().getHexValue64();
|
||||
RemoveEventHandler (ref);
|
||||
|
||||
removeWindowHidingHooks (comp);
|
||||
|
||||
CFUniquePtr<HIViewRef> dummyView ((HIViewRef) (void*) (pointer_sized_int)
|
||||
comp->getProperties() ["dummyViewRef"].toString().getHexValue64());
|
||||
|
||||
|
||||
File diff suppressed because it is too large
Load Diff
@@ -1,130 +1,130 @@
|
||||
/*
|
||||
==============================================================================
|
||||
|
||||
This file is part of the JUCE library.
|
||||
Copyright (c) 2020 - Raw Material Software Limited
|
||||
|
||||
JUCE is an open source library subject to commercial or open-source
|
||||
licensing.
|
||||
|
||||
By using JUCE, you agree to the terms of both the JUCE 6 End-User License
|
||||
Agreement and JUCE Privacy Policy (both effective as of the 16th June 2020).
|
||||
|
||||
End User License Agreement: www.juce.com/juce-6-licence
|
||||
Privacy Policy: www.juce.com/juce-privacy-policy
|
||||
|
||||
Or: You may also use this code under the terms of the GPL v3 (see
|
||||
www.gnu.org/licenses).
|
||||
|
||||
JUCE IS PROVIDED "AS IS" WITHOUT ANY WARRANTY, AND ALL WARRANTIES, WHETHER
|
||||
EXPRESSED OR IMPLIED, INCLUDING MERCHANTABILITY AND FITNESS FOR PURPOSE, ARE
|
||||
DISCLAIMED.
|
||||
|
||||
==============================================================================
|
||||
*/
|
||||
|
||||
|
||||
/*******************************************************************************
|
||||
The block below describes the properties of this module, and is read by
|
||||
the Projucer to automatically generate project code that uses it.
|
||||
For details about the syntax and how to create or use a module, see the
|
||||
JUCE Module Format.md file.
|
||||
|
||||
|
||||
BEGIN_JUCE_MODULE_DECLARATION
|
||||
|
||||
ID: juce_audio_plugin_client
|
||||
vendor: juce
|
||||
version: 6.1.2
|
||||
name: JUCE audio plugin wrapper classes
|
||||
description: Classes for building VST, VST3, AudioUnit, AAX and RTAS plugins.
|
||||
website: http://www.juce.com/juce
|
||||
license: GPL/Commercial
|
||||
minimumCppStandard: 14
|
||||
|
||||
dependencies: juce_audio_processors
|
||||
|
||||
END_JUCE_MODULE_DECLARATION
|
||||
|
||||
*******************************************************************************/
|
||||
|
||||
|
||||
#pragma once
|
||||
|
||||
#include <juce_gui_basics/juce_gui_basics.h>
|
||||
#include <juce_audio_basics/juce_audio_basics.h>
|
||||
#include <juce_audio_processors/juce_audio_processors.h>
|
||||
|
||||
/** Config: JUCE_VST3_CAN_REPLACE_VST2
|
||||
|
||||
Enable this if you want your VST3 plug-in to load and save VST2 compatible
|
||||
state. This allows hosts to replace VST2 plug-ins with VST3 plug-ins. If
|
||||
you change this option then your VST3 plug-in will be incompatible with
|
||||
previous versions.
|
||||
*/
|
||||
#ifndef JUCE_VST3_CAN_REPLACE_VST2
|
||||
#define JUCE_VST3_CAN_REPLACE_VST2 1
|
||||
#endif
|
||||
|
||||
/** Config: JUCE_FORCE_USE_LEGACY_PARAM_IDS
|
||||
|
||||
Enable this if you want to force JUCE to use a continuous parameter
|
||||
index to identify a parameter in a DAW (this was the default in old
|
||||
versions of JUCE). This is index is usually used by the DAW to save
|
||||
automation data and enabling this may mess up user's DAW projects.
|
||||
*/
|
||||
#ifndef JUCE_FORCE_USE_LEGACY_PARAM_IDS
|
||||
#define JUCE_FORCE_USE_LEGACY_PARAM_IDS 0
|
||||
#endif
|
||||
|
||||
/** Config: JUCE_FORCE_LEGACY_PARAMETER_AUTOMATION_TYPE
|
||||
|
||||
Enable this if you want to force JUCE to use a legacy scheme for
|
||||
identifying plug-in parameters as either continuous or discrete.
|
||||
DAW projects with automation data written by an AudioUnit, VST3 or
|
||||
AAX plug-in built with JUCE version 5.1.1 or earlier may load
|
||||
incorrectly when opened by an AudioUnit, VST3 or AAX plug-in built
|
||||
with JUCE version 5.2.0 and later.
|
||||
*/
|
||||
#ifndef JUCE_FORCE_LEGACY_PARAMETER_AUTOMATION_TYPE
|
||||
#define JUCE_FORCE_LEGACY_PARAMETER_AUTOMATION_TYPE 0
|
||||
#endif
|
||||
|
||||
/** Config: JUCE_USE_STUDIO_ONE_COMPATIBLE_PARAMETERS
|
||||
|
||||
Enable this if you want JUCE to use parameter ids which are compatible
|
||||
with Studio One, as Studio One ignores any parameter ids which are negative.
|
||||
Enabling this option will make JUCE generate only positive parameter ids.
|
||||
Note that if you have already released a plug-in prior to JUCE 4.3.0 then
|
||||
enabling this will change your parameter ids, making your plug-in
|
||||
incompatible with old automation data.
|
||||
*/
|
||||
#ifndef JUCE_USE_STUDIO_ONE_COMPATIBLE_PARAMETERS
|
||||
#define JUCE_USE_STUDIO_ONE_COMPATIBLE_PARAMETERS 1
|
||||
#endif
|
||||
|
||||
/** Config: JUCE_AU_WRAPPERS_SAVE_PROGRAM_STATES
|
||||
|
||||
Enable this if you want to receive get/setProgramStateInformation calls,
|
||||
instead of get/setStateInformation calls, from the AU and AUv3 plug-in
|
||||
wrappers. In JUCE version 5.4.5 and earlier this was the default behaviour,
|
||||
so if you have modified the default implementations of get/setProgramStateInformation
|
||||
(where the default implementations simply call through to get/setStateInformation)
|
||||
then you may need to enable this configuration option to maintain backwards
|
||||
compatibility with previously saved state.
|
||||
*/
|
||||
#ifndef JUCE_AU_WRAPPERS_SAVE_PROGRAM_STATES
|
||||
#define JUCE_AU_WRAPPERS_SAVE_PROGRAM_STATES 0
|
||||
#endif
|
||||
|
||||
/** Config: JUCE_STANDALONE_FILTER_WINDOW_USE_KIOSK_MODE
|
||||
|
||||
Enable this if you want your standalone plugin window to use kiosk mode.
|
||||
By default, kiosk mode is enabled on iOS and Android.
|
||||
*/
|
||||
|
||||
#ifndef JUCE_STANDALONE_FILTER_WINDOW_USE_KIOSK_MODE
|
||||
#define JUCE_STANDALONE_FILTER_WINDOW_USE_KIOSK_MODE (JUCE_IOS || JUCE_ANDROID)
|
||||
#endif
|
||||
|
||||
#include "utility/juce_CreatePluginFilter.h"
|
||||
/*
|
||||
==============================================================================
|
||||
|
||||
This file is part of the JUCE library.
|
||||
Copyright (c) 2022 - Raw Material Software Limited
|
||||
|
||||
JUCE is an open source library subject to commercial or open-source
|
||||
licensing.
|
||||
|
||||
By using JUCE, you agree to the terms of both the JUCE 7 End-User License
|
||||
Agreement and JUCE Privacy Policy.
|
||||
|
||||
End User License Agreement: www.juce.com/juce-7-licence
|
||||
Privacy Policy: www.juce.com/juce-privacy-policy
|
||||
|
||||
Or: You may also use this code under the terms of the GPL v3 (see
|
||||
www.gnu.org/licenses).
|
||||
|
||||
JUCE IS PROVIDED "AS IS" WITHOUT ANY WARRANTY, AND ALL WARRANTIES, WHETHER
|
||||
EXPRESSED OR IMPLIED, INCLUDING MERCHANTABILITY AND FITNESS FOR PURPOSE, ARE
|
||||
DISCLAIMED.
|
||||
|
||||
==============================================================================
|
||||
*/
|
||||
|
||||
|
||||
/*******************************************************************************
|
||||
The block below describes the properties of this module, and is read by
|
||||
the Projucer to automatically generate project code that uses it.
|
||||
For details about the syntax and how to create or use a module, see the
|
||||
JUCE Module Format.md file.
|
||||
|
||||
|
||||
BEGIN_JUCE_MODULE_DECLARATION
|
||||
|
||||
ID: juce_audio_plugin_client
|
||||
vendor: juce
|
||||
version: 7.0.2
|
||||
name: JUCE audio plugin wrapper classes
|
||||
description: Classes for building VST, VST3, AU, AUv3 and AAX plugins.
|
||||
website: http://www.juce.com/juce
|
||||
license: GPL/Commercial
|
||||
minimumCppStandard: 14
|
||||
|
||||
dependencies: juce_audio_processors
|
||||
|
||||
END_JUCE_MODULE_DECLARATION
|
||||
|
||||
*******************************************************************************/
|
||||
|
||||
|
||||
#pragma once
|
||||
|
||||
#include <juce_gui_basics/juce_gui_basics.h>
|
||||
#include <juce_audio_basics/juce_audio_basics.h>
|
||||
#include <juce_audio_processors/juce_audio_processors.h>
|
||||
|
||||
/** Config: JUCE_VST3_CAN_REPLACE_VST2
|
||||
|
||||
Enable this if you want your VST3 plug-in to load and save VST2 compatible
|
||||
state. This allows hosts to replace VST2 plug-ins with VST3 plug-ins. If
|
||||
you change this option then your VST3 plug-in will be incompatible with
|
||||
previous versions.
|
||||
*/
|
||||
#ifndef JUCE_VST3_CAN_REPLACE_VST2
|
||||
#define JUCE_VST3_CAN_REPLACE_VST2 1
|
||||
#endif
|
||||
|
||||
/** Config: JUCE_FORCE_USE_LEGACY_PARAM_IDS
|
||||
|
||||
Enable this if you want to force JUCE to use a continuous parameter
|
||||
index to identify a parameter in a DAW (this was the default in old
|
||||
versions of JUCE). This is index is usually used by the DAW to save
|
||||
automation data and enabling this may mess up user's DAW projects.
|
||||
*/
|
||||
#ifndef JUCE_FORCE_USE_LEGACY_PARAM_IDS
|
||||
#define JUCE_FORCE_USE_LEGACY_PARAM_IDS 0
|
||||
#endif
|
||||
|
||||
/** Config: JUCE_FORCE_LEGACY_PARAMETER_AUTOMATION_TYPE
|
||||
|
||||
Enable this if you want to force JUCE to use a legacy scheme for
|
||||
identifying plug-in parameters as either continuous or discrete.
|
||||
DAW projects with automation data written by an AudioUnit, VST3 or
|
||||
AAX plug-in built with JUCE version 5.1.1 or earlier may load
|
||||
incorrectly when opened by an AudioUnit, VST3 or AAX plug-in built
|
||||
with JUCE version 5.2.0 and later.
|
||||
*/
|
||||
#ifndef JUCE_FORCE_LEGACY_PARAMETER_AUTOMATION_TYPE
|
||||
#define JUCE_FORCE_LEGACY_PARAMETER_AUTOMATION_TYPE 0
|
||||
#endif
|
||||
|
||||
/** Config: JUCE_USE_STUDIO_ONE_COMPATIBLE_PARAMETERS
|
||||
|
||||
Enable this if you want JUCE to use parameter ids which are compatible
|
||||
with Studio One, as Studio One ignores any parameter ids which are negative.
|
||||
Enabling this option will make JUCE generate only positive parameter ids.
|
||||
Note that if you have already released a plug-in prior to JUCE 4.3.0 then
|
||||
enabling this will change your parameter ids, making your plug-in
|
||||
incompatible with old automation data.
|
||||
*/
|
||||
#ifndef JUCE_USE_STUDIO_ONE_COMPATIBLE_PARAMETERS
|
||||
#define JUCE_USE_STUDIO_ONE_COMPATIBLE_PARAMETERS 1
|
||||
#endif
|
||||
|
||||
/** Config: JUCE_AU_WRAPPERS_SAVE_PROGRAM_STATES
|
||||
|
||||
Enable this if you want to receive get/setProgramStateInformation calls,
|
||||
instead of get/setStateInformation calls, from the AU and AUv3 plug-in
|
||||
wrappers. In JUCE version 5.4.5 and earlier this was the default behaviour,
|
||||
so if you have modified the default implementations of get/setProgramStateInformation
|
||||
(where the default implementations simply call through to get/setStateInformation)
|
||||
then you may need to enable this configuration option to maintain backwards
|
||||
compatibility with previously saved state.
|
||||
*/
|
||||
#ifndef JUCE_AU_WRAPPERS_SAVE_PROGRAM_STATES
|
||||
#define JUCE_AU_WRAPPERS_SAVE_PROGRAM_STATES 0
|
||||
#endif
|
||||
|
||||
/** Config: JUCE_STANDALONE_FILTER_WINDOW_USE_KIOSK_MODE
|
||||
|
||||
Enable this if you want your standalone plugin window to use kiosk mode.
|
||||
By default, kiosk mode is enabled on iOS and Android.
|
||||
*/
|
||||
|
||||
#ifndef JUCE_STANDALONE_FILTER_WINDOW_USE_KIOSK_MODE
|
||||
#define JUCE_STANDALONE_FILTER_WINDOW_USE_KIOSK_MODE (JUCE_IOS || JUCE_ANDROID)
|
||||
#endif
|
||||
|
||||
#include "utility/juce_CreatePluginFilter.h"
|
||||
|
||||
@@ -1,26 +1,26 @@
|
||||
/*
|
||||
==============================================================================
|
||||
|
||||
This file is part of the JUCE library.
|
||||
Copyright (c) 2020 - Raw Material Software Limited
|
||||
|
||||
JUCE is an open source library subject to commercial or open-source
|
||||
licensing.
|
||||
|
||||
By using JUCE, you agree to the terms of both the JUCE 6 End-User License
|
||||
Agreement and JUCE Privacy Policy (both effective as of the 16th June 2020).
|
||||
|
||||
End User License Agreement: www.juce.com/juce-6-licence
|
||||
Privacy Policy: www.juce.com/juce-privacy-policy
|
||||
|
||||
Or: You may also use this code under the terms of the GPL v3 (see
|
||||
www.gnu.org/licenses).
|
||||
|
||||
JUCE IS PROVIDED "AS IS" WITHOUT ANY WARRANTY, AND ALL WARRANTIES, WHETHER
|
||||
EXPRESSED OR IMPLIED, INCLUDING MERCHANTABILITY AND FITNESS FOR PURPOSE, ARE
|
||||
DISCLAIMED.
|
||||
|
||||
==============================================================================
|
||||
*/
|
||||
|
||||
#include "AAX/juce_AAX_Wrapper.cpp"
|
||||
/*
|
||||
==============================================================================
|
||||
|
||||
This file is part of the JUCE library.
|
||||
Copyright (c) 2022 - Raw Material Software Limited
|
||||
|
||||
JUCE is an open source library subject to commercial or open-source
|
||||
licensing.
|
||||
|
||||
By using JUCE, you agree to the terms of both the JUCE 7 End-User License
|
||||
Agreement and JUCE Privacy Policy.
|
||||
|
||||
End User License Agreement: www.juce.com/juce-7-licence
|
||||
Privacy Policy: www.juce.com/juce-privacy-policy
|
||||
|
||||
Or: You may also use this code under the terms of the GPL v3 (see
|
||||
www.gnu.org/licenses).
|
||||
|
||||
JUCE IS PROVIDED "AS IS" WITHOUT ANY WARRANTY, AND ALL WARRANTIES, WHETHER
|
||||
EXPRESSED OR IMPLIED, INCLUDING MERCHANTABILITY AND FITNESS FOR PURPOSE, ARE
|
||||
DISCLAIMED.
|
||||
|
||||
==============================================================================
|
||||
*/
|
||||
|
||||
#include "AAX/juce_AAX_Wrapper.cpp"
|
||||
|
||||
@@ -2,15 +2,15 @@
|
||||
==============================================================================
|
||||
|
||||
This file is part of the JUCE library.
|
||||
Copyright (c) 2020 - Raw Material Software Limited
|
||||
Copyright (c) 2022 - Raw Material Software Limited
|
||||
|
||||
JUCE is an open source library subject to commercial or open-source
|
||||
licensing.
|
||||
|
||||
By using JUCE, you agree to the terms of both the JUCE 6 End-User License
|
||||
Agreement and JUCE Privacy Policy (both effective as of the 16th June 2020).
|
||||
By using JUCE, you agree to the terms of both the JUCE 7 End-User License
|
||||
Agreement and JUCE Privacy Policy.
|
||||
|
||||
End User License Agreement: www.juce.com/juce-6-licence
|
||||
End User License Agreement: www.juce.com/juce-7-licence
|
||||
Privacy Policy: www.juce.com/juce-privacy-policy
|
||||
|
||||
Or: You may also use this code under the terms of the GPL v3 (see
|
||||
|
||||
@@ -1,26 +1,26 @@
|
||||
/*
|
||||
==============================================================================
|
||||
|
||||
This file is part of the JUCE library.
|
||||
Copyright (c) 2020 - Raw Material Software Limited
|
||||
|
||||
JUCE is an open source library subject to commercial or open-source
|
||||
licensing.
|
||||
|
||||
By using JUCE, you agree to the terms of both the JUCE 6 End-User License
|
||||
Agreement and JUCE Privacy Policy (both effective as of the 16th June 2020).
|
||||
|
||||
End User License Agreement: www.juce.com/juce-6-licence
|
||||
Privacy Policy: www.juce.com/juce-privacy-policy
|
||||
|
||||
Or: You may also use this code under the terms of the GPL v3 (see
|
||||
www.gnu.org/licenses).
|
||||
|
||||
JUCE IS PROVIDED "AS IS" WITHOUT ANY WARRANTY, AND ALL WARRANTIES, WHETHER
|
||||
EXPRESSED OR IMPLIED, INCLUDING MERCHANTABILITY AND FITNESS FOR PURPOSE, ARE
|
||||
DISCLAIMED.
|
||||
|
||||
==============================================================================
|
||||
*/
|
||||
|
||||
#include "RTAS/juce_RTAS_Wrapper.cpp"
|
||||
/*
|
||||
==============================================================================
|
||||
|
||||
This file is part of the JUCE library.
|
||||
Copyright (c) 2022 - Raw Material Software Limited
|
||||
|
||||
JUCE is an open source library subject to commercial or open-source
|
||||
licensing.
|
||||
|
||||
By using JUCE, you agree to the terms of both the JUCE 7 End-User License
|
||||
Agreement and JUCE Privacy Policy.
|
||||
|
||||
End User License Agreement: www.juce.com/juce-7-licence
|
||||
Privacy Policy: www.juce.com/juce-privacy-policy
|
||||
|
||||
Or: You may also use this code under the terms of the GPL v3 (see
|
||||
www.gnu.org/licenses).
|
||||
|
||||
JUCE IS PROVIDED "AS IS" WITHOUT ANY WARRANTY, AND ALL WARRANTIES, WHETHER
|
||||
EXPRESSED OR IMPLIED, INCLUDING MERCHANTABILITY AND FITNESS FOR PURPOSE, ARE
|
||||
DISCLAIMED.
|
||||
|
||||
==============================================================================
|
||||
*/
|
||||
|
||||
#include "ARA/juce_ARA_Wrapper.cpp"
|
||||
@@ -2,15 +2,15 @@
|
||||
==============================================================================
|
||||
|
||||
This file is part of the JUCE library.
|
||||
Copyright (c) 2020 - Raw Material Software Limited
|
||||
Copyright (c) 2022 - Raw Material Software Limited
|
||||
|
||||
JUCE is an open source library subject to commercial or open-source
|
||||
licensing.
|
||||
|
||||
By using JUCE, you agree to the terms of both the JUCE 6 End-User License
|
||||
Agreement and JUCE Privacy Policy (both effective as of the 16th June 2020).
|
||||
By using JUCE, you agree to the terms of both the JUCE 7 End-User License
|
||||
Agreement and JUCE Privacy Policy.
|
||||
|
||||
End User License Agreement: www.juce.com/juce-6-licence
|
||||
End User License Agreement: www.juce.com/juce-7-licence
|
||||
Privacy Policy: www.juce.com/juce-privacy-policy
|
||||
|
||||
Or: You may also use this code under the terms of the GPL v3 (see
|
||||
@@ -48,23 +48,3 @@
|
||||
#define ENTRY_POINT JucePlugin_AUExportPrefixQuoted "Entry"
|
||||
|
||||
#include "AUResources.r"
|
||||
|
||||
//==============================================================================
|
||||
// component resources for Audio Unit Carbon View
|
||||
|
||||
#ifndef BUILD_AU_CARBON_UI
|
||||
#define BUILD_AU_CARBON_UI 1
|
||||
#endif
|
||||
|
||||
#if BUILD_AU_CARBON_UI
|
||||
#define RES_ID 2000
|
||||
#define COMP_TYPE kAudioUnitCarbonViewComponentType
|
||||
#define COMP_SUBTYPE JucePlugin_AUSubType
|
||||
#define COMP_MANUF JucePlugin_AUManufacturerCode
|
||||
#define VERSION JucePlugin_VersionCode
|
||||
#define NAME JucePlugin_Manufacturer ": " JucePlugin_Name " View"
|
||||
#define DESCRIPTION NAME
|
||||
#define ENTRY_POINT JucePlugin_AUExportPrefixQuoted "ViewEntry"
|
||||
|
||||
#include "AUResources.r"
|
||||
#endif
|
||||
|
||||
@@ -2,15 +2,15 @@
|
||||
==============================================================================
|
||||
|
||||
This file is part of the JUCE library.
|
||||
Copyright (c) 2020 - Raw Material Software Limited
|
||||
Copyright (c) 2022 - Raw Material Software Limited
|
||||
|
||||
JUCE is an open source library subject to commercial or open-source
|
||||
licensing.
|
||||
|
||||
By using JUCE, you agree to the terms of both the JUCE 6 End-User License
|
||||
Agreement and JUCE Privacy Policy (both effective as of the 16th June 2020).
|
||||
By using JUCE, you agree to the terms of both the JUCE 7 End-User License
|
||||
Agreement and JUCE Privacy Policy.
|
||||
|
||||
End User License Agreement: www.juce.com/juce-6-licence
|
||||
End User License Agreement: www.juce.com/juce-7-licence
|
||||
Privacy Policy: www.juce.com/juce-privacy-policy
|
||||
|
||||
Or: You may also use this code under the terms of the GPL v3 (see
|
||||
|
||||
@@ -2,15 +2,15 @@
|
||||
==============================================================================
|
||||
|
||||
This file is part of the JUCE library.
|
||||
Copyright (c) 2020 - Raw Material Software Limited
|
||||
Copyright (c) 2022 - Raw Material Software Limited
|
||||
|
||||
JUCE is an open source library subject to commercial or open-source
|
||||
licensing.
|
||||
|
||||
By using JUCE, you agree to the terms of both the JUCE 6 End-User License
|
||||
Agreement and JUCE Privacy Policy (both effective as of the 16th June 2020).
|
||||
By using JUCE, you agree to the terms of both the JUCE 7 End-User License
|
||||
Agreement and JUCE Privacy Policy.
|
||||
|
||||
End User License Agreement: www.juce.com/juce-6-licence
|
||||
End User License Agreement: www.juce.com/juce-7-licence
|
||||
Privacy Policy: www.juce.com/juce-privacy-policy
|
||||
|
||||
Or: You may also use this code under the terms of the GPL v3 (see
|
||||
@@ -62,9 +62,6 @@ JUCE_BEGIN_IGNORE_WARNINGS_GCC_LIKE ("-Wparentheses",
|
||||
|
||||
#include "AU/CoreAudioUtilityClasses/AUBase.cpp"
|
||||
#include "AU/CoreAudioUtilityClasses/AUBuffer.cpp"
|
||||
#include "AU/CoreAudioUtilityClasses/AUCarbonViewBase.cpp"
|
||||
#include "AU/CoreAudioUtilityClasses/AUCarbonViewControl.cpp"
|
||||
#include "AU/CoreAudioUtilityClasses/AUCarbonViewDispatch.cpp"
|
||||
#include "AU/CoreAudioUtilityClasses/AUDispatch.cpp"
|
||||
#include "AU/CoreAudioUtilityClasses/AUInputElement.cpp"
|
||||
#include "AU/CoreAudioUtilityClasses/AUMIDIBase.cpp"
|
||||
@@ -76,7 +73,6 @@ JUCE_BEGIN_IGNORE_WARNINGS_GCC_LIKE ("-Wparentheses",
|
||||
#include "AU/CoreAudioUtilityClasses/CAMutex.cpp"
|
||||
#include "AU/CoreAudioUtilityClasses/CAStreamBasicDescription.cpp"
|
||||
#include "AU/CoreAudioUtilityClasses/CAVectorUnit.cpp"
|
||||
#include "AU/CoreAudioUtilityClasses/CarbonEventHandler.cpp"
|
||||
#include "AU/CoreAudioUtilityClasses/ComponentBase.cpp"
|
||||
#include "AU/CoreAudioUtilityClasses/MusicDeviceBase.cpp"
|
||||
|
||||
|
||||
@@ -2,15 +2,15 @@
|
||||
==============================================================================
|
||||
|
||||
This file is part of the JUCE library.
|
||||
Copyright (c) 2020 - Raw Material Software Limited
|
||||
Copyright (c) 2022 - Raw Material Software Limited
|
||||
|
||||
JUCE is an open source library subject to commercial or open-source
|
||||
licensing.
|
||||
|
||||
By using JUCE, you agree to the terms of both the JUCE 6 End-User License
|
||||
Agreement and JUCE Privacy Policy (both effective as of the 16th June 2020).
|
||||
By using JUCE, you agree to the terms of both the JUCE 7 End-User License
|
||||
Agreement and JUCE Privacy Policy.
|
||||
|
||||
End User License Agreement: www.juce.com/juce-6-licence
|
||||
End User License Agreement: www.juce.com/juce-7-licence
|
||||
Privacy Policy: www.juce.com/juce-privacy-policy
|
||||
|
||||
Or: You may also use this code under the terms of the GPL v3 (see
|
||||
|
||||
@@ -1,26 +1,26 @@
|
||||
/*
|
||||
==============================================================================
|
||||
|
||||
This file is part of the JUCE library.
|
||||
Copyright (c) 2020 - Raw Material Software Limited
|
||||
|
||||
JUCE is an open source library subject to commercial or open-source
|
||||
licensing.
|
||||
|
||||
By using JUCE, you agree to the terms of both the JUCE 6 End-User License
|
||||
Agreement and JUCE Privacy Policy (both effective as of the 16th June 2020).
|
||||
|
||||
End User License Agreement: www.juce.com/juce-6-licence
|
||||
Privacy Policy: www.juce.com/juce-privacy-policy
|
||||
|
||||
Or: You may also use this code under the terms of the GPL v3 (see
|
||||
www.gnu.org/licenses).
|
||||
|
||||
JUCE IS PROVIDED "AS IS" WITHOUT ANY WARRANTY, AND ALL WARRANTIES, WHETHER
|
||||
EXPRESSED OR IMPLIED, INCLUDING MERCHANTABILITY AND FITNESS FOR PURPOSE, ARE
|
||||
DISCLAIMED.
|
||||
|
||||
==============================================================================
|
||||
*/
|
||||
|
||||
#include "RTAS/juce_RTAS_DigiCode1.cpp"
|
||||
/*
|
||||
==============================================================================
|
||||
|
||||
This file is part of the JUCE library.
|
||||
Copyright (c) 2022 - Raw Material Software Limited
|
||||
|
||||
JUCE is an open source library subject to commercial or open-source
|
||||
licensing.
|
||||
|
||||
By using JUCE, you agree to the terms of both the JUCE 7 End-User License
|
||||
Agreement and JUCE Privacy Policy.
|
||||
|
||||
End User License Agreement: www.juce.com/juce-7-licence
|
||||
Privacy Policy: www.juce.com/juce-privacy-policy
|
||||
|
||||
Or: You may also use this code under the terms of the GPL v3 (see
|
||||
www.gnu.org/licenses).
|
||||
|
||||
JUCE IS PROVIDED "AS IS" WITHOUT ANY WARRANTY, AND ALL WARRANTIES, WHETHER
|
||||
EXPRESSED OR IMPLIED, INCLUDING MERCHANTABILITY AND FITNESS FOR PURPOSE, ARE
|
||||
DISCLAIMED.
|
||||
|
||||
==============================================================================
|
||||
*/
|
||||
|
||||
#include "LV2/juce_LV2_Client.cpp"
|
||||
@@ -1,26 +1,26 @@
|
||||
/*
|
||||
==============================================================================
|
||||
|
||||
This file is part of the JUCE library.
|
||||
Copyright (c) 2020 - Raw Material Software Limited
|
||||
|
||||
JUCE is an open source library subject to commercial or open-source
|
||||
licensing.
|
||||
|
||||
By using JUCE, you agree to the terms of both the JUCE 6 End-User License
|
||||
Agreement and JUCE Privacy Policy (both effective as of the 16th June 2020).
|
||||
|
||||
End User License Agreement: www.juce.com/juce-6-licence
|
||||
Privacy Policy: www.juce.com/juce-privacy-policy
|
||||
|
||||
Or: You may also use this code under the terms of the GPL v3 (see
|
||||
www.gnu.org/licenses).
|
||||
|
||||
JUCE IS PROVIDED "AS IS" WITHOUT ANY WARRANTY, AND ALL WARRANTIES, WHETHER
|
||||
EXPRESSED OR IMPLIED, INCLUDING MERCHANTABILITY AND FITNESS FOR PURPOSE, ARE
|
||||
DISCLAIMED.
|
||||
|
||||
==============================================================================
|
||||
*/
|
||||
|
||||
#include "RTAS/juce_RTAS_DigiCode2.cpp"
|
||||
/*
|
||||
==============================================================================
|
||||
|
||||
This file is part of the JUCE library.
|
||||
Copyright (c) 2022 - Raw Material Software Limited
|
||||
|
||||
JUCE is an open source library subject to commercial or open-source
|
||||
licensing.
|
||||
|
||||
By using JUCE, you agree to the terms of both the JUCE 7 End-User License
|
||||
Agreement and JUCE Privacy Policy.
|
||||
|
||||
End User License Agreement: www.juce.com/juce-7-licence
|
||||
Privacy Policy: www.juce.com/juce-privacy-policy
|
||||
|
||||
Or: You may also use this code under the terms of the GPL v3 (see
|
||||
www.gnu.org/licenses).
|
||||
|
||||
JUCE IS PROVIDED "AS IS" WITHOUT ANY WARRANTY, AND ALL WARRANTIES, WHETHER
|
||||
EXPRESSED OR IMPLIED, INCLUDING MERCHANTABILITY AND FITNESS FOR PURPOSE, ARE
|
||||
DISCLAIMED.
|
||||
|
||||
==============================================================================
|
||||
*/
|
||||
|
||||
#include "juce_audio_plugin_client_LV2.cpp"
|
||||
@@ -1,7 +0,0 @@
|
||||
|
||||
/*
|
||||
This dummy file is added to the resources section of the project to
|
||||
force Xcode to create some resources for the dpm. If there aren't any
|
||||
resources, PT will refuse to load the plugin..
|
||||
*/
|
||||
|
||||
@@ -1,26 +0,0 @@
|
||||
/*
|
||||
==============================================================================
|
||||
|
||||
This file is part of the JUCE library.
|
||||
Copyright (c) 2020 - Raw Material Software Limited
|
||||
|
||||
JUCE is an open source library subject to commercial or open-source
|
||||
licensing.
|
||||
|
||||
By using JUCE, you agree to the terms of both the JUCE 6 End-User License
|
||||
Agreement and JUCE Privacy Policy (both effective as of the 16th June 2020).
|
||||
|
||||
End User License Agreement: www.juce.com/juce-6-licence
|
||||
Privacy Policy: www.juce.com/juce-privacy-policy
|
||||
|
||||
Or: You may also use this code under the terms of the GPL v3 (see
|
||||
www.gnu.org/licenses).
|
||||
|
||||
JUCE IS PROVIDED "AS IS" WITHOUT ANY WARRANTY, AND ALL WARRANTIES, WHETHER
|
||||
EXPRESSED OR IMPLIED, INCLUDING MERCHANTABILITY AND FITNESS FOR PURPOSE, ARE
|
||||
DISCLAIMED.
|
||||
|
||||
==============================================================================
|
||||
*/
|
||||
|
||||
#include "RTAS/juce_RTAS_DigiCode3.cpp"
|
||||
@@ -1,26 +0,0 @@
|
||||
/*
|
||||
==============================================================================
|
||||
|
||||
This file is part of the JUCE library.
|
||||
Copyright (c) 2020 - Raw Material Software Limited
|
||||
|
||||
JUCE is an open source library subject to commercial or open-source
|
||||
licensing.
|
||||
|
||||
By using JUCE, you agree to the terms of both the JUCE 6 End-User License
|
||||
Agreement and JUCE Privacy Policy (both effective as of the 16th June 2020).
|
||||
|
||||
End User License Agreement: www.juce.com/juce-6-licence
|
||||
Privacy Policy: www.juce.com/juce-privacy-policy
|
||||
|
||||
Or: You may also use this code under the terms of the GPL v3 (see
|
||||
www.gnu.org/licenses).
|
||||
|
||||
JUCE IS PROVIDED "AS IS" WITHOUT ANY WARRANTY, AND ALL WARRANTIES, WHETHER
|
||||
EXPRESSED OR IMPLIED, INCLUDING MERCHANTABILITY AND FITNESS FOR PURPOSE, ARE
|
||||
DISCLAIMED.
|
||||
|
||||
==============================================================================
|
||||
*/
|
||||
|
||||
#include "RTAS/juce_RTAS_WinUtilities.cpp"
|
||||
@@ -1,26 +0,0 @@
|
||||
/*
|
||||
==============================================================================
|
||||
|
||||
This file is part of the JUCE library.
|
||||
Copyright (c) 2020 - Raw Material Software Limited
|
||||
|
||||
JUCE is an open source library subject to commercial or open-source
|
||||
licensing.
|
||||
|
||||
By using JUCE, you agree to the terms of both the JUCE 6 End-User License
|
||||
Agreement and JUCE Privacy Policy (both effective as of the 16th June 2020).
|
||||
|
||||
End User License Agreement: www.juce.com/juce-6-licence
|
||||
Privacy Policy: www.juce.com/juce-privacy-policy
|
||||
|
||||
Or: You may also use this code under the terms of the GPL v3 (see
|
||||
www.gnu.org/licenses).
|
||||
|
||||
JUCE IS PROVIDED "AS IS" WITHOUT ANY WARRANTY, AND ALL WARRANTIES, WHETHER
|
||||
EXPRESSED OR IMPLIED, INCLUDING MERCHANTABILITY AND FITNESS FOR PURPOSE, ARE
|
||||
DISCLAIMED.
|
||||
|
||||
==============================================================================
|
||||
*/
|
||||
|
||||
#include "RTAS/juce_RTAS_MacUtilities.mm"
|
||||
@@ -1,49 +1,49 @@
|
||||
/*
|
||||
==============================================================================
|
||||
|
||||
This file is part of the JUCE library.
|
||||
Copyright (c) 2020 - Raw Material Software Limited
|
||||
|
||||
JUCE is an open source library subject to commercial or open-source
|
||||
licensing.
|
||||
|
||||
By using JUCE, you agree to the terms of both the JUCE 6 End-User License
|
||||
Agreement and JUCE Privacy Policy (both effective as of the 16th June 2020).
|
||||
|
||||
End User License Agreement: www.juce.com/juce-6-licence
|
||||
Privacy Policy: www.juce.com/juce-privacy-policy
|
||||
|
||||
Or: You may also use this code under the terms of the GPL v3 (see
|
||||
www.gnu.org/licenses).
|
||||
|
||||
JUCE IS PROVIDED "AS IS" WITHOUT ANY WARRANTY, AND ALL WARRANTIES, WHETHER
|
||||
EXPRESSED OR IMPLIED, INCLUDING MERCHANTABILITY AND FITNESS FOR PURPOSE, ARE
|
||||
DISCLAIMED.
|
||||
|
||||
==============================================================================
|
||||
*/
|
||||
|
||||
#include <juce_core/system/juce_TargetPlatform.h>
|
||||
|
||||
#if JucePlugin_Build_Standalone
|
||||
|
||||
#if ! JUCE_MODULE_AVAILABLE_juce_audio_utils
|
||||
#error To compile AudioUnitv3 and/or Standalone plug-ins, you need to add the juce_audio_utils and juce_audio_devices modules!
|
||||
#endif
|
||||
|
||||
#include "Standalone/juce_StandaloneFilterApp.cpp"
|
||||
|
||||
#if JUCE_USE_CUSTOM_PLUGIN_STANDALONE_APP
|
||||
extern juce::JUCEApplicationBase* juce_CreateApplication();
|
||||
|
||||
#if JUCE_IOS
|
||||
extern void* juce_GetIOSCustomDelegateClass();
|
||||
#endif
|
||||
|
||||
#else
|
||||
JUCE_CREATE_APPLICATION_DEFINE(juce::StandaloneFilterApp)
|
||||
#endif
|
||||
|
||||
JUCE_MAIN_FUNCTION_DEFINITION
|
||||
|
||||
#endif
|
||||
/*
|
||||
==============================================================================
|
||||
|
||||
This file is part of the JUCE library.
|
||||
Copyright (c) 2022 - Raw Material Software Limited
|
||||
|
||||
JUCE is an open source library subject to commercial or open-source
|
||||
licensing.
|
||||
|
||||
By using JUCE, you agree to the terms of both the JUCE 7 End-User License
|
||||
Agreement and JUCE Privacy Policy.
|
||||
|
||||
End User License Agreement: www.juce.com/juce-7-licence
|
||||
Privacy Policy: www.juce.com/juce-privacy-policy
|
||||
|
||||
Or: You may also use this code under the terms of the GPL v3 (see
|
||||
www.gnu.org/licenses).
|
||||
|
||||
JUCE IS PROVIDED "AS IS" WITHOUT ANY WARRANTY, AND ALL WARRANTIES, WHETHER
|
||||
EXPRESSED OR IMPLIED, INCLUDING MERCHANTABILITY AND FITNESS FOR PURPOSE, ARE
|
||||
DISCLAIMED.
|
||||
|
||||
==============================================================================
|
||||
*/
|
||||
|
||||
#include <juce_core/system/juce_TargetPlatform.h>
|
||||
|
||||
#if JucePlugin_Build_Standalone
|
||||
|
||||
#if ! JUCE_MODULE_AVAILABLE_juce_audio_utils
|
||||
#error To compile AudioUnitv3 and/or Standalone plug-ins, you need to add the juce_audio_utils and juce_audio_devices modules!
|
||||
#endif
|
||||
|
||||
#include "Standalone/juce_StandaloneFilterApp.cpp"
|
||||
|
||||
#if JUCE_USE_CUSTOM_PLUGIN_STANDALONE_APP
|
||||
extern juce::JUCEApplicationBase* juce_CreateApplication();
|
||||
|
||||
#if JUCE_IOS
|
||||
extern void* juce_GetIOSCustomDelegateClass();
|
||||
#endif
|
||||
|
||||
#else
|
||||
JUCE_CREATE_APPLICATION_DEFINE(juce::StandaloneFilterApp)
|
||||
#endif
|
||||
|
||||
JUCE_MAIN_FUNCTION_DEFINITION
|
||||
|
||||
#endif
|
||||
|
||||
@@ -1,26 +1,26 @@
|
||||
/*
|
||||
==============================================================================
|
||||
|
||||
This file is part of the JUCE library.
|
||||
Copyright (c) 2020 - Raw Material Software Limited
|
||||
|
||||
JUCE is an open source library subject to commercial or open-source
|
||||
licensing.
|
||||
|
||||
By using JUCE, you agree to the terms of both the JUCE 6 End-User License
|
||||
Agreement and JUCE Privacy Policy (both effective as of the 16th June 2020).
|
||||
|
||||
End User License Agreement: www.juce.com/juce-6-licence
|
||||
Privacy Policy: www.juce.com/juce-privacy-policy
|
||||
|
||||
Or: You may also use this code under the terms of the GPL v3 (see
|
||||
www.gnu.org/licenses).
|
||||
|
||||
JUCE IS PROVIDED "AS IS" WITHOUT ANY WARRANTY, AND ALL WARRANTIES, WHETHER
|
||||
EXPRESSED OR IMPLIED, INCLUDING MERCHANTABILITY AND FITNESS FOR PURPOSE, ARE
|
||||
DISCLAIMED.
|
||||
|
||||
==============================================================================
|
||||
*/
|
||||
|
||||
#include "Unity/juce_Unity_Wrapper.cpp"
|
||||
/*
|
||||
==============================================================================
|
||||
|
||||
This file is part of the JUCE library.
|
||||
Copyright (c) 2022 - Raw Material Software Limited
|
||||
|
||||
JUCE is an open source library subject to commercial or open-source
|
||||
licensing.
|
||||
|
||||
By using JUCE, you agree to the terms of both the JUCE 7 End-User License
|
||||
Agreement and JUCE Privacy Policy.
|
||||
|
||||
End User License Agreement: www.juce.com/juce-7-licence
|
||||
Privacy Policy: www.juce.com/juce-privacy-policy
|
||||
|
||||
Or: You may also use this code under the terms of the GPL v3 (see
|
||||
www.gnu.org/licenses).
|
||||
|
||||
JUCE IS PROVIDED "AS IS" WITHOUT ANY WARRANTY, AND ALL WARRANTIES, WHETHER
|
||||
EXPRESSED OR IMPLIED, INCLUDING MERCHANTABILITY AND FITNESS FOR PURPOSE, ARE
|
||||
DISCLAIMED.
|
||||
|
||||
==============================================================================
|
||||
*/
|
||||
|
||||
#include "Unity/juce_Unity_Wrapper.cpp"
|
||||
|
||||
@@ -1,26 +1,26 @@
|
||||
/*
|
||||
==============================================================================
|
||||
|
||||
This file is part of the JUCE library.
|
||||
Copyright (c) 2020 - Raw Material Software Limited
|
||||
|
||||
JUCE is an open source library subject to commercial or open-source
|
||||
licensing.
|
||||
|
||||
By using JUCE, you agree to the terms of both the JUCE 6 End-User License
|
||||
Agreement and JUCE Privacy Policy (both effective as of the 16th June 2020).
|
||||
|
||||
End User License Agreement: www.juce.com/juce-6-licence
|
||||
Privacy Policy: www.juce.com/juce-privacy-policy
|
||||
|
||||
Or: You may also use this code under the terms of the GPL v3 (see
|
||||
www.gnu.org/licenses).
|
||||
|
||||
JUCE IS PROVIDED "AS IS" WITHOUT ANY WARRANTY, AND ALL WARRANTIES, WHETHER
|
||||
EXPRESSED OR IMPLIED, INCLUDING MERCHANTABILITY AND FITNESS FOR PURPOSE, ARE
|
||||
DISCLAIMED.
|
||||
|
||||
==============================================================================
|
||||
*/
|
||||
|
||||
#include "VST/juce_VST_Wrapper.cpp"
|
||||
/*
|
||||
==============================================================================
|
||||
|
||||
This file is part of the JUCE library.
|
||||
Copyright (c) 2022 - Raw Material Software Limited
|
||||
|
||||
JUCE is an open source library subject to commercial or open-source
|
||||
licensing.
|
||||
|
||||
By using JUCE, you agree to the terms of both the JUCE 7 End-User License
|
||||
Agreement and JUCE Privacy Policy.
|
||||
|
||||
End User License Agreement: www.juce.com/juce-7-licence
|
||||
Privacy Policy: www.juce.com/juce-privacy-policy
|
||||
|
||||
Or: You may also use this code under the terms of the GPL v3 (see
|
||||
www.gnu.org/licenses).
|
||||
|
||||
JUCE IS PROVIDED "AS IS" WITHOUT ANY WARRANTY, AND ALL WARRANTIES, WHETHER
|
||||
EXPRESSED OR IMPLIED, INCLUDING MERCHANTABILITY AND FITNESS FOR PURPOSE, ARE
|
||||
DISCLAIMED.
|
||||
|
||||
==============================================================================
|
||||
*/
|
||||
|
||||
#include "VST/juce_VST_Wrapper.cpp"
|
||||
|
||||
@@ -1,26 +1,26 @@
|
||||
/*
|
||||
==============================================================================
|
||||
|
||||
This file is part of the JUCE library.
|
||||
Copyright (c) 2020 - Raw Material Software Limited
|
||||
|
||||
JUCE is an open source library subject to commercial or open-source
|
||||
licensing.
|
||||
|
||||
By using JUCE, you agree to the terms of both the JUCE 6 End-User License
|
||||
Agreement and JUCE Privacy Policy (both effective as of the 16th June 2020).
|
||||
|
||||
End User License Agreement: www.juce.com/juce-6-licence
|
||||
Privacy Policy: www.juce.com/juce-privacy-policy
|
||||
|
||||
Or: You may also use this code under the terms of the GPL v3 (see
|
||||
www.gnu.org/licenses).
|
||||
|
||||
JUCE IS PROVIDED "AS IS" WITHOUT ANY WARRANTY, AND ALL WARRANTIES, WHETHER
|
||||
EXPRESSED OR IMPLIED, INCLUDING MERCHANTABILITY AND FITNESS FOR PURPOSE, ARE
|
||||
DISCLAIMED.
|
||||
|
||||
==============================================================================
|
||||
*/
|
||||
|
||||
#include "VST3/juce_VST3_Wrapper.cpp"
|
||||
/*
|
||||
==============================================================================
|
||||
|
||||
This file is part of the JUCE library.
|
||||
Copyright (c) 2022 - Raw Material Software Limited
|
||||
|
||||
JUCE is an open source library subject to commercial or open-source
|
||||
licensing.
|
||||
|
||||
By using JUCE, you agree to the terms of both the JUCE 7 End-User License
|
||||
Agreement and JUCE Privacy Policy.
|
||||
|
||||
End User License Agreement: www.juce.com/juce-7-licence
|
||||
Privacy Policy: www.juce.com/juce-privacy-policy
|
||||
|
||||
Or: You may also use this code under the terms of the GPL v3 (see
|
||||
www.gnu.org/licenses).
|
||||
|
||||
JUCE IS PROVIDED "AS IS" WITHOUT ANY WARRANTY, AND ALL WARRANTIES, WHETHER
|
||||
EXPRESSED OR IMPLIED, INCLUDING MERCHANTABILITY AND FITNESS FOR PURPOSE, ARE
|
||||
DISCLAIMED.
|
||||
|
||||
==============================================================================
|
||||
*/
|
||||
|
||||
#include "VST3/juce_VST3_Wrapper.cpp"
|
||||
|
||||
@@ -2,15 +2,15 @@
|
||||
==============================================================================
|
||||
|
||||
This file is part of the JUCE library.
|
||||
Copyright (c) 2020 - Raw Material Software Limited
|
||||
Copyright (c) 2022 - Raw Material Software Limited
|
||||
|
||||
JUCE is an open source library subject to commercial or open-source
|
||||
licensing.
|
||||
|
||||
By using JUCE, you agree to the terms of both the JUCE 6 End-User License
|
||||
Agreement and JUCE Privacy Policy (both effective as of the 16th June 2020).
|
||||
By using JUCE, you agree to the terms of both the JUCE 7 End-User License
|
||||
Agreement and JUCE Privacy Policy.
|
||||
|
||||
End User License Agreement: www.juce.com/juce-6-licence
|
||||
End User License Agreement: www.juce.com/juce-7-licence
|
||||
Privacy Policy: www.juce.com/juce-privacy-policy
|
||||
|
||||
Or: You may also use this code under the terms of the GPL v3 (see
|
||||
|
||||
@@ -1,26 +1,26 @@
|
||||
/*
|
||||
==============================================================================
|
||||
|
||||
This file is part of the JUCE library.
|
||||
Copyright (c) 2020 - Raw Material Software Limited
|
||||
|
||||
JUCE is an open source library subject to commercial or open-source
|
||||
licensing.
|
||||
|
||||
By using JUCE, you agree to the terms of both the JUCE 6 End-User License
|
||||
Agreement and JUCE Privacy Policy (both effective as of the 16th June 2020).
|
||||
|
||||
End User License Agreement: www.juce.com/juce-6-licence
|
||||
Privacy Policy: www.juce.com/juce-privacy-policy
|
||||
|
||||
Or: You may also use this code under the terms of the GPL v3 (see
|
||||
www.gnu.org/licenses).
|
||||
|
||||
JUCE IS PROVIDED "AS IS" WITHOUT ANY WARRANTY, AND ALL WARRANTIES, WHETHER
|
||||
EXPRESSED OR IMPLIED, INCLUDING MERCHANTABILITY AND FITNESS FOR PURPOSE, ARE
|
||||
DISCLAIMED.
|
||||
|
||||
==============================================================================
|
||||
*/
|
||||
|
||||
#include "utility/juce_PluginUtilities.cpp"
|
||||
/*
|
||||
==============================================================================
|
||||
|
||||
This file is part of the JUCE library.
|
||||
Copyright (c) 2022 - Raw Material Software Limited
|
||||
|
||||
JUCE is an open source library subject to commercial or open-source
|
||||
licensing.
|
||||
|
||||
By using JUCE, you agree to the terms of both the JUCE 7 End-User License
|
||||
Agreement and JUCE Privacy Policy.
|
||||
|
||||
End User License Agreement: www.juce.com/juce-7-licence
|
||||
Privacy Policy: www.juce.com/juce-privacy-policy
|
||||
|
||||
Or: You may also use this code under the terms of the GPL v3 (see
|
||||
www.gnu.org/licenses).
|
||||
|
||||
JUCE IS PROVIDED "AS IS" WITHOUT ANY WARRANTY, AND ALL WARRANTIES, WHETHER
|
||||
EXPRESSED OR IMPLIED, INCLUDING MERCHANTABILITY AND FITNESS FOR PURPOSE, ARE
|
||||
DISCLAIMED.
|
||||
|
||||
==============================================================================
|
||||
*/
|
||||
|
||||
#include "utility/juce_PluginUtilities.cpp"
|
||||
|
||||
Some files were not shown because too many files have changed in this diff Show More
Reference in New Issue
Block a user