html Javascript プログラミング 楽器

ギターの指板上にある音名を覚えるためのアプリを作った

そろそろ指板上の音名を覚えたい

死ぬまでにやりたいことの一つにギターの指板上の音名を覚えるというのがあります。

ギターは指板上の音を全部覚えなくても楽しめるのですが、やっぱり覚えた方いいです。

人生の残り時間もまぁまぁ減ってきたのでそろそろ本気を出すべく指板上の音名を暗記するためのアプリをつくってみました。

アプリは要するに単語帳的なものです。

ランダムに音名が出題されて、指板上でその音の出る場所を押さえるというものです。

アプリはこちらです↓(github Pages)

https://ryjkmr.github.io/memorize-notes-on-guitar-fretboard/

ソースコード(github)

モグラ叩き式にゲーム感覚で練習

使い方は簡単です。

アプリのページを開いたら出題欄の"click to start"をクリックします

ランダムに選んだ音名が表示され、その音が鳴ります

画面のギター指板上でその音名の場所をクリックします。音名が表示されて、音が鳴ります。

正解するとすぐに次の音名が表示されます。オクターブの高低は考慮していません。音名が合っていれば正解としています。

指板上でその音名の場所をクリックします。これを繰り返して練習します。

下部のラジオボタンで半音を#で表示するかbで表示するかを選べます。

まだフレットの音が分からない時は"show tone name"にチェックを入れるとフレット上に音名が表示されます。

使うフレットと弦を限定して練習

各フレットと弦の端にあるチェックボックスを使って、使用するフレットと弦を限定できます。

例えば1、2弦だけ練習するとか、1フレットから3フレットの間だけ練習することができます。

ベースギターの場合は1、2弦をオフにすればよいでしょう。

弦とフレットを制限すると、出題される音名もその制限で出せる音に限定されます。

ある程度覚えたらテンポに合わせて練習

テンポに合わせたリアルタイム練習も可能です。

"practice to tempo"ボタンでカウントがスタート、以降、4拍毎に出題欄の音名が変わります。

1拍目に出題された音を3拍目に当てられると良い感じです。

下のスライダーでテンポを変えられます。

このモードでは当たり判定はしていません。自習用アプリは

当たり判定がないので、本物のギターで練習することもできます。むしろその方が良いと思います。

場所による得意不得意がはっきり分かる

実際にやってみると意外と難しいです。

ローポジションの音名はそれなりに覚えているつもりでしたが、

よく覚えている場所とうろ覚えの場所がの濃淡が激しいことが分かりました。

このアプリにどれくらいの学習効果があるのかは分かりません。

自分で使ってみた感じは悪くないですが、このアプリだけで全部の指板を覚えられるものでもないでしょう。

個人的には、この練習をきっかけにこれまで手癖で引いていたフレーズでも音名を意識するようになりました。

とりあえず何もしないよりマシなことは確かなのでこのまま使ってみようと思います。

母体は以前作ったコードトーンやスケールの表示アプリ

プログラムは以前作ったコードトーンやスケールの表示アプリを母体に作りました。

このアプリは入力したコードの音を指板上で表示するものです。

このアプリの指板表示部分を流用して作りました。

ギターの指板はテーブルセルのbackgroundに画像を設定

ギターの指板は、最初は母体のアプリと同じくHTMLのtableだけで作っていました。

しかし、もうちょっとギター感が欲しいなということで、Illustratorで描いた指板の絵を分割して各tdに割り当てています。

imgタグではなくtdのbackground imageとして割り当てています。

background imageは以下のようにcssで割り当てられるので使いやすいですね。

td.pos-0.str1 {
  background: url("./pics/flet-str1-pos0.png") right bottom no-repeat;
  background-size: 100% 100%;
}

問題はクラスを使って処理を簡単にした

問題はquestionsという専用のクラスを作ってそこにデータを格納することで、次の問題を取得したり、順番をランダムにシャッフルするといった処理を自動的に行えるようにしています。

例えば、questionsClass.get()とやるだけで、新しい問題が取得できます。内部のカウンターが自動更新されるのでメインプログラムはカウンタを持つ必要がありません。

また、単純に問題の配列からランダムに取得すると同じ問題が続いたり、短期的に偏りが生じてしまいます。

そこで、ランダムに取り出すのではなく配列をランダムに並び替えて、順番に取り出す処理を行っています。処理はクラス内で自動的に行われるのでメインプログラムからはノータッチです。

配列を一周すると自動的に再シャッフルします。このとき、前回の最終問題と次周の最初の問題が同じにならないようにしています。

いちおう、単純なランダムで取り出すメソッドも搭載してあります。

  class quenstionsClass {
    constructor(_q_array) {
      this._data = _q_array;
      this._counter = 0;
      this._shuffle();
    }
    get random() {
      //ランダムにデータをひとつ選んで返す
      const i = Math.floor(Math.random() * this._data.length);
      return this._data[i];
    }
    get data() {
      return questions._data;
    }

    _shuffle() {
      const _lastQuestion = this._data[this._counter];
      for (let _i = this._data.length - 1; _i > 0; _i--) {
        let _j = Math.floor(Math.random() * (_i + 1)); // 0 から i のランダムなインデックス
        [this._data[_i], this._data[_j]] = [this._data[_j], this._data[_i]]; // 要素を入れ替え
      }
      if (_lastQuestion == this._data[0]) [this._data[0], this._data[1]] = [this._data[1], this._data[0]];
    }

    get get() {
      const _result = this._data[this._counter];
      if (this._counter === (this._data.length - 1)) {
        this._shuffle();
        this._counter = 0
      } else {
        this._counter++;
      }
      return _result;
    }

    get next() {
      return this._data[this._counter];
    }

    set data(_a) {
      this._data = _a;
      this._counter = 0;
      if (_a.length > 1) this._shuffle();
    }
  }

音はTone.jsで出力

すべての音はTone.jsライブラリを使って出力しています。

オリジナル音源を使ったサンプラーシンセを作れたり、正確なテンポで演奏させることができます。こういうアプリにはぴったりです。

Tone.jsは以下の記事で扱っています。

また、レスポンス重視の楽器アプリならhowler.jsがおすすめです。

-html, Javascript, プログラミング, 楽器