Daniel@0
|
1 # Part of DML (Digital Music Laboratory)
|
Daniel@0
|
2 #
|
Daniel@0
|
3 # This program is free software; you can redistribute it and/or
|
Daniel@0
|
4 # modify it under the terms of the GNU General Public License
|
Daniel@0
|
5 # as published by the Free Software Foundation; either version 2
|
Daniel@0
|
6 # of the License, or (at your option) any later version.
|
Daniel@0
|
7 #
|
Daniel@0
|
8 # This program is distributed in the hope that it will be useful,
|
Daniel@0
|
9 # but WITHOUT ANY WARRANTY; without even the implied warranty of
|
Daniel@0
|
10 # MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
Daniel@0
|
11 # GNU General Public License for more details.
|
Daniel@0
|
12 #
|
Daniel@0
|
13 # You should have received a copy of the GNU General Public
|
Daniel@0
|
14 # License along with this library; if not, write to the Free Software
|
Daniel@0
|
15 # Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA
|
Daniel@0
|
16
|
Daniel@0
|
17 # -*- coding: utf-8 -*-
|
Daniel@0
|
18 __author__="hargreavess"
|
Daniel@0
|
19
|
Daniel@0
|
20 from rdflib import Namespace, BNode, RDF, Literal
|
Daniel@0
|
21 from n3Parser import get_rdf_graph_from_n3
|
Daniel@0
|
22 from csvParser import get_dict_from_csv
|
Daniel@0
|
23
|
Daniel@0
|
24 dml_ns = Namespace("http://dml.org/dml/cla#")
|
Daniel@0
|
25 semitone_labels = ("C", "C#", "D", "D#", "E", "F", "F#", "G", "G#", "A", "A#", "B")
|
Daniel@0
|
26 semitone_label_codes = dict()
|
Daniel@0
|
27 for octave in range(0, 11):
|
Daniel@0
|
28
|
Daniel@0
|
29 semitone_idx = 1
|
Daniel@0
|
30
|
Daniel@0
|
31 for semitone_label in semitone_labels:
|
Daniel@0
|
32
|
Daniel@0
|
33 semitone_label_with_octave = semitone_label + str(octave)
|
Daniel@0
|
34 semitone_label_codes[semitone_label_with_octave] = semitone_idx
|
Daniel@0
|
35 semitone_idx += 1
|
Daniel@0
|
36
|
Daniel@0
|
37
|
Daniel@0
|
38 # normalisation per clip ?
|
Daniel@0
|
39 perfilenorm = 1
|
Daniel@0
|
40
|
Daniel@0
|
41 # Add triples representing a 'pitch histogram' result to
|
Daniel@0
|
42 # an RDF graph
|
Daniel@0
|
43 def add_semitone_histogram_to_graph(semitone_histogram, output_rdf_graph, transform, sample_count, input_f_files):
|
Daniel@0
|
44
|
Daniel@0
|
45 output_bnode = BNode()
|
Daniel@0
|
46 output_rdf_graph.add((transform, dml_ns.output, output_bnode))
|
Daniel@0
|
47 for input_f_file in input_f_files:
|
Daniel@0
|
48 output_rdf_graph.add((transform, dml_ns.input, input_f_file))
|
Daniel@0
|
49 output_rdf_graph.add((output_bnode, RDF.type, dml_ns.SemitoneHistogram))
|
Daniel@0
|
50 output_rdf_graph.add((output_bnode, dml_ns.sample_count, Literal(sample_count)))
|
Daniel@0
|
51
|
Daniel@0
|
52 for semitone in semitone_histogram:
|
Daniel@0
|
53
|
Daniel@0
|
54 bin_bnode = BNode()
|
Daniel@0
|
55 output_rdf_graph.add((output_bnode, dml_ns.bin, bin_bnode))
|
Daniel@0
|
56 output_rdf_graph.add((bin_bnode, dml_ns.bin_number, Literal(semitone)))
|
Daniel@0
|
57 output_rdf_graph.add((bin_bnode, dml_ns.bin_value, Literal(semitone_histogram.get(semitone))))
|
Daniel@0
|
58 output_rdf_graph.add((bin_bnode, dml_ns.bin_name, Literal(semitone_labels[semitone - 1])))
|
Daniel@0
|
59
|
Daniel@0
|
60 return output_rdf_graph
|
Daniel@0
|
61
|
Daniel@0
|
62 # Parse an input_f_file n3 file, and generate
|
Daniel@0
|
63 # a semitone histogram
|
Daniel@0
|
64 def find_semitone_histogram(input_f_file, perfilenorm):
|
Daniel@0
|
65
|
Daniel@0
|
66 piece_semitone_hist = dict()
|
Daniel@0
|
67
|
Daniel@0
|
68 for x in range(1, 13):
|
Daniel@0
|
69
|
Daniel@0
|
70 piece_semitone_hist[x] = 0
|
Daniel@0
|
71
|
Daniel@0
|
72 piece_duration = 0
|
Daniel@0
|
73
|
Daniel@0
|
74 if input_f_file.endswith('.csv'):
|
Daniel@0
|
75
|
Daniel@0
|
76 csv_dict = get_dict_from_csv(input_f_file, columtype = ['time','duration','pitch','velocity','label'])
|
Daniel@0
|
77
|
Daniel@0
|
78 for row in csv_dict:
|
Daniel@0
|
79
|
Daniel@0
|
80 duration = float(row['duration'])
|
Daniel@0
|
81 piece_semitone_hist[semitone_label_codes[row['label']]] += duration
|
Daniel@0
|
82 piece_duration += duration
|
Daniel@0
|
83
|
Daniel@0
|
84 else:
|
Daniel@0
|
85
|
Daniel@0
|
86 f_file_graph = get_rdf_graph_from_n3(input_f_file)
|
Daniel@0
|
87
|
Daniel@0
|
88 qres = f_file_graph.query(
|
Daniel@0
|
89 """prefix dml: <http://dml.org/dml/cla#>
|
Daniel@0
|
90 prefix tl: <http://purl.org/NET/c4dm/timeline.owl#>
|
Daniel@0
|
91 prefix af: <http://purl.org/ontology/af/>
|
Daniel@0
|
92 SELECT ?event ?pitch ?duration
|
Daniel@0
|
93 WHERE {
|
Daniel@0
|
94 ?event a af:Note .
|
Daniel@0
|
95 ?event event:time ?event_time .
|
Daniel@0
|
96 ?event_time tl:duration ?duration .
|
Daniel@0
|
97 ?event rdfs:label ?pitch .
|
Daniel@0
|
98 }""")
|
Daniel@0
|
99
|
Daniel@0
|
100 for row in qres:
|
Daniel@0
|
101
|
Daniel@0
|
102 # parse xsd:duration type
|
Daniel@0
|
103 tl_duration_str_len = len(row.duration)
|
Daniel@0
|
104 tl_duration = float(row.duration[2:tl_duration_str_len-1])
|
Daniel@0
|
105
|
Daniel@0
|
106 piece_semitone_hist[semitone_label_codes[row.pitch.__str__()]] += tl_duration
|
Daniel@0
|
107 piece_duration += tl_duration
|
Daniel@0
|
108
|
Daniel@0
|
109 # normalise if necessary
|
Daniel@0
|
110 if perfilenorm:
|
Daniel@0
|
111
|
Daniel@0
|
112 for x in range(1, 13):
|
Daniel@0
|
113
|
Daniel@0
|
114 piece_semitone_hist[x] /= piece_duration
|
Daniel@0
|
115
|
Daniel@0
|
116 return piece_semitone_hist
|
Daniel@0
|
117
|
Daniel@0
|
118 # Parse the input_f_files n3 files, and generate
|
Daniel@0
|
119 # a collection-level semitone histogram
|
Daniel@0
|
120 def find_cla_semitone_histogram(input_f_files):
|
Daniel@0
|
121
|
Daniel@0
|
122 num_f_files = len(input_f_files)
|
Daniel@0
|
123 semitone_hist = dict()
|
Daniel@0
|
124
|
Daniel@0
|
125 for x in range(1, 13):
|
Daniel@0
|
126
|
Daniel@0
|
127 semitone_hist[x] = 0
|
Daniel@0
|
128
|
Daniel@0
|
129 for input_f_file in input_f_files:
|
Daniel@0
|
130
|
Daniel@0
|
131 piece_semitone_hist = find_semitone_histogram(input_f_file, perfilenorm)
|
Daniel@0
|
132
|
Daniel@0
|
133 for x in range(1, 13):
|
Daniel@0
|
134
|
Daniel@0
|
135 semitone_hist[x] += piece_semitone_hist[x]
|
Daniel@0
|
136
|
Daniel@0
|
137 # normalise the collection histogram by duration
|
Daniel@0
|
138 hist_total = 0
|
Daniel@0
|
139
|
Daniel@0
|
140 for semitone_bin in semitone_hist:
|
Daniel@0
|
141
|
Daniel@0
|
142 hist_total += semitone_hist[semitone_bin]
|
Daniel@0
|
143
|
Daniel@0
|
144 for semitone_bin in semitone_hist:
|
Daniel@0
|
145
|
Daniel@0
|
146 semitone_hist[semitone_bin] /= hist_total
|
Daniel@0
|
147
|
Daniel@0
|
148 return (semitone_hist, num_f_files)
|