((color red 以下の項目は書きかけです!)) !!! SDL(Simple DirectMedia Layer) * 非常にシンプルなAPI ** 厳選された機能を,高性能で提供することを目指した,らしい * あまり使いやすいものではない,という評価が多く,現在では別のライブラリが利用されることも多い !!! チュートリアル !! コンパイル,リンク時の注意 SDL,SDL_mixer を使ったプログラムには 8< #include #include >8 が必要です.また,コンパイル時には 8< $ gcc -o sound sound.c `sdl-config --cflags --libs` -lSDL_mixer >8 のように,sdl-config と -lSDL_mixer の指定が必要です. !! 初期化と終了 SDL_mixer の初期化と終了はそれぞれ * [Mix_OpenAudio()|http://www.libsdl.org/projects/SDL_mixer/docs/SDL_mixer.html#SEC11] * [Mix_CloseAudio()|http://www.libsdl.org/projects/SDL_mixer/docs/SDL_mixer.html#SEC12] です. :'''Mix_OpenAudio(int frequency, Uint16 format, int channels, int chunksize)''' ::frequency:サンプリング周波数(Hz)を指定します.特に気にしない場合はMIX_DEFAULT_FREQUENCYでOK. ::format:波形サンプルの型(8ビット,16ビット,など)を指定します.これも通常はMIX_DEFAULT_FORMATでOK. ::channels:チャンネル数を指定します.1ならモノラル,2ならステレオです. ::chunksize:サウンドバッファのサイズをバイト数で指定します.あまり気にする必要はないので,1024あたりでOK. !! BGMを鳴らす [Mix_LoadMUS()|http://www.libsdl.org/projects/SDL_mixer/docs/SDL_mixer.html#SEC55]で曲をロードし,[Mix_PlayMusic()|http://www.libsdl.org/projects/SDL_mixer/docs/SDL_mixer.html#SEC57]で再生するだけです. 6< 8< Mix_Music *music; music = Mix_LoadMUS( "hoge.mp3" ); // ファイルから読み込み Mix_PlayMusic( music, -1 ); // 2番目の引数は演奏回数. // -1なら無限に繰り返す. >8 >9 BGMを止めたいときは,[Mix_HaltMusic()|http://www.libsdl.org/projects/SDL_mixer/docs/SDL_mixer.html#SEC67]で演奏を停止し,[Mix_FreeMusic()|http://www.libsdl.org/projects/SDL_mixer/docs/SDL_mixer.html#SEC56]で曲を解放します. 6< 8< Mix_HaltMusic(); // 演奏停止 Mix_FreeMusic(music); // 曲を解放 >8 >9 !! 効果音を鳴らす BGMの再生とほとんど同じですが,効果音は'''同時に複数鳴らすことがある'''ため,'''再生時にチャンネル番号を指定する'''必要があります. ((color green 1つのチャンネルでは,同時に1つの音しか再生できません)).つまり,同時に複数の音を鳴らすためには複数のチャンネルを使用する必要があります. また,再生停止するときも「チャンネル○番を停止」というように,チャンネル番号を指定する必要があります. 具体的なコードは以下です.[Mix_LoadWAV()|http://www.libsdl.org/projects/SDL_mixer/docs/SDL_mixer.html#SEC19]で効果音をロードし,[Mix_PlayChannel()|http://www.libsdl.org/projects/SDL_mixer/docs/SDL_mixer.html#SEC28]で再生します. 6< 8< Mix_Chunk *chunk; int channel; chunk = Mix_LoadWAV( "hoge.wav" ); // wavファイルを読み込む channel = Mix_PlayChannel( -1, chunk, 0 ); // 再生 /* * ● 1番目の引数はチャンネル番号の指定 * -1にすると空チャンネルが自動的に割り当てられる * ● 3番目の引数は再生繰り返し数の指定 * 0なら1回再生,1なら2回再生,...となり,-1なら無限に繰り返す * ● 戻り値は割り当てられたチャンネル番号 */ >8 >9 後始末には[Mix_HaltChannel()|http://www.libsdl.org/projects/SDL_mixer/docs/SDL_mixer.html#SEC34]と[Mix_FreeChunk()|http://www.libsdl.org/projects/SDL_mixer/docs/SDL_mixer.html#SEC24]を使用します. 6< 8< Mix_HaltMusic( channel ); // チャンネル番号channelの再生停止 // -1を与えると全チャンネル停止 Mix_FreeChunk( chunk ); // 音の解放 >8 >9 !!! SDLを用いたサンプル ---- !!! OpenAL (Open Audio Library) * クロスプラットフォームのオーディオAPI * マルチチャンネル3次元定位オーディオを効率よく表現するように設計されている * APIのスタイルと慣習は意図的にOpenGLと似せてある * [本家@|http://kcat.strangesoft.net/openal.html] !!! Hello, Worldを喋らせる 8< #include int main(int argc, char** argv) { ALuint buffer, source; // 初期化 alutInit(&argc,argv); // 有効なバッファとソース番号を取得 alGenBuffers( 1, &buffer ); alGenSources( 1, &source ); // 提供されている"hello world"の音声バッファを作成 buffer = alutCreateBufferHelloWorld (); // ソースとバッファを結び付ける alSourcei( source, AL_BUFFER, buffer ); // 再生 alSourcePlay( source ); // 1秒待って,終了処理 alutSleep (1); alutExit(); return 0; } >8 コンパイル,実行 8< $ gcc -o testal testal.c -lopenal -lalut $ ./testal >8 !!! wavファイルを鳴らす 先のサンプルで,バッファに読み込む部分でwavファイルを指定すればOK. 例えば,se.wavを鳴らしたければ 6< 8< buffer = alutCreateBufferFromFile( "se.wav" ); >8 >9 と変更するだけです. !!! sin波の作成と再生 sin波を作って再生するサンプル. 8< #include #include int main(int argc, char** argv) { ALuint buffer, source; alutInit(&argc,argv); alGenBuffers( 1, &buffer ); alGenSources( 1, &source ); // サンプリング周波数と音階の設定 const int freq = 10000 , Hz = 440; // sin波データ作成 ALshort data[freq/Hz]; for (int i = 0; i < freq/Hz ; ++i) { data[i] = 32767 * sin(i * 3.14159 * 2 * Hz / freq); } // バッファに音データを渡す alBufferData( buffer, AL_FORMAT_MONO16, data, freq/Hz*sizeof(ALshort), freq ); alSourcei( source, AL_BUFFER, buffer ); alSourcei( source, AL_LOOPING, AL_TRUE ); alSourcePlay( source ); alutSleep (1); alutExit(); return 0; } >8 6< * 上記プログラムをコンパイルするには,-std=c99 オプションが必要です. * const int freq = 10000 , Hz = 440;で,サンプリング周波数を10000Hz,音階を440Hz(「ラ」)としています. ** もちろん,音階の数値を変えれば音が変わります. * for文でデータを作っています. * alBufferData( buffer, AL_FORMAT_MONO16, data, freq/Hz*sizeof(ALshort), freq ); ** 第2引数のAL_FORMAT_MONO16は,モノラル16bit-PCM音源であることを示しています. ** 第4引数は渡すデータの長さ(byte単位),第5引数はサンプリング周波数です. * このプログラムでは1波長分しか音データを作成していないので,alSourcei( source, AL_LOOPING, AL_TRUE );を呼んで,ループ再生をオンにしています. ** alutSleep()の時間を長くすれば,その分,鳴り続けます. >9 ちなみに, * AL_FORMAT_MONO8は,8bit-PCM音源,0~255の値 * AL_FORMAT_STEREO8は,ステレオの8bit-PCM音源 * AL_FORMAT_STEREO16は,ステレオ16bit-PCM音源,データは左右左右・・・と交互に並べます !!! BGMとして流したい 以下未確認. * alSourcei(source,AL_LOOPING,AL_TRUE) で繰り返しONにしておき, * 何かのイベントをトリガーにして alSourcePlay(source) を呼び出して再生スタート, * 何かのイベントをトリガーにして alSourceStop(source) で再生ストップ, * alutExit()が呼ばれた場合は無条件停止? のような形にすれば実現可能? もしかすると音専用のスレッドを作成しなければダメかも. * [[GLib::スレッド]] * [[マルチスレッド]] ---- !!! 設定 端末で使うためには, * libopenal-dev * libalut-dev のインストールが必要.