4

マイクのサンプルをキャプチャして ffmpeg で mp3 にエンコードする必要があるオーディオ アプリがあります。

最初にオーディオを構成します。

/**  
     * 作業したい形式を指定する必要があります。
     * 非圧縮の Linear PCM を使用し、生データで作業します。
     * 詳細については、チェックしてください。
     *
     * 8khz でパケット/フレームごとに 16 ビット、2 バイト (短いバイト) が必要です
     */
    AudioStreamBasicDescription audioFormat;
    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);

録音コールバックは次のとおりです。

static OSStatus recordingCallback(void *inRefCon,
                                  AudioUnitRenderActionFlags *ioActionFlags,
                                  const AudioTimeStamp *inTimeStamp,
                                  UInt32 inBusNumber、
                                  UInt32 inNumberFrames、
                                  AudioBufferList *ioData)
{
    NSLog(@"ログ レコード: %lu", inBusNumber);
    NSLog(@"ログ レコード: %lu", inNumberFrames);
    NSLog(@"ログ記録: %lu", (UInt32)inTimeStamp);

    // データはここにレンダリングされます
    AudioBuffer バッファ;

    // ステータスをチェックする変数
    OSStatus ステータス。

    /**
     これは、コールバックを所有するオブジェクトへの参照です。
     */
    AudioProcessor *audioProcessor = (__bridge AudioProcessor*) inRefCon;

    /**
     この時点で、モノラルであるチャンネル数を定義します
     アイフォン用。フレーム数は通常 512 または 1024 です。
     */
    buffer.mDataByteSize = inNumberFrames * sizeof(SInt16); // サンプルサイズ
    buffer.mNumberChannels = 1; // 1 チャンネル

    buffer.mData = malloc( inNumberFrames * sizeof(SInt16) ); // バッファサイズ

    // レンダリングのためにバッファを bufferlist 配列に入れます
    AudioBufferList bufferList;
    bufferList.mNumberBuffers = 1;
    bufferList.mBuffers[0] = バッファ;

    // 入力をレンダリングしてエラーをチェック
    status = AudioUnitRender([audioProcessor audioUnit], ioActionFlags, inTimeStamp, inBusNumber, inNumberFrames, &bufferList);
    [audioProcessor hasError:status:__FILE__:__LINE__];

    // オーディオ プロセッサでバッファリストを処理します
    [audioProcessor processBuffer:&bufferList];

    // バッファをクリーンアップ
    free(bufferList.mBuffers[0].mData);


    //NSLog(@"RECORD");
    noErr を返します。
}

データあり:

インバス番号 = 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 に答える