🎸

BASS練習用Webアプリ『シドノート』の開発

に公開

作ったアプリの画面。

スクロールすると、こんな感じ。

モチベーションとしては……
ベース初心者(=私)が練習するための、現状の教材に不満を感じて
解消するために、新規アプリが必要だった。

同じような問題を抱えてる楽器初心者は多いかもしれないので
こういうアプリがあったら便利ッスか……? って世に問うために、まず公開してみた。

https://github.com/kako-jun/sid-note

5W1Hを説明していきます。

いつ作ったのか?

2025年の春に、30時間かけて作った。

金沢って冬の間、室内がメインになるのだけど
Alexaで音楽を垂れ流してるうちに、ふと

「1番好きな音色を、あえて1つだけ挙げるとしたら……?」

って考えて、FF5の戦闘曲で鳴ってるベースの音が1番好きだなーって
心から再確認した。

どの楽器も大して弾けないのだけど
ベースだけは弾いてみたい! 少なくともFF5の曲を弾けるくらいには!
って、急にやる気を出した。

すぐに開進堂でベースを買った。
ヘルナンデスくんみたい名前のやつ。

けど、普通の練習をしても上手くならなかった。


フレットごとの鳴る音の法則が気になって、集中できない。

植松さんが、このように編曲したからには、音符1つ1つに理由があるはず。
どの程度まで自動的に決まってる世界なのか……?
法則から、あえて外した音もあるのか……?

それらを知らずに弾いても、「弾けた」とは言えない気がする。
真の「好き」ではない気がする。

プログラミングの世界では、設計こそがプログラミングであって
コーディングしかできない人はコーダーと呼ばれ、プログラマーほどの尊敬はされない。

「……演奏側だけではダメだ。作曲側も知らなければ……!」

自分は形から入るタイプでもあるけど、頭から入るタイプでもある、と分かった。
弦楽器は仕組みがむき出しなので、周波数など物理法則との関係も気になった。

自然界の連続的な音から、人間が離散的な音だけを抽出し
スケール、コードなどを発見?発明?していった歴史にも興味を持った。

そのへんを納得できるまで練習を中断して
冬に音楽理論を調べまくった。
1冊2時間くらいで3冊、動画を数十個。

その後、やっと弾く行為を再開したら、今度は
余弦ミュートしないと、ぜんぜん音が汚いことが分かった。


左手ミュートも、右手ミュートも、TAB譜での記述方法はある。
×記号と、P.M.(Palm Mute)。

参考に、アジカンのバンドスコアも買った。
ミュートは省略されてた。

私が上手くなるには、「この場所では、こうミュートするんだ!」
という自身向けの指示を書いて、それを見ながら練習できる必要があった。

どのミュート方法が正解かは試行錯誤するので、本には書き足せない。

ましてや、FF5のバンドスコアは(たぶん)存在せず
親切な人が耳コピしたPDFに頼るしかない。

「PDFをわざわざ印刷して、書き足す……? そんな無駄な……」
って考えた時に、あっ!ってアイデアが浮かんだ。


TAB譜でなく、指板を音ゲーのような抽象的なグラフィックで表現して、そこに

  • 左手のこの指で、この弦の、このフレットを押さえろ!
  • 別のこの指で、この弦の、このフレットのあたりをミュートしろ!
  • 右手は、このあたりをまとめて手刀でミュートしろ!

みたいに絵として表示できれば、ひと目で理解できる。

それを実現したのが、上のスクショ。
TAB譜は横に向かって読むけど、この形式(指板譜?)では縦に向かって読む。

この見せ方を思いつくまで、冬の間
「自分にベースは合わないのかな……」って悶々と考えて

春に思いついて、1週間くらいでプロトタイプを作って
家族に使ってもらいながら、2週間かけて改善していった。


アプリに実装したいアイデアは、Cosense(旧Scrapbox)に箇条書きした。
https://scrapbox.io

シャワー中によく思いついたけど、スマホから1行追加するだけ。
インデントもつけてない。

優先度の高いタスクほど上に書き
実装したら、その行の左端に○を書くだけ。

バンカラマッチのマッチング待ちや
デスノートを読み返しながら、アイデアを追加した結果
100行以上になったけど、20行くらいでVer.1としては充分だった。

完璧より完成。


「ロビンソンクルーソーセット」(39巻)より

誰が作ったのか?

金沢にいる kako-jun が1人で作った。

ググると分かるけど
はてな、FF14、Instagram、Note、Zennなどで、いろいろ書いてる。

日本のゲーム、漫画、アニメがバイブル。

「ほかの誰ともかぶらない。かぶってたら書く意味がない」
が基本なので、ニッチでマイナーな内容が多い。

園芸も釣りもプログラミングも、趣味なので
プロだと逆にできないような、遠回りを楽しむ実験が多い。

たぶん都市部の人が想像できないような、金沢の田園環境。
ブドウとか趣味で作って、ニワトリやネコに攻撃されながら
デスノートのニアのマネとかしてるうちに、プログラミングが進んだ。

みなと模型でやっとHGジークアクスを買えたけど
こっちを優先するくらい、いまは音楽に夢中。

どこで作ったのか?

サポート期限が切れたせいか
Windows 11のアップデートすら降ってこなくなったThinkPad X13。

デュアルブートできるほどディスク容量がないので
USBメモリブートのLinuxを入れたら遅かったので、外付けSSDに入れた。

上からチョップしてもボキッってならないように
下にプラダンをくっつけて、黒いマスキングテープでぐるぐる巻き。

ボヨヨン岩のように、優しく跳ね返してくれる。

どうやって作ったのか?

Nextで作った。
Nextを使うのは初めて。

TypeScriptは、ぜんぜん初めてじゃない。
フロントエンドも、サーバーサイドも何回も作ってる。
Denoも試して飽きた。

Viteで雛形を作ったプロジェクトに対して、中文サイトを頼りに、
esbuildを使って、Electron版とWebブラウザ版をビルドし分ける
スクリプトを書いたこともある。

仮想DOMなフレームワークはVueから始めて、こんなサイトを作ったこともある。


名詞の性別を、言語ごとに一覧できるWebサービス

けど、Vue3がドリームキャスト並みに機会損失したので
待ってる間にReactを勉強した結果

チョコラータに興味なくなるセッコのような気持ちになり
それからは、ずっとReact。


今回のアプリも、Viteで作れるだろうけど
楽勝って分かってる方法を選んでも、つまらない……。

Nextについては
「Reactを使う時点でMetaに囲い込まれてるのに、なぜさらにVercelに囲い込まれる必要があるの?マゾなの?ふん!」
って、好感を持ってなかったけど

今では「三井は髪を切った」の後の三井なみに、好感を持ってる。

初めてのNextでは

  • Turbopackが新しすぎて、エラーで動かない。
  • 何もいじってないのに、Notoフォント関連のエラーが出る。

などのバグと

  • .next に画像が残ってると、public 内の画像を差し替えても古いものが表示され続ける。
  • Copilotにきいても .next を消すコマンドはわからなかったので、手動で消した。

など、初体験を楽しんだ。

用意されてたページの例は、Gridレイアウトだったので
すぐFlexレイアウトに書き換えた。

GitHubにpushするだけで、Vercelが認識して
ビルドして、Vercelのサブドメインにホストする体験は、ほかのクラウドでも良くある挙動だけど

これを初めて味わったら、感動してVercel信者になるのも無理ないって思った。
負荷分散とか、転送量(料)とか、なんも(←能登弁)考えんでええもん。

もともと持ってた独自ドメインに
1個サブドメインを作って転送するだけで、アプリの公開が済んでしまった。

ただ、VercelにホストされたNextアプリと、Cloudflareとの相性?問題があって
思いっきり該当したので
https://polidog.jp/2024/03/07/next-vercel-cloudflare-proxy/
の通り、Cloudflare側プロキシをオフにしたら解決した。

(上のスクショで「プロキシ済み」になってる箇所が、ホントは良くなかったってこと)


「本当に理解できてるか確認するためには、人に説明してみるのがイイ」
ってよく聞く。

でも、説明する相手もいないので
「本当に理解できてるか確認するためには、それをプログラミングで表現してみるのがイイ」
も成り立つのでは……?
と仮説を立てて、実践してみた。

つまり、音楽理論の関数化に挑戦した。

結果的に、勉強してそれができたから、アプリが動作してるわけだけど
最初は chordcode だと思い込んでたレベルからスタートした。

Ver.1がリリースできた時点で
今まで聞かされてた音楽理論の、ウソに気づけるくらいにはなったので
自作して良かったと思う。

コード表記のデコード処理や、キーごとのダイアトニックコードの列挙処理などは
そのための npm が山ほどあるし

LLMは音楽理論も習得済みだから、GitHub Copilotに「関数化しておくれー!」
って願えば叶う。

いまの時代はもう、そういうドラゴンボールのバーゲンセール状態に突入したわけだけど
今回は勉強のためだから、カンニングしなかった。

自力で作るべき関数まで、生成AIに頼んだら
これからずっと、その選択肢が入り込むと思うんだ。

GitHub Copilotは、UIのめんどいスタイリング指定とかで使った。
モデルは、Claude 4 Sonnetの1択!


なぜ作ったのか?

あとは、「なぜ作ったのか?」と「何を作ったのか?」だけだけど
ここからが無茶苦茶長い。

論文なら、フォーマット通りに短くまとめるし
脚本なら、枝葉は省くのだけど

Zennでの「作ってみた」系は、思考と試行の過程を
すべて残すことに価値があると思ってる。

リバートしたアイデアだろうと、恥ずかしがらず公開してこそ
未来の初心者たちの参考になると思う。

でないと、すっごくスムーズに最短ルートで開発できたかのように見えちゃって
それってSNSで、マイナス面を隠すキラキラ系じゃん。


それに私の場合、興味駆動開発や、怒り駆動開発なので
なぜ興味を持つのか、何に対して怒ってるのかも書かないと
再現性ある手順にならない。

Zennの基準は知らないけど
noteでは5,000文字を使わないと、私が能登地震で感じたことを書けなかった。
https://note.com/kako_jun/n/n81678fda88a6

ひぐらしは20万文字以上あっても、サラッと読めたので
読み手の興味を維持できるよう気をつけながら、以下、続けてく。

脱線のように見える章もあるかもしれないけど
実は脱線でなく……

無関係に思えた複数の経験が
偶然1つのアプリの形になってくことってあるから……。


なぜ作ったかは、上で書いたように
「ベースの演奏練習のため」だけど

この世って、理由が1つのケースはめったに無くて
チコちゃんのような子供になら、1つ教えとけば済むのだけど

読んでるのは大人だろうから、ごまかさず
ほかの理由も書いておこう。

  • 音楽を楽しめるようになるため
  • ベースを始めたきっかけはロックやジャズが多いけど、ゲーム音楽で始めた例を示すため
  • 音楽関係者の、音楽理論を他人に説明する言語能力に低さがイヤになったため
  • 1指1フレットができない人への、ハラスメントがイヤになったため

などの理由がある。


音楽を楽しめるようになるため

音楽って「音を楽しむ」から、そう名付けられたのでしょう?

数学のほうがよっぽど数楽なので、プログラミングは楽しい。

私はひどい音楽教師に当たったせいで
音楽を楽しめない頭になってしまった。

教師の選んだ曲だけを聞かされ
ロックは1曲もなかった。

調のない現代音楽を聞かされ、これが最高であり理解できないのはおかしいと強制された。

気持ち悪いフランス語の洗脳ソングを歌わされた。

質問を許されなかった。

なぜ五線譜がいまのルールになってるのか、など
合理的な経緯は省略されたまま、権威が決めたのだから黙って覚えることを強制された。

音楽のテストでは、クラシック作曲家の生まれた西暦を書かされた。

五線譜の左端にフラットがあれば、その音は「常に半音下がる」と習った。
それは正しいけど、その音は「常にファになる」とも習った。
シャープなら、「常にシになる」らしい。

1度覚えてしまった頭を、訂正するのは難しい。

私は、フラット記号を見た時、それがファの位置を変える場合も
知らないだけで、ひょっとしたらあるのかも……?
って、いまでも何が正しいのか分からない。


楽譜を演奏することが音楽だと習った。

正確にトレースできるピアニストより、数小節でも理論でアレンジできる人のほうがスゴイと思ってたので、演奏より理論を知りたかった。

だって、著作権って作曲、作詞、編曲のもので
歌手は歌う権利を与えられただけの弱い立場だし
有名なバンドを見ても、作曲できるメンバーとそれ以外に格差があるし

トレース技術に割く時間がもったいないと思った。

演奏してるうちに、自動的にアレンジ技術が習得できる!とでも思わないと、続けられない……
と思って、ピアノの上手い人に聞いたら
小学生からピアノを続けてても、コードは理解らないし、作曲もできないらしい。

そんな音楽が楽しくなかった。
音楽以外が私の心を癒やしてくれた。

シン・エヴァのゲンドウの逆ぅ……。

ハズレ教師に当たったんだろう、とあきらめてはいるけど
トラウマを克服しとかないと、未来に進めない気がする。

ほとばしる熱いパトスで思い出を裏切ろう。

身につけたプログミング能力によって、音楽と和解するという作戦だった。


ベースを始めたきっかけはロックやジャズが多いけど、ゲーム音楽で始めた例を示すため

FF4, 5, 6あたりのベース音が好き。
ソニー製チップの音なのかな。

ドドドって感じでなく、ビャンビャン、ジクジク鳴ってる。
盛り上がった波形のてっぺんが、ぜんぶ破裂してるような。

音楽に対して、初めて感じた喜びを思い出すと
FFのいろんな主旋律に、勝手にふんふん低音を口ずさんで
偶然バッチリ合った感じになった時に
不思議だ……って感じた科学的な発見だったと思う。

つまり、すでにある曲にオレオレベースを付けることが
興味の出発点だった。

自分の中では植松さんが神であり、ロックバンドが次だけど
何年間も、何十曲も聴いたバンドでも、ベースの名前は知らない。

ポール・マッカートニーがギターでなくベース担当ってことも、最近知ったくらい。

そんなだから、ベース・マガジンを読んで
ジャコ・パストリアスがすげーって、いろんなベーシストが書いてるのを見ても
違う世界だ……って感じちゃうし

興味を持とうと頑張れば、すげーって思うのだろうけど
ほかの人にとってはジャコ・パストリアスが神でも
私にとっては植松伸夫が神だから

原始的な喜びじゃなく、養殖的な喜びが限界だと思う。


YouTubeでのベース講座の動画を見ても
やっぱりベーシストって、バンドに憧れて始めたケースが大多数っぽくて

ゲーム曲の弾いてみた動画は
すでに上手い人が、人気を得るために弾いたの順で

ゲーム曲を弾きたいから始めた、というケースを知らない。

興味の対象も違うし、スゴイの基準も
自分は世間とズレてると感じる。

速い演奏ほどスゴイとは思わない。
細かい音が多いほどスゴイとも思わない。

同じ感動を呼ぶなら、音は少ないほど良い。
「オッカムの剃刀」の「前提は少ないほどよい」と同じ。

ヘタに見せないための装飾とか、間が持たない不安を埋めるだけの音はいらない。
グルーブ感とか、どうでもいい。

速ッ!すごいテク! って思わせてしまってる時点で、聞き手に雑念が生まれてて
雑念を生ませない、曲に集中させる演奏のほうが上だと思う。

だから、私にとっては
演奏の良い/悪い、音の良い/悪いの常識に従う意志が、もともと無くて

ベースラインがFF5と比べて感動できたか?
しか尺度がないし

ゲームと似てない、ぼんぼん音の聞き取れないベースにも興味はなかった。


そんなストライクゾーンの狭さだったけど
向井秀徳が金沢に来た時に、誘われてライブハウスに行って

向井にしか書けない、狂った歌詞や
向井にしか書けない、狂ったコード進行

なんかペダル操作で録音しながら
即興で音楽を組み立てる、ホントの芸といえる芸に
すげー興味を持った。

行く前は、誰……それ……って感じだったけど
なぜかライブの終わりには、観客全員がステージに上がって、私も向井秀徳に触れてた。

それからは、キレイに録音されたポップとか
スタジオで多重録音された洋楽とかでなく

完全に4人だけで成立し、ステージのたびにアレンジが変わるほど
応用の効きまくるロックというものに興味を持った。

けいおんを見た。ぼっち・ざ・ろっく!を見た。

ジャンプルーキーで『ふつうの軽音部』にオーラを感じて
投票して、連載が決まって嬉しかった。

https://x.com/kuwahali/status/1602226960188731392?t=nH_hveKZp7uHVFObvJOJLg&s=19


漫画の人気が出ると、BSSってこういう感情なの……? って痛かった。

クライマックスで『IGGY POP FAN CLUB』が出てきた時は
NUMBER GIRLで1番好きな曲だったので、作者に対してもBSS!だった。

でも、『ふつうの軽音部』の作者はベースを弾ける。
漫画家になる前に、『IGGY POP FAN CLUB』も弾いてたかもしれない。

音楽漫画って、練習シーンをすっ飛ばす。
特にベースの初心者は、打ち切りの危険が増えるのか、漫画には出てこない。
(ドラムなら『BLUE GIANT』があるけど……)

実際、NUMBER GIRLの曲を弾こうとしたけど、弾けない。
4本の狂ったハガネの振動が、別の意味で狂ってる。

FF5のバトル1も、TAB譜のあったサイトに
戦闘曲の中では簡単、って書かれてたのに、まったく簡単じゃない。

そんなレベルから、無事に弾けるようになって
それが自作したアプリのおかげでした、って例になったら
夢があると思った。


音楽関係者の、音楽理論を他人に説明する言語能力に低さがイヤになったため

私の、音楽教師のガチャ運が悪いことは分かってたけど
このアプリを作るために調査した過程で、どうやらそれは偶然でなく

音楽をやってる人って、音楽に能力を全振りしてるのか
音楽家同士だと、ニュータイプ同士みたく言葉を必要としないのか

初心者に言葉で説明する能力が、育ってないケースが多いと分かってきた。

具体的に限定すると
「1通りの意味にしか解釈できない表現で説明しようと、努力する感覚自体が育ってない」

プログラミングの世界では、例えばコメントや仕様を記述する時に
「一意でない」表現は、悪い例として定着してる。

それに慣れてると、音楽では
曖昧な説明がまかり通って、ぜんぜん言葉に責任を持ってない感じに

信号無視が基本の北京を旅行したときのような
カルチャーショックを受けた。


YouTubeで解説してるような人は、流暢で
しかも言葉が正確で、一意に受け取れる表現だけを使ってる。

なのに、なぜか文章で初心者向けに音楽理論を説明してるサイトのほうが
ゆっくり推敲して、リライトもできるはずなのに、言葉が正確でない。

私が知りたいのは

  • どうやってキー、スケール、コードなどの概念ができたのか?
  • もし、それらルールに違反して弾いたら、どんな音楽(印象)になるのか?
  • ダイアトニックスケールは全全半全全全半だけど、なぜ全全全半全全半にしなかったのか?
  • それを決めたのはギリシャ人の誰か?
  • なぜ人間は、この比率で半音が混じると心地よく感じるように進化してるのか?
  • 自然界の音は半音間隔でないのに、なぜ敢えてC4の音は何ヘルツみたいにバッチリ定義して、半音間隔以外の音を弾けない楽器を主流にしたのか?
  • そうやって自由度を下げると、俳句のルールのように作曲は楽になるだろうけど、作曲者は自由にほかの音を使ってみたくならないのか?

そういう網羅的な情報だった。

音楽って、歴史、数学、物理、生物も絡む。
どこまでが自然法則の発見で
どこからが人間の発明なのかを把握してこそ、人間賛歌ッ!って感じがするから。

生き残ったルールには、競争に勝てた理由があるはずなので、できればすべて知っておきたい。

解説してくれる動画やサイトを探したのだけど
見つけても、最終的には濁されていた。

いま主流の音楽は西洋発祥のスケールで作られてて
その解説では、教会での宗教音楽としての歴史を避けられないので
音大でも省略される世界なのか、英語版だけになってしまう。


結局、そういう黎明期の知識は、Copilotが超詳しくて
100個くらい質問しまくって解決した。

  • keyscale の違い
  • note namepitch の違い
  • intervaldegree の違い

は、変数名を決める時に必要で
人間よりCopilotのほうが正確だった。

プログラミング中にも、ふと疑問は浮かぶもので
例えば……

「Cというコードと、Cmというコードの違いは、3度の音がマイナーかだけ」
なのは分かったし、
「CメジャースケールとAマイナースケールは、Ⅰに該当する音が違うだけで、使える音の面子は一緒」なのも分かったけど、

コードの話に出てくる「マイナー」って言葉と
スケールの話に出てくる「マイナー」って言葉に、なんの関係があるのよ?

別物だから、混ぜて考えちゃダメなの?
別物なら、Aマイナースケールって、なんで「マイナー」って呼んでるのよ?

みたいにモヤモヤした時に、Copilotのおかげでスッキリできるのは
すげー楽しくて、音楽が好きになれた。

「メジャー」や「マイナー」に、「明るい」「暗い」という意味はありません。
音程での「メジャー」や「マイナー」は、「長い」「短い」という意味があります。

Aマイナースケール(A, B, C, D, E, F, G)では、
C、F、Gの音がそれぞれメジャースケールの対応する音よりも半音低くなっています。

ブラックジャックのように「その言葉が聞きたかった!」って思った。

Cから数えて3度の音であるEは、ホントに3度だからCメジャースケールで
AからCまでの音程は、(B-C間が半音なせいで)3度でなく♭3度だから
Aマイナースケールと呼ぶルールなのね。

疑問を翌日まで残してはいけない。


他の例としては……

「使える音はCから1オクターブ上のCまでの間に、12個しかない」
は理解できる。
「キーとスケールが決まれば、Ⅰ~Ⅶの音が決まり、Ⅰ~Ⅶに該当する3和音も、4和音も自動的に決まる」
も理解できる。

でも、使える音は12個しかないので、
あるスケールでのⅤの和音が、別のスケールでのⅠの和音でもある
みたいな、かぶりが起きる。

先入観なしで、その和音だけポーンと聴けば、全く同じ。
けど、曲としての繋がりの中で聴けば、それぞれの曲での役割が違うって分かる。

そのへんの説明が、人間はヘタ。

Copilotなら

ドミナントノートは、通常、スケールの5番目の音を指します。
Cメジャースケールの場合、これはGの音です。

このGの音は、ドミナントコード(G7)のルート音でもあり、
トニックコード(C)の構成音の一部でもあります。

って断言してくれるし
「つまり……? どういうことだってばよ?」って聞けば、理解できるまで付き合ってくれる。


ギターの場合、Fは難しい……って
ネタのようになってるけど

ベースでは、Fは何も特別な言葉でなく、単なるファ。

スタンドに強い弱いの概念がないように、
CからBまでの音名に、明るい/暗い、簡単/難しいみたいな個性はない。

カラオケでキーの上げ下げボタンを押して
CがFになろうと、曲の印象は変わらない。

単に、作曲した本人の歌いやすい高さにしたかったとか
ギターの運指が楽とかで、とりあえず公式としてのキーを決めてるだけ。

『転がる岩 君に朝が降る』を、ぼっちちゃんが歌うことになれば
キーを上げるだけの話。

クラシックで嬰ホ長調とか、イ短調とかを見ると
すげー、ハじゃないなんて難しそうー!って思っちゃうけど
ビビる必要はなくて

この高さで演奏してほしい。
楽しようと移調すんな。半音ズレすら許さん!ってこだわる作曲者ってだけ。

ベースにとっては、押さえるスタート位置が変わるだけで
そこからの相対的な指の動きは変わらない。

……ということですよね!?
ってCopilotに聞けば、ぶっちゃけそうですって言ってくれる。


そうやって、Copilot先生に
ぶっちゃけモードでサクサク回答されると、音楽って思ってたより難しくないって思えた。

アホな説明をしてる本を読んだ時も
Copilot先生に、こんなことが書かれてましたけど、アホですよね!?
って聞いたら同意してもらえるし、

ドラえもんの『うそつきかがみ』のように
Copilot先生なしではダメな身体にされた。


「うそつきかがみ」(2巻)より

例えば、本に
「ドからミは長3度で、ミからソは黒鍵が少ないから3度」
みたいな説明があった。

……逆やん!?
ピアノは楽器としては後発で、ピアノの発明前から人類は度で数えてたやん?

ピアノの鍵盤は結果であって、原因じゃない。
鍵盤がそうなってるから、自然法則や用語が決まったわけじゃない。

「弦の長さが半分になると、音が1オクターブ高くなる(振動数が倍になる)」
って法則をピラゴラスが発見してから、まずは全音だけの曲が主流だったけど

宗教音楽を厳かな印象にするためには
全音と半音をブレンドするのがコツって分かって

その比率と半音を挟む場所の候補が、複数あった中から
競争を勝ち抜いて、いまの全全半全全全半が主流になり
ピアノはそれを弾きやすい形にしただけ。


ドレミファソラシドを弾くと、ミ-ファ間、シ-ド間は半音なのに
違和感なく聞こえちゃうのは、耳が慣れちゃってるからで

ドからドまでを
全音だけで弾いたのを当たり前に感じる世界線もある。

ミからソが長3度でなく3度な理由は、「どうせ半音にするなら、ミとファの間がイイネ!」
って、昔の人達が実質多数決で決めたからであって、黒鍵は後付け!

みたいな判断を、関数を実装してるうちに自然とできるようになると思った。

AIが堂々と嘘をつくハルシネーションが有名だけど
音楽に関しては、人間がハルシネーションを起こしまくって、AIが逆に訂正してる……。

ベース歴の長さを自己紹介に書いてるのに、文章内の1弦~4弦が逆な人。

ダイアトニックコードを、7th入り限定の呼び方だと主張して癇癪を起こすギタリスト。
(ダイアトニックコードは3和音のことで、4和音の正式名称はダイアトニック7thコード)

プログラミングと違って、他者によるレビューのない世界の年配者はヤバイと知った。


1指1フレットができない人への、ハラスメントがイヤになったため

YouTubeのベーシストでも、真っ二つに分かれてる。

  • 「初心者のうちから指を広げる訓練をして、小指でも押さえるべき」派と
  • 「押さえ方なんてどうでもイイんだよ。個性で乗り切れ」派

大多数に向けての動画だから
ミスター平均値みたいな人に対する指導になるのは分かるけど

小指を使えない人もいるのよ。(ヤクザリーグ的な理由でなくても)
使えない理由すら言いたくない場合だってあるのよ。

その場合は、後者の考え方しかない。
動画やTAB譜で、小指を使っていたら、自分向けにアレンジするしかない。

それは工夫であって、戦略であって、能力が低いわけじゃないのよ。

個性を尊重してくれる後者の派閥だと、自由が許されるのだけど

前者の派閥は、自分は努力してできたから、できない人は努力が足りない
練習量が足りないって発想にまず行くので、無自覚に指ハラしまくって来るのよ。


  • どんな弾き方が良いか
  • どんな弾き方をしてるか

みたいな情報の共有は、動画が1番なのは明らかなので
YouTubeに正面向きの演奏動画が溢れてるけど

あれをできるのは、プライベート?一向に構わんッッな、健康な男性。
ベーシストのほとんどは男だし、指が届くかの基準も男の指。

それに合わせろっていう同調圧力も、ハズレ教師と同じで
音楽を楽しめなくなる圧なのよ。

結束バンドのリョウだって、1指1フレットで押さえてないし。

こんな押さえ方、どうかな……?
って質問する時に、動画を撮れないから
高速に、何度でも、パターンを変えて図示できる、このアプリが必要なわけ。

ちなみに、世間は正面から撮られた動画がほとんどだけど
演奏者の視点から指板を見下ろした動画も作ればイイのに……って思う。


あと、このアプリを作ってる間
ベース練習をしてないことを、疑われ続けるのがイヤだった。
(実際、してなかったのだけど)

すでに楽器のできる人は
継続しろ、考えるより手を動かせ、みたいに言う。

練習しなくて済む理由を探してる、逃げている、と断言してくる。
雛見沢症候群のL5か? ってくらい疑ってくる。

これがプログラミングなら
「いきなり設計に興味もたずに、まずはコードを書け」とは言わないでしょう?

初心者がコードを書く前に、Gang of Fourが……みたいな歴史を読んでもイイはずだし
むしろ、そっちの方が成長が早そう。

それが、なぜか音楽だと
初心者のくせに頭でっかちに考えず、まずは弾け
理論などまだ早い、みたいな

寿司を握る前に、卵焼きを10年焼かせる寿司屋みたいな、昭和が残留してる。

定型との乖離はまったく怖くない。
1番恐れるのは「ベースを弾きたい」という気持ちが、やがて風化してしまわないかということだ。

楽器から逃げてた期間じゃないことを証明するためにも、このアプリが必要だった。


何を作ったのか?

まずセットリストから始まる。
ベースで練習したい曲が並んでる。

「セットリスト」は、向井秀徳のライブで、帰るときに壁に貼られてた紙で初めて知った言葉。
ネタバレ防止のため、いつの間にか貼られてるのが、サンタのプレゼントみたいで素敵。

1曲をタップすると、トラック画面に遷移する。
モバイルファーストだけど、レスポンシブなので、PCでもクリックで操作できる。

曲名、作者名、年代、サムネイルなどを表示できる。
長文のうんちくなど、その曲の思い出も打てる。

階層構造を整理した結果、
セットリスト → トラック → コードセグメント → ノートの4階層になった。

コードセグメントは、だいたい小節のことなのだけど
小節の途中でコードが変わることはザラなので、小節という言葉は使えなかった。

ノートは音符1つに相当する。(単音も和音も可)


コードセグメント、ノートでは、指板を表示する。

コードセグメントの指板では、そのコード(Cmとか)を構成する音(3つ、4つが多い)
が、指板のどこに位置しているか、が分かる。

ノートの指板では
そのコードに属する1音を弾くのがベースの仕事(ほかの音を弾いても良い)なのだけど

その1音を出すために、何弦、何フレットを、どの指で押さえるべきで
その時、ほかのどの指でどの弦をミュートすべきか? が分かる。

私のベースは20フレットまでなのだけど
24フレットまでのベースもあるそうなので、最大数に合わせた。

いまは4弦だけで、5弦、6弦ベースには対応してない。
だって、6弦ベースを買った初心者をキターンしか知らないし……。

アプリ名の由来

英語では、音符のことをノートと呼ぶ。
なので、ダジャレでノートっぽい見た目のアプリにしたかった。

自分はこのアプリをスマホで使うので、画面は縦長。
ますますノートっぽい。

ベースといえばシド・ビシャス。

そして、(20周くらい読んだ)デスノートにシドウという死神が出てくる。
月が最初に拾うデスノートは、リュークのでなくシドウのノート。

シドウが始めた物語だろ。
シドウはアホだし、シド・ビシャスはベースを弾けなかった伝説がある。

上手くなくても衝動を表現できればイイんだ、で通るパンクロックの寛容さは
初心者に勇気を与えてくれる。

このようなダジャレで決まった。
ドロップダウンなど、いかにもアプリな見た目は排除した。

かすれたノートの感じを出すため、グランジなスタイルを多用したけど
Tailwindの良さは、最後まで分からなかった。
(私には合わないわ)

指板の横スクロール位置を、すべての指板で共通にした

この指板表示がアプリのメインなので、使いやすいギミックがある。

具体的には、指板のスライダ位置が「すべての指板で共通」になってる。

https://youtu.be/bE_fR3AcX78

ベースという楽器は、3フレット目の直後に7フレット、10フレットみたいに
駆け上がって弾くこともあるのだけど
スマホの幅では、せいぜい5フレットぶんしか表示できない。

かといって、押さえる場所が自動的に中心になるように、勝手にスライドさせちゃうと
ノートごとに、指板の見た目が似てるのに
実は異なるフレットを意味してることが続出して、見にくいし
駆け上がってく感がなくなっちゃう。

この、横スクロール量をすべてのスライダで共通にするアイデアを思いついた時
エレガントだと思った。
(この動きを実現した既存アプリってあるのかな?)

Jotaiを使うまでもなく、2段程度のprops地獄で実現できた。

スマホとPCで、別のイベント実装方法が必要だった。

スマホだとスライダを付けるだけでスワイプできるようになったのだけど
PCのマウスで似た動作をさせるには
canvasに対して、TypeScriptでイベントハンドラを書く必要があった。


ベースだけでなく、ピアノでの押さえ方も見られる

のように、五線とキーボードも表示した。

以前、TMIDI Playerの画面を見たことあって、カッケー!
けど、C言語では作れるイメージが湧かなかった。

TypeScriptで、いまの自分なら作れる気がする、と試したら作れた。

ト音記号、へ音記号は簡略化した。
音符を横長にもしなかった。

五線はしょせん道具なので
既存記法からの引き算と、0ベースからの足し算の合流箇所のようなデザインした。

次に弾く音を、マリカーのゴーストのように半透明で見られる

1手先を、見られる機能。
ストZERO3のVイズムが好きなので、その残像をイメージした。

TAB譜だと、次に弾く音がすぐ右に書かれてるけど
この指板譜だと、下にスクロールするまで見られないので困る。

それを解決するための、未来予知のような予告表示。

押さえる指を、かまいたちの夜のシルエットのように見られる

押さえるのに使う指は「人差し指が2」のように、丸に書いてもいるのだけど
それだけだと、TAB譜から情報量が増えてないので、かまいたちのような半透明な指を表示してみた。

色はかまいたち1準拠の青紫色。
(2以降は水色で目立ちすぎる)

上のスクショで分かるように、開放弦にも対応してる。

親指だけは上向きに表示する必要があり、めんどいので未実装。
チョーキングは親指で4弦を押さえるらしいので、そんな曲を演るまでには作ろう……。

五度圏を確認できる

勉強し始めた当初は、五度圏が
トラックの話なのか、コードの話なのか、さっぱり分からず混乱したのだけど
曲のキーの話だから、トラックの情報として表示することにした。

後述するけど、このアプリは曲の途中での転調もサポートしたので
転調してる期間だけは別の五度圏になってるはずだけど、細かいことはどうでもイイんだよ!

このアプリのヒントが得られれば、と
石川県立図書館でやってたDTMの発表会を見学したのだけど
そこでヤマハの中の人にCubaseを習った。

Cubaseでは、コードごとにも五度圏を表示してて
円の中心に1度の音名を描くデザインだった。

やっぱ五度圏って、トラック単位だけの話じゃないのかな?
あと、Cubaseではコードの表記に、min. とか sus4/7 などが登場して
えっ! DTM業界だとこっちの表記が主流なのー? ってビビった。

その曲のダイアトニックコード(機能和声)を見られて、しかも鳴らせる

いわゆるⅠ~Ⅶ。
Ⅰがトニックで、Ⅴに行って聴き手を不安にさせた後、Ⅰに戻ってきてスッキリさせろ的な
コード進行の基本のこと。

https://youtu.be/dC3ExuoQqVo

適当に弾くと、エイトメロディーズっぽくなる法則……

例えば、

  • Ⅰ → Cmaj7 → C - E - G - B
  • Ⅱ → Dm7 → D - F - A - C
  • Ⅲ → Em7 → E - G - B - D
  • Ⅳ → Fmaj7 → F - A - C - E
  • Ⅴ → G7 → G - B - D - F
  • Ⅵ → Am7 → A - C - E - G
  • Ⅶ → Bm7♭5 → B - D - F - A

Ⅰの部分をタップすると、トニックの役割がポップアップする。

(画面録画だと、どこをタップしてるのか分からないけど……)
Cmaj7の部分をタップすると、その和音が鳴り、構成音がポップアップする。
それら構成音1つ1つもタップでき、単音が鳴る。

最初は、ブラウザ上でリアルなベース音源を鳴らせるのか? って疑問だったけど
私が好きなのはFF5の音なので、三角波とかの組み合わせならTypeScriptで鳴らせる。

音ごとの周波数も、絶対値が決まってる。
例えば、基本のド(C4)は261.63 Hz。
ベースの音域の全通りの周波数を、定数のテーブルで持ったら実現できた。

「ボタン1つでコードを演奏できる楽器」って、初心者用にあるけど
作った後で、それを同じ機能って気づいた。
無料で手に入っちゃった。

試しに、スピッツの『チェリー』を、連続タップだけで弾いたら楽しかった。
あれ? もう楽しめたのに、あえてタップでなく弦楽器で再現する意味とは……?
いや、わざわざ手で弾く行為の、意味は理解してる。

「このタイミングで、指をパッと切り替えてることができたらゴールなんだな」
って、先に正解が見えるのは、予想してなかった感覚だった。

ゴールを下見できた、というか。

弾こうとしているコードの、そのトラック内での役割とカデンツがわかる

その曲で使えるダイアトニックコードの一覧は、上部に表示してるけど
下にスクロールして、いま弾こうとしているコードの指板を見てるときには
もう「このコードってⅠだっけ?」みたいに、覚えてなかった。

……ので、毎回表示するようにした。

https://youtu.be/mKFl2B_kxRM

Ⅰ~Ⅶまでの7つだし
このアプリはデスノートをイメージしてるので、
最初は死神っぽい顔文字を自作しようとしてたのだけど……

死神の個性とあまりマッチしてなかったので
個人的に分かりやすいラミエルにした。

序で変形しまくるアレを、トニックとかサブドミナントに見立てた。
Copilotにイメージを聞いたところ

  • Ⅰ(トニック): 安心感、安定感を表す穏やかな緑色の円。
  • Ⅱ: 導くような、わずかな動きを感じさせる黄色の右向きの矢印。
  • Ⅲ: 曖昧さ、中間的な印象を表す紫色のぼかしのある円。
  • Ⅳ(サブドミナント): 広がり、柔和さを表す水色の曲線。
  • Ⅴ(ドミナント): 不安定さ、緊張感を表す鋭い赤い三角形。
  • Ⅵ: 落ち着き、内向的な印象を表す濃い青色の小さな四角。
  • Ⅶ: 強い指向性、緊張感をより強く表すオレンジ色の斜めの線。

だったので、そのように描いた。

1つ前のコードから、いまのコードへの変化に、特定の名前のカデンスがある場合は
それを表示した。

いま弾こうとしてる音が、そのコードの構成音に属する場合は
ルート音か? 何度の音か? などを表示し

構成音に属さない場合は、経過音なのだろうけど
半音ズレで次の音に向かう音(クロマチックノート)か? を表示した。

なにしろ、目的が「植松さんが当時その音に込めた意味」を書き出すことなので
ルールで解析可能なものは、自動判定させてる。

指板をタップすると、実際に弾ける

https://youtu.be/o0caEnb_Lh8

ここまで作って
アレ……? コードをタップして音を鳴らせるなら
いっそ指板の、フレットと弦の交点をクリックすることで
その位置の音を鳴らせば

Webブラウザ上でベースを再現できるのでは? と気づいた。

音楽理論の汎用的な関数化は済んでたので
けっこう簡単に機能追加できた。

いま弾こうとしてる音以外の、すべての交点でも鳴らすべきか?
考えたけど、鳴らさないことにした。
誤タップで狙い以外が鳴るのは、ややこしいので……。

ミュートを意味する丸をタップしても、音は鳴らない。

ちなみに、TAB譜ではミュートは×記号なのだけど
このアプリでは、「どの指でミュートすべきかの提案を書ける」を実現したかったので
×でなく、左手の指番号を書ける。

「すべての交点で音を鳴らせる」状態の指板も作ってみた。

こういうのも、読ませるYAMLをちょこっと書き換えるだけで
簡単に実現できる。

https://youtu.be/MatsIe3Pgoc

適当に弾くと、デスピサロっぽくなる法則……

指板への直リンクは
https://sid-note.llll-ll.com/tracks/5#All Keys

ベースが弾いてる時、Vo.やGt.などほかの楽器が、どの音を弾いてるかを表示できる

これは興味あったから付けた機能。

指板にはベースの弾くべき音を、丸で表示してるのだけど
その音は、いまのコードのルート音か
ルート音でないが、コードの構成音なことが多い。

……ってことは、ほかの楽器はそのタイミングで
同じコードの、別の構成音を弾いてるはずだ、と予想した。

それを指板上に表示すれば
「確かにその法則に従ってるね」と、ひと目でわかって面白いし

「コードに属してるのに使われてない音」や「コード外の音」があったら気づけるのも
面白いと思った。

最初は、それぞれの楽器をアイコンで表示するつもりだったのだけど
ベースとギターの見た目が似てるし
ギター以外に、ボーカルもギターを弾いてるわけで、分かりにくすぎた。

次に『ふつうの軽音部』準拠で、Vo.はイワトビペンギンなど
動物で表示しようと思ったけど、
Vo.としてのはとっちと、Gt.としてのはとっちの区別がつかないのであきらめた。

機能を作った後、実際に『Stand By Me』のVo.を打ち込んでみたら
ぜんぜんコードに属してない音ばかりで……意外な結果になった。

ただ、特別なのはVo. = 主旋律 = メロディーだけみたいで
ほかの楽器は法則に従ってた。

ソルファのバンド・スコアを1音1音、全楽器を見ていって
「確かにそうなってる!」と確認するのが楽しかった。

音楽は耳でなく、目でも楽しめるのだと知った。


開発時に効率アップに貢献したテク

これらのテクを
みんな知ってることなのか、よく知らないので、紹介してみます。

「canvasに描く」という発想でなく、「ビューアを作る」という発想が大事

手段じゃなく、目的が大事。
「指板をcanvasに描く」のでなく、「指板ビューアとして機能するcanvasを作る」という発想。

開発の序盤で作ると、デバッグにも使えるので効率的。
観測手段がまず必要って、『Dr. STONE』でもオシロを作るシーンで言ってた気がする。

UIの自動テストは作ってないけど、ビューアがテストを兼ねてくれた。
デグレしてたら目で気づける。

「指板にコードを表示する」わけだけど、それもいきなりやろうとせず
金田一少年の言ってた「困難の分割」というか、分割統治法で

  • 1オクターブだけまず表示できるようにして、ほかのオクターブを増やす。
  • Cメジャーコードだけ、まず解釈できるようにして、他のコードを増やす。
  • 1つの弦だけをまず作って、ほかの弦の同音を表示できるようにする。

など、「ここまでは正しく動作する」を、1つずつ確定させていった。

draw.ioでSVGを描く時、拡張子を .drawio.svg にすると、エクスポートなしで表示できる

draw.ioで、音価のアイコンを描いた。
なぜなら、テキストで表示できる記号が、♪、♫、♫だけだったため。

SVGを描くのはdraw.ioが簡単。
VSCodeの拡張機能を使うと、アカウントの作成すら必要ない。

編集中の拡張子は .drawio なので
描いた後、普通はエクスポートして、.svg を保存して
それをReactでimportすると思うのだけど……

裏技があって、最初から .drawio でなく .drawio.svg にして編集すると
draw.ioに読ませれば再編集できるし、ブラウザに読ませれば SVG として表示できる
ハイブリッドな形式になる。

.drawio.png や .drawio.webp でも可能。

付点や三連符も、すべて描いた。
透明な正方形を背面に置いて、音符とそれだけの画像にすると
draw.ioのどこに置こうと、自動的に最小範囲の正方形のアイコンになる。

五線での正式な記号通りに作ってもしょうがないので
玉部分を大きく、リーダブルにした。

類似アプリ、使えそうなライブラリなどの調査を、敢えてしない

似たアプリがあるかの調査は、敢えてしなかった。

ベースをやろうと考える人は、ギターの1/10しかおらず
ベーシストは変人ばかり、というネタもあるらしい。

そんなベースに特化したアプリなんて、たぶん無いだろうと決めつけた。
「ほかの楽器のついでにベースもサポートしてる」の方向性だと、一芸を作りにくい。

それに、先行者がいたとして、その画面を見て先入観ができるのを避けたかった。

  • 開発者が楽器を始める。
  • 音楽をする人がプログラミングを始める。

どっちかが起こらないと、企業が作らないような、ニッチな音楽アプリは生まれない。
せっかくの外様なので、弾ける人には逆に考えつかないような発想を大事にしたい。

すぎやまこういちだって、音大に行かずに大成したんだー。


作ってるうちに、Csus4など音楽コードの書き方があまりに多岐すぎて
デコードだけは、NPMにある既存のライブラリを使っては? とも思った。

Copilotに訊いたところ、候補はあったけど
機能が増えるものじゃないので、最終更新が5年前とか。
サンプルが require の時代で止まってる。

ベースはギターのついでにサポートしてる感じ。
弦の意味が変わるので、ベースに特化しててほしい。

あと、英語圏のライブラリしかなかった。
シャープは#だけど、フラットは(♭を打てないので)bと書く文化。

シドノートも、デフォルトは英語なのだけど、日本語をサポートしたい。
つまり、#と♭に統一する。

シャープには♯という記号もあり、
入力時と、出力時に、そういう表記のゆらぎのノーマライズ処理が必要になる。

当然、既存のライブラリには#とbへのノーマライズ処理が入ってるわけだけど
このb表記が、コードに含まれると読みにくくてキライなので

bを認めてラッパーを書くこと自体が、負けた気がしてイヤだった。
ので、全角で車輪を再発明した。

ほか、弦の数え方を
私は「1弦なら、変数の値も1」にしたのだけど
既存ライブラリは stringIndex を0スタートにしたものばかりだった。

ふざけろ。
number 型の慣習よりも、「違和感最小の法則」が勝つだろうがよぉォオオオオーーーッ!!

UIから呼び出す音楽理論の便利関数を、すべて純粋関数として定義した

音楽理論を表現した関数を、utils ディレクトリ内に
コード、ノートなど、分類ごとの .ts に分けて、大量に書いた。

  • キーを渡すと、ダイアトニックコードの配列を返す関数
  • コードを渡すと、構成音の音名の配列を返す関数
  • 音名を渡すと、ベースの指板で表現可能なオクターブに拡張して、ピッチの配列を返す関数
  • ピッチを渡すと、何弦何フレットかを返す関数

など。

すべて状態を持たない純粋関数にしてあるので、
Jestでのテストが簡単。

テスト項目は、超いじわるなコード表記を
AIに100個くらい考えさせて、それを突破できるようにデコード処理を育てていった。

オクターブユニゾン、パワーコードなどは
厳密にはコードではないのかもしれないけど、C8、C5などの表記があるためサポートした。

コードというものは、「1文字でも略せるように」という観点で決められた記法なので
「略したら暗黙でこの意味」というルールが複数ある。

それを「プログラミングでのデフォルト引数の発想と似てる……」
って気づいたら、楽に実装できた。

たとえば、「Cと書いたらCメジャーであり、CマイナーにしたいならCmと書け」というルールは
min3 というフラグを作って、それをデコーダ関数に引数で渡し、
デフォルト値をfalseにしておけばイイ。

それでも、なかなかテストをパスできなかった。

まず、正規表現をミスりまくった。
maj7dimm を含むので、マイナーコードだと誤判定された。

そもそも、コードの意味を誤解してたケースも2例あった。

  • aug7 はオーギュメントコードに短7度を加えたものなので、7度だけでなく5度の音も変わる!
  • aug と書いた場合は5度だけ

……初見で分かるか!

  • Bdim と書いた時点で、「Bのディミニッシュ3和音(短3度+♭5)」が自動的に適用される!

何度も

の感情に襲われた。

オクターブの境界も、直感に反してて
G2の次がA3になるのでなく、G2、A2、B2、C3が正解で
そこもC始まりなのかよ、って思った。

もう……! すべてがCを基準にしてるなら、なぜCをAと呼ばなかったんだよ
って不思議になったので、AIに訊いたら面白い歴史だったので、ぜひ質問してみて。


コードの中には、7thより多くの和音として
9th、11th、13thなど、FFのナンバリングみたいな数字の世界もある。

もうオクターブを1周して、不協和音になってそう。
それらがゲーム音楽やロックに出てくるかは知らないけど、いちおうサポートしといた。

ただ、実装した本人は、さっぱり聞き取れない。
テンションでの表情を聞き分けられる人はスゴイ。

この辺の実装は、「こんなの誤差!」って思いながらやった。
神の宿らない細部もあるだろう……って思った。

Photoshopでのお絵描きに例えると
RGBの1違いまでこだわるような、1ピクセルのゴミが気になるような
そういう本人以外にとって、どうでもイイ部分なんじゃないのー?

だって、超有名なDQ3の戦闘曲って
実は指定をミスってる1音があって、後に修正版に差し替わってるらしい。

何百万人がクリアまでに何百回も聴いた曲でも、誰も気づかない。
耳のイイ人が気づいたとしても、ミスでなくそういう曲だと思ってたのかも。


面白かったバグ

なぜかOSごとにcanvas内の線の太さが違った

スマホだと普通なのに、Windowsだと五線が細すぎて、縮小表示で消える。

OSによってcanvas内の描画が微妙に違った。
えっ、そういうのを吸収するためのcanvasだと思ってたわ……。

上のスクショは、EdgeとChromeとFirefoxだけど
ブラウザによる差ではなかったし、フォントと関係ある場所でもない。

OSでの分岐を作って、無理やり解決した。

5回目のタップから音が鳴らなくなる

コードや単音をタップしたときに、音が鳴る機能だけど
なぜか4回までしか鳴らなかった。

    audioContext = new AudioContext();

のように、タップのたびにインスタンス化してたのが原因。

AIが言うには

この現象は、Android Chrome で Web Audio API の AudioContext のインスタンスを
短時間に何度も生成・破棄すると、AudioContext の作成上限(多くのブラウザで4つ程度)に達し、
音が鳴らなくなったり、遅延してまとめて再生されることが原因です。

【解決策】
AudioContext を毎回 new するのではなく、グローバルで1つだけ生成し、
それを使い回すように修正しましょう。

4つって数字、そのものズバリ当たってんじゃあねーかよォオオオオ……


追加したい機能

Ver.1はとりあえずのリリースだったので、やりたいこと全部はできてない。

運指をアニメーション表示する

運指を説明するには
実演動画を撮るか、TAB譜から想像するしかなかったけど

このアプリを使えば、
擬似的にアニメーションで表示できるはず。

動画ではなく、あくまでcanvasのまま
タイムラインのスライダを動かして、1手先に進んだり、一手前に戻したりできるUIが
1番使いやすいと思う。

かまいたちのシルエットみたいな指が、ボワーと左右に動いてアニメーションする予定。

クロマチックスケールの練習とか
長いベースラインとかが
滑らかにアニメーションで見られたら、たぶん「うぉぉ!」って感動するわ。

楽譜に運指の指示を書いても、
それを絵としてイメージできるかは、読み手次第なわけで
万人がイメージできるためには、面倒でも誰かに弾いてもらって動画で撮る必要があったけど

人間に頼まなくても、アニメーションで運指を伝えられる
というのは、共有方法として便利だと思う。

API化して、誰でもサイトに埋め込めるようにする

Next製なので、簡単にWeb APIを生やせる。

指板に描画したい内容をJSONで受け取るような
GETのAPIを追加して、画像化して返せば、それだけで成立するのでは?

まだ調べてないけど、canvasを返してもイイのかな?
iframeの時代でもないだろうし……。

ユーザーがどのフレットのあたりを欲しいか分からないと
24フレットぶんの横長い画像になっちゃうので、オフセットとか幅のパラメータも必要そう。

そのAPIの使い方説明のために、サンプルページも必要だろう。
エディットボックスにYAMLかJSONを入力してボタンを押すと、指板が生成されるやつ。

これが実現できれば
弾き方についてLINEとかでやり取りするときに、
「ここの弾き方はこれでいい?」「いや、こう」を、言葉でなく画像で済ませられる。

指板上で丸をドラッグして生成できるような
リッチなGUIエディタは作る予定なし。

だって、YAMLで書くのが個人的に1番速くて楽なので……。

このアプリの便利な使い方の、サンプルをたくさん載せる

ベースの指板を、図で載せてるサイトは多くあって
「+1弦の+5フレットは同じ音」とか「-2弦の+2フレットは1オクターブ上」とかの
説明に使われてるけど

Photoshop?で作られたカラフルな画像が多いから、統一されたエディタはないのだろう、と思った。
少し編集し直すだけでも、レイヤーのある原本が残ってないと大変そう。

このアプリを使って、運指、押弦の案を画像化すれば
原本を失う心配がない。

  • 同じ音はここ
  • オクターブ違いはここ
  • 7度はここ

みたいな、定番の法則を覚えるため以外の使い道としては

  • ペンタトニックの運指
  • クロマチックスケールの運指
  • 各スケールでの、各ダイアトニックコードでの運指
  • 各コードの構成音が、指板上にどう配置されているか

も表現できるし、

  • すべてのキーの一覧
  • すべてのスケールの一覧
  • すべてのコードの一覧

も作れるし、

  • 著名な進行の、押さえ方の流れ
  • 人差し指ルート、中指ルート、薬指ルートで、どんな動きになるかの比較実験
  • 左手ミュートと右手ミュートの分担案

などを、上手い人は作れるだろうし

最初に書いたように、もし「小指を使わない」という制約があったら
どんな運指が考えられるだろうか……? を試作できる。
つまり、ニーズが少なすぎて、ダウンロード販売ですら見かけないような
障害者用の譜面を量産できる。


出力された画像を、そのまま使うのでなく

PhotoshopとかPowerPointなど、各人の慣れたツールで
説明を書き足すための、背景レイヤーとして使うこともできる。

例えば、オクターブはニコニコと覚えよう、って色を付けたり。
各弦に、5度違いで同じ音が帯状に連なってる様子を、虹色で塗り分けて表現したり。

個人的には、各フレットを濃度で色分けしてみたいと思う。
どういう意味かというと……

1フレットは常に半音を意味する。弦楽器は自然法則そのままの形なので。
いっぽう、度で数える音程の座標系は、人間の発明なので
半音1つが何度に相当するかは、フレットによって変わる。

ミ-ファ、シ-ドをまたいだ回数だけ、2つの座標系はズレていく。
ミ-ファ、シ-ドだけ濃度が薄くて、そこを通過してもポイントが貯まらないイメージ。

そういう、「言葉での説明だと複雑だけど、つまりこういうことだろ!?」
って、積極的に絵で示そうとチャレンジする土台にできると思う。

押下すべきポジションを当てる、正確さと速度を競うゲームを作りたい

問題文の表示と、正解を判定する処理は
そんな大変じゃなさそうなので

お互いに問題を出しあえるゲームとして追加できたら
理解度の確認テストみたいで面白そう。

理解度といえば……
弾けるようになった部分に、ノートらしくチェックをつけて
LocalStorageかIndexedDBに保存し、カバレッジを把握できるようにしたら便利かも。


ボツにしたアイデア

画面がシンプルでなくなる表現は、削除した

元々は、各指に指番号の数字だけでなく、アイコンを表示しようと思ってた。

AIに訊いて

親指: 「いいね!」のジェスチャーを表すアイコン。例えば、シンプルな👍の絵。
人差し指: 指示や指差しを表すアイコン。例えば、矢印の絵。
中指: 失礼なジェスチャーを表すアイコン。例えば、怒りや反抗を示す絵。
薬指: 結婚指輪を表すアイコン。例えば、指輪の絵。
小指: 「指切りげんまん」を表すアイコン。例えば、約束の絵や小さなピンキーリングの絵。

という案も出してもらったのだけど、表示してみたらさっぱりだった。
中指のアイコンがヤバイし。

あと、指板のポジションマークは表示してるけど、実際に弾くときに見るのは
サイドポジションマークなので、それも表示する予定だった。

けど、点々が多くなりすぎて見にくいのでボツ。

デスノートのLっぽいフォントを表示したら、カッコイイに違いない!
って試したけど、全OSに共通の便利な内蔵フォント、Webフォントはなかった。

無理やり表示もしてみたけど、そもそも使い所がなくて……。

打ち込みを楽にするために、MIDIからの変換を考えたけど、やめた

たとえ数分の曲でも、ベースとしては4フレーズ覚えれば弾けるような曲もある。

それでもTAB譜から、押弦を頭で考えながらYAMLに打ち込むのは、けっこう時間が掛かった。
MIDIファイルがあれば、キーや音階を読み込むことで
押弦以外の部分は自動生成できるはずだけど、あまり意味ないと思った。

だって、ほとんどは繰り返しなのだから……。
MIDIは専用のシーケンサで読み込んで、その画面を見て
重複部分を省いて打ち込んだほうが楽。

TAB譜とのシームレスな表示切り替えは、しないことにした

最初は、WebブラウザでよくあるTAB譜表示サイトのような
メトロノームや自動スクロールを考えてた。

このアプリは、TAB譜を横長から縦長に変換したようなものだと考えてたし
Reactなら、タブ譜と自由に行き来できるような表現も可能だろうと思ったから。

でも、可能だろうと、やるメリットがなく、デメリットだけがあると判断した。

なぜなら、曲全体を打ち込むことになり、時間が掛かるし
引用の範囲を超えてしまう。

このアプリは、1曲を最初から最後まで網羅する必要なんて無い。
押弦の難しい箇所をピックアップしてるだけ、という扱いがベスト。

不特定多数が自由にアップロードできるインフラは、用意しないことにした

自由に曲をアップロードできるようにするには、永続化のDBが必要になる。
……預かりたくない。
ユーザー登録とか認証とかも、預かる責任を負いたくない……。

やっぱり、大きなJSONを送りつけて、画像化して返すだけにして、
状態を持たないツールにしたい。

その種となったJSONは、自身で保管してくれ、と割り切る。

実際に私が打ち込んでるYAMLのサンプルは、以下。

title: Battle 1
artist: Nobuo Uematsu
album: Final Fantasy 5
year: 1992
cover: track_11.webp
key: Am
time_signature: 4/4
bpm: 130
remarks:
  - FF5はグラフィック、シナリオが明るく、FF4ほどじゃないけどバトル1も明るい。
  - けど、短調なのね。Aマイナースケールは白鍵が多いので、ピアノでも弾けそう。
sections:
  - name: Intro
    chord_segments:
      - chord: Am
        on:
        remarks:
          - スケールのⅠから始まるのが基本らしい。
        notes:
          - pitch: A3
            value: 8th
            remarks:
              - FF戦闘曲のイントロで頻出するダダダダドド。
              - ダダダダの音名はA。開放弦で弾ける。ゴブリンのように簡単。
            tags: [easy]
            lefts:
              - finger: 2
                string: 4
                fret: 2
                type: mute
              - finger: 3
                string: 3
                fret: 0
                type: press
              - finger: 4
                string: 2
                fret: 4
                type: mute
            right:
              string: 3
              stroke: down
              mute_strings: [1, 2]
      - chord: G
        on:
        remarks:
          - 4/4拍子では1小節内に8分音符が8つ入るけど、1小節の途中でコードが変わる。
          - 五線だと1つ下なだけだけど、7度の変化となる。
        notes:
          - pitch: G3
            value: 8th
            remarks:
              - ドドの音名はG。
            tags: [easy]
            lefts:
              - finger: 3
                string: 4
                fret: 3
                type: press
              - finger: 4
                string: 3
                fret: 4
                type: mute
            right:
              string: 4
              stroke: down
              mute_strings: [1, 2, 3]

このYAMLをTypeScriptで読み込んで、オブジェクト型にしてる。
それはZodで簡単にできる。

私はTypeScriptで消耗したくないので、ゆるく使ってる。

TypeScriptの濃い記事では
enum を使うなとか、interfacetype の違いとか
function とアロー関数の違いとか、いろいろ書かれてるけど、

enum は使うし、type とアロー関数しか使わんと決めてる。
こういう場合はこっちのほうが便利とか、
もっと最適な書き方があるんじゃないかとか、よぎるコストが無駄。

そういうのは作った後で、「改善点ない?」って、AIに訊けばイイ。


だいたい、TypeはZodのスキーマから作るものであって
type 単独で書くケースはあまりない。

Zodでバリデーションしても、入力も出力も型としては同じなので、
安心感以外にメリットはないのだけど

PythonのPydanticはめっちゃメリットある。
dict 型をクラスに変えてくれるので、hoge["piyo"] だの hoge.get("piyo", 0) だので
ハラハラする必要がなく、hoge.piyo と書けるようになり補完が効きまくる。

PydanticとZodの使い方は
ほぼ同じなので、Zodで慣れることで、Pydanticも簡単そうって思える流れが大事。

上記のYAMLのスキーマ定義では、
z.string().nullable().optional(), にしてある箇所が多い。

この2つはセットで書くと、YAMLで hoge: と書いて改行できるので便利。
optional() だけだと hoge: [] と書く必要がある。

.json にしなかった理由は、閉じ括弧を打つのがメンドイし、
保留にしたい部分をコメントアウトできないから。

.ts にして、1曲1曲をオブジェクトとして定義するやり方もあったけど
括弧が多くて見にくいフォーマットでは、これからたくさん打っていける気がしなかった。


VSCodeは、YAMLのシンタックスチェックはしてくれるけど
スキーマを守ってるかはチェックしてくれない。

……けど、拡張機能を入れて、JSONスキーマのファイルを用意すれば
リアルタイムで赤い下線が出てくれる。

ZodからJSONスキーマへの変換は、AIが一撃でやってくれる。

アップロード機能をなくして、自作のYAML以外をサポートしないメリットして
YAMLをプロジェクトに静的に同梱できる。

DBから取得するためのAPIを呼んでしまうと、その部分はSSRできなくなっちゃうけど
静的に同梱してれば、YAMLの読み込みだろうとSSR可能!

このアプリの場合、セットリスト自体と、そこに載ってる各トラックが
YAMLで定義されてるのだけど、いずれもアプリを表示直後に必要な情報たちなので
SSRできると、一瞬で表示されて美味しい。

Nextのルールとして、コンポーネントの先頭に use client; を書いたものは
ごく当たり前のクライアントサイドレンダリング。
自身で書かない限りこの行がないので、すべてSSRしようとする。

useEffect とか useMemo とか、onClick イベントハンドラとか使ってたら
SSRできず use client; って書け! ってエラーになるので分かる。

実際は use client; って書いた場合でも、useState の値で
SSRしてるらしくて、あまり気にしなくても、できる限り高速化してくれてる感じ。

曲のキーを変えると、自動的にコードが変わってくれる機能は、作らない

カラオケのキー上げ下げボタンのような機能。

移調させると、弾くべきコードも全部ずれる。

例として、スピッツの『運命の人』は
アルバムバージョンが半音低い。

ほか、バンドだとギターの弾きやすさを優先して
キーを変えて演奏することがあり
有名な曲は、移調済みのバンドスコアもあったりする。

移調が大変な楽器と、別に……な楽器に分かれ
ベースは、特に影響を受けないほう。
キーボードやギターは大変そう……。

この機能をサポートしなかった理由として、
コードの表示を変化させることは簡単なのだけど、
このアプリって、指板でどこを押弦するかの表示がメインだから……。

「コードが変わったら、押さえるべき場所はたぶんここに変わる!」
みたいな対応はあるのだけど、それが本当にユーザーの押さえたい場所とは限らない……。

勝手な想像はやらないほうがイイ。


この機能を検討してるときに、転調について調べて
曲の中での一時的な転調は、しょっちゅう起こってることを知った。

小節単位ですらないし
1つ音符だけ、ほかの調から借りてくる
みたいなテクが、有名な曲でも使われてる。

トラック → コードセグメント → ノート
の3階層すべてでキーを書けるようにして、書かなかったら上の層のままのキーとみなす
というルールにした。

そうやっていろんな楽譜を見てると
ベースなのに単音でなく、2音同時に弾いてる箇所が
ビートルズにあったので、それも定義可能にした。


エピローグ

32,000文字も打ったけど、これで終わり。

このアプリで使ったAIは、GitHub Copilot経由で呼び出す方法だったのだけど
時々は変な修正をされて、エージェントモード怖いなーって思う程度だった。

ちょうどアプリが形になった頃に、Claude Codeが出て
文句なしのコードを連発するようになり

「このアプリが、自分でコードを書いた最後のアプリになったのかも……」
と気づいた。

このアプリの機能追加、リファクタリングや
次のアプリは、Claude Codeに仕様を語って、CLAUDE.mdを作らせることから始まるだろう。


慣れないものはない。
どうせ慣れるのだからと、難度が高いものを積極的に選んできた。

Vimに慣れ、トラックボールに慣れ、US配列に慣れ、タイル型ウインドウマネージャに慣れ、
FF14の高難度周回に慣れ、ソイチューバーに慣れ、日本語に慣れ、
何も拒まないという流星街イズムを貫いてきた。

ヒトは、幼少期に
食わず嫌いなど、新しいものをとりあえず嫌がる時期があり
そういう軽いネオフォビアなら、誰にでもあるもの。
そして、高齢で守りに入ると、またネオフォビアが現れる。

新しいものをとりあえず否定すると、本能に身体を自動操縦されてるようでイヤだし
流れに抵抗する時間がもったいない。

地震で原風景が崩壊して、心のやらかい場所を締めつけられるのも慣れた。
AIを使いまくる時代にも慣れるのだろう。

22世紀までに、ドラえもんが間に合いそうで良かった。
まさかペタリハンドとか胴体よりも、頭脳のほうが先にメドが立つとは思わなかった。

スカム映画じゃないほうの『君たちはどう生きるか』には、
文字を発明して、経験を共有し合って、比べて矛盾のないようにまとめたのが、学問の始まりだった
と書いてあったけど

この1ヶ月間、多くの人がClaude Codeの記事を書きまくって
気づいたコツを発表し合ってるのは、原点って感じで、いま楽しい。

Discussion