comparison vamp/collect.py @ 117:2370b942cd32

Docs, make collect() return a dict so it can be more easily tested for shape, and rationalise some function naming etc
author Chris Cannam
date Wed, 17 Jun 2015 15:31:16 +0100
parents 9343eee50605
children b8fe675f9c3f
comparison
equal deleted inserted replaced
115:899095c8760f 117:2370b942cd32
1 #!/usr/bin/env python
2
3 # Python Vamp Host
4 # Copyright (c) 2008-2015 Queen Mary, University of London
5 #
6 # Permission is hereby granted, free of charge, to any person
7 # obtaining a copy of this software and associated documentation
8 # files (the "Software"), to deal in the Software without
9 # restriction, including without limitation the rights to use, copy,
10 # modify, merge, publish, distribute, sublicense, and/or sell copies
11 # of the Software, and to permit persons to whom the Software is
12 # furnished to do so, subject to the following conditions:
13 #
14 # The above copyright notice and this permission notice shall be
15 # included in all copies or substantial portions of the Software.
16 #
17 # THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,
18 # EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
19 # MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND
20 # NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY
21 # CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF
22 # CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION
23 # WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
24 #
25 # Except as contained in this notice, the names of the Centre for
26 # Digital Music and Queen Mary, University of London shall not be
27 # used in advertising or otherwise to promote the sale, use or other
28 # dealings in this Software without prior written authorization.
29
1 '''A high-level interface to the vampyhost extension module, for quickly and easily running Vamp audio analysis plugins on audio files and buffers.''' 30 '''A high-level interface to the vampyhost extension module, for quickly and easily running Vamp audio analysis plugins on audio files and buffers.'''
2 31
3 import vampyhost 32 import vampyhost
4 import vamp.load 33 import vamp.load
5 import vamp.process 34 import vamp.process
47 for s in stamped: 76 for s in stamped:
48 yield s 77 yield s
49 78
50 def deduce_shape(output_desc): 79 def deduce_shape(output_desc):
51 if output_desc["hasDuration"]: 80 if output_desc["hasDuration"]:
52 return "individual" 81 return "list"
53 if output_desc["sampleType"] == vampyhost.VARIABLE_SAMPLE_RATE: 82 if output_desc["sampleType"] == vampyhost.VARIABLE_SAMPLE_RATE:
54 return "individual" 83 return "list"
55 if not output_desc["hasFixedBinCount"]: 84 if not output_desc["hasFixedBinCount"]:
56 return "individual" 85 return "list"
57 if output_desc["binCount"] == 0: 86 if output_desc["binCount"] == 0:
58 return "individual" 87 return "list"
59 if output_desc["binCount"] == 1: 88 if output_desc["binCount"] == 1:
60 return "vector" 89 return "vector"
61 return "matrix" 90 return "matrix"
62 91
63 92
64 def reshape(results, sample_rate, step_size, output_desc): 93 def reshape(results, sample_rate, step_size, output_desc, shape):
65 94
66 output = output_desc["identifier"] 95 output = output_desc["identifier"]
67 shape = deduce_shape(output_desc)
68 out_step = get_feature_step_time(sample_rate, step_size, output_desc) 96 out_step = get_feature_step_time(sample_rate, step_size, output_desc)
69 97
70 if shape == "vector": 98 if shape == "vector":
71 rv = ( out_step, 99 rv = ( out_step,
72 np.array([r[output]["values"][0] for r in results], np.float32) ) 100 np.array([r[output]["values"][0] for r in results], np.float32) )
95 123
96 If the parameters dict is non-empty, the plugin will be configured 124 If the parameters dict is non-empty, the plugin will be configured
97 by setting its parameters according to the (string) key and 125 by setting its parameters according to the (string) key and
98 (float) value data found in the dict. 126 (float) value data found in the dict.
99 127
100 The structure in which the results are returned depends upon the 128 The results are returned in a dictionary which will always contain
101 output descriptor for the requested plugin output, as follows: 129 exactly one element, whose key is one of the strings "vector",
130 "matrix", or "list". Which one is used depends on the structure of
131 features set out in the output descriptor for the requested plugin
132 output:
102 133
103 * If the plugin output emits single-valued features at a fixed 134 * If the plugin output emits single-valued features at a fixed
104 sample-rate, then this function will return a tuple of step time 135 sample-rate, then the "vector" element will be used. It will
105 (the time in seconds between consecutive feature values) and a 136 contain a tuple of step time (the time in seconds between
106 one-dimensional NumPy array of feature values. An example of 137 consecutive feature values) and a one-dimensional NumPy array of
107 such a feature might be a loudness curve against time. 138 feature values. An example of such a feature might be a loudness
139 curve against time.
108 140
109 * If the plugin output emits multiple-valued features, with an 141 * If the plugin output emits multiple-valued features, with an
110 equal number of bins per feature, at a fixed sample-rate, then 142 equal number of bins per feature, at a fixed sample-rate, then
111 this function will return a tuple of step time (the time in 143 the "matrix" element will be used. It will contain a tuple of
112 seconds between consecutive feature values) and a 144 step time (the time in seconds between consecutive feature
113 two-dimensional NumPy array of feature values. An example of 145 values) and a two-dimensional NumPy array of feature values. An
114 such a feature might be a spectrogram. 146 example of such a feature might be a spectrogram.
115 147
116 * Otherwise this function will return a list of features, where 148 * Otherwise, the "list" element will be used, and will contain a
117 each feature is represented as a dictionary containing a 149 list of features, where each feature is represented as a
118 timestamp (always) and a duration (optionally), a label 150 dictionary containing a timestamp (always) and a duration
119 (string), and a 1-dimensional array of float values. 151 (optionally), a label (string), and a 1-dimensional array of
152 float values.
120 153
121 If you would prefer to obtain features as they are calculated 154 If you would prefer to obtain features as they are calculated
122 (where the plugin supports this) and with the format in which the 155 (where the plugin supports this) and with the format in which the
123 plugin returns them, via an asynchronous generator function, use 156 plugin returns them, via an asynchronous generator function, use
124 vamp.process() instead. 157 vamp.process() instead.
158
125 """ 159 """
126 160
127 plugin, step_size, block_size = vamp.load.load_and_configure(data, sample_rate, key, parameters) 161 plugin, step_size, block_size = vamp.load.load_and_configure(data, sample_rate, key, parameters)
128 162
129 if output == "": 163 if output == "":
134 168
135 ff = vamp.frames.frames_from_array(data, step_size, block_size) 169 ff = vamp.frames.frames_from_array(data, step_size, block_size)
136 170
137 results = vamp.process.process_with_initialised_plugin(ff, sample_rate, step_size, plugin, [output]) 171 results = vamp.process.process_with_initialised_plugin(ff, sample_rate, step_size, plugin, [output])
138 172
139 rv = reshape(results, sample_rate, step_size, output_desc) 173 shape = deduce_shape(output_desc)
174 rv = reshape(results, sample_rate, step_size, output_desc, shape)
140 175
141 plugin.unload() 176 plugin.unload()
142 return rv 177 return { shape : rv }
143 178