2015-07-03 130 views
0

我正在開發一個原生的android項目,並嘗試使用OpenSL來播放一些音頻效果。使用VisualGDB提供的本地音頻樣例項目,我編寫了下面的代碼。OpenSL:通過AAsset_read加載wav文件時導致靜態的是什麼?

接近尾聲時,您可以看到我註釋了一行,它將緩存中名爲hello的變量的內容存儲到目標中。你好來自示例項目,幷包含大約700行字符像這樣:

「\ x02 \ x00 \ x01 \ x00 \ xff \ xff \ x09 \ x00 \ x0c \ x00 \ x10 \ x00 \ x07 \ x00 \ x07 \ x00「

其中有人說」你好「的音頻文件。當將該字節數據讀入流中時,我的代碼工作正常,並且在運行應用程序時聽到「hello」。然而,當我從wav文件讀取播放我想要的資產時,我只聽到靜止的聲音。數據緩衝區的大小與文件的大小相同,因此它看起來正在被正確讀取。靜態播放的wav文件(或非常接近它)的持續時間。

我對數據格式或音頻編程一無所知。我試着用不同的枚舉值調整一些format_pcm變量,但沒有成功。使用我在Internet上找到的名爲GSpot的工具,我知道以下關於我試圖播放的音頻文件:

文件大小:557 KB(570,503字節)(與數據緩衝區的大小相同 AAsset_read返回

編解碼器:PCM音頻

採樣率:48000Hz

比特率:1152 kb/s的

通道:1

任何幫助或方向將不勝感激。

SLDataLocator_AndroidSimpleBufferQueue loc_bufq = { SL_DATALOCATOR_ANDROIDSIMPLEBUFFERQUEUE, 1 }; 
SLDataFormat_PCM format_pcm; 
format_pcm.formatType = SL_DATAFORMAT_PCM; 
format_pcm.numChannels = 1; 
format_pcm.samplesPerSec = SL_SAMPLINGRATE_48;// SL_SAMPLINGRATE_8; 
format_pcm.bitsPerSample = SL_PCMSAMPLEFORMAT_FIXED_8; // SL_PCMSAMPLEFORMAT_FIXED_16; 
format_pcm.containerSize = 16; 
format_pcm.channelMask = SL_SPEAKER_FRONT_CENTER; 
format_pcm.endianness = SL_BYTEORDER_LITTLEENDIAN; 

SLDataSource audioSrc = { &loc_bufq, &format_pcm }; 

// configure audio sink 
SLDataLocator_OutputMix loc_outmix = { SL_DATALOCATOR_OUTPUTMIX, manager->GetOutputMixObject() }; 
SLDataSink audioSnk = { &loc_outmix, NULL }; 

//create audio player 
const SLInterfaceID ids[3] = { SL_IID_BUFFERQUEUE, SL_IID_EFFECTSEND, SL_IID_VOLUME }; 
const SLboolean req[3] = { SL_BOOLEAN_TRUE, SL_BOOLEAN_TRUE, SL_BOOLEAN_TRUE }; 

SLEngineItf engineEngine = manager->GetEngine(); 
result = (*engineEngine)->CreateAudioPlayer(engineEngine, &bqPlayerObject, &audioSrc, &audioSnk, 
    3, ids, req); 

// realize the player 
result = (*bqPlayerObject)->Realize(bqPlayerObject, SL_BOOLEAN_FALSE); 

// get the play interface 
result = (*bqPlayerObject)->GetInterface(bqPlayerObject, SL_IID_PLAY, &bqPlayerPlay); 

// get the buffer queue interface 
result = (*bqPlayerObject)->GetInterface(bqPlayerObject, SL_IID_BUFFERQUEUE, 
    &bqPlayerBufferQueue); 

// register callback on the buffer queue 
result = (*bqPlayerBufferQueue)->RegisterCallback(bqPlayerBufferQueue, bqPlayerCallback, NULL); 

// get the effect send interface 
result = (*bqPlayerObject)->GetInterface(bqPlayerObject, SL_IID_EFFECTSEND, 
    &bqPlayerEffectSend); 

// get the volume interface 
result = (*bqPlayerObject)->GetInterface(bqPlayerObject, SL_IID_VOLUME, &bqPlayerVolume); 

// set the player's state to playing 
result = (*bqPlayerPlay)->SetPlayState(bqPlayerPlay, SL_PLAYSTATE_PLAYING); 

uint8* pOutBytes = nullptr; 
uint32 outSize = 0; 
result = MyFileManager::GetInstance()->OpenFile(m_strAbsolutePath, (void**)&pOutBytes, &outSize, true); 
const char* filename = m_strAbsolutePath->GetUTF8String(); 
result = (*bqPlayerBufferQueue)->Enqueue(bqPlayerBufferQueue, pOutBytes, outSize); 
// result = (*bqPlayerBufferQueue)->Enqueue(bqPlayerBufferQueue, hello, sizeof(hello)); 
if (SL_RESULT_SUCCESS != result) { 
    return JNI_FALSE; 
} 

回答

0

有幾件事是應該責怪的。我正在測試的wave文件的格式與規範描述不符。第一批數據頭後面似乎有很多空的數據。此外,需要傳遞給隊列的緩衝區必須是隻包含wav數據的char *,而不是頭部。我錯誤地認爲隊列解析了標題。