I need to capture audio frames with a frequency of 48000, and Int16 bit frames. I need it in that format cause that is what my client expects. Right now the audio goes through but it sounds really funny. I'm using avcapture session with the following settings.
let audioSettings = [AVFormatIDKey : kAudioFormatLinearPCM,
AVSampleRateKey : 48000,
AVLinearPCMBitDepthKey : 16,
AVLinearPCMIsFloatKey : false] as [String : Any]
I add those settings to AVCaptureDataOutput object
private func setAudioDataOutput() -> EErrorCode {
if dataOutput == nil {
dataOutput = AVCaptureAudioDataOutput()
}
dataOutput!.setSampleBufferDelegate(self, queue: DispatchQueue(label: "myApp.AudioStreaming"))
dataOutput!.audioSettings = audioSettings
guard captureSession!.canAddOutput(dataOutput!) else {
VsLogger.logError(logTag, "setAudioDataOutput() failed to add dataOutput for \(getName() ?? "no name found")")
return .AudioOtherError
}
captureSession!.addOutput(dataOutput!)
return .Success
}
and this is where I get the data from the CMSampleBuffer.
guard let bufferData = self.getBlockDataBuffer(from: buffer) else { return }
delegate.audioDataUpdate(bufferData, Int(sampleDescription.mSampleRate),
Int(sampleDescription.mChannelsPerFrame),
duration)
my getBlockDataBuffer func
private func getBlockDataBuffer(from sampleBuffer: CMSampleBuffer) -> Data? {
guard let blockBuffer = CMSampleBufferGetDataBuffer(sampleBuffer) else { return nil }
let dataLength = CMBlockBufferGetDataLength(blockBuffer)
var blockBufferData = [UInt8](repeating: 0, count: dataLength)
let status = CMBlockBufferCopyDataBytes(blockBuffer, atOffset: 0, dataLength: dataLength,
destination: &blockBufferData)
guard status == noErr else {
return nil
}
return Data(bytes: blockBufferData , count: dataLength)
when I print the AudioStreamBasicDescription I get the following.
sampleDescription.mChannelsPerFrame -> 2
sampleDescription.mSampleRate -> 48000
sampleDescription.mBytesPerFrame -> 2
sampleDescription.mFramesPerPacket -> 1
sampleDescription.mBytesPerPacket -> 2
duration -> 1
and here is what my cmSampleBuffer looks like:
buffer numSamples: 557
buffer duration seconds: 0.011604166666666667
buffer isValid: true
buffer totalSampleSize: 0
buffer numSamples: 557
buffer dataReadiness: ready
sampleDescription: AudioStreamBasicDescription(mSampleRate: 48000.0,
mFormatID: 1819304813,
mFormatFlags: 44,
mBytesPerPacket: 2,
mFramesPerPacket: 1,
mBytesPerFrame: 2,
mChannelsPerFrame: 2,
mBitsPerChannel: 16,
mReserved: 0)
so my settings are not persiting in my capture session?
CodePudding user response:
It turns out (as @RhythmicFistman suggested) I was just missing setting weather or not I wanted the frame to be interleaved. So my settings look like this now:
let audioSettings = [AVFormatIDKey : kAudioFormatLinearPCM,
AVSampleRateKey : 48000,
AVLinearPCMBitDepthKey : 16,
AVLinearPCMIsFloatKey : false,
AVLinearPCMIsNonInterleaved : false] as [String : Any]