Arduino+YMZ294+tinyMML+MetroでPSG演奏(失敗編)

いつものセット

YMZ294いつもの感じで組みます。
PSG-Shield

Arduino用にA tiny MML parserYMZ294ライブラリを使います。
今回は3音同時に鳴らしたいので、delay()関数ではなく、複数のタイマを同時に使えるMetroというライブラリを使います。
使い方はArduinoでタイマ/スレッドプログラミング – DiaryExceptionを参考にさせて頂きました。

1.YMZ294に鳴らす音を投げる(ymz.SetFrequency)

2.次の音を鳴らすタイミングにタイマを仕掛ける(Metro.interval)

3.タイマで仕掛けた時間が経過したら(Metro.check()==1)、次の音を拾う(mml_fetch)

1に戻って繰り返し
みたいなのを3パート分やります。
やってるはず、なんですが……
とりあえずスケッチはこんなの

#include <Metro.h>
#include <YMZ294.h>
#include <mml.h>

// YMZ294 defines
const byte WRCS_PIN = 8;
const byte A0_PIN = 9;
const byte RESET_PIN = 10;
YMZ294 ymz(WRCS_PIN, A0_PIN, RESET_PIN);

Metro psgMetro[CH_COUNT] = {Metro(),Metro(),Metro()};

// mml defines
MML mml[CH_COUNT];
MML_OPTION mmlopt[CH_COUNT];

char *text[CH_COUNT] = {
  "o6 l16 cegeg>c4."
  "o6 l16 eg>c<g>ce4.",
  "o5 l16 cegeg>c4."
};

static Channel ch[CH_COUNT] = {CH_A, CH_B, CH_C};
static void mml_callback(MML_INFO *p, void *extobj)
{
  Channel* c = (Channel*)extobj;
  switch (p->type) {
    case MML_TYPE_NOTE:
      {
      MML_ARGS_NOTE *args = &(p->args.note);
      snd(args->number, args->ticks, *c);
      }
      break;
    case MML_TYPE_REST:
      {
      MML_ARGS_REST *args = &(p->args.rest);
      snd(0, args->ticks, *c);
      }
      break;
    default:
      snd(0,0,*c);
      break;
  }
}

void snd(int num, int ms, Channel ch)
{
  if (num == 0)
    ymz.SetFreqBit(ch, 0);
  else{
    ymz.SetEnvShape(1,0,0,1);
    ymz.SetEnvFrequency(15);
    ymz.SetFrequency(ch, noteFreq[num]);
  }
  psgMetro[ch].interval(ms);
}

void setup() {
  DDRD = 0b11111111;
  pinMode(WRCS_PIN, OUTPUT);
  pinMode(A0_PIN, OUTPUT);
  pinMode(RESET_PIN, OUTPUT);
  
  ymz.Reset();
  ymz.SetMixer(0b111, 0b000);

  for (int i = 0; i < CH_COUNT; i++){
    MML_OPTION_INITIALIZER_DEFAULT(&mmlopt[i]);
//    ymz.SetVolume((Channel)i, 0x0f);
    ymz.SetEnvEnable((Channel)i, true);
    mml_init(&mml[i], mml_callback, &ch[i]);
    snd(0, 1, (Channel)i);
    mml_setup(&mml[i], &mmlopt[i], text[i]);
  }
}

void loop() {
  for (int i = 0; i < CH_COUNT; i++){
    if (psgMetro[i].check() == 1){
      if(mml_fetch(&mml[i]) != MML_RESULT_OK){
        mml_setup(&mml[i], &mmlopt[i], text[i]);
      }
    }
  }
}

本来鳴らしたかった音→沙羅曼蛇とは (サラマンダとは) [単語記事] - ニコニコ大百科のピコカキコ「CREDIT」の音(♪チロリチロリーってやつ)

実際に鳴った音

何このコレジャナイ感。
それっぽい音は鳴っているので、回路じゃなくてスケッチの方に何かしら間違いがあるのは分かりますが、どこなんだ。

あ、あとArduino全然関係ないですが、また勇者部(というか、ほぼ東郷さんオンリー)のMAD動画作りました。
ドが付くほどネタバレ全開な動画ですが、見て頂けると嬉しいです。

ゆゆゆ見てない人を全力で置いてけぼりにしているので、逆にまったくネタバレになっていない気もします。


コメントを残す