Щелчки при использовании LAME для кодирования из PCM в MP3 в iOS

Я не первый с такой проблемой, однако я не смог ее решить.

Я кодирую LinearPCM в MP3 в iOS. Он работает, хотя я испытываю щелчки между каждым буфером.

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);

Однако это также вызовет всплеск (я думаю, в конце кадра вводятся нули). Попытка это заставила меня понять, что я не кодирую некоторые из последних аудиопакетов inBuffer->mAudioData, и это может быть причиной щелчка. Однако я не уверен, как вычислить, сколько из них осталось (если бы я знал, я мог бы просто сохранить эти пакеты в «остаточном» буфере, который добавляется к входящему следующему буферу).

Вот еще немного информации о моих настройках:

У меня есть следующий формат ввода:

- (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 следующим образом:

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);

person JonathanC    schedule 07.11.2012    source источник


Ответы (1)


Раньше я вызывал lame_init() каждый раз, когда кодировал буфер.

Однажды я переместил этот код установки, чтобы он вызывался только после устранения проблемы.

Я предполагаю, что происходит то, что mp3 должен кодировать не менее 1152 кадров за раз, а кодировщик lame_t отслеживает данные, которые не были закодированы при последнем вызове. Итак, lame_encode_buffer может начинаться с того места, где мы остановились.

lame_encode_flush следует использовать только в самом конце файла (иначе несколько последних кадров будут обрезаны, если только количество кадров не кратно 1152 — маловероятно).

person JonathanC    schedule 07.11.2012