1
0
mirror of https://github.com/cookiengineer/audacity synced 2025-08-06 15:19:29 +02:00

AudioUnits rework...

They now work on Yosemite.

AudioUnits with a custom Cocoa UI now display graphically
instead of reverting to the generic view

The Cocoa version of the generic view is now used when
needed...instead of the Carbon version.

The order of UI preference is Cocoa, Carbon, Generic,
unless force to Generic view user setting.

They now support realtime preview.

They also support dialog resizing as I found many that
scaled nicely (mostly Apple's).

Uses the new Effect format so now supports user and
factory presets.

NOTE:  Be VERY critical when testing this as I've
       never written Objective-C or Cocoa code
       before!
This commit is contained in:
lllucius@gmail.com 2014-11-25 08:08:15 +00:00
parent b16db7ca2b
commit 540f5c78c9
12 changed files with 2606 additions and 884 deletions

View File

@ -324,7 +324,6 @@
1790B12C09883BFD008A330A /* Dither.cpp in Sources */ = {isa = PBXBuildFile; fileRef = 1790AFF909883BFD008A330A /* Dither.cpp */; };
1790B12E09883BFD008A330A /* Amplify.cpp in Sources */ = {isa = PBXBuildFile; fileRef = 1790AFFE09883BFD008A330A /* Amplify.cpp */; };
1790B12F09883BFD008A330A /* AudioUnitEffect.cpp in Sources */ = {isa = PBXBuildFile; fileRef = 1790B00109883BFD008A330A /* AudioUnitEffect.cpp */; };
1790B13009883BFD008A330A /* LoadAudioUnits.cpp in Sources */ = {isa = PBXBuildFile; fileRef = 1790B00409883BFD008A330A /* LoadAudioUnits.cpp */; };
1790B13409883BFD008A330A /* ChangePitch.cpp in Sources */ = {isa = PBXBuildFile; fileRef = 1790B00C09883BFD008A330A /* ChangePitch.cpp */; };
1790B13509883BFD008A330A /* ChangeSpeed.cpp in Sources */ = {isa = PBXBuildFile; fileRef = 1790B00E09883BFD008A330A /* ChangeSpeed.cpp */; };
1790B13609883BFD008A330A /* ChangeTempo.cpp in Sources */ = {isa = PBXBuildFile; fileRef = 1790B01009883BFD008A330A /* ChangeTempo.cpp */; };
@ -484,6 +483,7 @@
28105DAC0AD09FC500BB4269 /* px_mixer.h in Headers */ = {isa = PBXBuildFile; fileRef = 28105DA20AD09FC500BB4269 /* px_mixer.h */; };
2810644B1818EEB5004F678B /* cpu_detect_x86.cpp in Sources */ = {isa = PBXBuildFile; fileRef = 2810644A1818EEB5004F678B /* cpu_detect_x86.cpp */; };
2810644D1818EED3004F678B /* cpu_detect.h in Headers */ = {isa = PBXBuildFile; fileRef = 2810644C1818EED3004F678B /* cpu_detect.h */; };
2812E9D91A1F773A001C24D3 /* AudioUnitCocoaHelper.m in Sources */ = {isa = PBXBuildFile; fileRef = 2812E9D81A1F773A001C24D3 /* AudioUnitCocoaHelper.m */; };
2816372E0BAE3B6C0079C746 /* LinkingHtmlWindow.cpp in Sources */ = {isa = PBXBuildFile; fileRef = 2816372C0BAE3B6C0079C746 /* LinkingHtmlWindow.cpp */; };
282D474C0B9E8D900034BC49 /* Snap.cpp in Sources */ = {isa = PBXBuildFile; fileRef = 282D474A0B9E8D900034BC49 /* Snap.cpp */; };
283135EC0DFB9D110076D551 /* ImportFFmpeg.cpp in Sources */ = {isa = PBXBuildFile; fileRef = 283135EA0DFB9D110076D551 /* ImportFFmpeg.cpp */; };
@ -1312,7 +1312,6 @@
ED663B9A16543647007F53A5 /* Dither.cpp in Sources */ = {isa = PBXBuildFile; fileRef = 1790AFF909883BFD008A330A /* Dither.cpp */; };
ED663B9B16543647007F53A5 /* Amplify.cpp in Sources */ = {isa = PBXBuildFile; fileRef = 1790AFFE09883BFD008A330A /* Amplify.cpp */; };
ED663B9C16543647007F53A5 /* AudioUnitEffect.cpp in Sources */ = {isa = PBXBuildFile; fileRef = 1790B00109883BFD008A330A /* AudioUnitEffect.cpp */; };
ED663B9D16543647007F53A5 /* LoadAudioUnits.cpp in Sources */ = {isa = PBXBuildFile; fileRef = 1790B00409883BFD008A330A /* LoadAudioUnits.cpp */; };
ED663BA016543647007F53A5 /* ChangePitch.cpp in Sources */ = {isa = PBXBuildFile; fileRef = 1790B00C09883BFD008A330A /* ChangePitch.cpp */; };
ED663BA116543647007F53A5 /* ChangeSpeed.cpp in Sources */ = {isa = PBXBuildFile; fileRef = 1790B00E09883BFD008A330A /* ChangeSpeed.cpp */; };
ED663BA216543647007F53A5 /* ChangeTempo.cpp in Sources */ = {isa = PBXBuildFile; fileRef = 1790B01009883BFD008A330A /* ChangeTempo.cpp */; };
@ -1637,7 +1636,6 @@
ED85B47316A47353006DA21D /* Dither.cpp in Sources */ = {isa = PBXBuildFile; fileRef = 1790AFF909883BFD008A330A /* Dither.cpp */; };
ED85B47416A47353006DA21D /* Amplify.cpp in Sources */ = {isa = PBXBuildFile; fileRef = 1790AFFE09883BFD008A330A /* Amplify.cpp */; };
ED85B47516A47353006DA21D /* AudioUnitEffect.cpp in Sources */ = {isa = PBXBuildFile; fileRef = 1790B00109883BFD008A330A /* AudioUnitEffect.cpp */; };
ED85B47616A47353006DA21D /* LoadAudioUnits.cpp in Sources */ = {isa = PBXBuildFile; fileRef = 1790B00409883BFD008A330A /* LoadAudioUnits.cpp */; };
ED85B47816A47353006DA21D /* ChangePitch.cpp in Sources */ = {isa = PBXBuildFile; fileRef = 1790B00C09883BFD008A330A /* ChangePitch.cpp */; };
ED85B47916A47353006DA21D /* ChangeSpeed.cpp in Sources */ = {isa = PBXBuildFile; fileRef = 1790B00E09883BFD008A330A /* ChangeSpeed.cpp */; };
ED85B47A16A47353006DA21D /* ChangeTempo.cpp in Sources */ = {isa = PBXBuildFile; fileRef = 1790B01009883BFD008A330A /* ChangeTempo.cpp */; };
@ -2846,8 +2844,6 @@
1790AFFF09883BFD008A330A /* Amplify.h */ = {isa = PBXFileReference; fileEncoding = 30; indentWidth = 3; lastKnownFileType = sourcecode.c.h; path = Amplify.h; sourceTree = "<group>"; tabWidth = 3; };
1790B00109883BFD008A330A /* AudioUnitEffect.cpp */ = {isa = PBXFileReference; fileEncoding = 30; indentWidth = 3; lastKnownFileType = sourcecode.cpp.cpp; path = AudioUnitEffect.cpp; sourceTree = "<group>"; tabWidth = 3; };
1790B00209883BFD008A330A /* AudioUnitEffect.h */ = {isa = PBXFileReference; fileEncoding = 30; indentWidth = 3; lastKnownFileType = sourcecode.c.h; path = AudioUnitEffect.h; sourceTree = "<group>"; tabWidth = 3; };
1790B00409883BFD008A330A /* LoadAudioUnits.cpp */ = {isa = PBXFileReference; fileEncoding = 30; indentWidth = 3; lastKnownFileType = sourcecode.cpp.cpp; path = LoadAudioUnits.cpp; sourceTree = "<group>"; tabWidth = 3; };
1790B00509883BFD008A330A /* LoadAudioUnits.h */ = {isa = PBXFileReference; fileEncoding = 30; indentWidth = 3; lastKnownFileType = sourcecode.c.h; path = LoadAudioUnits.h; sourceTree = "<group>"; tabWidth = 3; };
1790B00C09883BFD008A330A /* ChangePitch.cpp */ = {isa = PBXFileReference; fileEncoding = 30; indentWidth = 3; lastKnownFileType = sourcecode.cpp.cpp; path = ChangePitch.cpp; sourceTree = "<group>"; tabWidth = 3; };
1790B00D09883BFD008A330A /* ChangePitch.h */ = {isa = PBXFileReference; fileEncoding = 30; indentWidth = 3; lastKnownFileType = sourcecode.c.h; path = ChangePitch.h; sourceTree = "<group>"; tabWidth = 3; };
1790B00E09883BFD008A330A /* ChangeSpeed.cpp */ = {isa = PBXFileReference; fileEncoding = 30; indentWidth = 3; lastKnownFileType = sourcecode.cpp.cpp; path = ChangeSpeed.cpp; sourceTree = "<group>"; tabWidth = 3; };
@ -3177,6 +3173,8 @@
2812A5B90DF63FF000576305 /* Debug_Static.xcconfig */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = text.xcconfig; path = Debug_Static.xcconfig; sourceTree = "<group>"; };
2812A5BB0DF63FFD00576305 /* Release_Shared.xcconfig */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = text.xcconfig; path = Release_Shared.xcconfig; sourceTree = "<group>"; };
2812A5BD0DF6400E00576305 /* Release_Static.xcconfig */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = text.xcconfig; path = Release_Static.xcconfig; sourceTree = "<group>"; };
2812E9D71A1F773A001C24D3 /* AudioUnitCocoaHelper.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = AudioUnitCocoaHelper.h; sourceTree = "<group>"; };
2812E9D81A1F773A001C24D3 /* AudioUnitCocoaHelper.m */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.objc; path = AudioUnitCocoaHelper.m; sourceTree = "<group>"; };
2813897919E6163C004111ED /* SelectedRegion.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = SelectedRegion.h; sourceTree = "<group>"; };
2816372C0BAE3B6C0079C746 /* LinkingHtmlWindow.cpp */ = {isa = PBXFileReference; fileEncoding = 5; indentWidth = 3; lastKnownFileType = sourcecode.cpp.cpp; path = LinkingHtmlWindow.cpp; sourceTree = "<group>"; tabWidth = 3; };
2816372D0BAE3B6C0079C746 /* LinkingHtmlWindow.h */ = {isa = PBXFileReference; fileEncoding = 5; indentWidth = 3; lastKnownFileType = sourcecode.c.h; path = LinkingHtmlWindow.h; sourceTree = "<group>"; tabWidth = 3; };
@ -5276,10 +5274,10 @@
1790B00009883BFD008A330A /* audiounits */ = {
isa = PBXGroup;
children = (
2812E9D71A1F773A001C24D3 /* AudioUnitCocoaHelper.h */,
2812E9D81A1F773A001C24D3 /* AudioUnitCocoaHelper.m */,
1790B00109883BFD008A330A /* AudioUnitEffect.cpp */,
1790B00209883BFD008A330A /* AudioUnitEffect.h */,
1790B00409883BFD008A330A /* LoadAudioUnits.cpp */,
1790B00509883BFD008A330A /* LoadAudioUnits.h */,
);
path = audiounits;
sourceTree = "<group>";
@ -8860,7 +8858,6 @@
1790B12C09883BFD008A330A /* Dither.cpp in Sources */,
1790B12E09883BFD008A330A /* Amplify.cpp in Sources */,
1790B12F09883BFD008A330A /* AudioUnitEffect.cpp in Sources */,
1790B13009883BFD008A330A /* LoadAudioUnits.cpp in Sources */,
1790B13409883BFD008A330A /* ChangePitch.cpp in Sources */,
1790B13509883BFD008A330A /* ChangeSpeed.cpp in Sources */,
1790B13609883BFD008A330A /* ChangeTempo.cpp in Sources */,
@ -9159,6 +9156,7 @@
28001B3E1A0F0E5D007DD161 /* NumericTextCtrl.cpp in Sources */,
28001B4B1A0F0EB6007DD161 /* SpectralSelectionBar.cpp in Sources */,
28BB98051A15BE6800D1CC80 /* NoiseReduction.cpp in Sources */,
2812E9D91A1F773A001C24D3 /* AudioUnitCocoaHelper.m in Sources */,
);
runOnlyForDeploymentPostprocessing = 0;
};
@ -9373,7 +9371,6 @@
ED663B9A16543647007F53A5 /* Dither.cpp in Sources */,
ED663B9B16543647007F53A5 /* Amplify.cpp in Sources */,
ED663B9C16543647007F53A5 /* AudioUnitEffect.cpp in Sources */,
ED663B9D16543647007F53A5 /* LoadAudioUnits.cpp in Sources */,
ED663BA016543647007F53A5 /* ChangePitch.cpp in Sources */,
ED663BA116543647007F53A5 /* ChangeSpeed.cpp in Sources */,
ED663BA216543647007F53A5 /* ChangeTempo.cpp in Sources */,
@ -9681,7 +9678,6 @@
ED85B47316A47353006DA21D /* Dither.cpp in Sources */,
ED85B47416A47353006DA21D /* Amplify.cpp in Sources */,
ED85B47516A47353006DA21D /* AudioUnitEffect.cpp in Sources */,
ED85B47616A47353006DA21D /* LoadAudioUnits.cpp in Sources */,
ED85B47816A47353006DA21D /* ChangePitch.cpp in Sources */,
ED85B47916A47353006DA21D /* ChangeSpeed.cpp in Sources */,
ED85B47A16A47353006DA21D /* ChangeTempo.cpp in Sources */,
@ -10474,6 +10470,8 @@
"-framework",
CoreAudio,
"-framework",
CoreAudioKit,
"-framework",
CoreMIDI,
"-framework",
AudioUnit,
@ -10825,6 +10823,8 @@
"-framework",
CoreAudio,
"-framework",
CoreAudioKit,
"-framework",
CoreMIDI,
"-framework",
AudioUnit,
@ -11142,6 +11142,8 @@
"-framework",
CoreAudio,
"-framework",
CoreAudioKit,
"-framework",
CoreMIDI,
"-framework",
AudioUnit,
@ -11650,6 +11652,8 @@
"-framework",
CoreAudio,
"-framework",
CoreAudioKit,
"-framework",
CoreMIDI,
"-framework",
AudioUnit,

View File

@ -1869,6 +1869,10 @@ const PluginDescriptor *PluginManager::GetFirstPluginForEffectType(EffectType ty
{
PluginDescriptor & plug = mPluginsIter->second;
bool familyEnabled;
if (type == PluginTypeEffect)
{
gPrefs->Read(plug.GetEffectFamily() + wxT("/Enable"), &familyEnabled, true);
}
gPrefs->Read(plug.GetEffectFamily() + wxT("/Enable"), &familyEnabled, true);
if (plug.IsEnabled() && plug.GetEffectType() == type && familyEnabled)
{

View File

@ -1669,7 +1669,24 @@ sampleCount Effect::RealtimeProcess(int group,
}
// Finally call the plugin to process the block
len = mClient->RealtimeProcess(mCurrentGroup++, clientIn, clientOut, numSamples);
len = 0;
sampleCount maxBlock = mClient->GetBlockSize(numSamples);
for (sampleCount block = 0; block < numSamples; block += maxBlock)
{
sampleCount cnt = (block + maxBlock > numSamples ? numSamples - block : maxBlock);
len += mClient->RealtimeProcess(mCurrentGroup, clientIn, clientOut, cnt);
for (int i = 0 ; i < mNumAudioIn; i++)
{
clientIn[i] += cnt;
}
for (int i = 0 ; i < mNumAudioOut; i++)
{
clientOut[i] += cnt;
}
}
mCurrentGroup++;
}
return len;
@ -1993,7 +2010,8 @@ END_EVENT_TABLE()
EffectUIHost::EffectUIHost(wxWindow *parent,
EffectHostInterface *host,
EffectUIClientInterface *client)
: wxDialog(parent, wxID_ANY, host->GetName())
: wxDialog(parent, wxID_ANY, host->GetName(),
wxDefaultPosition, wxDefaultSize, wxDEFAULT_DIALOG_STYLE|wxRESIZE_BORDER)
{
SetExtraStyle(wxWS_EX_VALIDATE_RECURSIVELY);
@ -2019,6 +2037,7 @@ EffectUIHost::~EffectUIHost()
bool EffectUIHost::Initialize()
{
wxBoxSizer *vs = new wxBoxSizer(wxVERTICAL);
wxBoxSizer *hs = new wxBoxSizer(wxHORIZONTAL);
EffectPanel *w = new EffectPanel(this);
@ -2030,7 +2049,8 @@ bool EffectUIHost::Initialize()
wxSizer *s = CreateStdButtonSizer(this, eSettingsButton | eOkButton | eCancelButton);
vs->Add(w, 1, wxEXPAND);
hs->Add(w, 1, wxEXPAND);
vs->Add(hs, 1, wxEXPAND);
vs->Add(s, 0, wxEXPAND | wxALIGN_CENTER_VERTICAL);
SetSizer(vs);

View File

@ -57,15 +57,6 @@
#include "ChangeTempo.h"
#endif
#ifdef USE_AUDIO_UNITS
#include "audiounits/LoadAudioUnits.h"
#endif
#ifdef USE_VAMP
#include "vamp/LoadVamp.h"
#endif
void LoadEffects()
{
@ -270,12 +261,6 @@ void LoadEffects()
// Analyze menu
em.RegisterEffect(new EffectFindClipping());
#ifdef USE_AUDIO_UNITS
if (gPrefs->Read(wxT("/AudioUnits/Enable"), true)) {
LoadAudioUnits();
}
#endif
}
void UnloadEffects()

View File

@ -554,7 +554,7 @@ bool VSTEffectsModule::RegisterPlugin(PluginManagerInterface & pm, const wxStrin
bool VSTEffectsModule::IsPluginValid(const PluginID & ID,
const wxString & path)
{
return wxFileName::FileExists(path);
return wxFileName::FileExists(path) || wxFileName::DirExists(path);
}
IdentInterface *VSTEffectsModule::CreateInstance(const PluginID & WXUNUSED(ID),

View File

@ -0,0 +1,28 @@
/**********************************************************************
Audacity: A Digital Audio Editor
AudioUnitCocoaHelper.h
Leland Lucius
**********************************************************************/
#ifndef AUDACITY_AUDIOUNIT_COCOA_HELPER_H
#define AUDACITY_AUDIOUNIT_COCOA_HELPER_H
#ifdef __cplusplus
extern "C" {
#endif
#include <AudioUnit/AudioUnitCarbonView.h>
HIViewRef createGeneric(AudioUnit unit);
HIViewRef createCocoa(AudioUnit unit);
HIViewRef createCarbon(AudioUnit unit, WindowRef window, AudioUnitCarbonView *carbonView);
#ifdef __cplusplus
}
#endif
#endif

View File

@ -0,0 +1,301 @@
/**********************************************************************
Audacity: A Digital Audio Editor
AudioUnitCocoaHelper.m
Leland Lucius
*******************************************************************//**
\class AUScrollView
\brief An NSScrollView subclass that hosts AUs
NOTE: I do NOT to Objective-C(++), so if you see ANYTHING wrong do
not hesitate to let me know. -Leland
*//*******************************************************************/
#import <Carbon/Carbon.h>
#import <AudioUnit/AudioUnit.h>
#import <AudioUnit/AUCocoaUIView.h>
#import <CoreAudioKit/CoreAudioKit.h>
#import <AppKit/NSScrollView.h>
#import "AudioUnitCocoaHelper.h"
@interface AUScrollView: NSScrollView
{
NSView *auView;
HIViewRef hiViewRef;
}
- (id)initWithFrame:(NSRect)frameRect;
/* Might be useful for improved resizing
- (void)auResized:(NSNotification *)notification;
- (void)myResized:(NSNotification *)notification;
*/
@end
@implementation AUScrollView
- (id)initWithFrame:(NSRect)frameRect
{
self = [super initWithFrame:frameRect];
return self;
}
- (void)reflectScrolledClipView:(NSClipView *)aClipView
{
[super reflectScrolledClipView:aClipView];
// Force a full refresh as some effects seem to need it
[self setNeedsDisplay:YES];
}
- (BOOL)autoresizesSubviews
{
// Let NSView automatically resize our children
return YES;
}
@end
/* Might be useful for improved resizing. I'd worked up this
really elaborate resizing stuff that "almost" worked. Rather
than spend even more time, I decided to get rid of it all and
let resizing happen as it will. This code should be short
lived anyway as it will probably not be needed once we convert
to wxWidgets 3+.
-(void) setViews:(NSView *)aView hiViewRef:(HIViewRef)hView
{
auView = aView;
hiViewRef = hView;
[[NSNotificationCenter defaultCenter]
addObserver:self
selector:@selector(myResized:) name:NSViewFrameDidChangeNotification object:self];
[[NSNotificationCenter defaultCenter]
addObserver:self
selector:@selector(auResized:) name:NSViewFrameDidChangeNotification object:auView];
}
- (void)myResized:(NSNotification *)notification
{
}
- (void)auResized:(NSNotification *)notification
{
}
*/
///////////////////////////////////////////////////////////////////////////////
// Create a Cocoa based generic AU view wrapped in a Carbon view
///////////////////////////////////////////////////////////////////////////////
HIViewRef createGeneric(AudioUnit unit)
{
HIViewRef hiView = NULL;
OSStatus result;
// Create a generic AU view
NSView *auView = [[AUGenericView alloc] initWithAudioUnit: unit];
if (auView != nil)
{
// Allow expert parameters to be used
[(AUGenericView *) auView setShowsExpertParameters:YES];
// Get the AU view's frame for later
NSRect viewFrame = [auView frame];
// Create the view that will host the AU view
AUScrollView *scrollView =
[[[AUScrollView alloc] initWithFrame:viewFrame] autorelease];
// Not sure if this is necessary, but crashes seemed to occur
// without it.
[scrollView retain];
// Set the scroller options
[scrollView setDrawsBackground:YES];
[scrollView setAutohidesScrollers:YES];
[scrollView setHasHorizontalScroller:YES];
[scrollView setHasVerticalScroller:YES];
[scrollView setBorderType:NSNoBorder];
[scrollView setAutoresizingMask:NSViewWidthSizable|NSViewHeightSizable];
// Let the scrollview know about the AU view
//
// Should the AU view be released after this???
[scrollView setDocumentView:auView];
// [auView release];
// Carbonize it
result = HICocoaViewCreate(scrollView, 0, &hiView);
if (result == noErr)
{
// Resize the HIView to match the AU view
SizeControl(hiView, viewFrame.size.width, viewFrame.size.height);
}
}
return hiView;
}
///////////////////////////////////////////////////////////////////////////////
// Create a Cocoa based custom AU view wrapped in a Carbon view
///////////////////////////////////////////////////////////////////////////////
HIViewRef createCocoa(AudioUnit unit)
{
HIViewRef hiView = NULL;
OSStatus result;
AudioUnitCocoaViewInfo cocoaViewInfo;
UInt32 dataSize = sizeof(AudioUnitCocoaViewInfo);
// Get info about first Cocoa view
result = AudioUnitGetProperty(unit,
kAudioUnitProperty_CocoaUI,
kAudioUnitScope_Global,
0,
&cocoaViewInfo,
&dataSize);
if (result != noErr)
{
return NULL;
}
// Looks like the AU has a Cocoa UI, so load the factory class
NSURL *bundleLoc = (NSURL *) cocoaViewInfo.mCocoaAUViewBundleLocation;
NSString *className = (NSString *) cocoaViewInfo.mCocoaAUViewClass[0];
if (!bundleLoc || !className)
{
return NULL;
}
// Load the bundle
NSBundle *bundle = [NSBundle bundleWithPath: [bundleLoc path]];
if (bundle != nil)
{
// Load the class from the bundle
Class factoryClass = [bundle classNamed: className];
if (factoryClass != nil)
{
// Create an instance of the class
id factoryInst = [[[factoryClass alloc] init] autorelease];
if (factoryInst != nil)
{
// Suggest a resonable size
NSSize size = {800, 600};
// Create the view
NSView *auView = [factoryInst uiViewForAudioUnit: unit withSize: size];
if (auView != nil)
{
// Get the AU views frame for later
NSRect viewFrame = [auView frame];
// Create the view that will host the AU view
AUScrollView *scrollView =
[[[AUScrollView alloc] initWithFrame:viewFrame] autorelease];
// Not sure if this is necessary, but crashes seemed to occur
// without it.
[scrollView retain];
// Set the scroller options
[scrollView setDrawsBackground:YES];
[scrollView setAutohidesScrollers:YES];
[scrollView setHasHorizontalScroller:YES];
[scrollView setHasVerticalScroller:YES];
[scrollView setBorderType:NSNoBorder];
// Let the scrollview know about the AU view
//
// Should the AU view be released after this???
[scrollView setDocumentView:auView];
// Carbonize it
result = HICocoaViewCreate(scrollView, 0, &hiView);
if (result == noErr)
{
// Resize the HIView to match the AU view
SizeControl(hiView, viewFrame.size.width, viewFrame.size.height);
}
}
}
}
// Release the bundle???
// [bundle release];
}
// Release the bundle path
[bundleLoc release];
return hiView;
}
///////////////////////////////////////////////////////////////////////////////
// Create a Carbon based AU view
///////////////////////////////////////////////////////////////////////////////
HIViewRef createCarbon(AudioUnit unit, WindowRef window, AudioUnitCarbonView *carbonView)
{
HIViewRef hiView = NULL;
OSStatus result;
// Retrieve the view component description
ComponentDescription compDesc;
UInt32 dataSize = sizeof(compDesc);
result = AudioUnitGetProperty(unit,
kAudioUnitProperty_GetUIComponentList,
kAudioUnitScope_Global,
0,
&compDesc,
&dataSize);
if (result != noErr)
{
return NULL;
}
// Try to open it
Component comp = FindNextComponent(NULL, &compDesc);
result = OpenAComponent(comp, carbonView);
if (result != noErr)
{
return NULL;
}
// Get the root control
ControlRef root = HIViewGetRoot(window);
GetRootControl(window, &root);
// Find the content view within our window
HIViewRef content;
result = HIViewFindByID(root, kHIViewWindowContentID, &content);
if (result != noErr)
{
CloseComponent(*carbonView);
return NULL;
}
// Suggest a reasonable size
Float32Point loc = {0.0, 0.0};
Float32Point size = {800.0, 600.0};
// And create it
result = AudioUnitCarbonViewCreate(*carbonView,
unit,
window,
root,
&loc,
&size,
&hiView);
return hiView;
}

File diff suppressed because it is too large Load Diff

View File

@ -5,6 +5,7 @@
AudioUnitEffect.h
Dominic Mazzoni
Leland Lucius
**********************************************************************/
@ -18,61 +19,255 @@
#include <AudioUnit/AUNTComponent.h>
#include <AudioUnit/AudioUnitProperties.h>
#include <AudioUnit/AudioUnitCarbonView.h>
#include <AudioToolbox/AudioUnitUtilities.h>
class AudioUnitEffect:public Effect {
#include "audacity/EffectInterface.h"
#include "audacity/ModuleInterface.h"
#include "audacity/PluginInterface.h"
public:
#define AUDIOUNITEFFECTS_VERSION wxT("1.0.0.0");
#define AUDIOUNITEFFECTS_FAMILY L"AudioUnit"
AudioUnitEffect(wxString name, Component component);
class AudioUnitEffect;
WX_DEFINE_ARRAY_PTR(AudioUnitEffect *, AudioUnitEffectArray);
class AudioUnitEffectEventHelper;
class AudioUnitEffect : public EffectClientInterface,
public EffectUIClientInterface
{
public:
AudioUnitEffect(const wxString & path,
const wxString & name,
Component component,
AudioUnitEffect *master = NULL);
virtual ~AudioUnitEffect();
virtual wxString GetEffectName();
// IdentInterface implementation
virtual std::set<wxString> GetEffectCategories();
virtual PluginID GetID();
virtual wxString GetPath();
virtual wxString GetName();
virtual wxString GetVendor();
virtual wxString GetVersion();
virtual wxString GetDescription();
virtual wxString GetEffectIdentifier();
// EffectIdentInterface implementation
virtual wxString GetEffectAction();
virtual EffectType GetType();
virtual wxString GetFamily();
virtual bool IsInteractive();
virtual bool IsDefault();
virtual bool IsLegacy();
virtual bool SupportsRealtime();
virtual bool SupportsAutomation();
virtual bool Init();
// EffectClientInterface implementation
virtual bool PromptUser();
virtual bool SetHost(EffectHostInterface *host);
virtual bool Process();
virtual int GetAudioInCount();
virtual int GetAudioOutCount();
virtual void End();
virtual int GetMidiInCount();
virtual int GetMidiOutCount();
private:
bool SetRateAndChannels(AudioUnit unit,
int numChannels, Float64 sampleRate);
virtual void SetSampleRate(sampleCount rate);
virtual sampleCount GetBlockSize(sampleCount maxBlockSize);
bool ProcessStereo(int count, WaveTrack * left, WaveTrack *right,
sampleCount lstart, sampleCount rstart,
sampleCount len);
virtual sampleCount GetLatency();
virtual sampleCount GetTailSize();
bool DoRender(AudioUnit unit, int numChannels,
float *leftBuffer, float *rightBuffer,
int len, int unitBlockSize,
AudioTimeStamp *timeStamp,
AudioBufferList *bufferList);
virtual bool IsReady();
virtual bool ProcessInitialize();
virtual bool ProcessFinalize();
virtual sampleCount ProcessBlock(float **inbuf, float **outbuf, sampleCount size);
virtual bool RealtimeInitialize();
virtual bool RealtimeAddProcessor(int numChannels, float sampleRate);
virtual bool RealtimeFinalize();
virtual bool RealtimeSuspend();
virtual bool RealtimeResume();
virtual sampleCount RealtimeProcess(int group,
float **inbuf,
float **outbuf,
sampleCount numSamples);
virtual bool ShowInterface(wxWindow *parent, bool forceModal = false);
virtual bool GetAutomationParameters(EffectAutomationParameters & parms);
virtual bool SetAutomationParameters(EffectAutomationParameters & parms);
// EffectUIClientInterface implementation
virtual void SetUIHost(EffectUIHostInterface *host);
virtual bool PopulateUI(wxWindow *parent);
virtual bool ValidateUI();
virtual bool HideUI();
virtual bool CloseUI();
virtual void LoadUserPreset(const wxString & name);
virtual void SaveUserPreset(const wxString & name);
virtual void LoadFactoryPreset(int id);
virtual void LoadFactoryDefaults();
virtual wxArrayString GetFactoryPresets();
virtual void ExportPresets();
virtual void ImportPresets();
virtual void ShowOptions();
// AudioUnitEffect implementation
private:
bool SetRateAndChannels();
bool CopyParameters(AudioUnit srcUnit, AudioUnit dstUnit);
static OSStatus
SimpleAudioRenderCallback(void *inRefCon,
AudioUnitRenderActionFlags *inActionFlags,
const AudioTimeStamp *inTimeStamp,
UInt32 inBusNumber,
UInt32 inNumFrames,
AudioBufferList *ioData);
// Realtime
int GetChannelCount();
void SetChannelCount(int numChannels);
Component GetCarbonViewComponent(OSType subtype);
static OSStatus RenderCallback(void *inRefCon,
AudioUnitRenderActionFlags *inActionFlags,
const AudioTimeStamp *inTimeStamp,
UInt32 inBusNumber,
UInt32 inNumFrames,
AudioBufferList *ioData);
OSStatus Render(AudioUnitRenderActionFlags *inActionFlags,
const AudioTimeStamp *inTimeStamp,
UInt32 inBusNumber,
UInt32 inNumFrames,
AudioBufferList *ioData);
static void EventListenerCallback(void *inCallbackRefCon,
void *inObject,
const AudioUnitEvent *inEvent,
UInt64 inEventHostTime,
AudioUnitParameterValue inParameterValue);
void EventListener(const AudioUnitEvent *inEvent,
AudioUnitParameterValue inParameterValue);
static pascal OSStatus WindowEventHandlerCallback(EventHandlerCallRef handler,
EventRef event,
void *data);
OSStatus WindowEventHandler(EventRef event);
static pascal OSStatus ControlEventHandlerCallback(EventHandlerCallRef handler,
EventRef event,
void *data);
OSStatus ControlEventHandler(EventRef event);
void GetChannelCounts();
void LoadParameters(const wxString & group);
void SaveParameters(const wxString & group);
wxString mPath;
wxString mName;
wxString mVendor;
Component mComponent;
AudioUnit mUnit;
bool mSupportsMono;
bool mSupportsStereo;
float *mLeftBufferForCallback;
float *mRightBufferForCallback;
EffectHostInterface *mHost;
int mAudioIns;
int mAudioOuts;
bool mInteractive;
bool mLatencyDone;
Float64 mLatency; // in seconds...multiply by samplerate
Float64 mTailTime; // in seconds...multiply by samplerate
UInt32 mBlockSize;
double mSampleRate;
int mBufferSize;
bool mUseBufferDelay;
AudioTimeStamp mTimeStamp;
bool mReady;
AudioBufferList *mInputList;
AudioBufferList *mOutputList;
EffectUIHostInterface *mUIHost;
wxWindow *mParent;
wxDialog *mDialog;
wxSizerItem *mContainer;
AudioUnitCarbonView mCarbonView;
bool mUseGUI;
HIViewRef mAUView;
EventTargetRef mEventRef;
bool mIsCocoa;
bool mIsCarbon;
bool mIsGeneric;
AudioUnitEffect *mMaster; // non-NULL if a slave
AudioUnitEffectArray mSlaves;
int mNumChannels;
float **mMasterIn;
int mMasterInLen;
float **mMasterOut;
int mMasterOutLen;
AUEventListenerRef mEventListenerRef;
EventHandlerRef mHandlerRef;
EventHandlerUPP mHandlerUPP;
EventHandlerRef mControlHandlerRef;
EventHandlerUPP mControlHandlerUPP;
AudioUnitEffectEventHelper *mEventHelper;
friend class AudioUnitEffectEventHelper;
};
///////////////////////////////////////////////////////////////////////////////
//
// AudioUnitEffectsModule
//
///////////////////////////////////////////////////////////////////////////////
class AudioUnitEffectsModule : public ModuleInterface
{
public:
AudioUnitEffectsModule(ModuleManagerInterface *moduleManager, const wxString *path);
virtual ~AudioUnitEffectsModule();
// IdentInterface implementatino
virtual wxString GetID();
virtual wxString GetPath();
virtual wxString GetName();
virtual wxString GetVendor();
virtual wxString GetVersion();
virtual wxString GetDescription();
// ModuleInterface implementation
virtual bool Initialize();
virtual void Terminate();
virtual bool AutoRegisterPlugins(PluginManagerInterface & pm);
virtual wxArrayString FindPlugins(PluginManagerInterface & pm);
virtual bool RegisterPlugin(PluginManagerInterface & pm, const wxString & path);
virtual bool IsPluginValid(const PluginID & ID, const wxString & path);
virtual IdentInterface *CreateInstance(const PluginID & ID, const wxString & path);
virtual void DeleteInstance(IdentInterface *instance);
// AudioUnitEffectModule implementation
void LoadAudioUnitsOfType(OSType inAUType, wxArrayString & effects);
Component FindAudioUnit(const wxString & path, wxString & name);
wxString FromOSType(OSType type);
OSType ToOSType(const wxString & type);
private:
ModuleManagerInterface *mModMan;
wxString mPath;
};

View File

@ -1,49 +0,0 @@
/**********************************************************************
Audacity: A Digital Audio Editor
LoadAudioUnits.cpp
Dominic Mazzoni
**********************************************************************/
#include <wx/defs.h>
#include <wx/wx.h>
#include "../EffectManager.h"
#include "AudioUnitEffect.h"
void LoadAudioUnitsOfType(OSType inAUType)
{
ComponentDescription desc;
Component component;
desc.componentType = inAUType;
desc.componentSubType = 0;
desc.componentManufacturer = 0;
desc.componentFlags = 0;
desc.componentFlagsMask = 0;
component = FindNextComponent(NULL, &desc);
while (component != NULL) {
ComponentDescription found;
Handle nameHandle = NewHandle(0);
GetComponentInfo(component, &found, nameHandle, 0, 0);
HLock(nameHandle);
int len = ((const char *)(*nameHandle))[0];
wxString name(((const char *)(*nameHandle)+1), wxConvISO8859_1, len);
HUnlock(nameHandle);
DisposeHandle(nameHandle);
EffectManager::Get().RegisterEffect(new AudioUnitEffect(name, component));
component = FindNextComponent (component, &desc);
}
}
void LoadAudioUnits()
{
LoadAudioUnitsOfType(kAudioUnitType_Effect); //'aufx'
LoadAudioUnitsOfType(kAudioUnitType_MusicEffect); //'aumf'
}

View File

@ -1,11 +0,0 @@
/**********************************************************************
Audacity: A Digital Audio Editor
LoadAudioUnits.h
Dominic Mazzoni
**********************************************************************/
void LoadAudioUnits();

View File

@ -59,7 +59,7 @@ void EffectsPrefs::PopulateOrExchange(ShuttleGui & S)
#if USE_AUDIO_UNITS
S.TieCheckBox(_("Audio Unit"),
wxT("/AudioUnits/Enable"),
wxT("/AudioUnit/Enable"),
true);
#endif