ios - Export audio file after adding an effect -
i have audio file want process using effects (like pitch effect) , write final result file.
before process file , save disc let user play pitch effect , listen changes in real time.
this how real time stuff:
let audiosession = avaudiosession.sharedinstance() audiosession.setcategory(avaudiosessioncategoryplayback, error: nil) audiosession.setactive(true, error: nil) audioengine = avaudioengine() audiofile = avaudiofile(forreading: audiourl!, error: nil) audioplayernode = avaudioplayernode() audioengine.attachnode(audioplayernode) changepitcheffect = avaudiounittimepitch() changepitcheffect.pitch = 1.0 // default audioengine.attachnode(changepitcheffect) audioengine.connect(audioplayernode, to: changepitcheffect, format: nil) audioengine.connect(changepitcheffect, to: audioengine.outputnode, format: nil) let framecapacity = uint32(audiofile.length) let buffer = avaudiopcmbuffer(pcmformat: audiofile.processingformat, framecapacity: framecapacity) if audiofile.readintobuffer(buffer, error: nil) { audioengine.startandreturnerror(nil) audioplayernode.schedulebuffer(buffer, attime: nil, options: .loops, completionhandler: nil) audioplayernode.play() // start playing in loop }
then using uislider
let user change value of pitch while listening audio in loop.
so when user finish playing pitch , tap next button, need save audio file chosen pitch value.
my question is, how create new audio file pitch effect?
i don't want record while user listening audio , play pitch effect, want export final result (without playing file of course)
since using avaudiosession
not explicit requirement in title of question, there 2 possible answers:
play through node (with avaudiosession)
install tap on node. see av foundation framework reference.
audioplayernode.installtaponbus(0, buffersize:framelength, format: audioinputnode.outputformatforbus(0), block: {(buffer, time) in let channels = unsafearray(start: buffer.floatchanneldata, length: int(buffer.format.channelcount)) let floats = unsafearray(start: channels[0], length: int(buffer.framelength)) var = 0; < int(self.audiobuffer.framelength); i+=int(self.audiomixernode.outputformatforbus(0).channelcount) { // process } })
the avaudiosession
tap mechanism requires play though. more recording while playing on stack overflow answer @matt.
use audiounit (without avaudiosession)
initialize audiosession
audiosessioninitialize
play & record, set read & write stream, , pass aurendercallbackstruct
pointing data processing code. this, however, precludes capitalizing upon avaudiounittimepitch
. can find out more solution in how realtime recording effect processing on ios article.
Comments
Post a Comment