-
Notifications
You must be signed in to change notification settings - Fork 0
Home
Welcome to the Learning-to-play-the-Piano-with-a-Python-Bot wiki!
- Manel Lurbe Sempere ([email protected])
This project is based on my interest in learning to play the piano in my spare time. As everyone knows, learning to play an instrument is difficult and requires a lot of time and dedication. In my case, I am a computer engineer and for lack of time I decided to start a project to learn playing the piano using a software teacher implemented with LED lights on each piano key. My interest in this software has increased throughout the development and has ended up becoming a bot that plays the piano.
- Program pianoPlayPi.py is the program to play with Servo motors.
- Folder music_sheets contains example music sheets to play with previous program.
- Actual version of the code supports only multiple notes with same tempo in the same thread. Multi-thread is supported for simulate two virtual hands with their own music sheet. Additionally, the actual implementation corresponds to two notes for each servo motor because the actual prototype doesn't have enough space between piano keys.
- Program buzzerPi.py is a program to play songs with a passive buzzer using the frequencies of piano notes. To play multiple notes at the same time you need as many as notes are wanted to play at the same time.
- Actual version of the code only supports one note each time.
- Program ledPi.py is a program to learn to play the piano using a servo controller for switching LEDs, each LED corresponds to one note, you need as many LEDs as notes are wanted to play.
- This program was the first implementation and was designed to learn to play the piano by placing a LED on top of each key to play it every time a LED was turned on.
- Actual version of the code supports multiple notes with same tempo in the same thread. No multi-thread support yet.
GOOGLE ASSISTANT SUPPORT
The bot can be executed from google assistant, creating commands from a google account and linking the controller device as a home IoT device to launch orders such as: "OK Google, play Bethoven's Fifth Symphony on the piano". Example:
-
Install python3 for develop (Ubuntu/Debian based systems):
sudo apt install python3-dev python3-pip python3-tk build-essential libi2c-dev i2c-tools libffi-dev
-
Install libs for python 3:
sudo -H python3 -m pip install adafruit-circuitpython-busdevice adafruit-circuitpython-servokit adafruit-circuitpython-pca9685 PCA9685-driver RPi.GPIO
- This lib translates a mid file into txt values, that can be interpreted by the programs.
git clone https://github.com/markc/midicomp
mkdir midicomp/build
cd midicomp/build
cmake ..
make
sudo make install #(optional)
- Raspberry Pi (any model) or other similar board with support of GPIO ports and python3. Buy on amazon
- Cables to connect anything with the GPIO ports. Buy on amazon
If you want to play pianoPlayPi.py program you need:
- Servo motors as many as notes you want to play. Buy on amazon
- PCA9685 16 Channel PWM Servo Driver, more than one if you want to support more than 16 servos at the same time. Buy on amazon
If you want to play buzzerPi.py program you need:
- As many passive Buzzers as notes you want to play at the same time. Buy on amazon
If you want to play ledPi.py program you need:
- LEDs, as many as notes you want to play. Buy on amazon
- buzzerPi.py: The following image shows how to connect one buzzer to the Raspberry Pi. If you have more than one, you have to connect each one to one of the available GPIO ports of your board and enable it in the code.
- ledPi.py: The following image shows how to connect one LED to the channel 0 of the controller. If you have more than one, you have to connect each one to each controller channel.
- pianoPlayPi.py: The following image shows how to connect one servo motor to the channel 0 of the controller. If you have more than one, you have to connect each one to each controller channel.
-
Set execution permissions:
chmod +x program.py
-
Usage:
python3 program.py music_sheets/music_sheet.txt
or:
./program.py music_sheets/music_sheet.txt
NOTE: Replace "program" with the name of the program you want to execute and "music_sheet" with the name of the song you want to play from the folder "music_sheets".
-
ONLY IN pianoPlayPi.pay FOR DUAL HAND EMULATION WITH THREADS:
python3 pianoPlayPi.py music_sheets/music_sheet_hand_1.txt music_sheets/music_sheet_hand_2.txt
or:
./pianoPlayPi.py music_sheets/music_sheet_hand_1.txt music_sheets/music_sheet_hand_2.txt
NOTE: Music sheets for dual hand simulated piano, as in real life, shouldn't contains the same notes (or piano keys) at the same time, there is no reason to play with two hands the same notes.
I'm trying to find a lib or website that provides music sheets in plain text for bots or in more complex way, develop a machine learning algorithm to recognise notes in pdf or image based music sheets. The idea is to give the piano bot the capacity of play any kind of song without having to rewrite the music sheet specifically for him.
Music Sheets for the piano are composed by a file of tuples (note,tempo), where "note" corresponds to the music note to be played and "tempo" the type of the note represented in the following table:
Music symbols | Code Style |
---|---|
π π | dr |
π | r |
π . | b+ |
π π | b- |
π | b |
π . | n+ |
π π | n- |
π | n |
π | c |
π ‘ | sc |
π £ | ssc |
π € | sssc |
β | *Write "b" after the note. Example: "mib" corresponds to note "mi flat".* |
β― | *Translate it to flats.* |
Silence | *Same as the type of the note tempo. Example: "(sil,n)" corresponds to silence with the tempo of quarter note( π ).* |
In addition, you can play two or more notes at the same time if they have the same tempo in the same thread, separating them with a tab value key (\t). The file will be like this:
-
For one note:
do,n re,n mi,n fa,n sol,n la,n si,n do2,n
-
For two (or more) notes with same tempo:
do,n do2,n re,n si,n mi,n la,n fa,n sol,n sol,n fa,n la,n mi,n si,n re,n do2,n do,n
NOTE: Remember that there are no spaces between notes, they are tab key values (\t).
Key Number | Franco-Belgian notation | Anglo-Saxon notation | Frecuency |
---|---|---|---|
88 | do7 | C8 | 4186,01 |
87 | si6 | B7 | 3951,07 |
86 | laβ―6/siβ6 | Aβ―7/Bβ7 | 3729,31 |
85 | la6 | A7 | 3520,00 |
84 | solβ―6/laβ6 | Gβ―7/Aβ7 | 3322,44 |
83 | sol6 | G7 | 3135,96 |
82 | faβ―6/solβ6 | Fβ―7/Gβ7 | 2959,96 |
81 | fa6 | F7 | 2793,83 |
80 | mi6 | E7 | 2637,02 |
79 | reβ―6/miβ6 | Dβ―7/Eβ7 | 2489,02 |
78 | re6 | D7 | 2349,32 |
77 | doβ―6/reβ6 | Cβ―7/Dβ7 | 2217,46 |
76 | do6 | C7 | 2093,00 |
75 | si5 | B6 | 1975,53 |
74 | laβ―5/siβ5 | Aβ―6/Bβ6 | 1864,66 |
73 | la5 | A6 | 1760,00 |
72 | solβ―5/laβ5 | Gβ―6/Aβ6 | 1661,22 |
71 | sol5 | G6 | 1567,98 |
70 | faβ―5/solβ5 | Fβ―6/Gβ6 | 1479,98 |
69 | fa5 | F6 | 1396,91 |
68 | mi5 | E6 | 1318,51 |
67 | reβ―5/miβ5 | Dβ―6/Eβ6 | 1244,51 |
66 | re5 | D6 | 1174,66 |
65 | doβ―5/reβ5 | Cβ―6/Dβ6 | 1108,73 |
64 | do5 | C6 | 1046,50 |
63 | si4 | B5 | 987,767 |
62 | laβ―4/siβ4 | Aβ―5/Bβ5 | 932,328 |
61 | la4 | A5 | 880,000 |
60 | solβ―4/laβ4 | Gβ―5/Aβ5 | 830,609 |
59 | sol4 | G5 | 783,991 |
58 | faβ―4/solβ4 | Fβ―5/Gβ5 | 739,989 |
57 | fa4 | F5 | 698,456 |
56 | mi4 | E5 | 659,255 |
55 | reβ―4/miβ4 | Dβ―5/Eβ5 | 622,254 |
54 | re4 | D5 | 587,330 |
53 | doβ―4/reβ4 | Cβ―5/Dβ5 | 554,365 |
52 | do4 | C5 | 523,251 |
51 | si3 | B4 | 493,883 |
50 | laβ―3/siβ3 | Aβ―4/Bβ4 | 466,164 |
49 | la3 | A4 | 440,000 |
48 | solβ―3/laβ3 | Gβ―4/Aβ4 | 415,305 |
47 | sol3 | G4 | 391,995 |
46 | faβ―3/solβ3 | Fβ―4/Gβ4 | 369,994 |
45 | fa3 | F4 | 349,228 |
44 | mi3 | E4 | 329,628 |
43 | reβ―3/miβ3 | Dβ―4/Eβ4 | 311,127 |
42 | re3 | D4 | 293,665 |
41 | doβ―3/reβ3 | Cβ―4/Dβ4 | 277,183 |
40 | do3 | C4 (central do) | 261,626 |
39 | si2 | B3 | 246,942 |
38 | laβ―2/siβ2 | Aβ―3/Bβ3 | 233,082 |
37 | la2 | A3 | 220,000 |
36 | solβ―2/laβ2 | Gβ―3/Aβ3 | 207,652 |
35 | sol2 | G3 | 195,998 |
34 | faβ―2/solβ2 | Fβ―3/Gβ3 | 184,997 |
33 | fa2 | F3 | 174,614 |
32 | mi2 | E3 | 164,814 |
31 | reβ―2/miβ2 | Dβ―3/Eβ3 | 155,563 |
30 | re2 | D3 | 146,832 |
29 | doβ―2/reβ2 | Cβ―3/Dβ3 | 138,591 |
28 | do2 | C3 | 130,813 |
27 | si1 | B2 | 123,471 |
26 | laβ―1/siβ1 | Aβ―2/Bβ2 | 116,541 |
25 | la1 | A2 | 110,000 |
24 | solβ―1/laβ1 | Gβ―2/Aβ2 | 103,826 |
23 | sol1 | G2 | 97,9989 |
22 | faβ―1/solβ 1 | Fβ―2/Gβ2 | 92,4986 |
21 | fa1 | F2 | 87,3071 |
20 | mi1 | E2 | 82,4069 |
19 | reβ―1/miβ1 | Dβ―2/Eβ2 | 77,7817 |
18 | re1 | D2 | 73,4162 |
17 | doβ―1/reβ1 | Cβ―2/Dβ2 | 69,2957 |
16 | do1 | C2 | 65,4064 |
15 | si0 | B1 | 61,7354 |
14 | laβ―0/siβ0 | Aβ―1/Bβ1 | 58,2705 |
13 | la0 | A1 | 55,0000 |
12 | solβ―0/laβ0 | Gβ―1/Aβ1 | 51,9130 |
11 | sol0 | G1 | 48,9995 |
10 | faβ―0/solβ0 | Fβ―1/Gβ1 | 46,2493 |
9 | fa0 | F1 | 43,6536 |
8 | mi0 | E1 | 41,2035 |
7 | reβ―0/miβ0 | Dβ―1/Eβ1 | 38,8909 |
6 | re0 | D1 | 36,7081 |
5 | doβ―0/reβ0 | Cβ―1/Dβ1 | 34,6479 |
4 | do0 | C1 | 32,7032 |
3 | si-1 | B0 | 30,8677 |
2 | laβ―-1/siβ-1 | Aβ―0/Bβ0 | 29,1353 |
1 | la-1 | A0 | 27,5000 |