サウンドの再生
前回の記事で『XAudio2の初期化』を行いました。
次はサウンドの再生部分を作っていきたいと思います。
XAudio2で個々のサウンドを制御するのはソースボイス(SourceVoice)が行います。
ソースボイスの作成
XAudio2の初期化と同じくソースボイスも作成は簡単です。
ただし、ソースボイスでサウンドを再生するには別途波形データの情報が必要となります。
どちらかと言えばこちらで苦労することが多くなってきます。
今回、先ずはソースボイスの初期化から順番に説明していきます。
SourceVoiceの作成
IXAudio2SourceVoice* pSourceVoice = nullptr; // wfexは後述する波形データのフォーマット情報となります pXAudio->CreateSourceVoice(&pSourceVoice, &wfex);
これだけで作成できます。
ただ、サウンドデータのフォーマット(wfex)が分からなければ作成ができません。
ソースボイスを作成するには前提としてサウンドデータのフォーマットを知っておく必要があります。
しかし、フォーマットと言ってもサウンドには定まったフォーマットがある訳ではありません。
なので事前にサウンドデータを読み込んでのフォーマットを取得しておく必要があります。
Waveファイルの読み込み
次はWave(.wav)ファイルを使った形で説明していきます。
今回は基本的なファイルフォーマットにのみ対応した例外無視の実装をしていきます。
Waveを読むために、先ずは各情報を読み取るための構造体を用意します。
// チャンクデータの基本構造 struct Chunk { char id[4]; // チャンク毎のID int32_t size; // チャンクサイズ }; // RIFFヘッダー struct RiffHeader { Chunk chunk; // "RIFF" char type[4]; // "WAVE" }; // FMTチャンク struct FormatChunk { Chunk chunk; // "fmt " WAVEFORMAT fmt; // 波形フォーマット };
こんな感じです。
この3つがあれば簡単にWAVEが読み込めてしまいます。
WaveファイルはChunkと呼ばれる形式で管理されています。
Chunkの基本フォーマットは下記です。
id | チャンクの識別子として4文字 |
---|---|
size | データ部のサイズ |
データ部 | 各チャンク毎のデータ |
Waveこのフォーマットで並べられたデータとなっています。
先ず先頭にRIFFチャンク
id | “RIFF” |
---|---|
size | データ部のサイズ |
データ部 | チャンクデータ一覧 |
このようにRIFFチャンクは全体のチャンクを内包したチャンクとなります。
sizeにはidとsizeの8バイトを除いたファイルサイズが入っています。
次にFormatチャンクです。
波形のフォーマットが格納されています。
id | “fmt “ |
---|---|
size | データ部のサイズ |
WAVEFORMAT | 波形のフォーマット |
この部分を元にSourceVoiceで再生するフォーマットを取得します。
最後にDataチャンクです。
ここに本体となる波形データが格納されています。
id | “data” |
---|---|
size | データ部のサイズ |
data | 波形データ |
この波形データをSourceVoiceに流し込むことで音が鳴るようになります。
ではこれらを読み込んで再生する処理を見ていきましょう。