Published Date : 2020年7月22日11:42

【Processing】簡単なギタータブ譜アプリっぽいやつを作るとどうなるかの総集編
Create an app to create your own guitar tab using [Processing]


This blog has an English translation



今回はYouTubeにアップした動画、「【Processing】簡単なギタータブ譜アプリっぽいやつを作るとどうなるかの総集編」の補足説明の記事です。

Here's a little more about the [Create an app to create your own guitar tab using [Processing]] video I uploaded to YouTube.


【Processing】簡単なギタータブ譜アプリっぽいやつを作るとどうなるかの総集編


Responsive image


まずは上の動画の趣旨を軽く説明します。 Processingを使用してギターのフレットボードから簡単なTAB譜を描画するアプリケーションを作成します。 このアプリケーションの利点は、ギターの弦と音階の関係をギターフレットボードから直接理解でき、1つずつ画像ファイルとして保存できることです。

First, let me briefly explain the purpose of the video above. Create an application to draw a simple TAB notation from a guitar fretboard with Processing. The advantage of this application is that you can understand the relationship between guitar strings and musical scales directly from the guitar fretboard and save them one by one as image files.

全体の説明は動画に任せるとして、補足が必要だろうと思われる部分を説明していきMASU。

I'll leave the entire explanation to the video, but I'll explain the parts that I think need to be supplemented.

過去に似たアプリをP5.jsとPythonを使ってブラウザに表示させるものを作ったのでこちらの記事も参考にしてみてください。

I've created a similar app in the past that uses P5.js and Python to display in the browser, so check out this post.


目次

Table of Contents




Part 1 -
Part 1 -



パート1ではギターのフレットボード部分を作っていきたいと思います。

This time, I will create the Fret board part of the guitar that is necessary for the application.

まず初期設定の変数の中身をざっと説明します。

First, let's take a quick look as the default variables.

float leftX, rightX, topLeftY, bottomLeftY, topRightY, bottomRightY;

これはフレットボードの四隅の座標です。 この4つの変数が基本中の基本です。

These are the coordinates of the four corners of the fretboard. These four variables are the basics of this application.

float widthSpacing, heightSpacing;

フレットボードを画面の端からどれだけ空けるかを決める変数です。

These are variables that determines how far away the fretboard is from the edge of the screen.

float boardLength, headSideLength, bodySideLength;

ボードの長さ、ヘッド側の長さ、所謂ナット部分です。 そしてボディ側の長さの変数です。

These are variables that the length of the board, the head side, the so-called nut part, and the body side length.

float boardRatio, headSideRatio, bodySideRatio;
~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
boardRatio = 0.91;
headSideRatio = 0.45;
bodySideRatio = 0.6;

これらは画面の幅と縦の長さと間隔の値からフレットボード、 ヘッド側、ボディ側の長さを決める為に使われる比率です。 よりギータのフレットボードらしい形になるように手元にあるギターを実際に測ってみて、そのフレットボードの比率を参考にしました。

These are based on the screen width and height and spacing values. The ratio used to determine the length of the head and body sides. I actually measured the guitar I had and referred to the ratio of the fretboard.

float[] spacingRatioOfFrets = {0, 3.4, 3.4, 3.4, 3.1, 2.8, 2.6, 2.6, 2.2, 2.2, 2.1, 2.0, 1.8, 1.8, 1.6, 1.6, 1.5, 1.4, 1.3, 1.3, 1.3, 1.1, 1};

続いてはフレットの並びの間隔の比率です。 これも実際測った結果、この値になってます。

Next is the ratio of fret spacing. This is also this value as a result of actually measuring.

String[][] standardTuning = {{"E4", "F4", "F#4", "G4", "G#4", "A4", "A#4", "B4", "C5", "C#5", "D5", "D#5", "E5", "F5", "F#5", "G5", "G#5", "A5", "A#5", "B5", "C6", "C#6", "D6"}, 
                    {"B3", "C4", "C#4", "D4", "D#4", "E4", "F4", "F#4", "G4", "G#4", "A4", "A#4", "B4", "C5", "C#5", "D5", "D#5", "E5", "F5", "F#5", "G5", "G#5", "A5"}, 
                    {"G3", "G#3", "A3", "A#3", "B3", "C4", "C#4", "D4", "D#4", "E4", "F4", "F#4", "G4", "G#4", "A4", "A#4", "B4", "C5", "C#5", "D5", "D#5", "E5", "F5"}, 
                    {"D3", "D#3", "E3", "F3", "F#3", "G3", "G#3", "A3", "A#3", "B3", "C4", "C#4", "D4", "D#4", "E4", "F4", "F#4", "G4", "G#4", "A4", "A#4", "B4", "C5"}, 
                    {"A2", "A#2", "B2", "C3", "C#3", "D3", "D#3", "E3", "F3", "F#3", "G3", "G#3", "A3", "A#3", "B3", "C4", "C#4", "D4", "D#4", "E4", "F4", "F#4", "G4"}, 
                    {"E2", "F2", "F#2", "G2", "G#2", "A2", "A#2", "B2", "C3", "C#3", "D3", "D#3", "E3", "F3", "F#3", "G3", "G#3", "A3", "A#3", "B3", "C4", "C#4", "D4"}};

次にギターの弦を基本のチューニングにした場合の音階を表す配列です。 チューニングや音階に関しては様々な意見がありますが、基本的に多く使われている音階を選んでます。

Next, it is an array that represents the scale when the guitar strings are tuned as the standard tuning. There are various opinions about tuning and musical scales, but I basically choose the most commonly used musical scales.

int sixStrings;
PVector[][] fretsAndNotes;

ギターの弦の数を表す変数と、後でTAB等に連動させやすい用PVector型の二次元配列としてフレットに触れる弦の位置を記録するための変数です。

These are variables that representing the number of guitar strings and for recording the position of the strings touching the fret as a two-dimentional array of PVector type for which it ts easy to be linked with TAB later.

次に、セットアップ関数内で行われているフレットボードを作る為の手順を図にして説明します。

Next, the procedure for creating a fretboard in the setup function is explained with a diagram.

次に、ギターの音の表示と、クリックした時に反応するエリアを、判別するためのフレットと弦が交わる場所の情報を、配列に記憶させる方法、そしてフレットがどのように作られるかを図で説明します。

Next, I'll show you how to store information in an array about where the frets and strings meet to determine the guitar notes display and the area that responds when you click, and how the frets are made.

前回の記事で説明したように、座標が簡単に求められない場合は まず最初に起点となるXとYと終点のXとYを決めてしまいます。

As I explained in the previous article, if the coordinates are not easily obtained, First, determine the starting points X and Y and the ending points X and Y.

今回の場合はフレットボードの四隅の座標が決定しているので求めやすいですね。

In this case, the coordinates of the four corners of the fretboard are determined, so it is easy to obtain.

そこからアークタンジェント2関数とディスティネーション関数を利用して アングルと弦の長さを求めます。

Then use the arctangent2 and the destination functions to find the angle and the guitar string length.

そうしたらあとはcosとsinを使い、さらに弦の長さをフレットボードとフレットの比率で割ってやると、フレットに触れる弦の中点の座標を求めることができます。

Then use cos and sin and divide the length of the string by the ratio of the fretboard to the fret to get the coordinates of the midpoint of the string touching the fret.

後はライン関数やエリプス関数、テキスト関数で線や楕円やテキストをその場所に描くだけです。

All you have to do is draw a line, ellipse, or text in place using the line, ellipse, or text functions.




Part 2 -
Part 2 -



パート2では少しコードを整理して、ControlP5(By Andreas Schlegel)を使用してギターノートを表示/非表示にするコードを作成します。 さらに、ギターノートのテキストの近くをクリックするとテキストの色が赤になるようなコードを書いてみますた。

This time, I'll clean up the code a bit and create a code that shows and hides the guitar note using ControlP5 (By Andreas Schlegel). In addition, I will try to write a code that turns the text color to red when I click near the text on the guitar note.

まずControlP5のインストールと基本的な使い方についてざっと説明します。

First, let's start with a quick overview of installing and using ControlP5.

インストールは簡単。 ファイルの上部にある、「Sketch」を選択、「Import Library」を選択、「Add Library」を選択、検索窓に「controlP5」と入力。 でてきたライブラリを選択して、インストールボタンを押すだけ。

Installation is simple. Select "Sketch" located at the top, select "Import Library", select "Add Library" and enter "ControlP5" in the search window. Simply select the library you created and press the install button.

このライブラリの作者であるAndreas Schlegelに感謝して使いましょう。

Thanks to Andreas Schlegel, the author of this library.

ControlP5の使い方ですが、今回は動画に出ているトグルスイッチの作り方を説明します。 ボタンを作成するにしても、大体同じような手順です。 詳しい使い方は作者のgithubページに載っています。

This time, I will explain how to make the toggle switch shown in the video. Creating a button is a similar precess. More details on how to use it can be found on the author's github page.

import controlP5.*;
ControlP5 cp5;
cp5 = new ControlP5(this);

まず、ライブラリをインポートする。 この「*」マークは「controlP5パッケージ」が持っているクラス全部を指している。 要するに一つ一つクラスを指名してインポートするのではなく まとめてインポートしてしまおうということ。

どんなクラスファイルをインポートしているのかは作者のgithubページの「src/controlP5」の中身を見てみれば分かります。

First, import the library. The "*" mark refers to all the classes that "controlP5 package" has. So instead of picking and importing classes one by one, The idea is to import them all together.

You can find out what class files are being imported by looking inside the author's github page "src/controlP5".

クラスをインポートしたら、あとはインポートしたクラスを使ってCP5のインスタンスを作成します。

After you import the classes, you create an instance of CP5 using the imported classes.

このコンストラクターに渡す引数の「this」はJAVAアプレットを指し、 簡単に言ってしまえば、書いているスケッチ自体のことです。 こうすることでProcessingが用意している様々な機能にCP5インスタンスはアクセスでき、 それによって便利なGUIの機能を提供しているとも言えます。

The "this" argument passed to this constructor points to a JAVA applet. To put it simply, it is the sketch you are writing. This gives the CP5 instance access to the useful features provided by Processing, which in turn provides GUI functionality.

cp5.addToggle("toggleNotes")
    .setPosition(widthSpacing/2,heightSpacing/2)
    .setSize(100,30)
    .setValue(true)
    .setCaptionLabel("Show:Notes/Hide:Notes")
    .setMode(ControlP5.SWITCH);

上から順に説明します。

I will explain from the top.

addToggleはトグルスイッチをスケッチに追加します。

addToggle adds a toggle switch to the sketch.

("toggleNotes")はこのトグルが切り替わった時にさせたい処理をする関数名です。

("toggleNotes") is the name of the function that performs the operation you want to perform when this toggle is switched.

setPositionはトグルスイッチを画面のどこに配置するかです。

setPosition is where the toggle switch should be placed on the screen.

setSizeはトグルスイッチの大きさ(横幅、縦幅)です。

setSize is the size (Width, Height) of the toggle switch.

setValueはスイッチの初期値です。トグルスイッチはTrueかFalseの切り替えをするスイッチですのでこの2つの真偽値のうちどれかです。

setValue is the initial value of the switch. The toggle switch is either true or false because it switches between true and false.

setCaptionLabelはトグルスイッチの下に文字を表示させることができます。

setCaptionLabel allows you to display characters under toggle switches.

setModeは見た目をどのようにするかです。SWITCHにすると今回のような見た目になります。

setMode can change how it looks. if you choose SWITCH, it will look like this time.

SWITCH

もうひとつDEFAULTが用意されています。

There is also mode called DEFAULT. like this.

OFF
ON

このようにDEFAULT MODEは色で切り替わる見た目になります。

In this way, "DEFAULT MODE" switches on and off by color.

他にも色やフォントを変える等色々な機能があるので、各自試してみてください。

There are many other functions such as changing colors and fonts, so please try each one.

次に、テキストの表示を調整するやり方を簡単に説明します。

Next, A brief explanation of how to adjust the display of text.

Processingのtext関数の引数はTEXT(文字、X座標、Y座標)となります。

The text function augument of the Processing is text(Text, x coordinate, y coordinate).

今回使用しているTextAlign関数はこのX座標とY座標の位置を変化させます。

The textAlign function is changes the position of the X and Y coordinates.

アニメーションにするとこのようになります。

This is what it looks like in animation

textAlign function
次に、マウス位置の判定方法を簡単に説明します。

The following is a brief explanation of how to determine the mouse position range.

フレットと円が触れる場所のX座標から、円のX軸の直径を引けば、左側のXの判定座標になり、 フレットと円が触れる場所のX座標が右側のXの判定座標、 フレットと円が触れる場所のY座標から、円のY軸の直径の半分を引けば、上側のYの判定座標 フレットと円が触れる場所のY座標から、円のY軸の直径の半分を足せば、下側のYの判定座標になります。

If the diameter of the X axis of the circle is subtracted from the X coordinate of the place where the fret and the circle touch, it becomes the decision coordinate of X on the left side. The X coordinate of the place where the fret and the circle touch is the determination coordinate of X on the right side. If you subtract half the diameter of the Y axis of the circle from the Y coordinate of the location where the fret and the circle touch, you get the upper Y decision coordinate. If you coordinate where the fret and circle touch, you get the bottom Y decision coordinate.

そしてその範囲内でマウスがクリックされれば、テキストや弦の色が変わる仕組みになります。

If the mouse is clicked within that range, the text and guitar strings will change color

そして、ControlP5をProcessingで連携させて使う簡単な方法を説明します。

Then, I'll show you how to use ControlP5 in conjunction with Processing.

cp5.addToggle("toggleNotes")

上で説明したCP5のトグルスイッチを作る際、名前を指定しました。

When creating the CP5 toggle switch described above, I specified a name.

これを関数名にして、行いたい処理を指定します。 その前にトグルスイッチと連動するBoolean変数を作りましょう。

Use this as a function name to specify what you want to do. Before that, let's create a Boolean variable that works with the toggle switch.

// toggle display for the notes on a guitar
boolean toggleDisplayNotes = false;
void toggleNotes(boolean theFlag){
    if(theFlag==true) {
        toggleDisplayNotes = true;
    } else {
        toggleDisplayNotes = false;
    }
    }

関数に渡すのはTrueかFalseのBoolean変数です。 これがTrueであればTrue、そうでないならFalseです。 トグルスイッチのONとOFFの結果を変数に格納するものだと思ってください。

You must pass a Boolean variable, either True or False, to the function. True if this is true, False otherwise. Think of it as storing the ON and OFF results of a toggle switch in a variable.

void darwGuitarNotes(){
    // Adding the ability to toggle the guitar note display
    if (toggleDisplayNotes) {

そして、toggleDisplayNotesの真偽値がTrueの時にギターノートが表示されるようにするだけです。

Then, when the true or false value of toggleDisplayNotes is True, the guitar notes is displayed.

最後に、音符の非表示と表示は上手くいきましたが、テキストが同じ弦で反応してしまうこと、 クリックした時の動作がおかしい等の失敗の原因と簡単な解決策について説明します。

Eventually, I managed to show and hide the notes, but when I clicked the mouse, the text changed color on the same guitar string, and sometimes it didn't respond or was delayed, resulting in strange behavior. This section describes the causes of failure and simple solutions.

Processingではループ関数(draw function)内で絵を描画しています。 この時、darwGuitarNotes関数はFor文で一気にギターノートの描画をしています。 そしてdarwGuitarNotes関数の処理が終わったら、またループを始めて処理を繰り返します。

Processing draws a figure inside a loop function (draw function). At this time, the drawGuitarNotes function used the For statement to draw the guitar notes all at once. After processing the drawGuitarNotes function, start the loop again and repeat.

このFor文が終わるまでギターノートの表示や更新がされないことの遅延が問題となります。

The problem is that the guitar note is not displayed or updated until the For statement is completed.

このループ速度は人間には感知できないぐらい超高速で行われいています。 クリックした時がたまたまdarwGuitarNotes関数の中で、かつクリックしたテキストの描画処理の直前であれば 反応しますが、それ以降はまた次のdarwGuitarNotes関数の処理が始まるまでクリックしても反応はありません。 これが問題の原因です。

This loop speed is so fast that humans can't sense it. However, if the click happens to be in the drawGuitarNotes function and just before the drawing of the clicked text. It will respond, but no further clicks until the next darwGuitarNotes function begins. This is the cause of the problem.

テキストの色を変える、同じ弦でギターノートが2つ以上反応しないようにする。 この2つの問題を解決するためには、弦に値を記憶させておくこと、かつ弦が一本ずつオブジェクトととして振る舞うように設計する必要があります。

Change the color of the text so that no more than one guitar note reacts to the same guitar string. To solve these two problems, it need to remember the value on the guitar strings and design them to behave as objects one by one.

そこで次回はこのギターフレットボードの弦とノート情報を取り扱うクラスファイルを作成することにします。

Next time, I will create a class file to handle the strings and note information of this guitar fretboard.




Part 3 -
Part 3 -



パート3、 今回の動画では、 ギターのフレットボードのフレットの近くをクリックすると、 弦を赤くするようなコードを書きます。 また、ギターの弦のノート情報をリセットすることができたり、 弦をミュートしたり、ノートテキストを隠すコードも書きます。

This time, In this video, when you click near the fret on the guitar's fretboard, I write a code that turns the strings red to indicate the vibration of the strings. I will also write a code that reset the note information for all the guitar strings, mute the strings, reset the strings one by one, and hide the notes.

前回の問題点を解消するために、ギターの弦とギターノートの表示部分をクラスにして、個別のオブジェクトととして扱います。

To solve my previous video problem, I will make the guitar strings and the display part of the guitar note into classed and treat them as separate objects.

仕組みはとても簡単で、まず「GStringsGNotes」クラスは コンストラクタを使用して、6本のギター弦のオブジェクトを作ることができます。

The system is very simple. First, the [GStringsGNotes] class can use the constructor to create an object of 6 guitar strings containing the guitar note information.

一つ一つのオブジェクトはフレットと弦が触れる場所の情報を記憶しているので、その場所の範囲内をクリックすると、オブジェクトが持っている「fretClicked」のJ番目にTrueが入ります。 すると、クリックした場所のフレットと弦が触れる部分から後の弦が「Line関数」によって赤色に再描写されます。

Each object stores information about where the frets and strings touch, so when you click within that area, the J-th of the object's [fretClicked] will be True. The fret where you click and the string from where it touches are redrawn in red by [line function]

そして、下にある図が前回の問題点を解決する為の肝の部分です。 このロジックも簡単で、違う場所をクリックした際に一度すべての「fretClicked」をFalseにします。所謂初期化をするということです。

And the diagram below is the essential part to solve the previous problem. This logic is also simple. If you click in a area where another guitar string touches, all [fretClicked] are set to False. It means to do so-called initialization.

こうすることによって、ギター弦やテキストが赤く表示されるだけでなく、ミュートにしたり、リセットをしたりと様々な動きを連携させて行えるようにできます。

This not only makes the guitar strings and text appear red, but also allows you to mute and reset them in a coordinated way.

一見、動作ごとに全ての値を初期化するという行為は非効率かのように思えますが、複雑に絡み合う分岐や変数の入れ替えを行う時には初期化作業は非常に有効だということを覚えて欲しいです。

At first glance, it may seem inefficient to initialize all values for each action, but remember that initialization is very useful for complex branching and variable swapping.

前回のような何度もクリックしないと赤くならない、同じ弦で複数のギターノートが表示されるなど、配列変数が原因でプログラムがうまく分岐しない場合の不具合をシンプルな解決策で回避できます。

This is a simple solution if the program doesn't branch well because of an array variable, such as a problem like the last one, where it doesn't respond until you click a few times, or where there are multiple guitar notes on the same string.

トグルスイッチの基本的な使い方は、前回のブログ記事で説明しました。

The basic use of toggle switches was explained in a previous blog post.

なので、今回は実際にこのプログラムでのトグルスイッチの使われ方の概要だけを説明します。

So this time, I'll just give you an overview of how toggle switches are actually used in this program.

図のようにCP5で作ったトグルスイッチのオンとオフの状態が、 TrueかFalseでグローバル変数toggleMuteに記憶されます。

As shown above, the on/off state of the toggle switch by CP5 is stored in the global variable toggleMute as true or false.

GStringsGNotesクラスによって作られた各ギター弦オブジェクトは、それぞれcheckMute変数を持っている。

Each guitar string object created by the GStringsGNotes class has a checkMute variable.

グローバル変数toggleMuteはオブジェクト全体から参照されているが、各オブジェクトの属性であるcheckMute変数は、それぞれが独立しています。

The global variable toggleMute is referenced throughout the object, but the checkMute variable, which is an attribute of each object, is independent of each other.

この性質を利用します。 つまり、ミュートスイッチがオンになっている状態で、各ギター弦オブジェクトのフレット番号0をクリックすると、クリックされた弦オブジェクトのみが、ミュートされるという仕組みです。

Take advantage of the nature of this useful object. In other words, if you click the fret number 0 of each guitar string object while the mute switch is on, only the string object that was clicked will be muted.

その後もミュートスイッチがオンになっていれば、好きな弦オブジェクトを選択してミュートにできます。

If the mute switch is still on, you can mute each selected guitar string.

そしてこの仕組みは各ギター弦毎にリセットする機能などでも同様です。

The same goes for the reset function for each guitar string.

逆にリセットオールやノートを隠す機能はスイッチのオンオフだけで一気にすべての弦に適用できます。

On the other hand, the reset all and the function to hide the note can be applied to all guitar strings at once only by turning on and off the switch.

つまり、グローバル変数だけで操作すればいい訳です。

In other words, you only need to work with global variables.




Part 4 -
Part 4 -



第4回のビデオでは、画面の左下隅に、ギターノートに連動た単純な五線譜とTAB表記を描くコードを書きます。 また、画面右下にギターのコード名をボタンのリストにして、ボタンを押すとギターコードがフレットボード等に表示されるようにしていきます。

Part 4, In this video, I'll write a code in the lower left corner of the screen that draws a simple staff and TAB notation linked to the note of a guitar. Also, I would like to make a list of guitar code name buttons in the bottom right corner of the screen so that the guitar code can be displayed on the fretboard when the button is pressed.

ギターのコードの一覧を、ボタンにするために使われる配列変数です。

An array variable used to turn a list of guitar chords into buttons.

動画では「オープンコード一覧」として書かれている箇所がありますが、バレーコード等が含まれています。 まあ、開放弦から6フレット ぐらいまでが使われているコード一覧として認識してもらえれば幸いです。

In the video, there is a part written "Open Chords", but Barre Chords is also included in the guitar chords charts. Well, it would be helpful if you could think of it as a chords charts that uses from open string to 6 fret.

// array of guitar chords charts
String[][] guitarChordChart = {
    {"A","Am","A7","Am7","AM7","Asus4","A7sus4","Aadd9","Am7♭5","Adim7","A6","Aaug","AmM7","Am6"},
    {"A#","A#m","A#7","A#m7","A#M7","A#sus4","A#7sus4","A#add9","A#m7♭5","A#dim7","A#6","A#aug","A#mM7","A#m6"},
    {"B","Bm","B7","Bm7","BM7","Bsus4","B7sus4","Badd9","Bm7♭5","Bdim7","B6","Baug","BmM7","Bm6"},
    {"C","Cm","C7","Cm7","CM7","Csus4","C7sus4","Cadd9","Cm7♭5","Cdim7","C6","Caug","CmM7","Cm6"},
    {"C#","C#m","C#7","C#m7","C#M7","C#sus4","C#7sus4","C#add9","C#m7♭5","C#dim7","C#6","C#aug","C#mM7","C#m6"},
    {"D","Dm","D7","Dm7","DM7","Dsus4","D7sus4","Dadd9","Dm7♭5","Ddim7","D6","Daug","DmM7","Dm6"},
    {"D#","D#m","D#7","D#m7","D#M7","D#sus4","D#7sus4","D#add9","D#m7♭5","D#dim7","D#6","D#aug","D#mM7","D#m6"},
    {"E","Em","E7","Em7","EM7","Esus4","E7sus4","Eadd9","Em7♭5","Edim7","E6","Eaug","EmM7","Em6"},
    {"F","Fm","F7","Fm7","FM7","Fsus4","F7sus4","Fadd9","Fm7♭5","Fdim7","F6","Faug","FmM7","Fm6"},
    {"F#","F#m","F#7","F#m7","F#M7","F#sus4","F#7sus4","F#add9","F#m7♭5","F#dim7","F#6","F#aug","F#mM7","F#m6"},
    {"G","Gm","G7","Gm7","GM7","Gsus4","G7sus4","Gadd9","Gm7♭5","Gdim7","G6","Gaug","GmM7","Gm6"},
    {"G#","G#m","G#7","G#m7","G#M7","G#sus4","G#7sus4","G#add9","G#m7♭5","G#dim7","G#6","G#aug","G#mM7","G#m6"}
    };

この中にフラット記号が含まれています。 これが使用するフォントによって文字化けになってしまうので、次にそれを防ぐために、ProcessingのCreateFontを使って、フォントを「メイリオ」にします。

The above array contains flat symbols. These may cause garbled characters depending on the font you are using in Processing. To prevent this, use createFont in Processing to make the font "Meiryo"

指定するフォントですが、「ユニコード」が扱えれば、「メイリオ」でなくても構いません。

But the specified font does not need to be "Meiryo" as long as it can handle Unicode.

// Use createFont to prevent the flat symbol from garbling
PFont font;
font = createFont("Meiryo", 15, true);
textFont(font);

続いては五線譜とTAB譜、それからコードチャートの描画をするための関数を作成します。

Next, you create a function that draws a staff, tab notation and guitar chords charts on the screen.

// Draw staff and Guitar TAB notation.
pushMatrix();
translate(-150,height/2);
drawStaffNotation();
drawTABNotation();
popMatrix();

// With controlP5, there were problems with function names and text display, so it was necessary to create a kind of homemade GUI to create a guitar chord chart.
pushMatrix();
translate(width/2-50, height/2);
drawChordChart();
popMatrix();

フレットボードの長さと座標を利用して五線譜やTAB譜を描画しますので、translate関数を使用してオリジン座標を移動しています。

It uses the length and coordinates of the fretboard to draw staff and TAB notes, so it uses the translate function to move the origin coordinates.

しかし、drawChordChart関数にtranslate関数を使用したことは間違いだったかもしれません。

However, using translate function for drawChordChart function might have been a mistake.

何故なら、マウスの座標を格納しているmouseXとmouseY変数はオリジン座標からの数値が入っています。 そうすると、translate関数で座標を移動しても、コードチャート関数内でのマウスの位置はオリジン座標からの座標のままです。 これではマウスの位置を正しく認識できずに上手く機能しません。

Because the mouseX and mouseY variables, which store the mouse coordinates, contain numeric values from the origin coordinates. Then, when you use the translate function to move the coordinates, the mouse position in the drawChordChart function remains at the coordinates from the origin coordinates. It doesn't recognize the position of the mouse properly and doesn't work well.

そこで、一時的な解決策として、マウスの位置の判定用としてもう一度translate関数で使用した座標をstartXとstartY変数に格納しています。

As a temporary solution, the coordinates used by the translate function are stored again in the startX and startY variables and used to recognize the mouse position.

これだと、汎用性にかけるので、少し工夫してコードを改良してみましょう。

This code is not generic, so let's improve it a bit.

pushMatrix();
// translate(width/2-50, height/2);
// drawChordChart();
drawChordChart(width/2-50, height/2);
popMatrix();
//void drawChordChart(){
void drawChordChart(float x, float y) {
    // float startX = width/2-50; 
    float startX = x;
    // float startY = height/2;
    float startY = y;
    pushStyle();
    for (int i = 0; i < 12; i++) {
        for (int j = 0; j < 14; j++) {
        // float rectX = i * 80;
        float rectX = i * 80 + startX;
        // float rectY = 5 + (j*30);
        float rectY = 5 + (j*30) + startY;
        // float textX = i * 80;
        float textX = i * 80 + startX;
        // float textY = 2 + (j*30);
        float textY = 2 + (j*30) + startY;
        float rectW = 75;
        float rectH = 25;
~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
// if ((startX+rectX+rectW/2 > mouseX)&&(startY+rectY-rectH/2 < mouseY)&&(startX+rectX-rectW/2 < mouseX)&&(startY+rectY+rectH/2 > mouseY)) {
if ((rectX+rectW/2 > mouseX)&&(rectY-rectH/2 < mouseY)&&(rectX-rectW/2 < mouseX)&&(rectY+rectH/2 > mouseY)) {

関数に移動したい座標を、引数として指定します。 変更前のコードは変更後の直前でコメントアウトしました。

Specify the coordinates you want to move to the function as arguments. The previous code was commented out just before the change code.

最後に説明するのは、マウスをクリックした時のフレットボードの動作です。 これはテスト用の関数を使用して、その動作を確かめています。 仕組みはとても単純です。

Finally, the behavior of the fretboard when you click the mouse. It uses a test function to verify its behavior. The mechanism is very simple.

if (mousePressed){
    fill(#3E7AB9, 200);
    rect(rectX, rectY, rectW+5, rectH+5);
    textSize(15);
    // Test function representing open chord "A" of guitar
    A(guitarChordChart[i][j]);
~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~

上のセクションで説明しましたが、事前にどのボタンの上にマウスがあるかの判定を行っています。 後はマウスをクリックした時にボタンとテキストのサイズと色を変化させ、 テスト関数の「A」を発動させます。

It determines in advance which button the mouse is on. That was explained in the above section. It then changes the size and color of the button and textg when you click the mouse and activates the A test function.

// Test function representing open chord "A" of guitar
void A(String theStr){
    if(theStr=="A") {
        for (GStringsGNotes sn : sns) {
        sn.initFretClicked();
        }
        sns[0].fretClicked[0] = true;
        sns[1].fretClicked[2] = true;
        sns[2].fretClicked[2] = true;
        sns[3].fretClicked[2] = true;
        sns[4].fretClicked[0] = true;
        
        // mute
        sns[5].checkMute = true;
        
    }
}

A関数で行っているのは、フレットボードの弦とノートを操るオブジェクトの初期化を行い、後は弦オブジェクト毎に指定したギターコードと同じ動作をするようにfretClickedをtrueにするだけです。

The A function simply initializes the object that handles the strings and notes of the fretboard, and then sets fretClicked to true so that it behaves the same as the guitar chord specified for each string object.




Part 5 -
Part 5 -



第5回のビデオでは、第4回のアプリの状態からさらに機能を追加しました。そして、TAB譜や五線譜などの描画の改善等も行い、様々な音符の表記ができるような下準備をします。

In the fifth video, I added more features from the state of the fourth app, then I improved the drawing of TAB and staff notation, and I created the prototype code to allow various note notations.

まずギターの弦毎に重複するノートが存在するので、 五線譜に対応させる為、Notes配列変数を用意します。

First of all, since there is a duplicate note for each guitar string, I prepare a notes array variable to correspond to the staff notation.

String[] notes = {"E2", "F2", "F#2", "G2", "G#2", "A2", "A#2", "B2", "C3", "C#3", "D3", "D#3", "E3", "F3", "F#3", "G3", "G#3", "A3", "A#3", "B3", "C4", "C#4", "D4", "D#4", "E4", "F4", "F#4", "G4", "G#4", "A4", "A#4", "B4", "C5", "C#5", "D5", "D#5", "E5", "F5", "F#5", "G5", "G#5", "A5", "A#5", "B5", "C6", "C#6", "D6"};

PVector型の二次元のcGNtoStaffNotation配列変数を用意します。 これは五線譜を16等分して、その16本の各ライン上に、 音符を表示できるようにするために、各座標を記録させておく為の配列変数です。

Declare a two-dimensional cGNtoStaffNotation array variable of thpe PVector. This is an array variable to store each staff coordinate that divided into 16 equal parts so that notes can be displayed on each of the 16 lines.

PVector[][] cGNtoStaffNotation = new PVector[notes.length][16];

checkNoteDurationには音符の長さが入ります。 0は何も表示させない。 1なら全音符、2なら2分音符といった具合です。

checkNoteDuration contains the length of the note. A value of 0 indicates nothing is displayed. 1 for the whole note, 2 for the Half note, and so on.

int checkNoteDuration = 0;

int型配列変数のeditableLineNumsは先程のcheckNoteDurationの値の分だけ編集できる線の番号を作ります。 つまり、4なら、「1、5、9、13」といった具合に五線譜を4等分します。

The int array variable editableLineNums creates line numbers that can be edited for the previous checkNoteDuration value. That is, if it is 4, divide the staff into 4 equal parts like [1, 5, 9, 13].

int[] editableLineNums;

dChordName変数はギターコードのコードネームが入り、 その文字を利用して、ギターのフレット番号や五線譜への音符表示を行えるようにします。

The dChordName variable takes stores the chord name of the guitar chord and used it to display notes on the guitar fret number or staff notation.

String dChordName = "";

ProcessingはJavaで作られているので、Javaのライブラリが使えます。そこでHashMapとういう便利な機能を使用して、キーワードから値を操作できるようにします。

Processing is built in Java, so you can use Java libraries. A handy feature called HashMap lets you manipulate values from keywords.

import java.util.Map;
import java.util.LinkedHashMap;
Map<String,Integer> noteDurations = new LinkedHashMap<String,Integer>(){
{
    put("Whole note", 1);
    put("Half note", 2);
    put("Quarter note", 4);
    put("8th note", 8);
    put("16th note", 16);
}
};

Map<String,Boolean> controlButtons = new LinkedHashMap<String,Boolean>(){
{
    put("Backward", false);
    put("Record", false);
    put("Forward", false);
    put("Down Stroke", false);
    put("Up Stroke", false);
}
};

こうすれば、noteDurations変数からキーワードをFor文で一つずつ取り出すことができます。

This way, you can retrieve the keywords from the noteDurations variable one by one in the For statement.

for (String nd : noteDurations.keySet())

取り出したキーワードをそのまま使用したり、getメソッドを使用して、値を取り出すこともできます。

You can use the retrieved keywords as is, or you can use the get method to retrieve the values.

fill(#1F0F04);
rect(rectX, rectY, rectW, rectH);
fill(#BC9C3D);
text(nd, rectX, rectY);

テキスト関数とRect関数を使ってボタンを作成したり、 SwitchーCase文を使って値によって処理を分けたりすることができます。

You can use the text and rect functions to create buttons, or you can use the switch-case statement to separate what you want to do by value.

switch (noteDurations.get(nd)) {
case 1:
    editableLineNums = new int[1];
    editableLineNums[0] = 0;
    break;

マウスの判定方法は前回のとおりです。

The method of judging the mouse is the same as before.

例えばマウスがコントロールボタンの「QuarterNotes」をクリックすると、 先程のnoteDurations変数からキーワードを取り出し、その値が4の時の処理を行います。

For example, if you click the [Quarter Note] control button with the mouse, you get the keyword from the noteDuration variable above and perform what you would do if the value were 4.

するとEditableLinesNumsは五線譜を4分割して、そのライン上で音符が表示されるようにラインナンバーを設定します。

EditableLineNums then divides the staff and tab notation into four, and sets the line number so that notes and fret number appear on that line.

その状態でコードボタンの一つをクリックすると、 ライン上にコードの音符が表示される仕組みです。

Then click one of the chord buttons. The notes of the guitar chord appear on the line.

ここで問題があります。 それは、今回のコードの場合、4つのライン上全てに同じコードが表示されてしまうことと、例えば4分音符を入力した後に、8分音符や16分音符等を入力できないことです。 そこで、次回ではこの問題を解決していきたいと思います。

Here's the problem. In this case, the same chord displayed on all 4 lines, and you cannot enter 8th or 16th notes after entering a Quarter note, for example. Therefore, I would like to solve this problem next time.




Part 6 - 8
Part 6 - 8



動画の続きはニコニコ動画にアップしました。

I uploaded the rest of the video to niconico video.


【Processing】簡単なギタータブ譜アプリっぽいやつを作るとどうなるかの総集編


Responsive image


このブログは以下のブログ記事の総集編です。

This blog is a compilation of the following my blog posts.

https://akasatanahama.com/posts/108

https://akasatanahama.com/posts/109

https://akasatanahama.com/posts/110

https://akasatanahama.com/posts/111

https://akasatanahama.com/posts/112

https://akasatanahama.com/posts/113

https://akasatanahama.com/posts/114

https://akasatanahama.com/posts/116

https://akasatanahama.com/posts/118



以上です。お疲れ様です。

That's all. Thank you for your hard work.

今回使用したソフトは素晴らしいことに全て無料で使用できます。 作ってくれた偉大なる先人達に感謝です。 さらにMac、Windows、Linuxどれでも動きます。 まだまだ色々なことがこれらのソフトを組み合わせてできます。 是非各自で創意工夫をして色々と作ってみてください。

The software I used this time can be used for free. I thank my great predecessors. It also supports Mac, Windows and Linux. You can do more with this software. Please try making various things with your own creativity.





See You Next Page!