Package jazzparser :: Package backoff :: Package ngram :: Module midi
[hide private]
[frames] | no frames]

Source Code for Module jazzparser.backoff.ngram.midi

  1  """Combination of HmmPath with chord recognizer 
  2   
  3  Simple extension of baseline to MIDI input by getting a lattice from an  
  4  HP chord labeler and decoding the baseline on the resulting lattice. 
  5   
  6  """ 
  7  """ 
  8  ============================== License ======================================== 
  9   Copyright (C) 2008, 2010-12 University of Edinburgh, Mark Granroth-Wilding 
 10    
 11   This file is part of The Jazz Parser. 
 12    
 13   The Jazz Parser is free software: you can redistribute it and/or modify 
 14   it under the terms of the GNU General Public License as published by 
 15   the Free Software Foundation, either version 3 of the License, or 
 16   (at your option) any later version. 
 17    
 18   The Jazz Parser is distributed in the hope that it will be useful, 
 19   but WITHOUT ANY WARRANTY; without even the implied warranty of 
 20   MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the 
 21   GNU General Public License for more details. 
 22    
 23   You should have received a copy of the GNU General Public License 
 24   along with The Jazz Parser.  If not, see <http://www.gnu.org/licenses/>. 
 25   
 26  ============================ End license ====================================== 
 27   
 28  """ 
 29  __author__ = "Mark Granroth-Wilding <mark.granroth-wilding@ed.ac.uk>"  
 30   
 31  from StringIO import StringIO 
 32   
 33  from jazzparser.utils.options import ModuleOption, ModuleOptionError 
 34  from jazzparser.grammar import get_grammar 
 35  from jazzparser.utils.strings import str_to_bool 
 36  from jazzparser.misc.chordlabel.hmm import HPChordLabeler 
 37   
 38  from .hmmpath import HmmPathBuilder 
 39  from ..base import BackoffBuilder 
40 41 -class MidiHmmPathBuilder(BackoffBuilder):
42 """ 43 Use an HP chord labeler to get a chord lattice and HmmPath on the lattice. 44 """ 45 MODEL_CLASS = None 46 BUILDER_OPTIONS = HmmPathBuilder.BUILDER_OPTIONS + [ 47 ModuleOption('labeling_model', 48 help_text="Model name for chord labeler", 49 usage="labeling_model=M, where M is a trained chord labeling model", 50 required=True), 51 ModuleOption('partition_labeler', filter=str_to_bool, 52 help_text="By default, the chord labeling model is not loaded "\ 53 "with a partition number, even if the supertagging model is. "\ 54 "If this is True, the same partition number will be used for "\ 55 "the labeler's model as was given to the supertagger.", 56 usage="partition_labeler=B, where B is True or False", 57 default=False), 58 ModuleOption('latticen', filter=int, 59 help_text="Number of chords per segment to get in the lattice", 60 usage="latticen=N, where N is an integer", 61 default=3), 62 ModuleOption('lattice_beam', filter=float, 63 help_text="Beam ratio to apply to the chord lattice. Removes all "\ 64 "chord labels with probability < ratio * highest probability "\ 65 "in timestep. Default: 1e-5", 66 usage="lattice_beam=F, where F is a float < 1.0 (e.g. 1e-6)", 67 default=1e-5), 68 ModuleOption('label_viterbi', filter=str_to_bool, 69 help_text="Use Viterbi decoding instead of forward-backward. "\ 70 "Only one chord will be returned for every timestep, no "\ 71 "matter what latticen is. Default: False", 72 usage="viterbi=B, where B is True or False", 73 default=False), 74 ] 75 INPUT_TYPES = ['segmidi'] 76
77 - def __init__(self, input, options={}, grammar=None, *args, **kwargs):
78 super(MidiHmmPathBuilder, self).__init__(input, options, *args, **kwargs) 79 if grammar is None: 80 self.grammar = get_grammar() 81 else: 82 self.grammar = grammar 83 84 # Make a copy of the options that we will pass through to HmmPath 85 options = self.options.copy() 86 # Remove the options that the tagger doesn't need 87 labeling_model_name = options.pop('labeling_model') 88 latticen = options.pop('latticen') 89 beam_ratio = options.pop('lattice_beam') 90 viterbi = options.pop('label_viterbi') 91 partition_labeler = options.pop('partition_labeler') 92 93 # Use an HP chord labeler to label the MIDI data 94 # Partition the labeling model if requested and a partition number 95 # was given for the supertagger 96 if partition_labeler and 'partition' in self.options and \ 97 self.options['partition'] is not None: 98 labeling_model_name += "%d" % self.options['partition'] 99 100 # First run the chord labeler on the MIDI input 101 # Load a labeling model 102 labeler = HPChordLabeler.load_model(labeling_model_name) 103 self.labeler = labeler 104 # Get chord labels from the model: get a lattice of possible chords 105 lattice = labeler.label_lattice(input, options={ 106 'n' : latticen, 107 'nokey' : True, 108 'viterbi' : viterbi }, 109 corpus=True) 110 # Store the lattice for later reference 111 self.lattice = lattice 112 # Beam the lattice to get rid of very low probability labels 113 lattice.apply_ratio_beam(ratio=beam_ratio) 114 115 # Tag the lattice 116 self.hmmpath = HmmPathBuilder(lattice, options, grammar, *args, **kwargs)
117 118 @property
119 - def num_paths(self):
120 return len(self.hmmpath._paths)
121
122 - def get_tonal_space_path(self, rank=0):
123 if rank >= len(self.hmmpath._paths): 124 return None 125 else: 126 return self.hmmpath._paths[rank]
127