3

私はこの種の問題を抱えた最初の人ではありませんが、それを解決することはできませんでした。

iOSでLinearPCMをMP3にエンコードしています。各バッファ間でクリックが発生していますが、機能しています。

memset(&mEncodedBuffer, 0, sizeof(mEncodedBuffer));

int encodedBytes = lame_encode_buffer(gfp, (short*)inBuffer->mAudioData,  NULL, inNumberPacketDescriptions, mEncodedBuffer, MP3_BUFFER_SIZE);

NSData* data = [NSData dataWithBytes:mEncodedBuffer length:encodedBytes];

次に、バッファを使用して次のことを行います。

AudioQueueEnqueueBuffer(vc.recordState.queue, inBuffer, 0, NULL);

lame_encode_bufferを呼び出した後、次の行を追加しようとしました。

encodedBytes += lame_encode_flush(gfp, mEncodedBuffer+encodedBytes, 0);

ただし、これによってブリップも発生します(フレームの最後にいくつかの0を入力すると思います)。それを試してみると、inBuffer-> mAudioDataの最後のオーディオパケットの一部をエンコードしておらず、クリックの原因になっている可能性があることに気付きました。ただし、残りのパケットの数を計算する方法がわかりません(わかっている場合は、これらのパケットを、着信する次のバッファーの前に追加される「残りの」バッファーに保存するだけで済みます)。

これが私の設定に関するもう少しの情報です:

私は次のinputFormatを持っています:

- (void)setupSourceAudioFormat:(AudioStreamBasicDescription*)format
 {
     format->mFormatID = kAudioFormatLinearPCM;

     format->mSampleRate = 44100;
     format->mFramesPerPacket = 1;
     format->mChannelsPerFrame = 1;
     format->mBytesPerFrame = 2;
     format->mBytesPerPacket = 2;
     format->mBitsPerChannel = 16;
     format->mReserved = 0;
     format->mFormatFlags = kLinearPCMFormatFlagIsBigEndian |
         kLinearPCMFormatFlagIsSignedInteger |
         kLinearPCMFormatFlagIsPacked;
 }

そして私はこのようにラメを設定します:

lame_t gfp = lame_init();
lame_set_num_channels(gfp, 1);
lame_set_in_samplerate(gfp, 44100);
lame_set_mode(gfp, MONO);
lame_set_brate(gfp, 64);
lame_init_params(gfp);
4

1 に答える 1

3

以前は、バッファをエンコードするたびにlame_init()を呼び出していました。

問題が修正されたときにのみ呼び出されるようにセットアップコードを移動した後。

何が起こっているのかというと、mp3は一度に少なくとも1152フレームをエンコードする必要があり、lame_tエンコーダーは最後の呼び出しでエンコードされなかったデータを追跡します。したがって、lame_encode_bufferは、中断したところから開始できます。

lame_encode_flushは、ファイルの最後でのみ使用する必要があります(または、フレーム数が1152の正確な倍数でない限り、最後の数フレームが切り取られます-ありそうにありません)。

于 2012-11-07T20:21:43.750 に答える