2 * @file main-win-sound.cpp
3 * @brief Windows版固有実装(効果音)
6 #include "main-win/main-win-sound.h"
7 #include "main-win/main-win-cfg-reader.h"
8 #include "main-win/main-win-define.h"
9 #include "main-win/main-win-file-utils.h"
10 #include "main-win/main-win-utils.h"
11 #include "main-win/wav-reader.h"
12 #include "util/angband-files.h"
14 #include "main/sound-definitions-table.h"
23 concptr ANGBAND_DIR_XTRA_SOUND;
28 CfgData *sound_cfg_data;
47 std::unique_ptr<BYTE[]> buf;
54 ::waveOutUnprepareHeader(hwo, &wh, sizeof(WAVEHDR));
64 std::queue<sound_res *> sound_queue;
69 * @param wf WAVEFORMATEXへのポインタ
70 * @param buf PCMデータバッファ
71 * @param bufsize バッファサイズ
72 * @retval true 正常に処理された
75 static bool add_sound_queue(const WAVEFORMATEX *wf, BYTE *buf, DWORD bufsize)
77 while (!sound_queue.empty()) {
78 auto res = sound_queue.front();
79 if (res->hwo == NULL || (res->wh.dwFlags & WHDR_DONE)) {
87 auto res = new sound_res(buf);
88 sound_queue.push(res);
90 MMRESULT mr = ::waveOutOpen(&res->hwo, WAVE_MAPPER, wf, NULL, NULL, CALLBACK_NULL);
91 if (mr != MMSYSERR_NOERROR) {
95 WAVEHDR *wh = &res->wh;
96 wh->lpData = (LPSTR)buf;
97 wh->dwBufferLength = bufsize;
100 ::waveOutPrepareHeader(res->hwo, wh, sizeof(WAVEHDR));
101 ::waveOutWrite(res->hwo, wh, sizeof(WAVEHDR));
110 * @retval true 正常に処理された
111 * @retval false 処理エラー
113 static bool play_sound_impl(char *filename)
116 if (!reader.open(filename))
118 auto wf = reader.get_waveformat();
120 auto data_buffer = reader.read_data();
121 if (data_buffer == nullptr)
124 return add_sound_queue(wf, data_buffer, reader.get_data_chunk()->cksize);
128 * @brief action-valに対応する[Sound]セクションのキー名を取得する
129 * @param index "term_xtra()"の第2引数action-valに対応する値
133 static concptr sound_key_at(int index, char *buf)
137 if (index >= SOUND_MAX)
140 return angband_sound_name[index];
144 * @brief 効果音の設定を読み込む。
146 * "sound_debug.cfg"ファイルを優先して読み込む。無ければ"sound.cfg"ファイルを読み込む。
147 * この処理は複数回実行されることを想定していない。複数回実行した場合には前回読み込まれた設定のメモリは解放されない。
149 void load_sound_prefs(void)
151 CfgReader reader(ANGBAND_DIR_XTRA_SOUND, { "sound_debug.cfg", "sound.cfg" });
152 sound_cfg_data = reader.read_sections({ { "Sound", TERM_XTRA_SOUND, sound_key_at } });
158 void finalize_sound(void)
160 while (!sound_queue.empty()) {
161 auto res = sound_queue.front();
169 * @param val see sound_type
172 * @retval -1 PlaySoundの戻り値が正常終了以外
174 errr play_sound(int val)
176 concptr filename = sound_cfg_data->get_rand(TERM_XTRA_SOUND, val);
181 char buf[MAIN_WIN_MAX_PATH];
182 path_build(buf, MAIN_WIN_MAX_PATH, ANGBAND_DIR_XTRA_SOUND, filename);
184 if (play_sound_impl(buf)) {