サウンドの再生
前回の記事で『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に流し込むことで音が鳴るようになります。
ではこれらを読み込んで再生する処理を見ていきましょう。