migrating to the latest JUCE version

This commit is contained in:
2022-11-04 23:11:33 +01:00
committed by Nikolai Rodionov
parent 4257a0f8ba
commit faf8f18333
2796 changed files with 888518 additions and 784244 deletions

View File

@ -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

View 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

View File

@ -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__

View File

@ -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

View File

@ -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__

View File

@ -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 &param, 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;
}

View File

@ -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__

View File

@ -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 &param, 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(&paramValue);
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, &currentPreset, &theSize);
if (result == noErr) {
#ifndef __LP64__
if (inProp.mPropertyID == kAudioUnitProperty_CurrentPreset && currentPreset.presetName)
CFRetain (currentPreset.presetName);
#endif
HandlePropertyChange(currentPreset);
return true;
}
}
return false;
}

View File

@ -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 &param, 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__

View File

@ -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;
}

View File

@ -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 *)&params->params[_index + 1];
#else
// parameters in reverse order, then comp instance
#define PARAM(_typ, _name, _index, _nparams) \
_typ _name = *(_typ *)&params->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 *)&params->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 *)&params->params[_index + 1];
#else
// parameters in reverse order, then comp instance
#define PARAM(_typ, _name, _index, _nparams) \
_typ _name = *(_typ *)&params->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 *)&params->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;
}

View File

@ -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__

View File

@ -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);
}

View File

@ -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__

View File

@ -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__

View File

@ -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 *)&params->params[_index + 1];
#else
// parameters in reverse order, then comp instance
#define PARAM(_typ, _name, _index, _nparams) \
_typ _name = *(_typ *)&params->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 *)&params->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 *)&params->params[_index + 1];
#else
// parameters in reverse order, then comp instance
#define PARAM(_typ, _name, _index, _nparams) \
_typ _name = *(_typ *)&params->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 *)&params->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

View File

@ -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__

View File

@ -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

View File

@ -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__

View File

@ -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;
}

View File

@ -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__

View File

@ -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__

View File

@ -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

View File

@ -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__

View File

@ -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__

View File

@ -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

View File

@ -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__

View File

@ -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__

View File

@ -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__

View File

@ -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]);
}
}
}

View File

@ -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

View File

@ -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

View File

@ -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

View File

@ -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

View File

@ -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__

View File

@ -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();
}
}

View File

@ -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__

View File

@ -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__

View File

@ -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__

View File

@ -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__

View File

@ -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;
}

View File

@ -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__

View File

@ -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

View File

@ -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__

View File

@ -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);
}
}

View File

@ -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__

View File

@ -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

View File

@ -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__

View File

@ -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 *)&params->params[_index + 1];
#else
// parameters in reverse order, then comp instance
#define PARAM(_typ, _name, _index, _nparams) \
_typ _name = *(_typ *)&params->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 *)&params->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 *)&params->params[_index + 1];
#else
// parameters in reverse order, then comp instance
#define PARAM(_typ, _name, _index, _nparams) \
_typ _name = *(_typ *)&params->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 *)&params->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

View File

@ -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__

View File

@ -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 (&param, 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")

View File

@ -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

View 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}")

View 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;
}

File diff suppressed because it is too large Load Diff

View File

@ -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

View File

@ -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

View File

@ -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

View File

@ -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

View File

@ -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

View File

@ -1,4 +0,0 @@
EXPORTS
NewPlugIn @1
_PI_GetRoutineDescriptor @2

Binary file not shown.

Before

Width:  |  Height:  |  Size: 3.1 KiB

View File

@ -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

View File

@ -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

View File

@ -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

View File

@ -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

View File

@ -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"

View File

@ -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"

View File

@ -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

View File

@ -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"

View File

@ -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

View File

@ -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

View File

@ -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"

View File

@ -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

View File

@ -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"

View File

@ -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"

View File

@ -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..
*/

View File

@ -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"

View File

@ -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"

View File

@ -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"

View File

@ -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

View File

@ -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"

View File

@ -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"

View File

@ -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"

View File

@ -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

View File

@ -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