見出し画像

【GAS】スプレッドシートの数字譜を元にピアノの音で自動演奏~解説編(1)WEBアプリの仕様と数字譜について~

この記事は、外部ファイルとしてピアノの音源を用意し、それをスプレッドシートに用意した数字譜を元に自動演奏させる、以下にご紹介するGAS(Google Apps Script)アプリの説明記事です。

音楽を奏でるGASのプログラム例の多くは、ピ・ポ・パ・・・という人工音によるものだと思いますが、本記事でご紹介する方法は、Googleドライブ上に音源ファイルを用意することで、ピアノの音色などを楽しめるのが特長です。

簡単なトイピアノ程度の機能ですが、インストール不要で、楽譜だけ編集するだけで、短い音楽をメンバーと共有できます。

簡単な合唱曲や合奏曲を練習するとき、”譜読み”や”音合わせ”の補助ツールに使えるかも知れません。

なおこのアプリでは、楽譜はGoogleスプレッドシートに「数字譜」で表記します。

このWEBアプリの仕様を再説明します

前の記事でWEBアプリの説明はしているのですが、再度ご説明させてください。


まず、Googleドライブ上に各音階(2オクターブぐらい)ごとの音源ファイルを用意します。

D4などとあるファイル名は音階名です。音階は、ドの音を、レをなどと表したもので、続く数字はオクターブの高い低いを、添え字のは半音階「#:シャープ」を表します。

また、Googleスプレッドシート上には、数字譜で音階を記載しておきます。

数字譜については後述しますが、ドを1,レを2に置き換えた記譜方法で、大正琴や二胡といった一部の楽器で用いられています。

上記は、『威風堂々』の有名なフレーズの出だしで、
「ドー、シドレー、| ラー ソー・・・」を表しています。

また、数字譜の下にあるCMなどは和音を表しています。(プログラム上、強制的に2文字で表現していますので、正規の表記とは少し違う)

そしてこれが、WEBアプリの外観です。先ほどの音源ファイルがAudio要素として取り込まれています。

上記のボタンを押すと、メロディーが鳴ります。音は以下を参照ください。


メロディーをスプレッドシートに表記するのに適した形式~数字譜とコードネームについて~

さまざまな記譜形式

このアプリではメロディを数字譜、伴奏をコードネームで記譜しています。こうした方法をとった理由をご説明します。

現在のほとんどの音楽は、「5線譜」で表記されているはずです。(以下の様な表記については、皆様ご存知かと思います)

5線譜

この表記方法は、音程の高い・低いが視覚的に判り易い上、音の長さや和音の表現も可能な優れた表記方法です。

和音の表記

しかし、この表現方法、スプレッドシート上に適用しようとすると、実装はかなり大変です。特別なインターフェースを別途作る必要があります


脇道にそれますが他の記譜方法



ところで、すべての音楽が5線譜で表現されているか、といえばそうではありません。

少し脇道にそれますが、他の表記方法には、大体「特有の楽器に便利な表現」「文字による音楽の表記」があります。

前者の、「特有の楽器に便利な表現」としては、例えば弦楽器のタブ譜や・・・

タブ譜


弦の押さえ位置とリンクしている

・・・打楽器のドラム譜などがあります。

ドラム譜:五線が楽器の種類に相当している


一方、後者の「文字による音楽の表記」には、音階を文字にしたものや、

邦楽の譜面:ドレミではない音階表現

数字に置き換えて記載するもの(数字譜)があります。

数字譜

数字譜を採用した理由


最後にご紹介した「数字譜」は、何しろ数字だけしか使わないので、スプレッドシートと非常に相性が良い表記方法と思われるため、これを採用した次第です。

数字譜の記載ルール

分野にもよりますが、数字譜の基本は、「ド・レ・ミ・・・」を数字に置き換えるものです。

ド ⇒ 1
レ ⇒ 2
ミ ⇒ 3

5線譜と対応させると以下の様になります。

数字譜:下側の部分が数字譜です

ハ長調以外だと、(これも分野にもよりますが)キー音を「ド」と読む「移動ド」を使って数字に置き換える方法がとられます。

例えばイ長調(キー音はD、すなわち固定ドの”レ”)だと、以下の様に表現します。

イ長調の数字譜

その他のルールとして、

オクターブの上下は、数字の上下に「●」で表現

音の長さは4分音符を基本とし、半分の8分音符はアンダーライン、倍の2分音符は長音記号「ー」で表す

楽曲の調は、1=「基音」で表す

・・・などがあります。

今回のアプリではハ長調(デフォルトで#も♭もない)しか対応していません。また、音の長さは8分、4分、2分音符のみです。

伴奏はコードネームを使う

楽譜とは違うのですが、このアプリでは伴奏はコードネームで表すことで鳴らしています。

コードネームは和音を文字で表す方法で、「ド・ミ・ソ」を C などと表します。ポップスやジャズなどの分野で使われますが、厳密な楽譜というよりも、演奏方針を表すものです。

たとえば、C とあった場合、演奏者は「(一度に)ド・ミ・ソ」(和音)と鳴らしても良いし、「(単音ずつ)ド⇒ソ⇒ミ⇒ソ」(分散和音)と鳴らしてもかまいません。

このアプリでは、代表的な和音だけを、一度に鳴らす方法で発音させることができます。

コードネームも単純なテキストで表現できるので、スプレッドシートでの記載方法に適しています。

以上、補足説明でした。

Audio要素を、譜面に従って発音させる仕組み

次に、このアプリで外部音源を取り込んだAudio要素を実装した後の、発音の仕組みをご紹介します。このアプリでのメロディーを鳴らす仕組みは単純です。骨子となるのは以下の2つです。

Audio要素を鳴らす仕組み

このアプリでは音階ごとにAudio要素を作っています。

テンプレート内に<Script>セクションを設け、対象の音階を埋め込んだAudio要素に対し、以下のコードを働かせる事で、狙った音を発音させる事ができます。

Audio要素.currentTime = 0;
Audio要素.play();

1行目で時刻をセットし、2行目で発音させています。

setTimeout()により適切な時刻で実行させる

一連のメロディーを奏でるには、個々の音階のオーディオ要素を適切なタイミングで発音させる必要があります。

こんな場合に重宝する関数が、Javascriptにある setTimeout() という関数です。

使い方は簡単で、実施したい命令文と遅延時間を記載するだけです。

   setTimeout(命令文, 遅延時間);

命令文が2行以上ある場合は、次の様に無理矢理に関数化させて、その中にコードを記載していきます。

   setTimeout(function(){
      Audio要素.currentTime = 0;
      Audio要素.play();
    }, 遅延時間);
 

ここで気をつけるところは、”遅延時間”が「この関数が働いた時刻」を起点にしているところです。

このアプリでは上記関数を次々に実行させますが、「関数が働いた時刻」はプログラムの実行状況に応じて、微妙にずれるので、結果としてあまり正確なスケジュールで発音されません。

あまり気になる範囲ではないのですが、それでも長い楽曲では無視できなくなって、伴奏とずれたりしますので、今回は楽曲が短い前提で、譜面も小さめのスペースとしています。

演奏中の画面は以下の様になります。各音階のAudio要素が、それぞれのタイミングで時刻0に戻って演奏されているのが判りますか。

以上がこのアプリの骨子です。


「Tone.js」などの便利なツールは使っていない

ところで音楽を演奏させるライブラリは色々あります。「Tone.js」などはその代表格で、GASでの利用を以下に記事にもしました。

このライブラリをGASで使用すれば、もっと複雑な演奏をとても簡単に実装できます。

しかも、「サンプリング機能」まであります・・・。この機能は、外部音源をURLで指定して、その音色を利用するものですが、まさに今回GASアプリで実装したかった機能です。

こうしたライブラリを使う訳にはいかないのでしょうか?

	Tone.Transport.loop = false;
	const sampler = new Tone.Sampler({
		'C1' : '/bd.mp3', // ← 音源を指定しています 
		'E1' : '/sd.mp3',
		'F#1': '/hh.mp3'
	}, ()=>{
	}).toMaster();

上記のコード例は、サンプル音源を指定しているところですが、通常はこうやってコードを記し、一般のサーバ上では問題なく機能します。

ところが、GASのテンプレート内では外部URLのリンクが働かず、これをどうしても解決できなかったため、使う事ができませんでした。

それで今回は、こうしたライブラリを利用しない、シンプルな機能のみとなった次第です。

本アプリでは、Audio要素に外部音源をBASE64エンコードという手法で取り込んでいるのですが、この方法、MHTMLファイルにおいて<~>で表記される要素へは対応できても、上記ライブラリには適用できませんでした。

なお、ここではGASとGoogleドライブのみを使い、外部のレンタルサーバなどは利用しないという縛りを入れているために、こうした課題が出ています。

次回は、スプレッドシートとどう連携させて音楽を奏でるかをご説明します。



この記事が気に入ったらサポートをしてみませんか?