Trying to setup an audio unit graph with a buffer of samples as the input -
i trying implement simple audio unit graph goes:
buffer of samples->low pass filter->generic output
where generic output copied new buffer processed further, saved disk, etc.
all of examples can find online having setting audio unit graph involve using generator kaudiounitsubtype_audiofileplayer input source... dealing buffer of samples acquired, examples not help... based on looking around in audiounitproperties.h file, looks should using using kaudiounitsubtype_scheduledsoundplayer?
i can't seem documentation on how hook up, quite stuck , hoping here can me out.
to simplify things, started out trying buffer of samples go straight system output, unable make work...
#import "effectmachine.h" #import <audiotoolbox/audiotoolbox.h> #import "audiohelpers.h" #import "buffer.h" @interface effectmachine () @property (nonatomic, strong) buffer *buffer; @end typedef struct effectmachinegraph { augraph graph; audiounit input; audiounit lowpass; audiounit output; } effectmachinegraph; @implementation effectmachine { effectmachinegraph machine; } -(instancetype)initwithbuffer:(buffer *)buffer { if (self = [super init]) { self.buffer = buffer; // buffer simple wrapper object holds 2 properties: // pointer array of samples (as doubles) , size (number of samples) } return self; } -(void)process { struct effectmachinegraph initialized = {0}; machine = initialized; checkerror(newaugraph(&machine.graph), "newaugraph failed"); audiocomponentdescription outputcd = {0}; outputcd.componenttype = kaudiounittype_output; outputcd.componentsubtype = kaudiounitsubtype_defaultoutput; outputcd.componentmanufacturer = kaudiounitmanufacturer_apple; aunode outputnode; checkerror(augraphaddnode(machine.graph, &outputcd, &outputnode), "augraphaddnode[kaudiounitsubtype_genericoutput] failed"); audiocomponentdescription inputcd = {0}; inputcd.componenttype = kaudiounittype_generator; inputcd.componentsubtype = kaudiounitsubtype_scheduledsoundplayer; inputcd.componentmanufacturer = kaudiounitmanufacturer_apple; aunode inputnode; checkerror(augraphaddnode(machine.graph, &inputcd, &inputnode), "augraphaddnode[kaudiounitsubtype_scheduledsoundplayer] failed"); checkerror(augraphopen(machine.graph), "augraphopen failed"); checkerror(augraphnodeinfo(machine.graph, inputnode, null, &machine.input), "augraphnodeinfo failed"); checkerror(augraphconnectnodeinput(machine.graph, inputnode, 0, outputnode, 0), "augraphconnectnodeinput"); checkerror(augraphinitialize(machine.graph), "augraphinitialize failed"); // prepare input audiobufferlist iodata = {0}; iodata.mnumberbuffers = 1; iodata.mbuffers[0].mnumberchannels = 1; iodata.mbuffers[0].mdatabytesize = (uint32)(2 * self.buffer.size); iodata.mbuffers[0].mdata = self.buffer.samples; scheduledaudioslice slice = {0}; audiotimestamp timestamp = {0}; slice.mtimestamp = timestamp; slice.mnumberframes = (uint32)self.buffer.size; slice.mbufferlist = &iodata; checkerror(audiounitsetproperty(machine.input, kaudiounitproperty_scheduleaudioslice, kaudiounitscope_global, 0, &slice, sizeof(slice)), "audiounitsetproperty[kaudiounitproperty_schedulestarttimestamp] failed"); audiotimestamp starttimestamp = {0}; starttimestamp.mflags = kaudiotimestampsampletimevalid; starttimestamp.msampletime = -1; checkerror(audiounitsetproperty(machine.input, kaudiounitproperty_schedulestarttimestamp, kaudiounitscope_global, 0, &starttimestamp, sizeof(starttimestamp)), "audiounitsetproperty[kaudiounitproperty_schedulestarttimestamp] failed"); checkerror(augraphstart(machine.graph), "augraphstart failed"); // augraphstop(machine.graph); <-- commented out make sure wasn't stopping before finishing playing. // augraphuninitialize(machine.graph); // augraphclose(machine.graph); }
does know doing wrong here?
i think documentation you're looking for.
to summarize: setup augraph, setup audio units & add them graph, write & attach rendercallback function on first node in graph. run graph. note rendercallback app asked provide buffers of samples augraph. you'll need read buffers , fill buffers supplied rendercallback. think you're missing.
if you're on ios8, recommend avaudioengine, helps conceal of grungier boiler-platey details of graphs , effects
extras:
- complete pre-ios8 example code on github
- ios music player app reads audio mp3 library circular buffer , processes via augraph (using mixer & eq au). can see how rendercallback setup read buffer, etc.
- amazing audio engine
- novocaine audio library
Comments
Post a Comment