Opusを使ったサウンドの読み込み

Opusとは?

Opusとは、低レンテンシで遅延を抑えることができる非可逆圧縮の音声フォーマットです。
又、Opusをカバーする既知の特許は全てロイヤリティーフリーのライセンスとされています。

今回はこのOpusの読み込みと再生を前回の『サウンドの再生』のWaveを置き換えるような形で説明していこうかと思います。

 

Opusの使用準備

Opusを読み込むには次のライブラリが必要となります。

  • libopus
  • opusfile
  • libogg

 

『libopus』と『opusfile』については下記のURLからダウンロードできます。
http://opus-codec.org/downloads/

 

『libogg』は下記のURLです。
https://xiph.org/downloads/

 

先ず、事前準備としてこれらのライブラリをダウンロードしてビルドする必要があります。
ビルド後に各ヘッダーと出力されたlibなどを自身のプログラム内で使用します。

ここまでできれば準備は完了です。

 

Opusの読み込み

本来、Opusはストリーミング再生するべきデータではあります。
ですが今回は説明の為に前回のWaveと同様でオンメモリー再生としていきます。

先ず、使う際は下記のようにヘッダとライブラリのリンクを行う必要があります。

ライブラリの使用準備
// opusfileのヘッダを含める
#include <opusfile.h>
// libopusとopusfileをリンク
#pragma comment(lib, "opus.lib")
#pragma comment(lib, "opusfile.lib")
// liboggをリンク
#pragma comment(lib, "libogg_static.lib")

事前にヘッダやライブラリのパスを通すようにしている必要があります。
※ライブラリの名前については各々のビルドした環境によって名前が違う可能性もあります。

これでopusfileの関数が使用できるようになりました。

opusファイルを開く
int ret;
OggOpusFile* of = op_open_file(filename, &ret);

これだけでopusファイルのオープンは完了です。

波形フォーマットの取得
// Opusのヘッダを取得
const OpusHead* pHead = op_head(of, -1);
if (!pHead) {
	return false;
}
WAVEFORMATEX wfex{};
// PCMなので固定
wfex.wFormatTag = WAVE_FORMAT_PCM;
// チャンネル数(モノラル:1 ステレオ:2など)
wfex.nChannels = pHead->channel_count;
// サンプリングレート(opusは48000固定)
wfex.nSamplesPerSec = 48000;
// サンプル当たりのビット数(16bit)
wfex.wBitsPerSample = 16;
// ブロックサイズ(16bitのステレオなら 2*2=4)
wfex.nBlockAlign = wfex.nChannels * wfex.wBitsPerSample / 8;
// データ速度(秒間当たりのデータ量)
wfex.nAvgBytesPerSec = wfex.nSamplesPerSec * wfex.nBlockAlign;

これで再生する波形のフォーマットが取得できます。
いくつか数値を設定していますが、opusは固定値の部分があるので指定しています。

波形サイズの取得
ogg_int64_t decodedSize = op_pcm_total(of, -1) * wfex.nBlockAlign;

これでop_pcm_totalで総サンプル数を取得してからブロックサイズ分を考慮してサイズを出しています。
後はこのサイズ分のバッファを確保して読み込めば完了です!

波形データの読み込み
//必要なメモリ確保
char* pDecodedBuf = (char*)malloc(decodedSize);
char* pBuf = pDecodedBuf;
// 波形データの読み込み(デコード)
int readSize;
while ((readSize = op_read(of, (opus_int16*)pBuf, 8096, NULL)) > 0) {
	pBuf += readSize * wfex.nBlockAlign;
}

これで確保したメモリに対して波形データが読み込まれる形となります。
op_readでサンプル数が帰ってくるのでBlockAlignで実際のバイト数に変換してずらしています。

ファイルを閉じる
op_free(of);

これでファイルを閉じたら全て完了です!

 

1 2

コメントを残す

メールアドレスが公開されることはありません。 * が付いている欄は必須項目です