view ipcluster/sonic_annotator_vamp.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)
# Copyright 2014-2015 Daniel Wolff, City University
 
# 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

#!/usr/bin/python
# -*- coding: utf-8 -*-

from __future__ import division

import matplotlib.pyplot as plt
import numpy as np
import sys
import shutil
import os
import errno
import subprocess
import time 
import random
import hashlib


# uses a separate console process to achieve the file conversion
def vamp_host_process(argslist):
    #"""Call sonic annotator"""

    vamp_host = 'sonic-annotator'
    command = [vamp_host]
    command.extend(argslist)
    
    # which sa version?
    #p = subprocess.Popen([vamp_host, '-v'], stdout=subprocess.PIPE, stderr=subprocess.STDOUT)
    #print(p.stdout.read())


    #stdout = subprocess.check_output(command, stderr=subprocess.STDOUT)
    p = subprocess.Popen(command, stdout=subprocess.PIPE, stderr=subprocess.STDOUT)
    text = p.stdout.read()
    retcode = p.wait()
    if (retcode==0):
        print "Finished " 
        return 1
    else:
        print "Error "  + text
        return text
    
    # time.sleep(random.random()*1.0)
    #res = subprocess.call(command)
    return res


# processes the given file using a vamp plugin and sonic annotator
# @param string wav_file file to be processed
def transform((wav_file, transform_file, hash, out_path)):

    # get filename of transform
    tpath = os.path.split(transform_file)
    
    # prepare output directory:
    # get audio file subpath
    # create directory _Features for output if doesnt exist
    spath = os.path.split(wav_file)
    
    if out_path == '':
        featpath = spath[0] + '/_Analysis/' + tpath[1] + "_" + hash[:5]
    else:
        folders = spath[0].split('/')
        featpath = out_path + folders[-1] + '/' + tpath[1] + "_" + hash[:5]

    #if not os.path.exists(featpath):
    #    os.makedirs(featpath)
    print 'Creating directory' + featpath
    try:
        os.makedirs(featpath)
    except OSError as exception:
        if exception.errno!= errno.EEXIST:
            raise   
    
    # copy transform file into directory
    try:
        shutil.copy(transform_file, featpath + '/' +  tpath[1][:-3] + '_' + hash[:5] + '.n3')
    except OSError as exception:
        v = 2 # dummy statement

    #./sonic-annotator -t silvet_settings.n3 input.wav -w csv
    # prepare arguments
    
    # this is the standard output for now
    args = ['-t', transform_file, wav_file, '-w', 'csv', '-w', 'rdf',
            '--rdf-basedir',featpath,'--csv-basedir',featpath, '--rdf-many-files', '--rdf-append']
    
    # csv only
    # args = ['-t', transform_file, wav_file, '-w', 'csv','--csv-basedir',featpath]
        
    # rdf only
    # args = ['-t', transform_file, wav_file, '-w', 'rdf','--rdf-basedir',featpath,
    #        '--rdf-many-files', '--rdf-append']
    
    # ---
    # below would also output midi 
    # @todo: make language, e.g. bnased on dictionaries, that defines vamp parameters per plugin
    # ---
    #args = ['-t', transform_file, wav_file, '-w', 'csv', '-w', 'rdf', '-w', 'midi',
    #        '--rdf-basedir',featpath,'--csv-basedir',featpath, '--rdf-many-files', '--rdf-append']
    #args = ['-t', transform_file, wav_file, '-w', 'csv', '--csv-force','--csv-basedir',featpath]


    print "Analysing " + wav_file
    
    result = vamp_host_process(args)
    # execute vamp host
    return [wav_file, result]

# entry function only for testing
# provide filename, uses fixed transform
if __name__ == "__main__":

    transform_file = 'silvet_settings_fast_finetune_allinstruments.n3'
    
    # get transform hash
    BLOCKSIZE = 65536
    hasher = hashlib.sha1()
    with open(transform_file, 'rb') as afile:
        buf = afile.read(BLOCKSIZE)
        while len(buf) > 0:
            hasher.update(buf)
            buf = afile.read(BLOCKSIZE)
    hash = str(hasher.hexdigest())
    transform(sys.argv[1])
    
    if len(sys.argv) >= 2:
        wav_file = sys.argv[1]
    else:
        wav_file = 'sweep.flac'
    
    transform((wav_file,transform_file,hash))