Last active
November 3, 2017 03:31
-
-
Save zonble/f7b2c52f724de196f0cc86fdbfd90378 to your computer and use it in GitHub Desktop.
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
import UIKit | |
import AVFoundation | |
class ViewController: UIViewController { | |
var audioEngine = AVAudioEngine() | |
var audioData = Data() | |
override func viewDidLoad() { | |
super.viewDidLoad() | |
func toData(PCMBuffer: AVAudioPCMBuffer) -> Data { | |
let channelCount = 1 // given PCMBuffer channel count is 1 | |
let channels = UnsafeBufferPointer(start: PCMBuffer.int16ChannelData, count: channelCount) | |
let ch0Data = NSData(bytes: channels[0], length:Int(PCMBuffer.frameCapacity * PCMBuffer.format.streamDescription.pointee.mBytesPerFrame)) as Data | |
return ch0Data | |
} | |
guard let outputFormat = AVAudioFormat(commonFormat: .pcmFormatInt16, sampleRate: 16_000, channels: AVAudioChannelCount(1), interleaved: false) else { | |
return | |
} | |
let inputFormat = self.audioEngine.inputNode.outputFormat(forBus: 0) | |
let converter = AVAudioConverter(from: inputFormat, to: outputFormat) | |
self.audioEngine.inputNode.installTap(onBus: AVAudioNodeBus(0), bufferSize: AVAudioFrameCount(32000), format: self.audioEngine.inputNode.outputFormat(forBus: 0)) { (pcmBuffer, time) in | |
guard let outputBuffer = AVAudioPCMBuffer(pcmFormat: outputFormat, frameCapacity:pcmBuffer.frameCapacity) else { | |
return | |
} | |
outputBuffer.frameLength = pcmBuffer.frameLength | |
let inputBlock: AVAudioConverterInputBlock = { inNumPackets, outStatus in | |
outStatus.pointee = AVAudioConverterInputStatus.haveData | |
return pcmBuffer | |
} | |
var error:NSError? = nil | |
converter?.convert(to: outputBuffer, error: &error, withInputFrom: inputBlock) | |
self.audioData.append(toData(PCMBuffer: outputBuffer)) | |
} | |
self.audioEngine.prepare() | |
do { | |
try self.audioEngine.start() | |
} catch { | |
print("\(error)") | |
} | |
} | |
} |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment
因為 resample 後 buffer 有意義的長度也會改變,converter 好像會把 frameCapacity 的長度塞滿(不確定),outputBuffer 若給一樣長,在down-sampling 時就會出現重複的音,比如說「今天」,聽到結果會變成「今天今天今天」(48_000 -> 16_000 時),所以下面這段 buffer declaration
可以改成如下以避免此問題