annotate vamp/process.py @ 112:9343eee50605

Update to Python 3. Currently crashes during tests (and also, two tests are now failing, even with Py2).
author Chris Cannam
date Wed, 17 Jun 2015 12:35:41 +0100
parents 72be91c3cb3d
children 2370b942cd32
rev   line source
Chris@56 1 '''A high-level interface to the vampyhost extension module, for quickly and easily running Vamp audio analysis plugins on audio files and buffers.'''
Chris@56 2
Chris@56 3 import vampyhost
Chris@112 4 import vamp.frames
Chris@112 5 import vamp.load
Chris@68 6
Chris@100 7 def process_with_initialised_plugin(ff, sample_rate, step_size, plugin, outputs):
Chris@89 8
Chris@98 9 out_indices = dict([(id, plugin.get_output(id)["output_index"])
Chris@98 10 for id in outputs])
Chris@89 11 plugin.reset()
Chris@89 12 fi = 0
Chris@89 13
Chris@89 14 for f in ff:
Chris@89 15 timestamp = vampyhost.frame_to_realtime(fi, sample_rate)
Chris@89 16 results = plugin.process_block(f, timestamp)
Chris@89 17 # results is a dict mapping output number -> list of feature dicts
Chris@89 18 for o in outputs:
Chris@89 19 ix = out_indices[o]
Chris@89 20 if ix in results:
Chris@89 21 for r in results[ix]:
Chris@89 22 yield { o: r }
Chris@89 23 fi = fi + step_size
Chris@89 24
Chris@89 25 results = plugin.get_remaining_features()
Chris@89 26 for o in outputs:
Chris@89 27 ix = out_indices[o]
Chris@89 28 if ix in results:
Chris@89 29 for r in results[ix]:
Chris@89 30 yield { o: r }
Chris@89 31
Chris@89 32
Chris@112 33 def process_audio(data, sample_rate, key, output = "", parameters = {}):
Chris@98 34 """Process audio data with a Vamp plugin, and make the results from a
Chris@98 35 single plugin output available as a generator.
Chris@98 36
Chris@98 37 The provided data should be a 1- or 2-dimensional list or NumPy
Chris@98 38 array of floats. If it is 2-dimensional, the first dimension is
Chris@98 39 taken to be the channel count.
Chris@98 40
Chris@98 41 The returned results will be those calculated by the plugin with
Chris@98 42 the given key and returned through its output with the given
Chris@98 43 output identifier. If the requested output is the empty string,
Chris@98 44 the first output provided by the plugin will be used.
Chris@98 45
Chris@98 46 If the parameters dict is non-empty, the plugin will be configured
Chris@98 47 by setting its parameters according to the (string) key and
Chris@98 48 (float) value data found in the dict.
Chris@98 49
Chris@98 50 This function acts as a generator, yielding a sequence of result
Chris@98 51 features as it obtains them. Each feature is represented as a
Chris@98 52 dictionary containing, optionally, timestamp and duration
Chris@98 53 (RealTime objects), label (string), and a 1-dimensional array of
Chris@98 54 float values.
Chris@99 55
Chris@99 56 If you would prefer to obtain all features in a single output
Chris@99 57 structure, consider using vamp.collect() instead.
Chris@98 58 """
Chris@89 59
Chris@112 60 plugin, step_size, block_size = vamp.load.load_and_configure(data, sample_rate, key, parameters)
Chris@89 61
Chris@89 62 if output == "":
Chris@89 63 output = plugin.get_output(0)["identifier"]
Chris@89 64
Chris@112 65 ff = vamp.frames.frames_from_array(data, step_size, block_size)
Chris@89 66
Chris@100 67 for r in process_with_initialised_plugin(ff, sample_rate, step_size, plugin, [output]):
Chris@89 68 yield r[output]
Chris@76 69
Chris@89 70 plugin.unload()
Chris@89 71
Chris@76 72
Chris@98 73 def process_frames(ff, sample_rate, step_size, key, output = "", parameters = {}):
Chris@98 74 """Process audio data with a Vamp plugin, and make the results from a
Chris@98 75 single plugin output available as a generator.
Chris@95 76
Chris@98 77 The provided data should be an enumerable sequence of time-domain
Chris@98 78 audio frames, of which each frame is 2-dimensional list or NumPy
Chris@98 79 array of floats. The first dimension is taken to be the channel
Chris@98 80 count, and the second dimension the frame or block size. The
Chris@98 81 step_size argument gives the increment in audio samples from one
Chris@98 82 frame to the next. Each frame must have the same size.
Chris@95 83
Chris@98 84 The returned results will be those calculated by the plugin with
Chris@98 85 the given key and returned through its output with the given
Chris@98 86 output identifier. If the requested output is the empty string,
Chris@98 87 the first output provided by the plugin will be used.
Chris@95 88
Chris@98 89 If the parameters dict is non-empty, the plugin will be configured
Chris@98 90 by setting its parameters according to the (string) key and
Chris@98 91 (float) value data found in the dict.
Chris@98 92
Chris@98 93 This function acts as a generator, yielding a sequence of result
Chris@98 94 features as it obtains them. Each feature is represented as a
Chris@98 95 dictionary containing, optionally, timestamp and duration
Chris@98 96 (RealTime objects), label (string), and a 1-dimensional array of
Chris@98 97 float values.
Chris@99 98
Chris@99 99 If you would prefer to obtain all features in a single output
Chris@99 100 structure, consider using vamp.collect() instead.
Chris@98 101 """
Chris@98 102 plugin = vampyhost.load_plugin(key, sample_rate,
Chris@98 103 vampyhost.ADAPT_INPUT_DOMAIN +
Chris@98 104 vampyhost.ADAPT_BUFFER_SIZE +
Chris@98 105 vampyhost.ADAPT_CHANNEL_COUNT)
Chris@98 106
Chris@98 107 fi = 0
Chris@98 108 channels = 0
Chris@98 109 block_size = 0
Chris@98 110
Chris@98 111 if output == "":
Chris@98 112 out_index = 0
Chris@98 113 else:
Chris@98 114 out_index = plugin.get_output(output)["output_index"]
Chris@95 115
Chris@98 116 for f in ff:
Chris@95 117
Chris@98 118 if fi == 0:
Chris@98 119 channels = f.shape[0]
Chris@98 120 block_size = f.shape[1]
Chris@98 121 plugin.set_parameter_values(parameters)
Chris@98 122 if not plugin.initialise(channels, step_size, block_size):
Chris@98 123 raise "Failed to initialise plugin"
Chris@98 124
Chris@98 125 timestamp = vampyhost.frame_to_realtime(fi, sample_rate)
Chris@98 126 results = plugin.process_block(f, timestamp)
Chris@98 127 # results is a dict mapping output number -> list of feature dicts
Chris@98 128 if out_index in results:
Chris@98 129 for r in results[out_index]:
Chris@98 130 yield r
Chris@98 131
Chris@98 132 fi = fi + step_size
Chris@98 133
Chris@98 134 if fi > 0:
Chris@98 135 results = plugin.get_remaining_features()
Chris@98 136 if out_index in results:
Chris@98 137 for r in results[out_index]:
Chris@98 138 yield r
Chris@98 139
Chris@95 140 plugin.unload()
Chris@95 141
Chris@95 142
Chris@84 143 def process_multiple_outputs(data, sample_rate, key, outputs, parameters = {}):
Chris@99 144 """Process audio data with a Vamp plugin, and make the results from a
Chris@99 145 set of plugin outputs available as a generator.
Chris@99 146
Chris@99 147 The provided data should be a 1- or 2-dimensional list or NumPy
Chris@99 148 array of floats. If it is 2-dimensional, the first dimension is
Chris@99 149 taken to be the channel count.
Chris@99 150
Chris@99 151 The returned results will be those calculated by the plugin with
Chris@99 152 the given key and returned through its outputs whose identifiers
Chris@99 153 are given in the outputs argument.
Chris@99 154
Chris@99 155 If the parameters dict is non-empty, the plugin will be configured
Chris@99 156 by setting its parameters according to the (string) key and
Chris@99 157 (float) value data found in the dict.
Chris@99 158
Chris@99 159 This function acts as a generator, yielding a sequence of result
Chris@99 160 feature sets as it obtains them. Each feature set is a dictionary
Chris@99 161 mapping from output identifier to a list of features, each
Chris@99 162 represented as a dictionary containing, optionally, timestamp and
Chris@99 163 duration (RealTime objects), label (string), and a 1-dimensional
Chris@99 164 array of float values.
Chris@99 165 """
Chris@68 166
Chris@112 167 plugin, step_size, block_size = vamp.load.load_and_configure(data, sample_rate, key, parameters)
Chris@64 168
Chris@112 169 ff = vamp.frames.frames_from_array(data, step_size, block_size)
Chris@64 170
Chris@100 171 for r in process_with_initialised_plugin(ff, sample_rate, step_size, plugin, outputs):
Chris@89 172 yield r
Chris@61 173
Chris@89 174 plugin.unload()
Chris@99 175
Chris@100 176
Chris@100 177 def process_frames_multiple_outputs(ff, sample_rate, step_size, key, outputs, parameters = {}):
Chris@100 178 """Process audio data with a Vamp plugin, and make the results from a
Chris@100 179 set of plugin outputs available as a generator.
Chris@100 180
Chris@100 181 The provided data should be an enumerable sequence of time-domain
Chris@100 182 audio frames, of which each frame is 2-dimensional list or NumPy
Chris@100 183 array of floats. The first dimension is taken to be the channel
Chris@100 184 count, and the second dimension the frame or block size. The
Chris@100 185 step_size argument gives the increment in audio samples from one
Chris@100 186 frame to the next. Each frame must have the same size.
Chris@100 187
Chris@100 188 The returned results will be those calculated by the plugin with
Chris@100 189 the given key and returned through its outputs whose identifiers
Chris@100 190 are given in the outputs argument.
Chris@100 191
Chris@100 192 If the parameters dict is non-empty, the plugin will be configured
Chris@100 193 by setting its parameters according to the (string) key and
Chris@100 194 (float) value data found in the dict.
Chris@100 195
Chris@100 196 This function acts as a generator, yielding a sequence of result
Chris@100 197 feature sets as it obtains them. Each feature set is a dictionary
Chris@100 198 mapping from output identifier to a list of features, each
Chris@100 199 represented as a dictionary containing, optionally, timestamp and
Chris@100 200 duration (RealTime objects), label (string), and a 1-dimensional
Chris@100 201 array of float values.
Chris@100 202 """
Chris@100 203 plugin = vampyhost.load_plugin(key, sample_rate,
Chris@100 204 vampyhost.ADAPT_INPUT_DOMAIN +
Chris@100 205 vampyhost.ADAPT_BUFFER_SIZE +
Chris@100 206 vampyhost.ADAPT_CHANNEL_COUNT)
Chris@100 207
Chris@100 208 out_indices = dict([(id, plugin.get_output(id)["output_index"])
Chris@100 209 for id in outputs])
Chris@100 210
Chris@100 211 fi = 0
Chris@100 212 channels = 0
Chris@100 213 block_size = 0
Chris@100 214
Chris@100 215 for f in ff:
Chris@100 216
Chris@100 217 if fi == 0:
Chris@100 218 channels = f.shape[0]
Chris@100 219 block_size = f.shape[1]
Chris@100 220 plugin.set_parameter_values(parameters)
Chris@100 221 if not plugin.initialise(channels, step_size, block_size):
Chris@100 222 raise "Failed to initialise plugin"
Chris@100 223
Chris@100 224 timestamp = vampyhost.frame_to_realtime(fi, sample_rate)
Chris@100 225 results = plugin.process_block(f, timestamp)
Chris@100 226 # results is a dict mapping output number -> list of feature dicts
Chris@100 227 for o in outputs:
Chris@100 228 ix = out_indices[o]
Chris@100 229 if ix in results:
Chris@100 230 for r in results[ix]:
Chris@100 231 yield { o: r }
Chris@100 232 fi = fi + step_size
Chris@100 233
Chris@100 234 if fi > 0:
Chris@100 235 results = plugin.get_remaining_features()
Chris@100 236 for o in outputs:
Chris@100 237 ix = out_indices[o]
Chris@100 238 if ix in results:
Chris@100 239 for r in results[ix]:
Chris@100 240 yield { o: r }
Chris@100 241
Chris@100 242 plugin.unload()
Chris@100 243
Chris@100 244