WonderSwan本体には、4チャンネルのPCM音源が搭載されています。それぞれのチャンネルには別の音源を設定でき、それらが合成された音が出力されます。 サウンドを鳴らすために必要なデータは波形データ、音量データ、使用チャンネルなどです。 波形データは4bit x 32step、16バイトのデータで表し、チャンネル毎に別な波形を設定できます。 また、チャンネル1以外の3つのチャンネルは、基本音源機能のほか、それぞれ個別の付加機能を持っています。 チャンネル別の付加機能
サウンドを鳴らす方法には@サウンド制御BIOSを使う、A付属のサウンドインダイレクトライブラリ (sound.il)を使うという2つの方法があります。@はBIOSを直接制御するため、実行ファイルのみ で動作しますが、Aは別に用意されたドライバを本体に転送して動作させます。 |
sound_init(); | サウンドBIOS初期化。 サウンドを全てオフにし、波形テーブルも0クリアします |
||||||||||||||||||
sound_set_output( 0x01 );
|
サウンドの出力先、本体出力時のスケーリングを設定します。 この例では本体スピーカ出力のみ設定しています。 |
||||||||||||||||||
unsigned char wave[] = { 0xa8, 0xdc, 0xee, 0xef, 0xde, 0xbc, 0x9a, 0x89, 0x67, 0x56, 0x34, 0x12, 0x01, 0x11, 0x32, 0x75, }; …… …… sound_set_wave( 0, wave );
|
波形データの設定を行います。 波形データを設定するチャンネル(0〜3(チャンネル1が0、チャンネル2が1、…))と、 設定する波形データの先頭アドレスを指定します。 波形データは、4bitx32step分を2step/1byteにパックし、16byteとした形式です。 各byteの下位4bitに偶数step、上位4bitに奇数stepのデータを格納します 左図ののような波形データを、例のように配列に初期設定し、それを指定します。 | ||||||||||||||||||
sound_set_volume( 0, 0x55 ); |
サウンド・チャンネルの出力音量を設定します。
音量を設定するチャンネル(0〜3(チャンネル1が0、チャンネル2が1、…))と、
左右の出力音量をそれぞれ4bitで指定します。 上位4bitが左チャンネル、下位4bitが右チャンネルの出力音量となります。 チャンネル2をボイス・モードで利用している際には、8bitを全て用いてボイス・データを与えます。 | ||||||||||||||||||
pitch=-(3072000L/(32*f)-2048); sound_set_pitch( 0, pitch );
f = 3.072x10の6乗 ÷ ((2048 - N) x 32 ) Hz
N = -( 3072000L ÷ ( 32 * f ) - 2048 );
となります。
|
サウンド・チャンネル1〜4の出力周波数を設定します。 周波数を設定するチャンネル(0〜3(チャンネル1が0、チャンネル2が1、…))と、 下位11bitにSOUND_SET_WAVEで設定する32stepの波形の周波数を指定します。 チャンネル3にスウィープ・モードが設定されている場合、この機能によって設定 される周波数がスウィープ開始時の初期周波数となります。 | ||||||||||||||||||
sound_set_channel( 0x0001 );
|
チャンネルのモードを設定し、出力します。
この例では単に、チャンネル1の出力を指定しています。 |
#include <sys/bios.h> unsigned char wave[] = { 0xa8, 0xdc, 0xee, 0xef, 0xde, 0xbc, 0x9a, 0x89, 波形データ 0x67, 0x56, 0x34, 0x12, 0x01, 0x11, 0x32, 0x75, }; void main() { int pitch,f = 440; 周波数440Hz sound_init(); @サウンド初期化 sound_set_output( 0x01 ); Aサウンドの出力先設定(本体、外部) sound_set_wave( 0, wave ); B波形データの設定 sound_set_volume( 0, 0x55 ); Cボューム(音量)の設定 pitch=-(3072000L/(32*f)-2048); 周波数値を計算 sound_set_pitch( 0, pitch ); D出力周波数を設定 sound_set_channel( 0x0001 ); Eチャンネルのモードを設定し、出力 key_wait(); キー入力待ち sound_set_channel( 0x0000 ); サウンド出力をオフ } |
UP,DOWNキーで出力周波数を変化させます。 画面に周波数値を表示させています。 |
#include <sys/bios.h> unsigned char wave[] = { 0xa8, 0xdc, 0xee, 0xef, 0xde, 0xbc, 0x9a, 0x89, 0x67, 0x56, 0x34, 0x12, 0x01, 0x11, 0x32, 0x75, }; void main() { int pitch,f = 440; int k; text_screen_init(); sound_init(); sound_set_output( 0x01 ); sound_set_wave( 0, wave ); sound_set_volume( 0, 0x55 ); sound_set_channel( 0x0001 ); while( (k=key_wait()) != KEY_START ){ switch(k){ case KEY_UP1 : f++; break; case KEY_DOWN1 : f--; break; } text_put_numeric( 1, 1, 4, 0, f ); pitch=-(3072000L/(32*f)-2048); sound_set_pitch( 0, pitch ); } sound_set_channel( 0x0000 ); } |
スイープはチャンネル3のみに割り当てられたの機能で、
指定するステップ・タイム毎に出力周波数に、設定した値連続的に加えていくものです。 効果音につかえそうな「ヒュ〜ゥゥン」といったサウンドを出力できます。 スイープの設定には sound_set_sweep関数を使います。 sound_set_sweep(スイープ値 , ステップタイム ) スイープ値 は 128(0x80)から+127(0x7F)の範囲 ステップタイムは 0〜31の範囲で 出力周波数が変化する時間間隔 T = 2.667 x (N + 1) ms のNで表されます。 この例題ではUP,DOWNキー単独で周波数変化、Aキーを押しながらでスイープ値変化、 Bキーを押しながらでステップタイム値を、それぞれ変化させます。STARTキーで終了します。 |
#include <sys/bios.h> unsigned char wave[] = { 0xa8, 0xdc, 0xee, 0xef, 0xde, 0xbc, 0x9a, 0x89, 0x67, 0x56, 0x34, 0x12, 0x01, 0x11, 0x32, 0x75, }; void main() { int pitch,f = 440,sw = 0, st=1; int k; text_screen_init(); /*1234567890123456789012345*/ text_put_string(1,1,"frequency sweep step"); sound_init(); sound_set_output( 0x01 ); sound_set_wave( 2, wave ); /* channel3 */ sound_set_volume( 2, 0x55 ); sound_set_channel( 0x44 ); /* channel3 sweep on */ while( (k=key_press_check()) != KEY_START ){ switch(k){ case KEY_UP1 : f++; break; case KEY_DOWN1 : f=f>1?f-1:1; break; case KEY_A | KEY_UP1 : sw=sw<127?sw+1:127; break; case KEY_A | KEY_DOWN1 : sw=sw>-128?sw-1:-128;break; case KEY_B | KEY_UP1 : st=st<31?st+1:31; break; case KEY_B | KEY_DOWN1 : st=st>0?st-1:0; break; } if( k != 0 ){ text_put_numeric( 3, 3, 4, 0, f ); text_put_numeric(13, 3, 4, NUM_SIGNED, sw ); text_put_numeric( 19, 3, 4, 0, st ); text_put_numeric( 23, 3, 4, 0, 2.667*(st+1) ); pitch=-(3072000L/(32*f)-2048); sound_set_pitch( 2, pitch ); sound_set_sweep(sw, st); sys_wait(5); } } sound_set_channel( 0x0000 ); } |