1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
189
190
191
192
193
194
195
196
197
198
199
200
201
202
203
204
205
206
207
208
209
210
211
212
213
214
215
216
217
218
219
220
221
222
223
224
225
226
227
228
229
230
231
232
233
234
235
236
237
238
239
240
241
242
243
244
245
246
247
248
249
250
251
252
253
254
255
256
257
258
259
260
261
262
263
264
265
266
267
268
269
270
271
272
273
274
275
276
277
278
279
280
281
282
283
284
285
286
287
288
289
290
291
292
293
294
295
|
\documentclass[a4paper, 10pt, conference]{IEEEtran}
% language / document
\usepackage[italian]{babel}
% font
\usepackage{lmodern} % font
\usepackage{anyfontsize}
% urls
\usepackage{url}
\urlstyle{tt}
% figures
\usepackage{float} % place figures
\usepackage{pgfplots} % plts
\usepackage{tikz-timing}
\usepackage[european]{circuitikz} % circuiti elettrici
\usepackage{tikzscale} % scale tikz images
\pgfplotsset{compat=1.15}
% tables
\usepackage{array}
\usepackage{booktabs}
% code
\usepackage{listings}
% parskip
\setlength{\parskip}{1em}
% metadata
\title{Xilofono MIDI}
\author{Naoki Pross, \textit{SAM Bellinzona}}
\begin{document}
\maketitle
%\begin{abstract}
%\end{abstract}
\section{Requisiti}
Lo Xilofono digitale \`e un dispositivo in grado di rilevare le note suonate dall'utente per poi salvarle in un dispositivo esterno in formato MIDI.
Esso \`e costruito utilizzando parti da uno Xilofono ``Sonor Tag 25'' modificato con dei circuiti di misura.
\section{Elemento piezoelettrico}
Il sensore piezoelettrico quando colpito genera una tensione oscillante come mostrato nella figura \ref{fig:piezo-waveform}. La tensione generata ha bisogno solamente di una correzzione minimale per poter entrare in un circuito di misura CMOS. \`E necessario quindi rimuovere o smorzare la parte negativa dell'oscillazione.
\begin{figure}[H] \centering
\begin{tikzpicture}
\begin{axis}[
ylabel={Tensione $u_x(t)$ [V]},
xlabel={Tempo $t$ [s]},
xmin=-0.05, xmax=0.4,
grid=major,
grid style=dotted
]
\addplot [color=black, smooth, thick] table [
mark=none,
each nth point=2,
x=Time, y=Smooth,
col sep=semicolon
] {data/piezo-waveform.csv};
\end{axis}
\end{tikzpicture}
\caption{
Tensione sull'elemento piezolettrico quando viene colpito.
\label{fig:piezo-waveform}
}
\end{figure}
\section{Circuito di misura}
Per ogni listello della tastiera dello strumento \`e presente un circuito di misura composto dall'elemento piezoelettrico, per rilevare il colpo, e dei diodi che limitano la tensione tra \(V_{cc}\) (5V) e \(V_{ss}\)(0V).
Il piezoelettrodo utilizzato \`e un Murata 7BB-20-06 con una frequenza di risonanza di \(6.3\pm 0.6~\mathrm{kHz}\).
\begin{figure}[H] \centering
\includegraphics[width=\linewidth]{figures/reduced-circ.tikz}
\caption{Circuito di misura}
\end{figure}
\section{Microcontroller}
Per gestire i segnali forniti dai circuiti di misura \`e presente un PIC18F44K22, che esporta le informazioni delle note suonate in formato MIDI via seriale.
\section{Protocollo MIDI}
L'acronimo MIDI (Musical Instrument Digital Interface) indica il protocollo standard per l'interazione degli strumenti musicali elettronici, anche tramite un computer\cite{wiki:midi}.
\subsection{Specifiche hardware}
Il protocollo MIDI \`e composto da pi\`u parti per il trasporto, i file e per l'hardware. Per questo progetto \`e utilizzato unicamente il protocollo di trasporto, le informazioni sono trasmesse attraverso una porta seriale RS232 a due fili, utilizzando il connettore di uscita DIN 5 Pin (DIN 41524).
\begin{figure}[H]
\centering
\begin{tikzpicture}[scale=1.5]
\timing at (0,1) {L4D{Status}4D{D0}4D{D1}4D{D2}4D{...}};
\timing at (0,.5) {L4D{0x90}4D{0x3C}4D{0x7F}4L4L};
%\timing at (0,0) {
\end{tikzpicture}
\caption{Esempio di trasmissione MIDI}
\end{figure}
Il formato originale per la trasmissione seriale MIDI \`e un \emph{current loop} a cui il valore logico 0 \`e assegnato al passaggio di una corrente di 5 mA\cite{gweep}.
\subsection{Specifiche software}
La trasmissione seriale MIDI \`e definita come standard a \(31'250\pm 1\%\) baud con 1 start bit, frame da 8 bit e 1 stop bit. Un messaggio (o pacchetto)\footnote{In questo documento i due termini sono utilizzati intercambiabilmente.} MIDI incomincia con uno \emph{Status Byte} (vedi tabella \ref{tab:status-bytes}) seguito se necessario da altri byte di dati.
Per migliorare le prestazioni \`e definito che se il byte di status viene omesso, il dispositivo ricevente assume che lo status sia uguale all'ultimo messaggio ricevuto (running status).
\subsection{Protocollo -- Messaggi di canale}
Il nibble (4 bit) basso del byte di status viene utilizzato per la selezione del canale. I 16 canali disponibili sono controllati mandando dei pacchetti di tipo \emph{channel voice} o di tipo \emph{channel mode}.
\subsubsection{Channel mode}
Un messaggio con status \texttt{0xBn} se il primo dato \(D_0 \geq 120\) \`e detto un pacchetto \emph{channel mode}. Il pacchetto viene interpretato come un impostazione del \emph{base channel}, ossia modifica le impostazioni dell'intero canale.
\begin{figure}[H]
\centering
\begin{tikzpicture}[scale=2]
\timing at (0, 0) {L5D{1000 nnnn}5D{0111 1011}5D{ 0000 0000 }L};
\end{tikzpicture}
\caption{Esempio di messaggio channel mode ANO (all notes off) che ha \(D_0 = 123\) (\(\geq 120\))}
\end{figure}
\subsubsection{Channel voice}
I messaggi con status tra \texttt{0x8n} e \texttt{0xEn}, esclusi i pacchetti channel voice, sono detti pacchetti \emph{channel voice} e servono per indicare al dispositivo come deve suonare una nota (controllo della voce).
\begin{figure}[H]
\centering
\begin{tikzpicture}[scale=2]
\timing at (0, 0) {L5D{1000 nnnn}5D{ 0111 0xxx }L};
\end{tikzpicture}
\end{figure}
\subsection{Protocollo -- Messaggi di sistema}
I messaggi di sistema generalmente sono utilizzati per impostare la configurazione del dispositivo ricevente e non sono quindi utilizzati per riprodurre suoni o note.
I messaggi di sistema sono a loro volta suddivisi in 3 tipi.
\subsubsection{System Exclusive}
\subsubsection{System Common}
\subsubsection{System Real Time}
\subsection{Messaggi di interesse per il progetto}
\section{Implementazione dell'API MIDI}
\subsection{API multipiattaforma}
Per il progetto \`e stato implementato un API (Application Programming Interface) che permette di generare in maniera conveniente dei messaggi MIDI.
La struttura dati \texttt{midi\_message\_t} \`e allineata con dei bit-fields\cite[P.150]{xc8} ed un flexible array member (\texttt{data[]}) in modo da poter essere mandata direttamente come \texttt{void*} (void pointer) attraverso la seriale.
% replace with lstings?
\begin{minipage}{\linewidth}
\begin{verbatim}
typedef struct {
unsigned status :4;
unsigned channel :4;
uint8_t data[];
} midi_message_t;
\end{verbatim}
\end{minipage}
Sono definite in oltre le seguenti enumerazioni per migliorare la leggibilit\`a del codice.
\begin{minipage}{\linewidth}
\begin{verbatim}
typedef enum {
C = 0, // Do
D = 1, // Re
E = 2, // Mi
F = 3, // Fa
G = 4, // Sol
A = 5, // La
B = 6, // Si
} midi_note_t;
\end{verbatim}
\end{minipage}
\begin{minipage}{\linewidth}
\begin{verbatim}
typedef enum {
NOTE_ON = 0x8,
NOTE_OFF = 0x9,
POLYPHONIC_KEYPRESS = 0xA,
CONTROLLER = 0xB,
PROGRAM_CHANGE = 0xC,
CHANNEL_PRESSURE = 0xD,
PITCH_BLEND = 0xF
} midi_status_t;
\end{verbatim}
\end{minipage}
\subsection{API per dispositivi senza allocazione di memoria dinamica}
Purtroppo alcuni microcontrollori, tra cui il PIC18F45K22 non supportano l'allocazione di memoria dinamica necessaria per instanziare il flexible array member della struttura \texttt{midi\_message\_t}. Dunque la libreria MIDI \`e stata modificata per utilizzare la struttura dati come segue.
\begin{minipage}{\linewidth}
\begin{verbatim}
typedef struct {
unsigned status :4;
unsigned channel :4;
size_t data_size;
uint8_t data[MIDI_DATA_MAX_SIZE];
} midi_message_t;
\end{verbatim}
\end{minipage}
Nello specifico, nel file header si presenta nel seguente modo.
La macro \texttt{MIDI\_DYNAMIC\_MEMORY\_ALLOC}, normalmente non definita, indica all'API che pu\`o usufruire dell'allocazione dinamica. Quindi che le funzioni \texttt{malloc} e \texttt{free} siano implementate.
\begin{minipage}{\linewidth}
\begin{verbatim}
typedef struct {
unsigned status :4;
unsigned channel :4;
#ifdef MIDI_DYNAMIC_MEMORY_ALLOC
uint8_t data[];
#else
size_t data_size;
uint8_t data[MIDI_DATA_MAX_SIZE];
#endif
} midi_message_t;
\end{verbatim}
\end{minipage}
Lo svantaggio di questa interfaccia \`e che non rende possibile mandare direttamente i pacchetti MIDI come un qualsiasi buffer. \`E necessario infatti implementare una funzione specifica per ogni piattaforma.
A seguire un esempio abbastanza generico per le piattaforme che implementano la funzione \texttt{putch}.
\begin{minipage}{\linewidth}
\begin{verbatim}
int eusart_write_midi(midi_message_t *pkt)
{
if (pkt == NULL) {
return -1;
}
if (pkt->data == NULL) {
return -2;
}
size_t length = pkt->data_size;
uint8_t *data = pkt->data;
putch((pkt->status<<4) | pkt->channel);
while (length--) {
putch(*(data++));
}
return 0;
}
\end{verbatim}
\end{minipage}
\begin{table*}[ht]
\caption{Sommario degli status bytes\label{tab:status-bytes}}
\centering
\begin{tabular}{>{\tt}c >{\tt}c c l}
\toprule
\multicolumn{2}{c}{\bfseries Status Byte} & \bfseries Data size & \bfseries Descrizione \\
\footnotesize Hex & \footnotesize Bin & & \\
\midrule
8n & 1000 nnnn & 2 & Note off \\
9n & 1001 nnnn & 2 & Note on \\
An & 1010 nnnn & 2 & Polyphonic key (Aftertouch) \\
Bn & 1011 nnnn & 2 & Controller \( D_0 < 120 \) \\
Cn & 1100 nnnn & 1 & Program change \\
Dn & 1101 nnnn & 1 & Channel pressure (Aftertouch) \\
En & 1110 nnnn & 2 & pitch bend \\
\midrule
Bn & 1011 nnnn & 2 & Select channel mode \(D_0 \geq 120 \) \\
\midrule
F0 & 1111 0000 & variable & System exclusive \\
Fx & 1111 0xxx & 0 to 2 & System common \\
Fx & 1111 1xxx & 0 & System real time \\
\bottomrule
\end{tabular}
\end{table*}
\begin{thebibliography}{9}
\bibitem{wiki:midi}
\textit{Musical Instrument Digital Interface},
[online], (visitato il 18.01.2018) \\
\url{https://it.wikipedia.org/w/index.php?title=Musical_Instrument_Digital_Interface}
\bibitem{somascape}
\textit{Guide to the MIDI Software Specification},
[online], (visitato il 18.01.2018) \\
\url{http://www.somascape.org/midi/tech/spec.html}
\bibitem{gweep}
\textit{The MIDI Specification},
[online], (visistato il 22.01.2018) \\
\url{http://www.gweep.net/~prefect/eng/reference/protocol/midispec.html}
\bibitem{xc8}
\textit{MPLAB® XC8 C Compiler User’s Guide},
2012 Microchip Technology Inc,
ISBN: 978-1-62076-375-9,
http://ww1.microchip.com/downloads/en/DeviceDoc/52053B.pdf
\end{thebibliography}
\end{document}
|