OpenSL на Android играет с большей скоростью, чем должен

Мне удалось создать контекст OpenSL и все такое, чтобы он воспроизводил звук.
Но у меня все еще есть проблема: я установил samplesPerSec для своего проигрывателя на 44.100 Hz, но на самом деле он работает на ~ 70.000 Hz. Как это можно исправить?

Что ж, я покажу вам, что я сделал (полностью на исходный код):

В PolyOpenSLInterface.cpp я инициализирую OpenSL и запускаю поставить буфер в очередь на мой SLAndroidSimpleBufferQueueItf. Я создаю Player следующим образом:

SLDataLocator_AndroidSimpleBufferQueue lDataLocatorIn;
lDataLocatorIn.locatorType = SL_DATALOCATOR_ANDROIDSIMPLEBUFFERQUEUE;
lDataLocatorIn.numBuffers = 1;

SLDataFormat_PCM lDataFormat;
lDataFormat.formatType = SL_DATAFORMAT_PCM;
lDataFormat.numChannels = POLY_NUM_CHANNELS;
lDataFormat.samplesPerSec = SL_SAMPLINGRATE_44_1; //sampling rate 44.100Hz
lDataFormat.bitsPerSample = SL_PCMSAMPLEFORMAT_FIXED_16;
lDataFormat.containerSize = SL_PCMSAMPLEFORMAT_FIXED_16;
if(POLY_NUM_CHANNELS > 1){
    lDataFormat.channelMask = SL_SPEAKER_FRONT_RIGHT | SL_SPEAKER_FRONT_LEFT;
} else {
    lDataFormat.channelMask = SL_SPEAKER_FRONT_CENTER;
}
lDataFormat.endianness = SL_BYTEORDER_LITTLEENDIAN;

SLDataSource lDataSource;
lDataSource.pLocator = &lDataLocatorIn;
lDataSource.pFormat = &lDataFormat;

SLDataLocator_OutputMix lDataLocatorOut;
lDataLocatorOut.locatorType = SL_DATALOCATOR_OUTPUTMIX;
lDataLocatorOut.outputMix = mOutputMixObj;

SLDataSink lDataSink;
lDataSink.pLocator = &lDataLocatorOut;
lDataSink.pFormat = NULL;

const SLuint32 lSoundPlayerIIDCount = 2;
const SLInterfaceID lSoundPlayerIIDs[] = { SL_IID_PLAY, SL_IID_ANDROIDSIMPLEBUFFERQUEUE };
const SLboolean lSoundPlayerReqs[] = { SL_BOOLEAN_TRUE, SL_BOOLEAN_TRUE };

lRes = (*mEngine)->CreateAudioPlayer(mEngine, &mPlayerObj, &lDataSource, &lDataSink, lSoundPlayerIIDCount, lSoundPlayerIIDs, lSoundPlayerReqs);
lRes = (*mPlayerObj)->Realize(mPlayerObj, SL_BOOLEAN_FALSE);

Мой зарегистрированный обратный вызов выглядит так (я беру уже использованный буфер, записываю в него следующие сэмплы и снова ставлю буфер в очередь):

void OpenSLAudioInterface::queueCallback(SLAndroidSimpleBufferQueueItf caller, void* pContext){
    OpenSLAudioInterface *audioInterface = (OpenSLAudioInterface*) pContext;
    if(audioInterface->buffer && audioInterface->getMixer()) {
        int16_t *out = (int16_t*)audioInterface->buffer;
        audioInterface->getMixer()->mixIntoBuffer(out, POLY_FRAMES_PER_BUFFER);
        (*(audioInterface->mPlayerQueue))->Enqueue(audioInterface->mPlayerQueue, out, sizeof(int16_t)*POLY_FRAMES_PER_BUFFER*POLY_NUM_CHANNELS);
    }
}

Итак, кто-нибудь может объяснить, почему звук воспроизводится ~2 times faster, чем должен быть, и почему сэмплы, которые мне нужно смешать, чтобы заполнить буфер, превышают 44,100 Гц в ~2 раз?
Нужно ли мне использовать кольцевой буфер (это тот, который я использую здесь, все еще используется OpenSL?)?

Спасибо за каждое предложение и помощь заранее!


person fodinabor    schedule 02.06.2016    source источник
comment
lDataFormat.samplesPerSec = SL_SAMPLINGRATE_48; у вас частота дискретизации 48 кГц, но вы сказали, что пытаетесь воспроизвести звук в 44,1 кГц. И еще одна вещь из этой строки lDataFormat.bitsPerSample = SL_PCMSAMPLEFORMAT_FIXED_16; - я вижу, что это 16-битные аудиоданные PCM на выборку. Но обычно SL_PCMSAMPLEFORMAT_FIXED_8 встречается в большинстве случаев.   -  person Reaz Murshed    schedule 12.06.2016
comment
О.. Я отредактировал вопрос, настроив его на 44.1, чтобы он соответствовал стандарту проекта.. И разве int16_t не должен использовать 16 бит? (Хотя я проверю его с 8 бит)   -  person fodinabor    schedule 12.06.2016
comment
@ReazMurshed Нет, 8 бит ужасно портит звук ... должно быть 16 бит.   -  person fodinabor    schedule 12.06.2016


Ответы (1)


Так что я решил эту проблему.
Фактически я дважды инициализировал OpenSL и, следовательно, также начал записывать в две параллельные буферные очереди из одного источника — это привело к тому, что половина кадров не воспроизводилась должным образом.

person fodinabor    schedule 28.06.2016