我有一个音频应用程序,我需要捕获麦克风样本以使用 ffmpeg 编码为 mp3
首先配置音频:
/**
* 我们需要指定我们想要处理的格式。
* 我们使用线性 PCM 导致其未压缩,我们处理原始数据。
*更多信息检查。
*
* 我们想要 16 位,2 个字节(短字节)每个数据包/帧在 8khz
*/
AudioStreamBasicDescription 音频格式;
audioFormat.mSampleRate = SAMPLE_RATE;
audioFormat.mFormatID = kAudioFormatLinearPCM;
audioFormat.mFormatFlags = kAudioFormatFlagIsPacked | kAudioFormatFlagIsSignedInteger;
audioFormat.mFramesPerPacket = 1;
audioFormat.mChannelsPerFrame = 1;
audioFormat.mBitsPerChannel = audioFormat.mChannelsPerFrame*sizeof(SInt16)*8;
audioFormat.mBytesPerPacket = audioFormat.mChannelsPerFrame*sizeof(SInt16);
audioFormat.mBytesPerFrame = audioFormat.mChannelsPerFrame*sizeof(SInt16);
录音回调是:
静态 OSStatus recordingCallback(void *inRefCon,
AudioUnitRenderActionFlags *ioActionFlags,
const AudioTimeStamp *inTimeStamp,
UInt32 inBusNumber,
UInt32 inNumberFrames,
音频缓冲区列表 *ioData)
{
NSLog(@"日志记录:%lu", inBusNumber);
NSLog(@"日志记录:%lu", inNumberFrames);
NSLog(@"日志记录:%lu", (UInt32)inTimeStamp);
// 数据在这里渲染
AudioBuffer 缓冲区;
// 一个我们检查状态的变量
OSStatus 状态;
/**
这是对拥有回调的对象的引用。
*/
AudioProcessor *audioProcessor = (__bridge AudioProcessor*) inRefCon;
/**
在这一点上我们定义了通道数,也就是单声道
为 iPhone。帧数通常为 512 或 1024。
*/
buffer.mDataByteSize = inNumberFrames * sizeof(SInt16); // 样本大小
缓冲区.mNumberChannels = 1; // 一个通道
buffer.mData = malloc(inNumberFrames * sizeof(SInt16)); // 缓冲区大小
// 我们将缓冲区放入缓冲区列表数组中进行渲染
AudioBufferList 缓冲区列表;
bufferList.mNumberBuffers = 1;
bufferList.mBuffers[0] = 缓冲区;
// 渲染输入并检查错误
status = AudioUnitRender([audioProcessor audioUnit], ioActionFlags, inTimeStamp, inBusNumber, inNumberFrames, &bufferList);
[audioProcessor hasError:status:__FILE__:__LINE__];
// 在音频处理器中处理缓冲区列表
[audioProcessor processBuffer:&bufferList];
// 清理缓冲区
免费(bufferList.mBuffers[0].mData);
//NSLog(@"记录");
返回无错误;
}
有数据:
总线编号 = 1
inNumberFrames = 1024
inTimeStamp = 80444304 // 一直都是相同的 inTimeStamp,这很奇怪
但是,我需要对 mp3 进行编码的帧大小是 1152。我该如何配置它?
如果我做缓冲,那意味着延迟,但我想避免这种情况,因为它是一个实时应用程序。如果我使用这种配置,每个缓冲区我都会得到垃圾尾随样本,1152 - 1024 = 128 个坏样本。所有样品均为 SInt16。