view 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 source
# 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