音楽クラス（オブジェクト指向）を作ってみた

ちょうど一年前のアドベントカレンダーで [MATLAB で音楽を生成してみた](https://qiita.com/backslash/items/356c4d59c196f7f4e4cc) という記事を書きました．




今回はその続編です．




一年前からの進化：



   1.  関数ベースからオブジェクト指向のプログラムへ（音楽クラス）
   1.  アプリ（GUI）の作成 



アプリはこんな感じです．


![image_0.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/194780/6a040d40-1b8f-a2f7-822b-33d519b257c3.png)


**アプリのコードの中身は乱雑でまあまあ長いのでまたの機会で解説をするとして，今回の記事では音楽クラスの解説をします．**


# まずは動かしてみよう
## `Note` クラス


一番基本となるクラスは `Note` クラス．つまり音符クラスですね．このクラスは，音程と長さを指定して定義します．



```matlab:Code
n = Note("C5","WholeNote")
```


```text:Output
n = 
  Note のプロパティ:

       Pitch: C5
    Duration: WholeNote
```



これでなにができるかというと



```matlab:Code
methods(n)
```


```text:Output
クラス Note に対するメソッド:

Note            generateSignal  play            

handle から継承された Note のメソッドです。
```



`generateSignal` は波形を出力します． `play` で音を再生します．



```matlab:Code
play(n)
```



[**聴いてみよう**](https://drive.google.com/uc?id=1y14I0QMbQ4oJuJy-TvIRvnmfcch8kpAn)


## `Part` クラス


ただし， `Note` クラスは一つ一つの音符を表すので，実際に音楽を作るには音符を組み合わせる必要がありますね．それに使うのが `Part` クラスです． `Part` クラスは，音符（音程と長さ）を複数指定することによって定義できます．



```matlab:Code
p1 = Part("C4","HalfNote","D4","QuarterNote","E4","QuarterNote",...
    "F4","QuarterNote","G4","QuarterNote","A4","QuarterNote",...
    "B4","QuarterNote","C5","WholeNote")
```


```text:Output
p1 = 
  Part のプロパティ:

     Name: "20221224T020652"
    Notes: [1x8 Note]
```



再生してみると



```matlab:Code(Display)
play(p1)
```



[**聴いてみよう**](https://drive.google.com/uc?id=1nDrwQigWdW5z-PXC_FmOPGv0sHY3UnKJ)




もう一つ `Part` クラスを作成してみましょう．



```matlab:Code
p2 = Part("C5","HalfNote","B4","QuarterNote","A4","QuarterNote",...
    "G4","QuarterNote","F4","QuarterNote","E4","QuarterNote",...
    "D4","QuarterNote","C4","WholeNote")
```


```text:Output
p2 = 
  Part のプロパティ:

     Name: "20221224T020652"
    Notes: [1x8 Note]
```



[**聴いてみよう**](https://drive.google.com/uc?id=1K9-9Qku7cnp9i_s6rZxl2ILOd_hsJpZl)


## `Music` クラス


最後に，複数のパートを組み合わせることによって， `Music` クラス（音楽クラス）を作成します． `Music` クラスはテンポとパートを指定します．



```matlab:Code
m = Music("Allegro",p1,p2)
```


```text:Output
m = 
  Music のプロパティ:

            Tempo: Allegro
    TimeSignature: "4/4"
            Parts: [1x2 Part]
```



[**聴いてみよう**](https://drive.google.com/uc?id=17HFovelyahCPgjjFNv_eMfXpgECkHFhx)


# 中身をみてみよう
## `NotePitch` クラス


`Note` クラスが必要とする音程は `NotePitch` 列挙型クラスで定義されています． `double` 型を継承し，音程の名前に対応する周波数を指定しています．

<details><summary>NotePitch.m</summary>

```matlab:Code(Display)
classdef NotePitch < double

    enumeration
        rest (0)
        C0	(16.35)
        Csharp0	(17.32)
        Dflat0	(17.32)
        D0	(18.35)
        Dsharp0	(19.45)
        Eflat0	(19.45)
        E0	(20.6)
        F0	(21.83)
        Fsharp0	(23.12)
        Gflat0	(23.12)
        G0	(24.5)
        Gsharp0	(25.96)
        Aflat0	(25.96)
        A0	(27.5)
        Asharp0	(29.14)
        Bflat0	(29.14)
        B0	(30.87)
        C1	(32.7)
        Csharp1	(34.65)
        Dflat1	(34.65)
        D1	(36.71)
        Dsharp1	(38.89)
        Eflat1	(38.89)
        E1	(41.2)
        F1	(43.65)
        Fsharp1	(46.25)
        Gflat1	(46.25)
        G1	(49)
        Gsharp1	(51.91)
        Aflat1	(51.91)
        A1	(55)
        Asharp1	(58.27)
        Bflat1	(58.27)
        B1	(61.74)
        C2	(65.41)
        Csharp2	(69.3)
        Dflat2	(69.3)
        D2	(73.42)
        Dsharp2	(77.78)
        Eflat2	(77.78)
        E2	(82.41)
        F2	(87.31)
        Fsharp2	(92.5)
        Gflat2	(92.5)
        G2	(98)
        Gsharp2	(103.83)
        Aflat2	(103.83)
        A2	(110)
        Asharp2	(116.54)
        Bflat2	(116.54)
        B2	(123.47)
        C3	(130.81)
        Csharp3	(138.59)
        Dflat3	(138.59)
        D3	(146.83)
        Dsharp3	(155.56)
        Eflat3	(155.56)
        E3	(164.81)
        F3	(174.61)
        Fsharp3	(185)
        Gflat3	(185)
        G3	(196)
        Gsharp3	(207.65)
        Aflat3	(207.65)
        A3	(220)
        Asharp3	(233.08)
        Bflat3	(233.08)
        B3	(246.94)
        C4	(261.63)
        Csharp4	(277.18)
        Dflat4	(277.18)
        D4	(293.66)
        Dsharp4	(311.13)
        Eflat4	(311.13)
        E4	(329.63)
        F4	(349.23)
        Fsharp4	(369.99)
        Gflat4	(369.99)
        G4	(392)
        Gsharp4	(415.3)
        Aflat4	(415.3)
        A4	(440)
        Asharp4	(466.16)
        Bflat4	(466.16)
        B4	(493.88)
        C5	(523.25)
        Csharp5	(554.37)
        Dflat5	(554.37)
        D5	(587.33)
        Dsharp5	(622.25)
        Eflat5	(622.25)
        E5	(659.25)
        F5	(698.46)
        Fsharp5	(739.99)
        Gflat5	(739.99)
        G5	(783.99)
        Gsharp5	(830.61)
        Aflat5	(830.61)
        A5	(880)
        Asharp5	(932.33)
        Bflat5	(932.33)
        B5	(987.77)
        C6	(1046.5)
        Csharp6	(1108.73)
        Dflat6	(1108.73)
        D6	(1174.66)
        Dsharp6	(1244.51)
        Eflat6	(1244.51)
        E6	(1318.51)
        F6	(1396.91)
        Fsharp6	(1479.98)
        Gflat6	(1479.98)
        G6	(1567.98)
        Gsharp6	(1661.22)
        Aflat6	(1661.22)
        A6	(1760)
        Asharp6	(1864.66)
        Bflat6	(1864.66)
        B6	(1975.53)
        C7	(2093)
        Csharp7	(2217.46)
        Dflat7	(2217.46)
        D7	(2349.32)
        Dsharp7	(2489.02)
        Eflat7	(2489.02)
        E7	(2637.02)
        F7	(2793.83)
        Fsharp7	(2959.96)
        Gflat7	(2959.96)
        G7	(3135.96)
        Gsharp7	(3322.44)
        Aflat7	(3322.44)
        A7	(3520)
        Asharp7	(3729.31)
        Bflat7	(3729.31)
        B7	(3951.07)
        C8	(4186.01)
        Csharp8	(4434.92)
        Dflat8	(4434.92)
        D8	(4698.63)
        Dsharp8	(4978.03)
        Eflat8	(4978.03)
        E8	(5274.04)
        F8	(5587.65)
        Fsharp8	(5919.91)
        Gflat8	(5919.91)
        G8	(6271.93)
        Gsharp8	(6644.88)
        Aflat8	(6644.88)
        A8	(7040)
        Asharp8	(7458.62)
        Bflat8	(7458.62)
        B8	(7902.13)
    end

end
```
</details>

## `NoteDuration` クラス


`Note` クラスが必要とするもう一つのパラメーターは音の長さです． `NoteDuration` クラスは `double` 型を継承し，音の長さに対応付けしています．この「長さ」は最終的に音楽のテンポによってスケールされます．

<details><summary>NoteDuration.m</summary>

```matlab:Code(Display)
classdef NoteDuration < double

    enumeration
        WholeNote (1)
        WholeNoteDot (1.5)
        HalfNote (1/2)
        HalfNoteDot (3/4)
        QuarterNote (1/4)
        QuarterNoteDot (3/8)
        EigthNote (1/8)
        EigthNoteDot (3/16)
        SixteenthNote (1/16)
        SixteenthNoteDot (3/32)
        ThirtysecondNote (1/32)
        ThirtysecondNoteDot (3/64)
        SixtyfourthNote (1/64)
        SixtyfourthNoteDot (3/128)
    end

end
```
</details>

## `Note` クラス


`Note` クラスは基本的には２つのプロパティをもっています： `Pitch` と `Duration`．また，再生の時に使われるサンプル周波数 `Fs` は Constant として定義されています．



```matlab:Code(Display)
classdef Note < handle

    properties
        Pitch = NotePitch.A4
        Duration = NoteDuration.QuarterNote
    end

    properties (Constant, Hidden)
        Fs = 44100
    end

end
```



`Note` クラスで重要となるのは音を生成する `play` メソッドと `generateSignal` メソッドです． `generateSignal` メソッドは後で説明する `Part` クラスと `Music` クラスでも呼ばれます．



```matlab:Code(Display)
function x = generateSignal(obj,bpm)
    arguments
        obj (1,:) Note
        bpm (1,1) double = 240
    end
    dur = [0, cumsum([obj.Duration])]*(240/bpm);
    t = 0:1/Note.Fs:dur(end);
    x = zeros(size(t));
    for id = 1:length(obj)
        ii = t >= dur(id) & t < dur(id+1);
        for id2 = 1:length(obj(id).Pitch)
            x(ii) = x(ii) + sin(2*pi*obj(id).Pitch(id2)*t(ii));
        end
    
        len = nnz(ii);
        if mod(len,2) == 0
            m = (1e5-[logspace(5,0,len/2),logspace(0,5,len/2)])/1e5;
        else
            m = (1e5-[logspace(5,0,len/2+1),logspace(0,5,len/2)])/1e5;
        end
        x(ii) = x(ii) .* m;
    end
    x = normalize(x,"range",[-1 1]);
end
```



`play` メソッドは `generateSignal` メソッドを呼んで，計算された信号を `sound` 関数で再生します．



```matlab:Code(Display)
function play(obj,bpm)
    arguments
        obj (1,:) Note
        bpm (1,1) double = 240
    end
    x = generateSignal(obj,bpm);
    sound(x,Note.Fs)
end
```

## `Part` クラス


`Part` クラスは端的に言うと， 複数の `Note` を組み合わせたものです．したがって，プロパティの一つは `Notes` です．その他， `Note` クラスと同様音の再生に活用されるサンプル周波数 `Fs` と，パートに付けられる名前 `Name` があります．



```matlab:Code(Display)
classdef Part < handle

    properties
        Name
        Notes
    end

    properties (Constant, Hidden)
        Fs = 44100
    end

end
```



コンストラクターは，連続して音程と音の長さを定義できるように改造してます．



```matlab:Code(Display)
function obj = Part(p,d)
    arguments (Repeating)
        p (1,:) NotePitch
        d (1,1) NoteDuration
    end
    obj.Name = string(datetime,"uuuuMMdd'T'HHmmss");
    if isempty(p)
        return
    end
    obj.Notes = Note(p{1},d{1});
    for id = 2:length(p)
        obj.Notes(id) = Note(p{id},d{id});
    end
end
```



`Note` クラスと同様， `Part` クラスにも `generateSignal` と `play` メソッドがありますが，これらは基本的 `Note` クラスのメソッドを呼んでいます．


## `MusicTempo` クラス


最後は `Music` クラスですが，それに必要なプロパティの一つが `MusicTempo` 列挙型クラスです．これは， `double` 型を継承し，テンポに値するスピード（bpm）に対応付けされています．

<details><summary>MusicTempo.m</summary>

```matlab:Code(Display)
classdef MusicTempo < double

    enumeration
        Larghissimo (25)
        Grave (35)
        Largo (50)
        Lento (52.5)
        Larghetto (63)
        Adagio (71)
        Adagietto (74)
        Andante (92)
        Andantino (94)
        AndanteModerato (102)
        Moderato (114)
        Allegretto (116)
        AllegroModerato (118)
        Allegro (144)
        Vivace (158)
        Allegrissimo (174)
        Vivacissimo (174)
        Presto (184)
        Prestissimo (200)
    end

end
```
</details>

## `Music` クラス


`Music` クラスが最終クラスで，テンポと複数のパートを指定して定義します．プロパティーは以下のようになってます．テンポに加えて拍子記号 `TimeSignature` も指定できます．



```matlab:Code(Display)
classdef Music < handle

    properties
        Tempo = MusicTempo.Moderato
        TimeSignature = "4/4"
        Parts
    end

    properties (Constant, Hidden)
        Fs = 44100
    end

end
```



テンポと複数のパートを定義できるようにコンストラクターを構築してます．



```matlab:Code(Display)
function obj = Music(bpm,p)
    arguments
        bpm (1,1) MusicTempo = MusicTempo.Moderato
    end
    arguments (Repeating)
        p (1,1) Part
    end
    ps = [p{:}];
    if isempty(ps)
        return
    end
    obj.Parts = ps;
    obj.Tempo = bpm;
end
```



他のクラスと同様， `generateSignal` と `play` メソッドを実装してますが， `Music` クラスではテンポと拍子記号によって音楽のスピードが設定されるため， `generateSignal` にそのような細工が加わっています．



```matlab:Code(Display)
function x = generateSignal(obj)
    ts = double(string(split(obj.TimeSignature,"/")));
    x = generateSignal(obj.Parts(1),obj.Tempo*(4/ts(2)));
    for iP = 2:length(obj.Parts)
        y = generateSignal(obj.Parts(iP),obj.Tempo*(4/ts(2)));
        if numel(y) == numel(x)
            x = x+y;
        elseif numel(y) < numel(x)
            x(1:numel(y)) = x(1:numel(y))+y;
        else
            y(1:numel(x)) = y(1:numel(x))+x;
            x = y;
        end
    end
    x = normalize(x,"range",[-1 1]);
end
```

# すべてのコード
## `Note.m`

<details><summary>コード</summary>

```matlab:Code(Display)
classdef Note < handle

    properties
        Pitch = NotePitch.A4
        Duration = NoteDuration.QuarterNote
    end

    properties (Constant, Hidden)
        Fs = 44100
    end

    methods
        function obj = Note(p,d)
            arguments
                p (1,1) NotePitch
                d (1,1) NoteDuration
            end
            obj.Pitch = p;
            obj.Duration = d;
        end

        function play(obj,bpm)
            arguments
                obj (1,:) Note
                bpm (1,1) double = 240
            end
            x = generateSignal(obj,bpm);
            sound(x,Note.Fs)
        end

        function x = generateSignal(obj,bpm)
            arguments
                obj (1,:) Note
                bpm (1,1) double = 240
            end
            dur = [0, cumsum([obj.Duration])]*(240/bpm);
            t = 0:1/Note.Fs:dur(end);
            x = zeros(size(t));
            for id = 1:length(obj)
                ii = t >= dur(id) & t < dur(id+1);
                for id2 = 1:length(obj(id).Pitch)
                    x(ii) = x(ii) + sin(2*pi*obj(id).Pitch(id2)*t(ii));
                end

                len = nnz(ii);
                if mod(len,2) == 0
                    m = (1e5-[logspace(5,0,len/2),logspace(0,5,len/2)])/1e5;
                else
                    m = (1e5-[logspace(5,0,len/2+1),logspace(0,5,len/2)])/1e5;
                end
                x(ii) = x(ii) .* m;
            end
            x = normalize(x,"range",[-1 1]);
        end
    end

end
```
</details>

## `Part.m`
<details><summary>コード</summary>

```matlab:Code(Display)
classdef Part < handle

    properties
        Name
        Notes
    end

    properties (Constant, Hidden)
        Fs = 44100
    end

    methods
        function obj = Part(p,d)
            arguments (Repeating)
                p (1,:) NotePitch
                d (1,1) NoteDuration
            end
            obj.Name = string(datetime,"uuuuMMdd'T'HHmmss");
            if isempty(p)
                return
            end
            obj.Notes = Note(p{1},d{1});
            for id = 2:length(p)
                obj.Notes(id) = Note(p{id},d{id});
            end
        end

        function play(obj,bpm)
            arguments
                obj (1,:) Part
                bpm (1,1) double = 240
            end
            x = generateSignal(obj,bpm);
            sound(x,Part.Fs)
        end

        function x = generateSignal(obj,bpm)
            arguments
                obj (1,:) Part
                bpm (1,1) double = 240
            end
            if isempty(obj.Notes)
                x = [];
            else
                x = generateSignal(obj.Notes,bpm);
            end
        end
    end
end
```
</details>

## `Music.m`
<details><summary>コード</summary>

```matlab:Code(Display)
classdef Music < handle

    properties
        Tempo = MusicTempo.Moderato
        TimeSignature = "4/4"
        Parts
    end

    properties (Constant, Hidden)
        Fs = 44100
    end

    methods
        function obj = Music(bpm,p)
            arguments
                bpm (1,1) MusicTempo = MusicTempo.Moderato
            end
            arguments (Repeating)
                p (1,1) Part
            end
            ps = [p{:}];
            if isempty(ps)
                return
            end
            obj.Parts = ps;
            obj.Tempo = bpm;
        end

        function play(obj)
            x = generateSignal(obj);
            sound(x,obj.Fs)
        end

        function x = generateSignal(obj)
            ts = double(string(split(obj.TimeSignature,"/")));
            x = generateSignal(obj.Parts(1),obj.Tempo*(4/ts(2)));
            for iP = 2:length(obj.Parts)
                y = generateSignal(obj.Parts(iP),obj.Tempo*(4/ts(2)));
                if numel(y) == numel(x)
                    x = x+y;
                elseif numel(y) < numel(x)
                    x(1:numel(y)) = x(1:numel(y))+y;
                else
                    y(1:numel(x)) = y(1:numel(x))+x;
                    x = y;
                end
            end
            x = normalize(x,"range",[-1 1]);
        end

    end
end
```
</details>

## `NotePitch.m`
<details><summary>コード</summary>

```matlab:Code(Display)
classdef NotePitch < double

    enumeration
        rest (0)
        C0	(16.35)
        Csharp0	(17.32)
        Dflat0	(17.32)
        D0	(18.35)
        Dsharp0	(19.45)
        Eflat0	(19.45)
        E0	(20.6)
        F0	(21.83)
        Fsharp0	(23.12)
        Gflat0	(23.12)
        G0	(24.5)
        Gsharp0	(25.96)
        Aflat0	(25.96)
        A0	(27.5)
        Asharp0	(29.14)
        Bflat0	(29.14)
        B0	(30.87)
        C1	(32.7)
        Csharp1	(34.65)
        Dflat1	(34.65)
        D1	(36.71)
        Dsharp1	(38.89)
        Eflat1	(38.89)
        E1	(41.2)
        F1	(43.65)
        Fsharp1	(46.25)
        Gflat1	(46.25)
        G1	(49)
        Gsharp1	(51.91)
        Aflat1	(51.91)
        A1	(55)
        Asharp1	(58.27)
        Bflat1	(58.27)
        B1	(61.74)
        C2	(65.41)
        Csharp2	(69.3)
        Dflat2	(69.3)
        D2	(73.42)
        Dsharp2	(77.78)
        Eflat2	(77.78)
        E2	(82.41)
        F2	(87.31)
        Fsharp2	(92.5)
        Gflat2	(92.5)
        G2	(98)
        Gsharp2	(103.83)
        Aflat2	(103.83)
        A2	(110)
        Asharp2	(116.54)
        Bflat2	(116.54)
        B2	(123.47)
        C3	(130.81)
        Csharp3	(138.59)
        Dflat3	(138.59)
        D3	(146.83)
        Dsharp3	(155.56)
        Eflat3	(155.56)
        E3	(164.81)
        F3	(174.61)
        Fsharp3	(185)
        Gflat3	(185)
        G3	(196)
        Gsharp3	(207.65)
        Aflat3	(207.65)
        A3	(220)
        Asharp3	(233.08)
        Bflat3	(233.08)
        B3	(246.94)
        C4	(261.63)
        Csharp4	(277.18)
        Dflat4	(277.18)
        D4	(293.66)
        Dsharp4	(311.13)
        Eflat4	(311.13)
        E4	(329.63)
        F4	(349.23)
        Fsharp4	(369.99)
        Gflat4	(369.99)
        G4	(392)
        Gsharp4	(415.3)
        Aflat4	(415.3)
        A4	(440)
        Asharp4	(466.16)
        Bflat4	(466.16)
        B4	(493.88)
        C5	(523.25)
        Csharp5	(554.37)
        Dflat5	(554.37)
        D5	(587.33)
        Dsharp5	(622.25)
        Eflat5	(622.25)
        E5	(659.25)
        F5	(698.46)
        Fsharp5	(739.99)
        Gflat5	(739.99)
        G5	(783.99)
        Gsharp5	(830.61)
        Aflat5	(830.61)
        A5	(880)
        Asharp5	(932.33)
        Bflat5	(932.33)
        B5	(987.77)
        C6	(1046.5)
        Csharp6	(1108.73)
        Dflat6	(1108.73)
        D6	(1174.66)
        Dsharp6	(1244.51)
        Eflat6	(1244.51)
        E6	(1318.51)
        F6	(1396.91)
        Fsharp6	(1479.98)
        Gflat6	(1479.98)
        G6	(1567.98)
        Gsharp6	(1661.22)
        Aflat6	(1661.22)
        A6	(1760)
        Asharp6	(1864.66)
        Bflat6	(1864.66)
        B6	(1975.53)
        C7	(2093)
        Csharp7	(2217.46)
        Dflat7	(2217.46)
        D7	(2349.32)
        Dsharp7	(2489.02)
        Eflat7	(2489.02)
        E7	(2637.02)
        F7	(2793.83)
        Fsharp7	(2959.96)
        Gflat7	(2959.96)
        G7	(3135.96)
        Gsharp7	(3322.44)
        Aflat7	(3322.44)
        A7	(3520)
        Asharp7	(3729.31)
        Bflat7	(3729.31)
        B7	(3951.07)
        C8	(4186.01)
        Csharp8	(4434.92)
        Dflat8	(4434.92)
        D8	(4698.63)
        Dsharp8	(4978.03)
        Eflat8	(4978.03)
        E8	(5274.04)
        F8	(5587.65)
        Fsharp8	(5919.91)
        Gflat8	(5919.91)
        G8	(6271.93)
        Gsharp8	(6644.88)
        Aflat8	(6644.88)
        A8	(7040)
        Asharp8	(7458.62)
        Bflat8	(7458.62)
        B8	(7902.13)
    end

end
```
</details>

## `NoteDuration.m`
<details><summary>コード</summary>

```matlab:Code(Display)
classdef NoteDuration < double

    enumeration
        WholeNote (1)
        WholeNoteDot (1.5)
        HalfNote (1/2)
        HalfNoteDot (3/4)
        QuarterNote (1/4)
        QuarterNoteDot (3/8)
        EigthNote (1/8)
        EigthNoteDot (3/16)
        SixteenthNote (1/16)
        SixteenthNoteDot (3/32)
        ThirtysecondNote (1/32)
        ThirtysecondNoteDot (3/64)
        SixtyfourthNote (1/64)
        SixtyfourthNoteDot (3/128)
    end

end
```
</details>

## `MusicTempo.m`
<details><summary>コード</summary>

```matlab:Code(Display)
classdef MusicTempo < double

    enumeration
        Larghissimo (25)
        Grave (35)
        Largo (50)
        Lento (52.5)
        Larghetto (63)
        Adagio (71)
        Adagietto (74)
        Andante (92)
        Andantino (94)
        AndanteModerato (102)
        Moderato (114)
        Allegretto (116)
        AllegroModerato (118)
        Allegro (144)
        Vivace (158)
        Allegrissimo (174)
        Vivacissimo (174)
        Presto (184)
        Prestissimo (200)
    end

end
```
</details>

# メヌエットを弾いてみよう


バッハのメヌエット　ト長調を弾いてみましょう



```matlab:Code(Display)
p1 = Part("D5","QuarterNote","G4","EigthNote","A4","EigthNote",...
    "B4","EigthNote","C5","EigthNote","D5","QuarterNote","G4","QuarterNote",...
    "G4","QuarterNote","E5","QuarterNote","C5","EigthNote","D5","EigthNote",...
    "E5","EigthNote","Fsharp5","EigthNote","G5","QuarterNote","G4","QuarterNote",...
    "G4","QuarterNote","C5","QuarterNote","D5","EigthNote","C5","EigthNote",...
    "B4","EigthNote","A4","EigthNote","B4","QuarterNote","C5","EigthNote",...
    "B4","EigthNote","A4","EigthNote","G4","EigthNote","Fsharp4","QuarterNote",...
    "G4","EigthNote","A4","EigthNote","B4","EigthNote","G4","EigthNote",...
    "A4","HalfNoteDot","D5","QuarterNote","G4","EigthNote","A4","EigthNote",...
    "B4","EigthNote","C5","EigthNote","D5","QuarterNote","G4","QuarterNote",...
    "G4","QuarterNote","E5","QuarterNote","C5","EigthNote","D5","EigthNote",...
    "E5","EigthNote","Fsharp5","EigthNote","G5","QuarterNote","G4","QuarterNote",...
    "G4","QuarterNote","C5","QuarterNote","D5","EigthNote","C5","EigthNote",...
    "B4","EigthNote","A4","EigthNote","B4","QuarterNote","C5","EigthNote",...
    "B4","EigthNote","A4","EigthNote","G4","EigthNote","A4","QuarterNote",...
    "B4","EigthNote","A4","EigthNote","G4","EigthNote","Fsharp4","EigthNote",...
    "G4","HalfNoteDot")

p2 = Part("B3","HalfNote","A3","QuarterNote","B3","HalfNoteDot",...
    "C4","HalfNoteDot","B3","HalfNoteDot","A3","HalfNoteDot","G3","HalfNoteDot",...
    "D4","QuarterNote","B3","QuarterNote","G3","QuarterNote","D4","QuarterNote",...
    "D3","EigthNote","C4","EigthNote","B3","EigthNote","A3","EigthNote",...
    "B3","HalfNote","A3","QuarterNote","G3","QuarterNote","B3","QuarterNote",...
    "G3","QuarterNote","C4","HalfNoteDot","B3","QuarterNote","C4","EigthNote",...
    "B3","EigthNote","A3","EigthNote","G3","EigthNote","A3","HalfNote",...
    "Fsharp3","QuarterNote","G3","HalfNote","B3","QuarterNote","C4","QuarterNote",...
    "D4","QuarterNote","D3","QuarterNote","G3","HalfNote","G2","QuarterNote")

m = Music("Allegretto",p1,p2);
m.TimeSignature = "3/4"

play(m)
```



[**聴いてみよう**](https://drive.google.com/uc?id=19O9XDAu5kI2_HPOtA0HGTQxcp8N3RWPu)