LastUpdate: 2025/05/17(Sat) 13:53:39 +0900

(snd)PlaySound について

WINAPI の sndPlaySound[A|W]() や PlaySound[A|W]() は簡単に音源を再生することができます。この関数の使い方や気づいた点についていくつか記しておこうと思います。
BOOL sndPlaySound( LPCTSTR lpszSoundName, UINT fuSound );
BOOL PlaySound( LPCTSTR lpszSound, HMODULE hmod, DWORD fdwSound );

基本的な使い方

#include <stdio.h>
#include <mmsystem.h>
#pragma comment( lib, "winmm.lib" )

// 1. WAVE ファイル (*.wav) を再生する
{
	// SND_ASYNC フラグを指定すると、処理が直ぐに返ってくる
	// SND_LOOP フラグを指定すると、無限回ループで再生する
	::sndPlaySoundA( "./sound.wav", SND_ASYNC | SND_LOOP );
}

// 2. メモリ上の WAVE ファイルを再生する
{
	FILE *fp;
	long len;
	char *pRiffWaveMemory;

	fp = fopen( "./sound.wav", "rb" );
	if ( fp != NULL ) {
		fseek( fp, 0, SEEK_END );
		len = ftell( fp );
		pRiffWaveMemory = new char[ len ];
		fseek( fp, 0, SEEK_SET );
		fread( pRiffWaveMemory, len, 1, fp );
		fclose( fp );
		// 再生中は pRiffWaveMemory を解放してはならないので注意
		// ここでは SND_SYNC フラグを指定して、再生終了まで待つ
		::sndPlaySoundA( pRiffWaveMemory, SND_SYNC | SND_MEMORY );
		// 再生が終了し、不要になったので解放する
		delete[] pRiffWaveMemory;
	}
}

// 3. 再生中の音源を停止する
{
	::sndPlaySoundA( NULL, SND_ASYNC );
}

// 4. リソース上の WAVE ファイルを再生する
{
	// hInst はアプリケーションのインスタンスハンドルであれば良い
	HINSTANCE hInst = ( HINSTANCE )::GetModuleHandleA( NULL );

	::PlaySoundA( "RESOURCE_NAME", hInst, SND_RESOURCE | SND_ASYNC );
}

少し変わった使い方

// 再生終了を待ってから新しい音源を再生する
{
	// 1つ目の音源を再生する
	::sndPlaySoundA( "./sound1.wav", SND_ASYNC );
	// Sleep() しないと再生中にならない
	// ただし、sound1.wav の再生開始に時間がかかると、このコードではうまくいかないので注意
	::Sleep( 0 );
	// 再生中は FALSE が返ってくるので、ループで待つ
	while ( !::sndPlaySoundA( "./sound2.wav", SND_ASYNC | SND_NOSTOP ) ) {
		::Sleep( 100 );
	}
}

補足

メモリ上の WAVE ファイルを再生する場合、再生しながら PCM を書き換えると変更が反映されるという、中々面白い事実が判明しました。これを利用すれば DirectSound 等を使わなくても音源を加工・再生する事ができますが、Microsoft が想定していない使い方かもしれないのであまりオススメはできません (また、16bit Stereo PCM 音源、Windows 2000 SP4 でしか試していません)。


注意事項

Valid XHTML 1.0 Strict Valid CSS!
Copyright © 2004-2026[juicy.gt] All rights reserved.