iPhone11 意外数量的音频样本
iPhone11 unexpected number of Audio Samples
我有一个使用 AVAssetWriter
捕获音频和视频的应用程序。它对音频运行快速傅立叶变换 (FFT),以实时创建捕获音频的视觉频谱。
在 iPhone11 发布之前,这一切都运行良好。但是,iPhone 11 的用户报告根本没有捕获音频。我设法缩小了问题的范围 - captureOutput(_ output: AVCaptureOutput, didOutput sampleBuffer: CMSampleBuffer, from connection: AVCaptureConnection)
中返回的样本数是 940 或 941 - 在以前的 phone 模型上,这始终是 1024 个样本。我使用 CMSampleBufferGetNumSamples
来获取样本数。我的 FFT 计算依赖于样本数是 2 的幂,所以它会在较新的模型 iPhones.
上丢弃所有帧
任何人都可以阐明为什么新的 iPhone11 会返回异常数量的样本吗?这是我配置 AVAssetWriter
:
的方式
self.videoWriter = try AVAssetWriter(outputURL: self.outputURL, fileType: AVFileType.mp4)
var videoSettings: [String : Any]
if #available(iOS 11.0, *) {
videoSettings = [
AVVideoCodecKey : AVVideoCodecType.h264,
AVVideoWidthKey : Constants.VIDEO_WIDTH,
AVVideoHeightKey : Constants.VIDEO_HEIGHT,
]
} else {
videoSettings = [
AVVideoCodecKey : AVVideoCodecH264,
AVVideoWidthKey : Constants.VIDEO_WIDTH,
AVVideoHeightKey : Constants.VIDEO_HEIGHT,
]
}
//Video Input
videoWriterVideoInput = AVAssetWriterInput(mediaType: AVMediaType.video, outputSettings: videoSettings)
videoWriterVideoInput?.expectsMediaDataInRealTime = true;
if (videoWriter?.canAdd(videoWriterVideoInput!))!
{
videoWriter?.add(videoWriterVideoInput!)
}
//Audio Settings
let audioSettings : [String : Any] = [
AVFormatIDKey : kAudioFormatMPEG4AAC,
AVSampleRateKey : Constants.AUDIO_SAMPLE_RATE, //Float(44100.0)
AVEncoderBitRateKey : Constants.AUDIO_BIT_RATE, //64000
AVNumberOfChannelsKey: Constants.AUDIO_NUMBER_CHANNELS //1
]
//Audio Input
videoWriterAudioInput = AVAssetWriterInput(mediaType: AVMediaType.audio, outputSettings: audioSettings)
videoWriterAudioInput?.expectsMediaDataInRealTime = true;
if (videoWriter?.canAdd(videoWriterAudioInput!))!
{
videoWriter?.add(videoWriterAudioInput!)
}
您不能假定固定的采样率。根据麦克风和设备的许多其他因素,您不能总是假设它是相同的。这对我正在使用的 FFT 库 (TempiFFT) 没有帮助 - 要使其正常工作,您需要提前检测采样率。
而不是:
let fft = TempiFFT(withSize: 1024, sampleRate: Constants.AUDIO_SAMPLE_RATE)
我需要在启动 AVCaptureSession 时首先检测采样率,然后将检测到的值传递给 FFT 库:
//During initialization of AVCaptureSession
audioSampleRate = Float(AVAudioSession.sharedInstance().sampleRate)
...
//Run FFT calculations
let fft = TempiFFT(withSize: 1024, sampleRate: audioSampleRate)
更新
在某些设备上,您可能无法在循环中收到完整的 1024 个样本(在 iPhone 11 上我收到了 941)- 如果它没有正确的帧数,您可能会遇到意外来自 FFT 的行为。我需要创建一个循环缓冲区来存储每个输出的 return 样本,直到我至少有 1024 个样本来执行 FFT。
我有一个使用 AVAssetWriter
捕获音频和视频的应用程序。它对音频运行快速傅立叶变换 (FFT),以实时创建捕获音频的视觉频谱。
在 iPhone11 发布之前,这一切都运行良好。但是,iPhone 11 的用户报告根本没有捕获音频。我设法缩小了问题的范围 - captureOutput(_ output: AVCaptureOutput, didOutput sampleBuffer: CMSampleBuffer, from connection: AVCaptureConnection)
中返回的样本数是 940 或 941 - 在以前的 phone 模型上,这始终是 1024 个样本。我使用 CMSampleBufferGetNumSamples
来获取样本数。我的 FFT 计算依赖于样本数是 2 的幂,所以它会在较新的模型 iPhones.
任何人都可以阐明为什么新的 iPhone11 会返回异常数量的样本吗?这是我配置 AVAssetWriter
:
self.videoWriter = try AVAssetWriter(outputURL: self.outputURL, fileType: AVFileType.mp4)
var videoSettings: [String : Any]
if #available(iOS 11.0, *) {
videoSettings = [
AVVideoCodecKey : AVVideoCodecType.h264,
AVVideoWidthKey : Constants.VIDEO_WIDTH,
AVVideoHeightKey : Constants.VIDEO_HEIGHT,
]
} else {
videoSettings = [
AVVideoCodecKey : AVVideoCodecH264,
AVVideoWidthKey : Constants.VIDEO_WIDTH,
AVVideoHeightKey : Constants.VIDEO_HEIGHT,
]
}
//Video Input
videoWriterVideoInput = AVAssetWriterInput(mediaType: AVMediaType.video, outputSettings: videoSettings)
videoWriterVideoInput?.expectsMediaDataInRealTime = true;
if (videoWriter?.canAdd(videoWriterVideoInput!))!
{
videoWriter?.add(videoWriterVideoInput!)
}
//Audio Settings
let audioSettings : [String : Any] = [
AVFormatIDKey : kAudioFormatMPEG4AAC,
AVSampleRateKey : Constants.AUDIO_SAMPLE_RATE, //Float(44100.0)
AVEncoderBitRateKey : Constants.AUDIO_BIT_RATE, //64000
AVNumberOfChannelsKey: Constants.AUDIO_NUMBER_CHANNELS //1
]
//Audio Input
videoWriterAudioInput = AVAssetWriterInput(mediaType: AVMediaType.audio, outputSettings: audioSettings)
videoWriterAudioInput?.expectsMediaDataInRealTime = true;
if (videoWriter?.canAdd(videoWriterAudioInput!))!
{
videoWriter?.add(videoWriterAudioInput!)
}
您不能假定固定的采样率。根据麦克风和设备的许多其他因素,您不能总是假设它是相同的。这对我正在使用的 FFT 库 (TempiFFT) 没有帮助 - 要使其正常工作,您需要提前检测采样率。
而不是:
let fft = TempiFFT(withSize: 1024, sampleRate: Constants.AUDIO_SAMPLE_RATE)
我需要在启动 AVCaptureSession 时首先检测采样率,然后将检测到的值传递给 FFT 库:
//During initialization of AVCaptureSession
audioSampleRate = Float(AVAudioSession.sharedInstance().sampleRate)
...
//Run FFT calculations
let fft = TempiFFT(withSize: 1024, sampleRate: audioSampleRate)
更新
在某些设备上,您可能无法在循环中收到完整的 1024 个样本(在 iPhone 11 上我收到了 941)- 如果它没有正确的帧数,您可能会遇到意外来自 FFT 的行为。我需要创建一个循环缓冲区来存储每个输出的 return 样本,直到我至少有 1024 个样本来执行 FFT。