Re: Using AUVarispeed
Re: Using AUVarispeed
- Subject: Re: Using AUVarispeed
- From: William Stewart <email@hidden>
- Date: Mon, 9 Jan 2006 11:25:32 -0800
On 08/01/2006, at 9:45 PM, Michael Hanna wrote:
Hi all,
based code in PlayFile, I'm creating an augraph as such:
auoutput -- auvarispeed -- aufileplayer
I'd like to control the playback speed without affecting pitch this
way.
The varispeed will change the pitch as the rate changes. You need to
use an AUTimePitch. You can play with this using the AU Lab
application - make a new document with just an output, add a file
player generator track, then you'll see both the varispeed and the
time pitch offered as choices to insert. The parameters that you see
exposed there are the same that you manipulate (and they are defined
in <AudioUnit/AudioUnitParameters.h>
so far I believe I've managed to connect the output of the
fileplayer to the input of the varispeed and the output of the
varispeed to the auoutput:
-(void)makeGraph
{
XThrowIfError (NewAUGraph (&fGraph), "NewAUGraph");
CAComponentDescription cd;
// output node
cd.componentType = kAudioUnitType_Output;
cd.componentSubType = kAudioUnitSubType_DefaultOutput;
cd.componentManufacturer = kAudioUnitManufacturer_Apple;
AUNode outputNode;
XThrowIfError (AUGraphNewNode (fGraph, &cd, 0, NULL, &outputNode),
"AUGraphNewNode");
// varispeed AU node
AUNode varispeedNode;
cd.componentType = kAudioUnitType_FormatConverter;
cd.componentSubType = kAudioUnitSubType_Varispeed;
XThrowIfError (AUGraphNewNode (fGraph, &cd, 0, NULL,
&varispeedNode), "AUGraphNewNode");
// file AU node
AUNode fileNode;
cd.componentType = kAudioUnitType_Generator;
cd.componentSubType = kAudioUnitSubType_AudioFilePlayer;
XThrowIfError (AUGraphNewNode (fGraph, &cd, 0, NULL, &fileNode),
"AUGraphNewNode");
// connect & setup
XThrowIfError (AUGraphOpen (fGraph), "AUGraphOpen");
// install overload listener to detect when something is wrong
AudioUnit anAU;
XThrowIfError (AUGraphGetNodeInfo(fGraph, fileNode, NULL, NULL,
NULL, &anAU), "AUGraphGetNodeInfo");
// here's where we connect the local fileNode reference to the
global AUFile
fFileAU = CAAudioUnit (fileNode, anAU);
// install overload listener to detect when something is wrong
AudioUnit anotherAU;
XThrowIfError (AUGraphGetNodeInfo(fGraph, varispeedNode, NULL,
NULL, NULL, &anotherAU), "AUGraphGetNodeInfo");
// here's where we connect the local varispeedNode reference to
the global AUVarispeed
fVarispeedAU = CAAudioUnit (varispeedNode, anAU);
you probably mean "anotherAU" here, not "anAU" - its always good to
choose good and descriptive variable names (like filePlayerAU,
varipseedAU)
// prepare the file AU for playback
// set its output channels
XThrowIfError (fFileAU.SetNumberChannels (kAudioUnitScope_Output,
0, fFileFormat.NumberChannels()), "SetNumberChannels");
// set the output sample rate of the file AU to be the same as the
file:
XThrowIfError (fFileAU.SetSampleRate (kAudioUnitScope_Output, 0,
fFileFormat.mSampleRate), "SetSampleRate");
// set the input sample rate of the varispeed AU to be the same as
the output of the file AU(ok I'm cheating, I'm getting the file
format sample rate):
That's the right thing to do
XThrowIfError (fVarispeedAU.SetSampleRate (kAudioUnitScope_Input,
0, fFileFormat.mSampleRate), "SetSampleRate");
When you make the connection, the varispeed's input format (sample
rate/num channels) will be set to be the same as the file player's
output, so strictly speaking you don't have to set this here (but it
doesn't hurt). You haven't taken care of the channels though.
// load in the file
XThrowIfError (fFileAU.SetProperty
(kAudioUnitProperty_ScheduledFileIDs,
kAudioUnitScope_Global, 0, &fAudioFile, sizeof
(fAudioFile)), "SetScheduleFile");
// connect file node to varispeed node
XThrowIfError (AUGraphConnectNodeInput (fGraph, fileNode, 0,
varispeedNode, 0), "AUGraphConnectNodeInput");
What format is your varispeed outputing? What would happen for
instance if you loaded a 4 channel file? You haven't set the num
channels on the output of varispeed, so if they don't match, you will
get an error here. My guess is that you have only tested stereo files
up to this point.
// connect varispeed node to output node
XThrowIfError (AUGraphConnectNodeInput (fGraph, varispeedNode, 0,
outputNode, 0), "AUGraphConnectNodeInput");
// AT this point we make sure we have the file player AU initialized
// this also propogates the output format of the AU to the output
unit
XThrowIfError (AUGraphInitialize (fGraph), "AUGraphInitialize");
This is where you'd see the error...
// workaround a race condition in the file player AU
usleep (10 * 1000);
// if we have a surround file, then we should try to tell the
output AU what the order of the channels will be
if (fFileFormat.NumberChannels() > 2) {
UInt32 layoutSize = 0;
OSStatus err;
XThrowIfError (err = AudioFileGetPropertyInfo (fAudioFile,
kAudioFilePropertyChannelLayout, &layoutSize, NULL),
"kAudioFilePropertyChannelLayout");
if (!err && layoutSize) {
char* layout = new char[layoutSize];
err = AudioFileGetProperty(fAudioFile,
kAudioFilePropertyChannelLayout, &layoutSize, layout);
XThrowIfError (err, "Get Layout From AudioFile");
// ok, now get the output AU and set its layout
XThrowIfError (AUGraphGetNodeInfo(fGraph, outputNode, NULL,
NULL, NULL, &anAU), "AUGraphGetNodeInfo");
err = AudioUnitSetProperty (anAU,
kAudioUnitProperty_AudioChannelLayout,
kAudioUnitScope_Input, 0, layout, layoutSize);
I would definitely not use the "auAU" here - good code is self
documenting :-)
XThrowIfError (err, "kAudioUnitProperty_AudioChannelLayout");
delete [] layout;
}
}
XThrowIfError(AudioUnitAddRenderNotify (anAU,
MyRenderNotification, self), "AudioUnitAddRenderNotify");
}
some questions:
am I setting the scope input of the AUVarispeed correctly?
how do I set the initial pitch rate of the AUVarispeed? I'm not
sure which audio unit property this is and how to do it exactly.
Finally, how do I change/set the pitch rate dynamically? Would I
need to set up another render callback, or set it directly, like
fVarispeedAU.SetPitchRate(0.5); or something like that. I looked
through AudioUnitProperties.h and AudioUnitParameters.h and could
not find anything...
// Parameters for the AUVarispeed
enum {
kVarispeedParam_PlaybackRate = 0,
kVarispeedParam_PlaybackCents = 1
};
// Parameters for AUTimePitch, AUOfflineTimePitch, AUPitch
enum {
kTimePitchParam_Rate = 0,
kTimePitchParam_Pitch = 1,
kTimePitchParam_EffectBlend = 2 // only for AUPitch
};
Bill
--
mailto:email@hidden
tel: +1 408 974 4056
________________________________________________________________________
__
"Much human ingenuity has gone into finding the ultimate Before.
The current state of knowledge can be summarized thus:
In the beginning, there was nothing, which exploded" - Terry Pratchett
________________________________________________________________________
__
_______________________________________________
Do not post admin requests to the list. They will be ignored.
Coreaudio-api mailing list (email@hidden)
Help/Unsubscribe/Update your Subscription:
This email sent to email@hidden