diff pyspark/transforms/tonicNormSemitoneHistogram.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/tonicNormSemitoneHistogram.py	Sat Feb 20 18:14:24 2016 +0100
@@ -0,0 +1,126 @@
+# 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"
+
+import rdflib
+from rdflib import Namespace, BNode, RDF, Literal
+from n3Parser import get_rdf_graph_from_n3
+from semitoneHistogram import find_semitone_histogram, semitone_labels
+from tonicHistogram import find_last_key_in_piece, find_most_common_key_in_piece
+
+dml_ns = Namespace("http://dml.org/dml/cla#")
+perfilenorm = 1
+
+# normalisation per clip ?
+perfilenorm = 1
+
+# Add triples representing a "pitch histogram" result to
+# an RDF graph
+def add_tonic_norm_semitone_histogram_to_graph(semitone_histogram, output_rdf_graph, transform, sample_count, input_f_files, input_rdf_graph):
+    
+    query = rdflib.plugins.sparql.prepareQuery(
+            """SELECT ?silvet_input ?tonic_input
+                WHERE {
+                    ?tonicNormSemitoneInput dml:silvetInputSetItem ?silvet_input .
+                    ?tonicNormSemitoneInput dml:tonicInputSetItem ?tonic_input .
+                }""", initNs = { "dml": dml_ns })
+
+    output_bnode = BNode()
+    output_rdf_graph.add((transform, dml_ns.output, output_bnode))
+    
+    for transform_input in input_f_files:
+
+        output_rdf_graph.add((transform, dml_ns.input, transform_input))
+        qres = input_rdf_graph.query(query, initBindings={'tonicNormSemitoneInput': transform_input})
+
+        for row in qres:
+
+            output_rdf_graph.add((transform_input, dml_ns.silvetInputSetItem, row.silvet_input))
+            output_rdf_graph.add((transform_input, dml_ns.tonicInputSetItem, row.tonic_input))
+
+    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 the transform_inputs (sets of n3 files), and generate
+# a tonic-normalised semitone histogram
+def find_cla_tonic_norm_semitone_histogram(transform_inputs, input_rdf_graph):
+
+    sample_count = len(transform_inputs)
+    semitone_hist = dict()
+
+    for x in range(1, 13):
+
+        semitone_hist[x] = 0
+    
+    query = rdflib.plugins.sparql.prepareQuery(
+    """SELECT ?silvet_input ?tonic_input
+        WHERE {
+            ?tonicNormSemitoneInput dml:silvetInputSetItem ?silvet_input .
+            ?tonicNormSemitoneInput dml:tonicInputSetItem ?tonic_input .
+        }""", initNs = { "dml": dml_ns })
+
+    for transform_input in transform_inputs:
+
+        qres = input_rdf_graph.query(query, initBindings={'tonicNormSemitoneInput': transform_input})
+
+        piece_semitone_hist = []
+
+        for row in qres:
+
+            piece_semitone_hist = find_semitone_histogram(row.silvet_input, perfilenorm)
+#            piece_tonic = find_last_key_in_piece(row.tonic_input)
+            piece_tonic = find_most_common_key_in_piece(row.tonic_input)
+            piece_semitone_hist = normalise_semitone_hist_by_tonic(piece_semitone_hist, piece_tonic)
+
+        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, sample_count)
+
+def normalise_semitone_hist_by_tonic(piece_semitone_hist, piece_tonic):
+        
+    tonic_norm_semitone_hist = dict()
+    
+    for semitone_bin in piece_semitone_hist:
+
+        shifted_bin = ((semitone_bin - piece_tonic) % 12) + 1
+        tonic_norm_semitone_hist[shifted_bin] = piece_semitone_hist[semitone_bin]
+        
+    return tonic_norm_semitone_hist