|
christopher@51
|
1 \section{Framework}
|
|
christopher@51
|
2
|
|
christopher@51
|
3 \begin{figure}[t]
|
|
christopher@51
|
4 \centering
|
|
christopher@51
|
5 \includegraphics[width=0.6\columnwidth]{images/framework.pdf}
|
|
christopher@51
|
6 \caption{Module hierarchy in the synpy toolkit: The top-level module provides a simple interface for the user to test different syncopation models. Musical constructs such as bars, velocity and note sequences, notes and time signatures are defined in the `music objects' module while support for common procedures such as sequence concatenation and subdivision is provided in `basic functions'. Models and file reading components can be interchanged as required by the user.\label{fig:framework}}
|
|
christopher@51
|
7 \end{figure}
|
|
christopher@51
|
8
|
|
christopher@54
|
9 The architecture of the toolkit is relatively simple (see Figure~\ref{fig:framework}). At the top level, syncopation values can be calculated for each bar in a given source of rhythm data; the user specifies which model to use and supplies any special parameters that are required. Sources of rhythm data can be a bar object or a list of bars (detailed below in section\ref{sec:musicobjects}) or, alternatively, the name of a file containing music data. Where a model is unable to calculate a value for a given rhythm pattern, a “None” value is recorded for that bar and the indices of unmeasured bars reported in the output. Output can optionally be saved directly to XML or JSON files.
|
|
christopher@54
|
10
|
|
christopher@54
|
11 \subsection{Music objects}
|
|
christopher@54
|
12 \label{sec:musicobjects}
|
|
christopher@54
|
13 The `music objects' module provides classes to represent musical constructs such as bars, velocity and note sequences, time signatures, and individual notes. A \code{Bar} object holds the rhythm information for a single bar of music along with its associated time signature and optional tempo and ticks-per-quarternote values. \code{Bar} objects may be initialised with either a note sequence or velocity sequence and can be chained together in the form of a doubly-linked \code{BarList} allowing syncopation models to access next and previous bars where appropriate\footnote{Several models \cite{LHL84,Keith91,Pressing97,Gomez05} implemented in the toolkit require knowledge of the contents of previous and/or next bars in order to calculate the syncopation of the current bar.}. The note sequence and velocity sequence classes are direct implementations of the sequences described in section~\ref{sec:background}. Common low-level procedures such as sequence concatenation and subdivision are provided in `basic functions'.
|
|
christopher@54
|
14
|
|
christopher@54
|
15 \subsection{File Input}
|
|
christopher@54
|
16 \label{sec:fileinput}
|
|
christopher@54
|
17 Two file reader modules are currently provided: one for for reading plain text rhythm annotation (\code{.rhy}) files and one for reading standard MIDI files (\code{.mid}). These modules open their respective file types and return a \code{BarList} object ready for processing.
|
|
christopher@54
|
18
|
|
christopher@51
|
19 \begin{figure}
|
|
christopher@51
|
20 \footnotesize{
|
|
christopher@51
|
21 \begin{minted}[frame=single,framesep=10pt]{python}
|
|
christopher@51
|
22 T{4/4} # time signature
|
|
christopher@51
|
23 TPQ{4} # ticks per quarternote
|
|
christopher@51
|
24 # Bar 1
|
|
christopher@51
|
25 Y{(0,3,2),(3,1,1),(6,2,2),(10,2,1),(12,4,1)}
|
|
christopher@51
|
26 # Bar 2
|
|
christopher@51
|
27 V{1,0,0,0.5,0,0,1,0,0,0,0.5,0,0.5,0,0,0}
|
|
christopher@51
|
28 \end{minted}
|
|
christopher@51
|
29 }
|
|
christopher@54
|
30 \caption{Example rhythm annotation \code{.rhy} file containing two bars of the Son Clave rhythm. The first is expressed as a note sequence with resolution of four ticks per quarternote; the second is the same rhythm expressed as a velocity sequence (see section~\ref{sec:background}).}
|
|
christopher@51
|
31 \label{ta:clave}
|
|
christopher@51
|
32 \end{figure}
|
|
christopher@54
|
33 Our \code{.rhy} annotation format is a light text syntax for descibing rhtyhm patterns directly in terms of note and velocity sequences (see Figure~\ref{ta:clave}).
|
|
christopher@54
|
34
|
|
christopher@54
|
35 \subsection{Plugin architecture}
|
|
christopher@54
|
36 The system architecture has been designed to allow new models to be added easily. Models have a common interface, exposing a single function that will return the syncopation value for a bar of music. Optional parameters may be supplied as a Python dictionary if the user wishes to specify settings different from the those given in the literature for a specific model.
|
|
christopher@54
|
37
|
|
christopher@51
|
38 \begin{figure}
|
|
christopher@51
|
39 \footnotesize{
|
|
christopher@51
|
40 \begin{minted}[frame=single,framesep=10pt]{python}
|
|
christopher@51
|
41 >>>from synpy import *
|
|
christopher@51
|
42 >>>import synpy.PRS as model
|
|
christopher@51
|
43 >>>calculate_syncopation(model, "clave.rhy")
|
|
christopher@51
|
44 {'bars_with_valid_output': [0, 1],
|
|
christopher@51
|
45 'mean_syncopation_per_bar': 8.625,
|
|
christopher@51
|
46 'model_name': 'PRS',
|
|
christopher@51
|
47 'number_of_bars': 2,
|
|
christopher@51
|
48 'number_of_bars_not_measured': 0,
|
|
christopher@51
|
49 'source': 'clave.rhy',
|
|
christopher@51
|
50 'summed_syncopation': 17.25,
|
|
christopher@51
|
51 'syncopation_by_bar': [8.625, 8.625]}
|
|
christopher@51
|
52 \end{minted}
|
|
christopher@51
|
53 }
|
|
christopher@54
|
54 \caption{To use the toolkit, the top level \code{synpy} module is imported along with a model (in this example Pressing \cite{Pressing97}); calling \code{calculate\_syncopation()} gives the syncopation results as shown.
|
|
christopher@51
|
55 \label{ta:example} }
|
|
christopher@51
|
56 \end{figure}
|
|
christopher@51
|
57
|
|
christopher@51
|
58
|
|
christopher@51
|
59
|
|
christopher@51
|
60
|
|
christopher@51
|
61
|
|
christopher@51
|
62
|
|
christopher@51
|
63 % \section{MIDI Input}\label{sec:midi}
|
|
christopher@51
|
64
|
|
christopher@51
|
65 % \cite{Taylor89MusicTheory}
|
|
christopher@51
|
66
|
|
christopher@51
|
67 % \section{Text Input}\label{sec:textinput}
|
|
christopher@51
|
68
|
|
christopher@51
|
69 % \begin{table*}
|
|
christopher@51
|
70 % \small{
|
|
christopher@51
|
71 % \begin{minted}[frame=single,framesep=10pt]{console}
|
|
christopher@51
|
72 % <piece> ::= [<comment-lines>] <timesig> <line> | <piece> <line>
|
|
christopher@51
|
73
|
|
christopher@51
|
74 % <comment-lines> ::= <comment> "\n" | <comment-lines> <comment> "\n"
|
|
christopher@51
|
75
|
|
christopher@51
|
76 % <line> ::= [<barlist>] [<comment>] "\n"
|
|
christopher@51
|
77
|
|
christopher@51
|
78 % <comment> ::= "#" <comment-text>
|
|
christopher@51
|
79
|
|
christopher@51
|
80 % <barlist> ::= <time-info> | [<time-info>] <bar> | <barlist> <bar>
|
|
christopher@51
|
81
|
|
christopher@51
|
82 % <time-info> ::= [<timesig>] [<ticks-per-quarter>] [<tempo>]
|
|
christopher@51
|
83
|
|
christopher@51
|
84 % <tempo> ::= "QPM{" <digits> "}"
|
|
christopher@51
|
85
|
|
christopher@51
|
86 % <ticks-per-quarter> ::= "TPQ{" <digits> "}"
|
|
christopher@51
|
87
|
|
christopher@51
|
88 % <timesig> ::= "T{" <digit> "/" <digit> "}"
|
|
christopher@51
|
89
|
|
christopher@51
|
90 % <bar> ::= "V{" <velocity-sequence> "}" | "Y{" <note-sequence> "}"
|
|
christopher@51
|
91
|
|
christopher@51
|
92 % <note-sequence> ::= <note> | <note-sequence> "," <note>
|
|
christopher@51
|
93
|
|
christopher@51
|
94 % <note> ::= "(" <digits> "," <digits> "," <digits> ")"
|
|
christopher@51
|
95
|
|
christopher@51
|
96 % <velocity-sequence> ::= <decimal> | <velocity-sequence> "," <decimal>
|
|
christopher@51
|
97
|
|
christopher@51
|
98 % <decimal> ::= "0" | "1" | "0." <digits>
|
|
christopher@51
|
99
|
|
christopher@51
|
100 % <digits> ::= <digit> | <digits> <digit>
|
|
christopher@51
|
101
|
|
christopher@51
|
102 % <digit> ::= "0" | "1" | "2" | "3" | "4" | "5" | "6" | "7" | "8" | "9"
|
|
christopher@51
|
103 % \end{minted}
|
|
christopher@51
|
104 % }
|
|
christopher@51
|
105 % \caption{Syntax of rhythm text format Backus-Naur Form}
|
|
christopher@51
|
106 % \label{ta:BNF}
|
|
christopher@51
|
107 % \end{table*}
|
|
christopher@51
|
108
|
|
christopher@51
|
109
|