1
0
mirror of https://github.com/cookiengineer/audacity synced 2025-11-08 22:23:59 +01:00

Locate and position the current Audacity source code, and clear a variety of old junk out of the way into junk-branches

This commit is contained in:
ra
2010-01-23 19:44:49 +00:00
commit e74978ba77
1011 changed files with 781704 additions and 0 deletions

View File

@@ -0,0 +1,952 @@
/**********************************************************************
Audacity: A Digital Audio Editor
AudioUnitEffect.cpp
Dominic Mazzoni
*******************************************************************//**
\class AudioUnitEffect
\brief An Effect class that handles a wide range of effects. ??Mac only??
*//****************************************************************//**
\class AudioUnitGUIControl
\brief Used with AudioUnitEffect
*//****************************************************************//**
\class AudioUnitDialog
\brief A Dialog used with AudioUnitEffect
*//*******************************************************************/
#include "AudioUnitEffect.h"
#include <wx/defs.h>
#include <wx/button.h>
#include <wx/control.h>
#include <wx/frame.h>
#include <wx/panel.h>
#include <wx/sizer.h>
#include <wx/settings.h>
#include <wx/tokenzr.h>
#if ((wxMAJOR_VERSION == 2) && (wxMINOR_VERSION < 6))
#error Audio Units support requires wxMac 2.6
#endif
#include <wx/mac/private.h>
//
// Forward declarations of GUI classes
//
class AudioUnitGUIControl : public wxControl
{
public:
inline AudioUnitGUIControl(wxWindow *parent, wxWindowID id,
wxPoint pos, wxSize size,
ControlRef controlRef) {
Create(parent, id, pos, size, controlRef);
}
virtual ~AudioUnitGUIControl();
bool Create(wxWindow *parent, wxWindowID id,
wxPoint pos, wxSize size,
ControlRef controlRef);
void OnMouse(wxMouseEvent &event);
private:
short GetModifiers(wxMouseEvent &event);
DECLARE_EVENT_TABLE()
};
class AudioUnitDialog : public wxDialog
{
public:
AudioUnitDialog(wxWindow *parent, wxWindowID id, wxString title,
AudioUnit unit,
AudioUnitCarbonView carbonView,
Effect *effect);
virtual ~AudioUnitDialog();
void RemoveHandler();
void OnOK(wxCommandEvent &event);
void OnCancel(wxCommandEvent &event);
void OnPreview(wxCommandEvent &event);
private:
AudioUnit mUnit;
AudioUnitGUIControl *mGUIControl;
wxBoxSizer *mMainSizer;
Effect *mEffect;
EventHandlerRef mHandlerRef;
EventHandlerUPP mHandlerUPP;
DECLARE_EVENT_TABLE()
};
//
// AudioUnitEffect
//
AudioUnitEffect::AudioUnitEffect(wxString name, Component component):
mName(name),
mComponent(component)
{
SetEffectFlags(PLUGIN_EFFECT | PROCESS_EFFECT);
mUnit = NULL;
OpenAComponent(mComponent, &mUnit);
}
AudioUnitEffect::~AudioUnitEffect()
{
if (mUnit) {
CloseComponent(mUnit);
}
}
wxString AudioUnitEffect::GetEffectName()
{
return mName;
}
std::set<wxString> AudioUnitEffect::GetEffectCategories()
{
return std::set<wxString>();
}
wxString AudioUnitEffect::GetEffectIdentifier()
{
wxStringTokenizer st(mName, wxT(" "));
wxString id;
// CamelCase the name
while (st.HasMoreTokens()) {
wxString tok = st.GetNextToken();
id += tok.Left(1).MakeUpper() + tok.Mid(1);
}
return id;
}
wxString AudioUnitEffect::GetEffectAction()
{
return wxString::Format(_("Performing Effect: %s"),
mName.c_str());
}
bool AudioUnitEffect::Init()
{
if (!mUnit) {
return false;
}
mSupportsMono = SetRateAndChannels(mUnit, 1, mProjectRate);
mSupportsStereo = SetRateAndChannels(mUnit, 2, mProjectRate);
if (!mSupportsMono && !mSupportsStereo) {
mSupportsMono = SetRateAndChannels(mUnit, 1, 44100.0);
mSupportsStereo = SetRateAndChannels(mUnit, 2, 44100.0);
if (!mSupportsMono && !mSupportsStereo) {
printf("Audio Unit doesn't support mono or stereo.\n");
return false;
}
}
return true;
}
bool AudioUnitEffect::PromptUser()
{
OSErr result;
ComponentDescription desc;
Component carbonViewComponent = NULL;
AudioUnitCarbonView carbonView = NULL;
GetComponentInfo(mComponent, &desc, 0, 0, 0);
carbonViewComponent = GetCarbonViewComponent(desc.componentSubType);
result = OpenAComponent(carbonViewComponent, &carbonView);
if (result != 0) {
printf("Couldn't open carbon view component\n");
return false;
}
AudioUnitDialog dlog(mParent, -1, mName,
mUnit, carbonView, this);
dlog.CentreOnParent();
dlog.ShowModal();
CloseComponent(carbonView);
return (dlog.GetReturnCode() == wxID_OK);
}
bool AudioUnitEffect::Process()
{
bool bGoodResult = true;
CopyInputTracks();
TrackListIterator iter(mOutputTracks);
int count = 0;
Track *left = iter.First();
Track *right;
while(left) {
sampleCount lstart, rstart;
sampleCount len;
GetSamples((WaveTrack *)left, &lstart, &len);
right = NULL;
if (left->GetLinked() && mSupportsStereo) {
right = iter.Next();
GetSamples((WaveTrack *)right, &rstart, &len);
}
bool success = false;
if (!mSupportsStereo && right) {
// If the effect is mono, apply to each channel separately
success = ProcessStereo(count, (WaveTrack *)left, NULL,
lstart, 0, len);
if (success)
success = ProcessStereo(count, (WaveTrack *)right, NULL,
rstart, 0, len);
}
else success = ProcessStereo(count,
(WaveTrack *)left, (WaveTrack *)right,
lstart, rstart, len);
if (!success) {
bGoodResult = false;
break;
}
left = iter.Next();
count++;
}
ReplaceProcessedTracks(bGoodResult);
return bGoodResult;
}
void AudioUnitEffect::End()
{
}
bool AudioUnitEffect::SetRateAndChannels(AudioUnit unit,
int numChannels,
Float64 sampleRate)
{
AudioStreamBasicDescription streamFormat;
ComponentResult auResult;
auResult = AudioUnitSetProperty(unit, kAudioUnitProperty_SampleRate,
kAudioUnitScope_Global, 0,
&sampleRate, sizeof(Float64));
if (auResult != 0) {
printf("Didn't accept sample rate\n");
return false;
}
streamFormat.mSampleRate = sampleRate;
streamFormat.mFormatID = kAudioFormatLinearPCM;
streamFormat.mFormatFlags = kAudioFormatFlagsNativeFloatPacked |
kAudioFormatFlagIsNonInterleaved;
streamFormat.mBitsPerChannel = 32;
streamFormat.mChannelsPerFrame = numChannels;
streamFormat.mFramesPerPacket = 1;
streamFormat.mBytesPerFrame = 4;
streamFormat.mBytesPerPacket = 4;
auResult = AudioUnitSetProperty(unit, kAudioUnitProperty_StreamFormat,
kAudioUnitScope_Input, 0,
&streamFormat,
sizeof(AudioStreamBasicDescription));
if (auResult != 0)
return false;
auResult = AudioUnitSetProperty(unit, kAudioUnitProperty_StreamFormat,
kAudioUnitScope_Output, 0,
&streamFormat,
sizeof(AudioStreamBasicDescription));
if (auResult != 0)
return false;
auResult = AudioUnitSetProperty(unit, kAudioUnitProperty_StreamFormat,
kAudioUnitScope_Global, 0,
&streamFormat,
sizeof(AudioStreamBasicDescription));
if (auResult != 0) {
printf("Didn't accept global stream format\n");
return false;
}
return true;
}
bool AudioUnitEffect::CopyParameters(AudioUnit srcUnit, AudioUnit dstUnit)
{
ComponentResult auResult;
int numParameters, i;
AudioUnitParameterID *parameters;
Float32 parameterValue;
UInt32 size;
// Get number of parameters by passing NULL in the data field and
// getting back the size of the parameter list
size = 0;
auResult = AudioUnitGetProperty(srcUnit, kAudioUnitProperty_ParameterList,
kAudioUnitScope_Global, 0,
NULL, &size);
if (auResult != 0) {
printf("Couldn't get number of parameters\n");
return false;
}
// Now get the list of all parameter IDs
numParameters = size / sizeof(AudioUnitParameterID);
parameters = new AudioUnitParameterID[numParameters];
auResult = AudioUnitGetProperty(srcUnit, kAudioUnitProperty_ParameterList,
kAudioUnitScope_Global, 0,
parameters, &size);
if (auResult != 0) {
printf("Couldn't get parameter list\n");
delete[] parameters;
return false;
}
// Copy the parameters from the main unit to the unit specific to
// this track
for(i=0; i<numParameters; i++) {
auResult = AudioUnitGetParameter(srcUnit, parameters[i],
kAudioUnitScope_Global, 0,
&parameterValue);
if (auResult != 0) {
printf("Couldn't get parameter %d: ID=%d\n", i, (int)parameters[i]);
continue;
}
auResult = AudioUnitSetParameter(dstUnit, parameters[i],
kAudioUnitScope_Global, 0,
parameterValue, 0);
if (auResult != 0)
printf("Couldn't set parameter %d: ID=%d\n", i, (int)parameters[i]);
}
delete[] parameters;
return true;
}
bool AudioUnitEffect::ProcessStereo(int count,
WaveTrack *left, WaveTrack *right,
sampleCount lstart,
sampleCount rstart,
sampleCount len)
{
int numChannels = (right != NULL ? 2 : 1);
Float64 sampleRate = left->GetRate();
AudioUnit trackUnit = mUnit;
AURenderCallbackStruct callbackStruct;
AudioTimeStamp timeStamp;
AudioBufferList *bufferList = NULL;
ComponentResult auResult;
int waveTrackBlockSize;
UInt32 size;
UInt32 unitBlockSize;
float *leftBuffer;
float *rightBuffer;
bool success = true;
if (!SetRateAndChannels(trackUnit, numChannels, sampleRate)) {
printf("Unable to setup audio unit for channels=%d rate=%.1f\n",
numChannels, sampleRate);
return false;
}
unitBlockSize = 0;
size = sizeof(UInt32);
auResult = AudioUnitGetProperty(trackUnit,
kAudioUnitProperty_MaximumFramesPerSlice,
kAudioUnitScope_Global,
0,
&unitBlockSize,
&size);
if (unitBlockSize == 0 || auResult != 0) {
printf("Warning: didn't get audio unit's MaximumFramesPerSlice\n");
printf("Trying to set MaximumFramesPerSlice to 512\n");
unitBlockSize = 512;
auResult = AudioUnitSetProperty(trackUnit,
kAudioUnitProperty_MaximumFramesPerSlice,
kAudioUnitScope_Global,
0,
&unitBlockSize,
sizeof(UInt32));
if (auResult != 0)
printf("Unable to set MaximumFramesPerSlice, rendering may fail...\n");
}
auResult = AudioUnitInitialize(trackUnit);
if (auResult != 0) {
printf("Couldn't initialize audio unit\n");
return false;
}
auResult = AudioUnitReset(trackUnit, kAudioUnitScope_Global, 0);
if (auResult != 0) {
printf("Reset failed.\n");
AudioUnitUninitialize(trackUnit);
return false;
}
callbackStruct.inputProc = SimpleAudioRenderCallback;
callbackStruct.inputProcRefCon = this;
auResult = AudioUnitSetProperty(trackUnit,
kAudioUnitProperty_SetRenderCallback,
kAudioUnitScope_Input,
0,
&callbackStruct,
sizeof(AURenderCallbackStruct));
if (auResult != 0) {
printf("Setting input render callback failed.\n");
AudioUnitUninitialize(trackUnit);
return false;
}
memset(&timeStamp, 0, sizeof(AudioTimeStamp));
timeStamp.mSampleTime = 0; // This is a double-precision number that should
// accumulate the number of frames processed so far
timeStamp.mFlags = kAudioTimeStampSampleTimeValid;
waveTrackBlockSize = left->GetMaxBlockSize() * 2;
leftBuffer = NULL;
rightBuffer = NULL;
mLeftBufferForCallback = NULL;
mRightBufferForCallback = NULL;
if (left) {
leftBuffer = new float[waveTrackBlockSize];
}
if (right) {
rightBuffer = new float[waveTrackBlockSize];
}
bufferList = (AudioBufferList *)malloc(sizeof(UInt32) +
numChannels * sizeof(AudioBuffer));
bufferList->mNumberBuffers = numChannels;
sampleCount originalLen = len;
sampleCount ls = lstart;
sampleCount rs = rstart;
while (len) {
int block = waveTrackBlockSize;
if (block > len) {
block = len;
}
if (left) {
left->Get((samplePtr)leftBuffer, floatSample, ls, block);
}
if (right) {
right->Get((samplePtr)rightBuffer, floatSample, rs, block);
}
success = DoRender(trackUnit, numChannels, leftBuffer, rightBuffer,
block, unitBlockSize, &timeStamp, bufferList);
if (!success) {
break;
}
if (left) {
left->Set((samplePtr)leftBuffer, floatSample, ls, block);
}
if (right) {
right->Set((samplePtr)rightBuffer, floatSample, rs, block);
}
len -= block;
ls += block;
rs += block;
if (left && right) {
if (TrackGroupProgress(count, (ls-lstart)/(double)originalLen)) {
success = false;
break;
}
}
else {
if (TrackProgress(count, (ls-lstart)/(double)originalLen)) {
success = false;
break;
}
}
}
if (bufferList) {
free(bufferList);
}
if (leftBuffer) {
delete[] leftBuffer;
}
if (rightBuffer) {
delete[] rightBuffer;
}
AudioUnitUninitialize(trackUnit);
return success;
}
bool AudioUnitEffect::DoRender(AudioUnit unit,
int numChannels,
float *leftBuffer,
float *rightBuffer,
int len,
int unitBlockSize,
AudioTimeStamp *timeStamp,
AudioBufferList *bufferList)
{
AudioUnitRenderActionFlags flags;
ComponentResult auResult;
int block;
for (int i = 0; i < len; i += block) {
block = unitBlockSize;
if (i + block > len) {
block = len - i;
}
for (int j = 0; j<numChannels; j++) {
bufferList->mBuffers[j].mNumberChannels = 1;
bufferList->mBuffers[j].mData = NULL;
bufferList->mBuffers[j].mDataByteSize = sizeof(float) * block;
}
if (leftBuffer) {
mLeftBufferForCallback = &leftBuffer[i];
bufferList->mBuffers[0].mData = mLeftBufferForCallback;
}
if (rightBuffer) {
mRightBufferForCallback = &rightBuffer[i];
bufferList->mBuffers[1].mData = mRightBufferForCallback;
}
flags = 0;
auResult = AudioUnitRender(unit, &flags, timeStamp,
0, block, bufferList);
if (auResult != 0) {
printf("Render failed: %d %4.4s\n", (int)auResult, (char *)&auResult);
return false;
}
timeStamp->mSampleTime += block;
}
return true;
}
// static
OSStatus AudioUnitEffect::SimpleAudioRenderCallback
(void *inRefCon,
AudioUnitRenderActionFlags *inActionFlags,
const AudioTimeStamp *inTimeStamp,
UInt32 inBusNumber,
UInt32 inNumFrames,
AudioBufferList *ioData)
{
AudioUnitEffect *This = (AudioUnitEffect *)inRefCon;
if (This->mLeftBufferForCallback) {
ioData->mBuffers[0].mData = This->mLeftBufferForCallback;
}
if (This->mRightBufferForCallback) {
ioData->mBuffers[1].mData = This->mRightBufferForCallback;
}
return 0;
}
Component AudioUnitEffect::GetCarbonViewComponent(OSType subtype)
{
ComponentDescription desc;
Component component;
desc.componentType = kAudioUnitCarbonViewComponentType; // 'auvw'
desc.componentSubType = subtype;
desc.componentManufacturer = 0;
desc.componentFlags = 0;
desc.componentFlagsMask = 0;
// First see if we can find a carbon view designed specifically for this
// plug-in:
component = FindNextComponent(NULL, &desc);
if (component)
return component;
// If not, grab the generic carbon view, which will create a GUI for
// any Audio Unit.
desc.componentSubType = kAUCarbonViewSubType_Generic;
component = FindNextComponent(NULL, &desc);
return component;
}
//
// AudioUnitGUIControl methods
//
BEGIN_EVENT_TABLE(AudioUnitGUIControl, wxControl)
EVT_MOUSE_EVENTS(AudioUnitGUIControl::OnMouse)
END_EVENT_TABLE()
AudioUnitGUIControl::~AudioUnitGUIControl()
{
// Don't want to dispose of it...
m_peer = NULL;
}
bool AudioUnitGUIControl::Create(wxWindow *parent, wxWindowID id,
wxPoint pos, wxSize size,
ControlRef controlRef)
{
m_macIsUserPane = FALSE ;
if ( !wxControl::Create(parent, id, pos, size,
0, wxDefaultValidator,
wxString(wxT("AudioUnitControl"))) )
return false;
m_peer = new wxMacControl(this, controlRef);
Rect outBounds;
GetControlBounds(controlRef, &outBounds);
pos.x = outBounds.left;
pos.y = outBounds.top;
size.x = outBounds.right - outBounds.left;
size.y = outBounds.bottom - outBounds.top;
MacPostControlCreate(pos, size);
return true;
}
short AudioUnitGUIControl::GetModifiers(wxMouseEvent &event)
{
short modifiers = 0;
if ( !event.m_leftDown && !event.m_rightDown )
modifiers |= btnState ;
if ( event.m_shiftDown )
modifiers |= shiftKey ;
if ( event.m_controlDown )
modifiers |= controlKey ;
if ( event.m_altDown )
modifiers |= optionKey ;
if ( event.m_metaDown )
modifiers |= cmdKey ;
return modifiers;
}
void AudioUnitGUIControl::OnMouse(wxMouseEvent &event)
{
int x = event.m_x ;
int y = event.m_y ;
MacClientToRootWindow( &x , &y ) ;
Point localwhere ;
ControlHandle control;
localwhere.h = x ;
localwhere.v = y ;
short modifiers = GetModifiers(event);
if (event.GetEventType() == wxEVT_LEFT_DOWN ||
event.GetEventType() == wxEVT_LEFT_DCLICK ) {
#if ((wxMAJOR_VERSION == 2) && (wxMINOR_VERSION <= 4))
WindowRef rootWindow = (WindowRef)GetParent()->MacGetRootWindow();
#else
WindowRef rootWindow = (WindowRef)GetParent()->MacGetTopLevelWindowRef();
#endif
ControlPartCode code;
code = FindControl(localwhere,
rootWindow,
&control);
if (code) {
Rect outBounds;
GetControlBounds((ControlRef)control, &outBounds);
code = ::HandleControlClick(control,
localwhere, modifiers,
(ControlActionUPP)-1) ;
}
}
}
//
// AudioUnitDialog methods
//
// Event handler to capture the window close event
static const EventTypeSpec eventList[] =
{
{kEventClassWindow, kEventWindowClose},
};
static pascal OSStatus EventHandler(EventHandlerCallRef handler, EventRef event, void *data)
{
OSStatus result = eventNotHandledErr;
AudioUnitDialog *dlg = (AudioUnitDialog *)data;
if (GetEventClass(event) == kEventClassWindow && GetEventKind(event) == kEventWindowClose) {
dlg->RemoveHandler();
dlg->Close();
result = noErr;
}
return result;
}
void EventListener(void *inUserData, AudioUnitCarbonView inView,
const AudioUnitParameter *inParameter,
AudioUnitCarbonViewEventID inEvent,
const void *inEventParam)
{
// We're not actually using this yet...
}
enum {
PreviewID = 1
};
BEGIN_EVENT_TABLE(AudioUnitDialog, wxDialog)
EVT_BUTTON(wxID_OK, AudioUnitDialog::OnOK)
EVT_BUTTON(wxID_CANCEL, AudioUnitDialog::OnCancel)
EVT_BUTTON(PreviewID, AudioUnitDialog::OnPreview)
END_EVENT_TABLE()
AudioUnitDialog::AudioUnitDialog(wxWindow *parent, wxWindowID id,
wxString title,
AudioUnit unit,
AudioUnitCarbonView carbonView,
Effect *effect):
mUnit(unit),
mEffect(effect),
mHandlerUPP(NULL),
mHandlerRef(NULL)
{
long style = wxDEFAULT_DIALOG_STYLE;
#if ((wxMAJOR_VERSION == 2) && (wxMINOR_VERSION <= 4))
wxDialog::Create(parent, id, title,
wxDefaultPosition, wxSize(500, 400),
style, title);
#else
// wxMac 2.5 version, all of this is just to attempt to turn off
// compositing...
// From wxDialog::Create
SetExtraStyle(GetExtraStyle() | wxTOPLEVEL_EX_DIALOG);
style |= wxTAB_TRAVERSAL;
// From wxTopLevelWindow::Create
wxTopLevelWindow::Init();
m_windowStyle = style;
// We added this line because many plug-ins are not happy with
// compositing...Requires a patch to wx such that the line
// "attr |= kWindowCompositingAttribute" only happens
// if m_macUsesCompositing is true...
//
// LL: Unfortunately, wxWidgets 2.7+ doesn't have a direct
// way to disable compositing, so bypass it until a way
// is found.
#if !wxCHECK_VERSION(2, 7, 0)
m_macUsesCompositing = false;
#endif
// Rest of wxTopLevelWindow::Create
SetName(title);
m_windowId = id == -1 ? NewControlId() : id;
MacCreateRealWindow(title, wxDefaultPosition, wxSize(500, 400),
MacRemoveBordersFromStyle(style) , title) ;
SetBackgroundColour(wxSystemSettings::GetColour(wxSYS_COLOUR_3DFACE));
wxTopLevelWindows.Append(this);
if ( parent )
parent->AddChild(this);
#endif
//
// On to our own code
//
WindowRef windowRef = (WindowRef)MacGetWindowRef();
ComponentResult auResult;
ControlRef rootControl = NULL;
GetRootControl(windowRef, &rootControl);
int width = 500;
int height = 400;
Float32Point location = {0, 0};
Float32Point size = {width, height};
ControlRef audioUnitControl = NULL;
auResult = AudioUnitCarbonViewCreate(carbonView,
unit,
windowRef,
rootControl,
&location,
&size,
&audioUnitControl);
AudioUnitCarbonViewSetEventListener(carbonView, EventListener, this);
mMainSizer = new wxBoxSizer(wxVERTICAL);
if (auResult == 0) {
mGUIControl = new AudioUnitGUIControl(this, -1,
wxPoint(0, 0),
wxSize(width, height),
audioUnitControl);
// Eventually, to handle resizing controls, call:
// AudioUnitCarbonViewSetEventListener with the event:
// kEventControlBoundsChanged
mMainSizer->Add(mGUIControl, 1, wxEXPAND);
mGUIControl->SetFocus();
}
else
mGUIControl = NULL;
wxBoxSizer *hSizer = new wxBoxSizer(wxHORIZONTAL);
wxButton *preview = new wxButton(this, PreviewID, _("Pre&view"));
hSizer->Add(preview, 0, wxALL, 10);
hSizer->Add(10, 10);
wxButton *ok = new wxButton(this, wxID_OK, _("OK"));
ok->SetDefault();
ok->SetFocus();
hSizer->Add(ok, 0, wxALL, 10);
wxButton *cancel = new wxButton(this, wxID_CANCEL, _("&Cancel"));
hSizer->Add(cancel, 0, wxALL, 10);
mMainSizer->Add(hSizer, 0, wxALIGN_CENTER);
this->SetAutoLayout(true);
this->SetSizer(mMainSizer);
mMainSizer->Fit(this);
mMainSizer->SetSizeHints(this);
// Some VST effects do not work unless the default handler is removed since
// it captures many of the events that the plugins need. But, it must be
// done last since proper window sizing will not occur otherwise.
::RemoveEventHandler((EventHandlerRef)MacGetEventHandler());
// Install a bare minimum handler so we can capture the window close event. If
// it's not captured, we will crash at Audacity termination since the window
// is still on the wxWidgets toplevel window lists, but it's already gone.
mHandlerUPP = NewEventHandlerUPP(EventHandler);
InstallWindowEventHandler(windowRef,
mHandlerUPP,
GetEventTypeCount(eventList),
eventList,
this,
&mHandlerRef);
}
AudioUnitDialog::~AudioUnitDialog()
{
RemoveHandler();
}
void AudioUnitDialog::RemoveHandler()
{
if (mHandlerRef) {
::RemoveEventHandler(mHandlerRef);
mHandlerRef = NULL;
MacInstallTopLevelWindowEventHandler();
}
if (mHandlerUPP) {
DisposeEventHandlerUPP(mHandlerUPP);
mHandlerUPP = NULL;
}
}
void AudioUnitDialog::OnOK(wxCommandEvent &event)
{
EndModal(wxID_OK);
}
void AudioUnitDialog::OnCancel(wxCommandEvent &event)
{
EndModal(wxID_CANCEL);
}
void AudioUnitDialog::OnPreview(wxCommandEvent &event)
{
mEffect->Preview();
}
// Indentation settings for Vim and Emacs and unique identifier for Arch, a
// version control system. Please do not modify past this point.
//
// Local Variables:
// c-basic-offset: 3
// indent-tabs-mode: nil
// End:
//
// vim: et sts=3 sw=3
// arch-tag: 21aef079-ec47-4ff9-a359-7d159e2ba0e6

View File

@@ -0,0 +1,91 @@
/**********************************************************************
Audacity: A Digital Audio Editor
AudioUnitEffect.h
Dominic Mazzoni
**********************************************************************/
#include <wx/dialog.h>
#include "../Effect.h"
#include <ApplicationServices/ApplicationServices.h>
#include <CoreServices/CoreServices.h>
#include <Carbon/Carbon.h>
#include <AudioUnit/AUNTComponent.h>
#include <AudioUnit/AudioUnitProperties.h>
#include <AudioUnit/AudioUnitCarbonView.h>
class AudioUnitEffect:public Effect {
public:
AudioUnitEffect(wxString name, Component component);
virtual ~AudioUnitEffect();
virtual wxString GetEffectName();
virtual std::set<wxString> GetEffectCategories();
virtual wxString GetEffectIdentifier();
virtual wxString GetEffectAction();
virtual bool Init();
virtual bool PromptUser();
virtual bool Process();
virtual void End();
private:
bool SetRateAndChannels(AudioUnit unit,
int numChannels, Float64 sampleRate);
bool ProcessStereo(int count, WaveTrack * left, WaveTrack *right,
sampleCount lstart, sampleCount rstart,
sampleCount len);
bool DoRender(AudioUnit unit, int numChannels,
float *leftBuffer, float *rightBuffer,
int len, int unitBlockSize,
AudioTimeStamp *timeStamp,
AudioBufferList *bufferList);
bool CopyParameters(AudioUnit srcUnit, AudioUnit dstUnit);
static OSStatus
SimpleAudioRenderCallback(void *inRefCon,
AudioUnitRenderActionFlags *inActionFlags,
const AudioTimeStamp *inTimeStamp,
UInt32 inBusNumber,
UInt32 inNumFrames,
AudioBufferList *ioData);
Component GetCarbonViewComponent(OSType subtype);
wxString mName;
Component mComponent;
AudioUnit mUnit;
bool mSupportsMono;
bool mSupportsStereo;
float *mLeftBufferForCallback;
float *mRightBufferForCallback;
};
// Indentation settings for Vim and Emacs and unique identifier for Arch, a
// version control system. Please do not modify past this point.
//
// Local Variables:
// c-basic-offset: 3
// indent-tabs-mode: nil
// End:
//
// vim: et sts=3 sw=3
// arch-tag:

View File

@@ -0,0 +1,56 @@
/**********************************************************************
Audacity: A Digital Audio Editor
LoadAudioUnits.cpp
Dominic Mazzoni
**********************************************************************/
#include <wx/defs.h>
#include <wx/wx.h>
#include "../EffectManager.h"
#include "AudioUnitEffect.h"
void LoadAudioUnits()
{
ComponentDescription desc;
Component component;
desc.componentType = kAudioUnitType_Effect; //'aufx'
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);
}
}
// Indentation settings for Vim and Emacs and unique identifier for Arch, a
// version control system. Please do not modify past this point.
//
// Local Variables:
// c-basic-offset: 3
// indent-tabs-mode: nil
// End:
//
// vim: et sts=3 sw=3
// arch-tag:

View File

@@ -0,0 +1,23 @@
/**********************************************************************
Audacity: A Digital Audio Editor
LoadAudioUnits.h
Dominic Mazzoni
**********************************************************************/
void LoadAudioUnits();
// Indentation settings for Vim and Emacs and unique identifier for Arch, a
// version control system. Please do not modify past this point.
//
// Local Variables:
// c-basic-offset: 3
// indent-tabs-mode: nil
// End:
//
// vim: et sts=3 sw=3
// arch-tag: