dimitris-c / AudioStreaming

An AudioPlayer/Streaming library for iOS written in Swift using AVAudioEngine.
MIT License
266 stars 56 forks source link

Adds frame filters to allow recording, monitoring, and observation of audio #18

Closed dimitris-c closed 3 years ago

dimitris-c commented 3 years ago

Description

Adds FrameFilterProcessor class that allows to attach frame filtering to the output node of the underlying AVAudioEngine.

Usage

let player = AudioPlayer(configuration: .init(enableLogs: true))

let outputUrl = \** URL(...) **\

let format = player.mainMixerNode.outputFormat(forBus: 0)

let settings = [
    AVFormatIDKey: kAudioFormatMPEG4AAC,
    AVSampleRateKey: format.sampleRate,
    AVNumberOfChannelsKey: format.channelCount
] as [String : Any]

var audioFile = try? AVAudioFile(
        forWriting: outputUrl,
        settings: settings,
        commonFormat: format.commonFormat,
        interleaved: format.isInterleaved)

let record = FilterEntry(name: "record") { buffer, when in
    try? audioFile?.write(from: buffer)
}

player.frameFiltering.add(entry: record)

See the FrameFiltering protocol for more options on adding and removing filters.

Note

The underlying implementation is using the mainMixerNode and installs a tap on it, this essentially is the output node.

Any custom nodes, including the default rate node, are attached before the mainMixerNode, since the frame filters are run inside the tap of the main mixer the output buffer will include any effects as defined by the attached nodes.

Extra care should be taken since the mainMixerNode is exposed publicly, AVAudioMixerNode allows only one tap for a given bus, since AudioPlayer uses only one bus, installing a tap on bus 0 while using frame filters will result in an exception.