Skip to content

Instantly share code, notes, and snippets.

@Ridwy
Created July 30, 2021 11:21
Show Gist options
  • Star 3 You must be signed in to star a gist
  • Fork 0 You must be signed in to fork a gist
  • Save Ridwy/025eb9318342cdd35fea1f412fde1067 to your computer and use it in GitHub Desktop.
Save Ridwy/025eb9318342cdd35fea1f412fde1067 to your computer and use it in GitHub Desktop.
How to use MTAudioProcessingTap in Swift 5
//
// Created by Chiharu Nameki @Ridwy on 2021/07/30.
//
import UIKit
import AVFoundation
/*
Using MTAudioProcessingTap, you can touch raw audio samples playing with AVPlayer.
This sample code shows how to use MTAudioProcessingTap in Swift 5.
*/
class ViewController: UIViewController {
// MTAudioProcessingTap works loacal and remote files, but not support streaming.
private let player = AVPlayer(url: Bundle.main.url(forResource: "sample", withExtension: "mp3")!)
override func viewDidLoad() {
super.viewDidLoad()
guard let track = player.currentItem?.asset.tracks(withMediaType: .audio).first else {
return
}
let audioMix = AVMutableAudioMix()
let params = AVMutableAudioMixInputParameters(track: track)
var callbacks = MTAudioProcessingTapCallbacks(version: kMTAudioProcessingTapCallbacksVersion_0, clientInfo: nil)
{ tap, _, tapStorageOut in
// initialize
} finalize: { tap in
// clean up
} prepare: { tap, maxFrames, processingFormat in
// allocate memory for sound processing
} unprepare: { tap in
// deallocate memory for sound processing
} process: { tap, numberFrames, flags, bufferListInOut, numberFramesOut, flagsOut in
guard noErr == MTAudioProcessingTapGetSourceAudio(tap, numberFrames, bufferListInOut, flagsOut, nil, numberFramesOut) else {
return
}
// retrieve AudioBuffer using UnsafeMutableAudioBufferListPointer
for buffer in UnsafeMutableAudioBufferListPointer(bufferListInOut) {
// process audio samples here
//memset(buffer.mData, 0, Int(buffer.mDataByteSize))
}
}
var tap: Unmanaged<MTAudioProcessingTap>?
let error = MTAudioProcessingTapCreate(kCFAllocatorDefault, &callbacks, kMTAudioProcessingTapCreationFlag_PreEffects, &tap)
assert(error == noErr)
params.audioTapProcessor = tap?.takeUnretainedValue()
tap?.release()
audioMix.inputParameters = [params]
player.currentItem?.audioMix = audioMix
player.play()
}
}
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment