サウンドの圧縮フォーマット Ogg Vorbisの再生を行います。
といっても、OpenSLでPCMデータを再生する処理はできていますので、VorbisデータをPCMデータにデコードする処理が主となります。
Vorbisのデコードには、xiph.orgの
Tremorを使用させていただきました。
※TremorはBSDライセンスです。詳しくは
プロジェクト内 jni\sys\Tremor\COPYING.txtを参照してください。
Sound.h
OggVorbis_File ov_file; // OggVorbisファイル情報
long ov_pos; // 現在位置
char pcm_buffer[2][0x400]; // PCMデータ展開バッファ
SLuint32 pcm_size; // PCMデータサイズ
int buf_cnt; // 使用バッファカウンタ
追加されたメンバ変数です。
ov_fileでデコードの管理、pcm_bufferにPCMデータをデコードします。
Sound.cpp
case 0x5367674f : // OGG
{
format = FORMAT_OGG;
sound_data = new SoundData((char*)_data, _size, _loop, _file_data);
ov_pos = 0; // 現在位置
if ( ::ov_open_callbacks(this, &ov_file, NULL, 0, callbacks) ) {
LOGE("ov_open_callbacks ERROR!");
::ov_clear(&ov_file);
delete sound_data;
return;
}
vorbis_info* _info = ::ov_info(&ov_file, -1);
format_pcm.formatType = SL_DATAFORMAT_PCM;
format_pcm.numChannels = (SLuint32)_info->channels;
format_pcm.samplesPerSec = (SLuint32)_info->rate*1000;
format_pcm.bitsPerSample = (SLuint32)SL_PCMSAMPLEFORMAT_FIXED_16;
format_pcm.containerSize = (SLuint32)SL_PCMSAMPLEFORMAT_FIXED_16;
format_pcm.channelMask = (_info->channels == 1) ? SL_SPEAKER_FRONT_CENTER : (SL_SPEAKER_FRONT_LEFT | SL_SPEAKER_FRONT_RIGHT);
format_pcm.endianness = SL_BYTEORDER_LITTLEENDIAN;
}
break;
再生準備関数 prepare内です。
sound_dataを設定した後、ov_open_callbacksで ov_fileを初期化します。このとき sounda_dataからデータを取り出すコールバック関数(後述)を指定します。
また、ov_infoでOGGデータのフォーマットを取得してプレイヤーの初期化変数に設定します。
case FORMAT_OGG : // OGG
{
result = (*bqPlayerBufferQueue)->RegisterCallback(bqPlayerBufferQueue, bqPlayerCallbackOGG, this);
assert(SL_RESULT_SUCCESS == result); // 再生コールバック設定
pcm_size = get_pcm_data(&pcm_buffer[0][0]); // データ読み込み
(*bqPlayerBufferQueue)->Enqueue(bqPlayerBufferQueue, &pcm_buffer[0][0], pcm_size);
buf_cnt = 1;
pcm_size = get_pcm_data(&pcm_buffer[1][0]);
}
break;
prepare内のデータ設定部分です。
まずは Ogg Vorbis用のコールバック関数を設定します。
次に get_pcm_dataで最初のデータをバッファにデコードして Enqueueでキューに送ります。そして、次のデータをデコードしておきます。
セコメントをする