2018/04/14

音を鳴らしてみよう(1)

またまた、久しぶりの更新です。

ゲームには何と言っても音関連が欠かせませんが
ゲームボーイのサウンドにはノイズやゾンビモードなど
厄介な問題が存在するため今まで避けてきました。
が、その辺りの事はとりあえず無視して音を鳴らしてみます。

といっても、音関係のレジスタに決まった値をセットするだけです。
資料となるページはこのあたりでしょうか。

では、プログラムを作ってみましょう。
#include <stdio.h>
#include <gb.h>

// タイルデータ
#include "Ascii_misaki.c"

UBYTE input_on, input_old, input_edge, input_trg;// キー入力用

// サウンド関連の全レジスタを初期化
void snd_reg_init()
{
 NR10_REG = 0;
 NR11_REG = 0;
 NR12_REG = 0;
 NR13_REG = 0;
 NR14_REG = 0;
 NR21_REG = 0;
 NR22_REG = 0;
 NR23_REG = 0;
 NR24_REG = 0;
 NR30_REG = 0;
 NR31_REG = 0;
 NR32_REG = 0;
 NR33_REG = 0;
 NR34_REG = 0;
 NR41_REG = 0;
 NR42_REG = 0;
 NR43_REG = 0;
 NR44_REG = 0;
 NR50_REG = 0;
 NR51_REG = 0;
 NR52_REG = 0;
}

void proc()
{
 if (input_trg & J_A) {
  gotoxy(5, 2);
  print("PLAY");
  // チャンネル制御
  NR52_REG = 0x80;// b7:全チャンネルON=1 / b3-0:チャンネル4~1再生中フラグは読込のみ
  NR50_REG = 0x77;// b7:左VinOF=0F / b6-4:左音量=7 / b3:右VinOFF=0 / b2-0:右音量=7
  NR51_REG = 0xFF;// b7-4:チャンネル4~1左出力ON=F(1111) / b3-0:チャンネル4~1右出力ON=F(1111)
  // チャンネル1(矩形波スイープあり)
  NR10_REG = 0x00;// b6-4:スイープ時間=0 / b3:スイープ方向=0(上) / b2-0:スイープ変化量=0
  NR11_REG = 0xC0;// b7-6:デューティ比=3 / b5-0:音長カウンタ=0
  NR12_REG = 0xF0;// b7-4:初期音量=15 / b3:エンベロープ増減=0(減) / b2-0:エンベロープ単位時間=0
  NR13_REG = 0x0A;// b7-0:周波数(11ビットの下位8ビット)
  NR14_REG = 0x86;// b7:開始フラグ=1 / b6:カウンタ再生フラグ=0 / b2-0:周波数(11ビットの上位3ビット)
 }

 if (input_trg & J_B) {
  gotoxy(5, 2);
  print("INIT");
  snd_reg_init();// サウンドレジスタ初期化
 }

}

// VBL割込で呼ばれる
void vbl_isr(void)
{
 // キー入力
 input_old = input_on;
 input_on = joypad();
 input_edge = input_on ^ input_old;
 input_trg = input_on & input_edge;
 
 proc();
}

void main()
{
 DISPLAY_OFF;// 画面全体を非表示
 HIDE_BKG;// BGを非表示
 HIDE_SPRITES;// スプライトを非表示

 print(" ");// ダミー描画
 set_bkg_data(32, 64, AsciiBgLabel);// アスキー文字

// SHOW_SPRITES;// スプライトを表示
 SHOW_BKG;// BGを表示
 DISPLAY_ON;// 画面全体を表示

 disable_interrupts();// 割込無効
 add_VBL(vbl_isr);// VBL割込に追加
 enable_interrupts();// 割込有効
 set_interrupts(VBL_IFLAG);// VBL割込セット

 snd_reg_init();// サウンドレジスタ初期化

 // メインループ(無くても良いけど何となく)
 while(1) {
  delay(1000UL);
 }
}
Aボタンを押すと音が鳴ります(音量注意)。
Bボタンを押すと音が止まります。

他のチャンネルも鳴らしてみます。
  // チャンネル2(矩形波)
  NR21_REG = 0xC0;// b7-6:デューティ比=3 / b5-0:音長カウンタ=0
  NR22_REG = 0xF0;// b7-4:初期音量=15 / b3:エンベロープ増減=0(減) / b2-0:エンベロープ単位時間=0
  NR23_REG = 0xB2;// b7-0:周波数(11ビットの下位8ビット)
  NR24_REG = 0x86;// b7:開始フラグ=1 / b6:カウンタ再生フラグ=0 / b2-0:周波数(11ビットの上位3ビット)
  // チャンネル3(波形メモリ音源)
  NR30_REG = 0x80;// b7:出力ON=1
  NR31_REG = 0x00;// b7-0:音長=0
  NR32_REG = 0x20;// b6-5:音量 100%出力=1 ※ミュート(0%出力)=0、50%出力=2、25%出力=3
  NR33_REG = 0x72;// b7-0:周波数(11ビットの下位8ビット)
  NR34_REG = 0x86;// b7:開始フラグ=1 / b6:カウンタ再生フラグ=0 / b2-0:周波数(11ビットの上位3ビット)
  // チャンネル4(ノイズ)
  NR41_REG = 0x00;// b5-0:音長=0
  NR42_REG = 0xF3;// b7-4:初期音量=15 / b3:エンベロープ増減=0(減) / b2-0:エンベロープ単位時間=3
  NR43_REG = 0x33;// b7-4:周波数シフト量=3 / b3:カウンタ単位(0:15/1:7)=0 / b2-0:周波数=7
  NR44_REG = 0x80;// b7:開始フラグ=1 / b6:カウンタ再生フラグ=0

4チャンネル同時に鳴りました。

0 件のコメント:

コメントを投稿