\documentclass[a4paper, 10pt]{report} % layout \usepackage[margin=3cm]{geometry} % 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} \chapter{Introduzione} \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=.5\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 allocare 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) { size_t lenght; uint8_t *data; if (pkt == NULL) { return -1; } length = pkt->data_size; 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}