Created
July 30, 2021 11:21
-
-
Save Ridwy/025eb9318342cdd35fea1f412fde1067 to your computer and use it in GitHub Desktop.
How to use MTAudioProcessingTap in Swift 5
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
// | |
// 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