Música codificada¶
L’exercici que ve a continuació, usa una codificació semblant al MIDI per representar partitures de música. La codificació que presentem seguirà els següents convenis:
La nota musical es representa per un enter de 0 fins 127. El silenci (cap nota) vindrà donat per l’enter 128. A la taula següent teniu una relació del nom de la nota (C, C#, D, D#, E, F, F#, G, G#, A, A#, B) i la seva correspondència amb l’enter que la representa i la octava on està.
Nota/Octava |
-1 |
0 |
1 |
2 |
3 |
4 |
5 |
6 |
7 |
8 |
9 |
C |
0 |
12 |
24 |
36 |
48 |
60 |
72 |
84 |
96 |
108 |
120 |
C# / Db |
1 |
13 |
25 |
37 |
49 |
61 |
73 |
85 |
97 |
109 |
121 |
D |
2 |
14 |
26 |
38 |
50 |
62 |
74 |
86 |
98 |
110 |
122 |
D# / Eb |
3 |
15 |
27 |
39 |
51 |
63 |
75 |
87 |
99 |
111 |
123 |
E |
4 |
16 |
28 |
40 |
52 |
64 |
76 |
88 |
100 |
112 |
124 |
F |
5 |
17 |
29 |
41 |
53 |
65 |
77 |
89 |
101 |
113 |
125 |
F# / Gb |
6 |
18 |
30 |
42 |
54 |
66 |
78 |
90 |
102 |
114 |
126 |
G |
7 |
19 |
31 |
43 |
55 |
67 |
79 |
91 |
103 |
115 |
127 |
G# / Ab |
8 |
20 |
32 |
44 |
56 |
68 |
80 |
92 |
104 |
116 |
– |
A |
9 |
21 |
33 |
45 |
57 |
69 |
81 |
93 |
105 |
117 |
|
A# / Bb |
10 |
22 |
34 |
46 |
58 |
70 |
82 |
94 |
106 |
118 |
|
B |
11 |
23 |
35 |
47 |
59 |
71 |
83 |
95 |
107 |
119 |
Suposem que disposem d’una llista d”strings que conté els noms de
les notes, com notes
en l’exemple següent:
>>> notes = ['C', 'C#', 'D', 'D#', 'E', 'F', 'Fa#', 'G',
... 'G#', 'A', 'A#', 'B']
Aleshores, donada una nota (un nombre natural), es pot calcular el seu
nom indexant la llista (notes
en l’exemple anterior) amb el residu
de la divisió entera per 12. Per exemple, el nom de la nota 40 és mi (E)
perquè 40 % 12 == 4
i notes[4] == 'E'
. La octava de la nota 40 és
(40 / 12) - 1 == 2
.
Alternativament, si la taula conté:
>>> notes = ['do', 'do#', 're', 're#', 'mi', 'fa', 'fa#', 'sol',
... 'sol#', 'la', 'la#', 'si']
notes[4]==”mi” en l’exemple anterior.
La durada d’una nota es codifica per un enter d’acord amb la taula que trobareu a continuació:
rodona |
blanca |
negra |
corxera |
semicorxera |
fusa |
semifusa |
garrapatea |
semigarrapatea |
256 |
128 |
64 |
32 |
16 |
8 |
4 |
2 |
1 |
On podem veure que la mínima unitat de temps és la semigarrapatea.
A partir d’aquí, proposem que resolguis el següent enunciat:
Decodificador¶
En el fitxer
notes.py
, dissenyeu les classesNotes
iNotesUK
que permetran convertir un iterador de tuples de codis de notes i temps a un iterador de tuples de noms de notes i de temps. La diferència entre les dues classes rau amb el nom que li donen les notes.Per exemple,
>>> import notes >>> part= [(48,256),(50,128),(52,64),(53,32),(55,16),(57,8),(59,4),(60,2),(62,1)] >>> for nota in notes.Notes(iter(part)): ... print(nota, end='-') ... ('do4', 'r')-('re4', 'b')-('mi4', 'n')-('fa4', 'c')-('sol4', 'sc')-('la4', 'f')-('si4', 'sf')-('do5', 'g')-('re5', 'sg')- >>> for nota in notes.NotesUK(iter(part)): ... print(nota, end='-') ... ('c4', 'r')-('d4', 'b')-('e4', 'n')-('f4', 'c')-('g4', 'sc')-('a4', 'f')-('b4', 'sf')-('c5', 'g')-('d5', 'sg')- >>> partMiM= [ (n + 25, t ) for n, t in part ] >>> for nota in notes.Notes(iter(partMiM)): ... print(nota, end='-') ... ('do6#', 'r')-('re6#', 'b')-('fa6', 'n')-('fa6#', 'c')-('sol6#', 'sc')-('la6#', 'f')-('do7', 'sf')-('do7#', 'g')-('re7#', 'sg')-
- class notes.Notes(codi)¶
A partir de l’iterador codi genera un objecte iterable de tuples amb el nom llatí de la nota i nom de temps que representen els dos valors de les tuples de l’iterador codi.
Atributs de classe:
- class notes.NotesUK(codi)¶
A partir de l’iterador codi genera un objecte iterable de tuples amb el nom anglosaxó de la nota i nom de temps que representen els dos valors de les tuples de l’iterador codi.
Atributs de classe:
Ens cal definir dos mètodes per la classe: __init__ on guardarem com a atribut el paràmetre codi, i el mètode __iter__ on escriurem un generador que faci l’iterador demanat.