Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

SWIFT - Is it possible to save audio from AVAudioEngine, or from AudioPlayerNode? If yes, how?

I've been looking around Swift documentation to save an audio output from AVAudioEngine but I couldn't find any useful tip.
Any suggestion?

Solution I found a way around thanks to matt's answer. Here a sample code of how to save an audio after passing it through an AVAudioEngine (i think that technically it's before)

newAudio = AVAudioFile(forWriting: newAudio.url, settings: nil, error: NSErrorPointer()) 
//Your new file on which you want to save some changed audio, and prepared to be bufferd in some new data...

var audioPlayerNode = AVAudioPlayerNode() //or your Time pitch unit if pitch changed   

//Now install a Tap on the output bus to "record" the transformed file on a our newAudio file.
audioPlayerNode.installTapOnBus(0, bufferSize: (AVAudioFrameCount(audioPlayer.duration)), format: opffb){
        (buffer: AVAudioPCMBuffer!, time: AVAudioTime!)  in 

        if (self.newAudio.length) < (self.audioFile.length){//Let us know when to stop saving the file, otherwise saving infinitely

        self.newAudio.writeFromBuffer(buffer, error: NSErrorPointer())//let's write the buffer result into our file

        }else{
             audioPlayerNode.removeTapOnBus(0)//if we dont remove it, will keep on tapping infinitely
            println("Did you like it? Please, vote up for my question")
        }

    }

Hope this helps !

One issue to solve:

Sometimes, your outputNode is shorter than the input: if you accelerate the time rate by 2, your audio will be 2 times shorter. This is the issue im facing for now since my condition for saving the file is (line 10)

if(newAudio.length) < (self.audioFile.length)//audiofile being the original(long) audio and newAudio being the new changed (shorter) audio.

Any help here?

like image 425
mlk Avatar asked May 08 '15 15:05

mlk


2 Answers

Yes, it's quite easy. You simply put a tap on a node and save the buffer into a file.

Unfortunately this means you have to play through the node. I was hoping that AVAudioEngine would let me process one sound file into another directly, but apparently that's impossible - you have to play and process in real time.

like image 189
matt Avatar answered Oct 22 '22 12:10

matt


Offline rendering Worked for me using GenericOutput AudioUnit. Please check this link, I have done mixing two,three audios offline and combine it to a single file. Not the same scenario but it may help you for getting some idea. core audio offline rendering GenericOutput

like image 28
Abdusha M A Avatar answered Oct 22 '22 11:10

Abdusha M A