diff pyspark/transforms/semitoneHistogram.py @ 0:e34cf1b6fe09 tip

commit
author Daniel Wolff
date Sat, 20 Feb 2016 18:14:24 +0100
parents
children
line wrap: on
line diff
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/pyspark/transforms/semitoneHistogram.py	Sat Feb 20 18:14:24 2016 +0100
@@ -0,0 +1,148 @@
+# Part of DML (Digital Music Laboratory)
+#
+# This program is free software; you can redistribute it and/or
+# modify it under the terms of the GNU General Public License
+# as published by the Free Software Foundation; either version 2
+# of the License, or (at your option) any later version.
+# 
+# This program is distributed in the hope that it will be useful,
+# but WITHOUT ANY WARRANTY; without even the implied warranty of
+# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+# GNU General Public License for more details.
+# 
+# You should have received a copy of the GNU General Public
+# License along with this library; if not, write to the Free Software
+# Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA  02110-1301  USA
+
+# -*- coding: utf-8 -*-
+__author__="hargreavess"
+
+from rdflib import Namespace, BNode, RDF, Literal
+from n3Parser import get_rdf_graph_from_n3
+from csvParser import get_dict_from_csv
+
+dml_ns = Namespace("http://dml.org/dml/cla#")
+semitone_labels = ("C", "C#", "D", "D#", "E", "F", "F#", "G", "G#", "A", "A#", "B")
+semitone_label_codes = dict()
+for octave in range(0, 11):
+
+    semitone_idx = 1
+
+    for semitone_label in semitone_labels:
+
+        semitone_label_with_octave = semitone_label + str(octave)
+        semitone_label_codes[semitone_label_with_octave] = semitone_idx
+        semitone_idx += 1
+
+
+# normalisation per clip ?
+perfilenorm = 1
+
+# Add triples representing a 'pitch histogram' result to
+# an RDF graph
+def add_semitone_histogram_to_graph(semitone_histogram, output_rdf_graph, transform, sample_count, input_f_files):
+    
+    output_bnode = BNode()
+    output_rdf_graph.add((transform, dml_ns.output, output_bnode))
+    for input_f_file in input_f_files:
+        output_rdf_graph.add((transform, dml_ns.input, input_f_file))
+    output_rdf_graph.add((output_bnode, RDF.type, dml_ns.SemitoneHistogram))
+    output_rdf_graph.add((output_bnode, dml_ns.sample_count, Literal(sample_count)))
+
+    for semitone in semitone_histogram:
+
+        bin_bnode = BNode()
+        output_rdf_graph.add((output_bnode, dml_ns.bin, bin_bnode))
+        output_rdf_graph.add((bin_bnode, dml_ns.bin_number, Literal(semitone)))
+        output_rdf_graph.add((bin_bnode, dml_ns.bin_value, Literal(semitone_histogram.get(semitone))))
+        output_rdf_graph.add((bin_bnode, dml_ns.bin_name, Literal(semitone_labels[semitone - 1])))
+
+    return output_rdf_graph
+
+# Parse an input_f_file n3 file, and generate
+# a semitone histogram
+def find_semitone_histogram(input_f_file, perfilenorm):
+    
+    piece_semitone_hist = dict()
+
+    for x in range(1, 13):
+
+        piece_semitone_hist[x] = 0
+
+    piece_duration = 0
+
+    if input_f_file.endswith('.csv'):
+
+        csv_dict = get_dict_from_csv(input_f_file, columtype = ['time','duration','pitch','velocity','label'])
+        
+        for row in csv_dict:
+            
+            duration = float(row['duration'])
+            piece_semitone_hist[semitone_label_codes[row['label']]] += duration
+            piece_duration += duration
+
+    else:
+
+        f_file_graph = get_rdf_graph_from_n3(input_f_file)
+    
+        qres = f_file_graph.query(
+        """prefix dml:     <http://dml.org/dml/cla#>
+           prefix tl:      <http://purl.org/NET/c4dm/timeline.owl#>
+           prefix af:      <http://purl.org/ontology/af/>
+            SELECT ?event ?pitch ?duration
+            WHERE {
+                ?event a af:Note .
+                ?event event:time ?event_time .
+                ?event_time tl:duration ?duration .
+                ?event rdfs:label ?pitch .
+            }""")
+
+        for row in qres:
+            
+            # parse xsd:duration type
+            tl_duration_str_len = len(row.duration)
+            tl_duration = float(row.duration[2:tl_duration_str_len-1])
+    
+            piece_semitone_hist[semitone_label_codes[row.pitch.__str__()]] += tl_duration
+            piece_duration += tl_duration
+
+    # normalise if necessary
+    if perfilenorm:
+
+        for x in range(1, 13):
+
+            piece_semitone_hist[x] /= piece_duration
+
+    return piece_semitone_hist
+
+# Parse the input_f_files n3 files, and generate
+# a collection-level semitone histogram
+def find_cla_semitone_histogram(input_f_files):
+
+    num_f_files = len(input_f_files)
+    semitone_hist = dict()
+    
+    for x in range(1, 13):
+
+        semitone_hist[x] = 0
+
+    for input_f_file in input_f_files:
+
+        piece_semitone_hist = find_semitone_histogram(input_f_file, perfilenorm)
+
+        for x in range(1, 13):
+
+            semitone_hist[x] += piece_semitone_hist[x]
+
+    # normalise the collection histogram by duration
+    hist_total = 0
+
+    for semitone_bin in semitone_hist:
+
+        hist_total += semitone_hist[semitone_bin]
+        
+    for semitone_bin in semitone_hist:
+
+        semitone_hist[semitone_bin] /= hist_total
+    
+    return (semitone_hist, num_f_files)