Ogg Vorbis再生
2013-11-23


/************************************* OGG展開PCMデータ取得 引数 _buf = バッファ 戻り値 データサイズ *************************************/ SLuint32 SoundPlayer::get_pcm_data(char* _buf) { long read_size; SLuint32 total = 0; while ( total < 0x400 ) { read_size = ::ov_read(&ampov_file, _buf + total, 0x400 - total, NULL); if ( bqPlayerObject == NULL ) { return 0; } else if ( read_size > 0 ) { total += read_size; } else if ( sound_data-&gtloop != 1 ) { ::ov_pcm_seek(&ampov_file, 0); // ループ if ( sound_data-&gtloop > 1 ) { sound_data-&gtloop--; } } else { if ( sound_data-&gtnext == NULL ) { // 終了 break; } SoundData* _next = sound_data-&gtnext; // 連続再生 sound_data-&gtnext = NULL; delete sound_data; sound_data = _next; ::ov_clear(&ampov_file); ov_pos = 0; if ( ::ov_open_callbacks(this, &ampov_file, NULL, 0, callbacks) ) { LOGE("ov_open_callbacks ERROR!"); ::ov_clear(&ampov_file); delete sound_data; return 0; } } } return total; }
デコードデータ取得関数です。
基本的には ov_readを呼んでバッファにデータをデコードしているだけです。
戻り値が0の場合は終端までデコードしてしまったということなので、ループのため先頭に戻す・連続再生のため次のデータを設定するといった処理を行っています。

void    SoundPlayer::callback_ogg(void)
{
        if ( pcm_size > 0 ) {
                (*bqPlayerBufferQueue)-&gtEnqueue(bqPlayerBufferQueue, &amppcm_buffer[buf_cnt][0], pcm_size);
                buf_cnt = ++buf_cnt % 2;
                pcm_size = get_pcm_data(&amppcm_buffer[buf_cnt][0]);
        }
        else {                                                                                          // 終了
                (*bqPlayerPlay)-&gtSetPlayState(bqPlayerPlay, SL_PLAYSTATE_STOPPED);
                ::ov_clear(&ampov_file);
                if ( sound_data ) {
                        delete  sound_data;
                        sound_data = NULL;
                }
                state = STOPPED;
        }
}

再生コールバック関数です。
データが残っている場合は、再生準備の時と同様にデータをキューに送り次のデータをデコードしています。
ループや連続再生の処理は get_pcm_dataの方で行っているので、WAVのコールバックより簡単になっています。


続きを読む
戻る
[Android プログラミング]

コメント(全0件)
コメントをする


記事を書く
powered by ASAHIネット