-
-
Save fewlinesofcode/e18a84965366bd0fec6493ab6481d721 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