Mercurial > hg > dml-open-backendtools
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)