4

我有一个音频应用程序,我需要捕获麦克风样本以使用 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。

4

1 回答 1

2

您可以使用属性配置 AudioUnit 将使用的每个切片的帧数kAudioUnitProperty_MaximumFramesPerSlice。但是,我认为在您的情况下最好的解决方案是将传入的音频缓冲到环形缓冲区,然后向您的编码器发出音频可用的信号。由于您要转码为 MP3,因此我不确定在这种情况下实时意味着什么。

于 2012-10-20T16:57:15.237 回答