【Melody Maker】Shape Of You Covered By Fujii Kaze

# Overview

As a children's programming education project, we attempted to code Ed Sheeran's 'Shape Of You,' covered by Fujii Kaze.

# Source Code

```python:main.py
from machine import Pin, PWM
from utime import sleep

################ 電子回路に応じてピン番号を変更する ################
# LED
led_pins = [0, 2, 3, 9, 10, 1, 11, 12]
leds = [Pin(pin, Pin.OUT, value=1) for pin in led_pins]

# NPNトランジスタのベース
buzzer = PWM(Pin(15))

# 再生ボタン
play_button = Pin(13, Pin.IN, Pin.PULL_DOWN)

# 停止ボタン
stop_button = Pin(14, Pin.IN, Pin.PULL_DOWN)

######################## グローバル変数 #########################
# 演奏中ならTrue, 演奏していない時はFalse
PLAYING = False
# メロディー
MELODY = []
# スケール（メロディーの中で使っている音階）
SCALE = []
# BPM（1分あたりの拍数）
BPM = 0

##################################################  音階周波数 ##################################################
REST=    0
C3, Db3, D3, Eb3, E3, F3, Gb3, G3, Ab3, A3, Bb3, B3 = 131, 139, 147, 156, 165, 175, 185, 196, 208, 220, 233, 247
C4, Db4, D4, Eb4, E4, F4, Gb4, G4, Ab4, A4, Bb4, B4 = 262, 277, 294, 311, 330, 349, 370, 392, 415, 440, 466, 494
C5, Db5, D5, Eb5, E5, F5, Gb5, G5, Ab5, A5, Bb5, B5 = 523, 554, 587, 622, 659, 698, 740, 784, 831, 880, 932, 988
C6, Db6, D6, Eb6, E6, F6, Gb6, G6, Ab6, A6, Bb6, B6 =1047,1109,1175,1245,1319,1397,1480,1568,1661,1760,1865,1976

####################### 共通メソッド #######################
def turn_on_led(index=None):
    """
    LEDを点灯する。
    """
    if index is None:
        for led in leds:
            led.value(0)
    else:
        leds[index].value(0)
        
def turn_off_led(index=None):
    """
    LEDを消灯する。
    """
    if index is None:
        for led in leds:
            led.value(1)
    else:
        leds[index].value(1)

def tone(frequency, duration):
    """
    音を鳴らす。

    Parameters:
        frequency(int): 周波数
        duration(int): 音符の音の長さ
            * 四分音符: 4
            * 八分音符: 8
            * 付点四分音符: 4/1.5
    """
    beat = 60 / BPM
    duration = beat * 4 / duration

    if frequency == REST:
        turn_on_led()
        sleep(duration)
        turn_off_led()
        return
    index = SCALE.index(frequency) % 8
    turn_on_led(index)
    buzzer.freq(frequency)
    buzzer.duty_u16(30000)
    sleep(duration)
    buzzer.duty_u16(0)
    sleep(0.002)
    turn_off_led(index)

def play():
    """
    演奏を開始する。
    """
    global PLAYING
    PLAYING = True
    turn_off_led()
    for m in MELODY:
        if PLAYING:
            tone(m[0], m[1])
        else:
            break

def stop(pin):
    """
    演奏を停止する。
    """
    global PLAYING
    PLAYING = False

# 停止ボタンが押されたら演奏を停止する
stop_button.irq(trigger=Pin.IRQ_RISING, handler=stop)


def melody():
    """
    Shape Of You Covered By Fujii Kaze
    """
    global BPM
    global MELODY
    global SCALE

    # BPMを定義する
    BPM = 208

    # メロディーを定義する
    MELODY = [
        (Db5,8),(Db3,8),(E3,8),(E5,4),(Db3,8),(Db5,8),(Db3,8),
        (Db5,8),(Db3,8),(E3,8),(E5,4),(Db3,8),(Db5,8),(Db3,8),
        (Db5,8),(B3,8),(E3,8),(E5,4),(B3,8),(Db5,8),(B3,8),
        (Eb5,8),(Ab3,8),(B3,8),(Db5,4),(B3,8),(B4,8),(B3,8),

        (E5,8),(E3,8),(Ab3,8),(Ab5,4),(Ab3,8),(E5,8),(E3,8),
        (E5,8),(E3,8),(Ab3,8),(Ab5,4),(Ab3,8),(E5,8),(E3,8),
        (E5,8),(B3,8),(Eb4,8),(Ab5,4),(Eb4,8),(E5,8),(B3,8),
        (Eb5,8),(Ab3,8),(B3,8),(Db5,4),(B3,8),(B4,8),(Ab3,8)

    ] 

    # スケールを更新する
    unique_elements = []
    for note in MELODY:
        if note[0] not in unique_elements and note[0] != REST:
            unique_elements.append(note[0])
    SCALE = sorted(unique_elements)

    # 演奏する
    play()

index = 0
while True:
    turn_on_led(index)
    if play_button.value() == 1:
        melody()
    sleep(0.1)
    turn_off_led(index)
    if index < 7:
        index += 1
    else:
        index = 0

```

# How to create a Melody Maker

This video explains how to create a melody maker in Japanese.

https://youtu.be/d7pTfG6R1M8