ノイズ再生関数用サンプルプログラム。


NDSのノイズチャンネルでノイズを鳴らすサンプルです。
どんな音が出せるのか知りたくて書いただけで
ハードウェア的な知識を僕は持ってません。ごめんなさい。
直接制御をしたいならNDSTEKとかで勉強することを進めます。


メインストリートで活躍なされてる
Moonlightさんやめらまんさんと違い、
ウチは在り物最新ライブラリ関数を使って
如何にして手を抜いて、自分の作りたいものを作ってくかという、
カジュアルデベロップな進行ですので。


ちょっと脱線。


ノイズ再生関数は
/devkitPro/libnds/include/nds/arm9/sound.h
で以下の記述があります。

/*! \fn int soundPlayNoise(u16 freq, u8 volume, u8 pan);
	\brief Plays white noise with the specified parameters
	\param freq The frequency in Hz of the sample
	\param volume The channel volume.  0 to 127 (min to max)
	\param pan The channel pan 0 to 127 (left to right with 64 being centered)
	\return An integer id coresponding to the channel of playback.  This value can be used to pause, resume, or kill the sound
	as well as adjust volume, pan, and frequency
*/
int soundPlayNoise(u16 freq, u8 volume, u8 pan);
引数
u16 freq		0〜65535の範囲で周波数を指定
u8 volume		0〜127の範囲で音量を指定(0は無音)
u8 pan		0〜127の範囲でパンを指定(数値が小さい程音を左に、大きい程に右に音を寄せる)

返値
int		-1, 14, 15の値(サウンドチャンネルID)が返る。
		14, 15 はノイズチャンネル1, 2
		-1 は利用できるチャンネルが使用中で、
		再生を実行できなかった場合に返ってくる値


大体の使いかたは以前にここのダイアリーで書いた
soundPlaySample 関数(WAV 再生関数)や、 soundPlayPSG 関数(PSG 再生関数)と同じです。


・最初に soundEnable 関数 でサウンドの利用を有効にすること
・再生中のサウンドIDをちゃんと取得しておくこと
・使用の終わったサウンドチャンネルは soundPause 関数などで再生を止めること


この3つを抑えてコーディングすれば、
既存ライブラリでのサウンド再生に詰まることはないです。
但しライブラリ関数がカバー出来る範囲外のことはライブラリ関数外でまかなうか
自前でライブラリを書き起こす必要がありますが
(再生開始のフレーム遅れや、長時間再生のWAV等)。


後、直接制御される場合には関係ないですがライブラリ関数で制御の場合、
任意のサウンドチャンネルを指定して再生開始することはできません。
空いてるチャンネルから昇順に割り当てられます。
再生を停止したチャンネルは開放され、空きチャンネルとして扱かわれます。
ということは複数チャンネルで複雑な制御を行う場合、
チャンネル管理を自前で起こす必要がある、ということになります。


以下はサンプルコードになります。v1.5.0用です。


追記。
周波数のビット表示を付加しときました。


noise play tips

●使いかた

上:周波数を1上げる
下:周波数を1下げる
右:周波数を10上げる
左:周波数を10下げる

A/X:ノイズを再生する
B/Y:ノイズを停止する

R:音量を1上げる
L:音量を1下げる

START:音を右に1寄せる
SELECT:音を左に1寄せる

※周波数、音量、パン(音を左右へ寄せる)は
 キーを押し続けることで増減を進めることが出来ます。


main.c

/*---------------------------------------------------------------------------------
	
	noise play tips
	
	version 0.02
	Oct 18, 2009
	
	(C)2009 REGEKATSU
	
---------------------------------------------------------------------------------*/
#include <nds.h>
#include <stdio.h>


typedef struct{
	int sound_id;
	u16 freq;
	u8 volume;
	u8 pan;
}NoiseStatus;

//setNoiseStatus
static NoiseStatus st_noise = {0, 0, 63, 63};


void numToBin(const u32 num, int bit_n);


//---------------------------------------------------------------------------------
void numToBin(const u32 num, int bit_n) {
//---------------------------------------------------------------------------------
	
		while(bit_n){
			bit_n--;
			printf("%01d", (num & (1 << (bit_n))) ? true:false);
		}
	
}



//---------------------------------------------------------------------------------
int main(void) {
//---------------------------------------------------------------------------------
	
	//setValue
	u32 kdr = 0;
	bool is_play = false;
	
	//initMain
	lcdSwap();
	consoleDemoInit();
	keysSetRepeat(20, 10);
	
	//initSound
	soundEnable();
	
	//drawTitle
	printf("noise play tips\n\nversion 0.02\nOct 18, 2009\n\n(C)2009 REGEKATSU\n\n\n");
	
	//drawUsage
	printf("\x01b[15;0H -------- usage --------\n"
			"\x01b[16;0HDN:decFreq     UP:incFreq\n"
			"LF:subFreq-10  RI:addFreq+10\n\n"
			"A/X:playNoise  B/Y:stopNoise\n\n"
			"L:decVolume    R:incVolume\n"
			"SL:setPanLeft  ST:setPanRight");
	
	
	while(1) {
		
		swiWaitForVBlank();
		scanKeys();
		
		kdr = keysDownRepeat();
		
		
		//drawNoiseStatus
		printf("\x01b[7;0HsoundPlayNoise(\n\t\t\t\tfreq   = %05d, \n", st_noise.freq);
		printf("\t (bit) ");
		numToBin(st_noise.freq, 16);
		printf(",\n");
		printf("\t\t\t\tvolume =   %03d, \n", st_noise.volume);
		printf("\t\t\t\tpan    =   %03d\n\t\t\t\t)\n", st_noise.pan);
		
		//drawSoundId
		printf("sound_id = %d", st_noise.sound_id);
		
		
		//playNoice
		if(keysDown() & (KEY_A | KEY_X)){
			if(!is_play){
				st_noise.sound_id = soundPlayNoise(st_noise.freq, st_noise.volume, st_noise.pan);
				is_play = true;
			}
		}
		//stopNoice
		if(keysDown() & (KEY_B | KEY_Y)){
			if(is_play){
				soundPause(st_noise.sound_id);
				is_play = false;
			}
		}
		
		
		//incNoiceFreq
		if(kdr & KEY_UP){
			st_noise.freq++;
		}
		//decNoiceFreq
		if(kdr & KEY_DOWN){
			st_noise.freq--;
		}
		//addNoiceFreq + 10
		if(kdr & KEY_RIGHT){
			st_noise.freq += 10;
		}
		//subNoiceFreq - 10
		if(kdr & KEY_LEFT){
			st_noise.freq -= 10;
		}
		
		
		//incVolume
		if(kdr & KEY_R){
			if(st_noise.volume < 127){
				st_noise.volume++;
			}else{
				st_noise.volume = 0;
			}
		}
		//decVolume
		if(kdr & KEY_L){
			if(st_noise.volume > 0){
				st_noise.volume--;
			}else{
				st_noise.volume = 127;
			}
		}
		
		
		//setPanLeft
		if(kdr & KEY_SELECT){
			if(st_noise.pan > 0){
				st_noise.pan--;
			}else{
				st_noise.pan = 127;
			}
		}
		//setPanRight
		if(kdr & KEY_START){
			if(st_noise.pan < 127){
				st_noise.pan++;
			}else{
				st_noise.pan = 0;
			}
		}
		
		
	}
	
}

//---------------------------------------------------------------------------------