Chris@0
|
1 /* -*- c-basic-offset: 4 indent-tabs-mode: nil -*- vi:set ts=8 sts=4 sw=4: */
|
Chris@0
|
2
|
Chris@0
|
3 /*
|
Chris@0
|
4 Sonic Annotator
|
Chris@0
|
5 A utility for batch feature extraction from audio files.
|
Chris@0
|
6 Mark Levy, Chris Sutton and Chris Cannam, Queen Mary, University of London.
|
Chris@0
|
7 Copyright 2007-2008 QMUL.
|
Chris@0
|
8
|
Chris@0
|
9 This program is free software; you can redistribute it and/or
|
Chris@0
|
10 modify it under the terms of the GNU General Public License as
|
Chris@0
|
11 published by the Free Software Foundation; either version 2 of the
|
Chris@0
|
12 License, or (at your option) any later version. See the file
|
Chris@0
|
13 COPYING included with this distribution for more information.
|
Chris@0
|
14 */
|
Chris@0
|
15
|
Chris@0
|
16 #ifndef _FEATURE_EXTRACTION_MANAGER_H_
|
Chris@0
|
17 #define _FEATURE_EXTRACTION_MANAGER_H_
|
Chris@0
|
18
|
Chris@0
|
19 #include <vector>
|
Chris@0
|
20 #include <set>
|
Chris@0
|
21 #include <string>
|
Chris@366
|
22 #include <memory>
|
Chris@0
|
23
|
Chris@45
|
24 #include <QMap>
|
Chris@45
|
25
|
Chris@0
|
26 #include <vamp-hostsdk/Plugin.h>
|
Chris@0
|
27 #include <vamp-hostsdk/PluginSummarisingAdapter.h>
|
Chris@0
|
28 #include <transform/Transform.h>
|
Chris@0
|
29
|
Chris@0
|
30 using std::vector;
|
Chris@0
|
31 using std::set;
|
Chris@0
|
32 using std::string;
|
Chris@0
|
33 using std::pair;
|
Chris@0
|
34 using std::map;
|
Chris@366
|
35 using std::shared_ptr;
|
Chris@0
|
36
|
Chris@0
|
37 class FeatureWriter;
|
Chris@45
|
38 class AudioFileReader;
|
Chris@0
|
39
|
Chris@0
|
40 class FeatureExtractionManager
|
Chris@0
|
41 {
|
Chris@0
|
42 public:
|
Chris@263
|
43 FeatureExtractionManager(bool verbose);
|
Chris@0
|
44 virtual ~FeatureExtractionManager();
|
Chris@0
|
45
|
Chris@0
|
46 void setChannels(int channels);
|
Chris@331
|
47 void setDefaultSampleRate(sv_samplerate_t sampleRate);
|
Chris@116
|
48 void setNormalise(bool normalise);
|
Chris@0
|
49
|
Chris@0
|
50 bool setSummaryTypes(const set<string> &summaryTypes,
|
Chris@0
|
51 const Vamp::HostExt::PluginSummarisingAdapter::SegmentBoundaries &boundaries);
|
Chris@0
|
52
|
Chris@102
|
53 void setSummariesOnly(bool summariesOnly);
|
Chris@102
|
54
|
Chris@0
|
55 bool addFeatureExtractor(Transform transform,
|
Chris@0
|
56 const vector<FeatureWriter*> &writers);
|
Chris@0
|
57
|
Chris@0
|
58 bool addFeatureExtractorFromFile(QString transformXmlFile,
|
Chris@0
|
59 const vector<FeatureWriter*> &writers);
|
Chris@0
|
60
|
Chris@0
|
61 bool addDefaultFeatureExtractor(TransformId transformId,
|
Chris@0
|
62 const vector<FeatureWriter*> &writers);
|
Chris@0
|
63
|
Chris@47
|
64 // Make a note of an audio or playlist file which will be passed
|
Chris@47
|
65 // to extractFeatures later. Amongst other things, this may
|
Chris@47
|
66 // initialise the default sample rate and channel count
|
Chris@106
|
67 void addSource(QString audioSource, bool willMultiplex);
|
Chris@47
|
68
|
Chris@47
|
69 // Extract features from the given audio or playlist file. If the
|
Chris@47
|
70 // file is a playlist and force is true, continue extracting even
|
Chris@47
|
71 // if a file in the playlist fails.
|
Chris@112
|
72 void extractFeatures(QString audioSource);
|
Chris@0
|
73
|
Chris@106
|
74 // Extract features from the given audio files, multiplexing into
|
Chris@106
|
75 // a single "file" whose individual channels are mixdowns of the
|
Chris@106
|
76 // supplied sources.
|
Chris@106
|
77 void extractFeaturesMultiplexed(QStringList sources);
|
Chris@106
|
78
|
Chris@0
|
79 private:
|
Chris@263
|
80 bool m_verbose;
|
Chris@366
|
81
|
Chris@366
|
82 // The plugins that we actually "run" may be wrapped versions of
|
Chris@366
|
83 // the originally loaded ones, depending on the adapter
|
Chris@366
|
84 // characteristics we need. Because the wrappers use raw pointers,
|
Chris@366
|
85 // we need to separately retain the originally loaded shared_ptrs
|
Chris@366
|
86 // so that they don't get auto-deleted. Same goes for any wrappers
|
Chris@366
|
87 // that may then be re-wrapped. That's what these are for.
|
Chris@366
|
88 set<shared_ptr<Vamp::PluginBase>> m_allLoadedPlugins;
|
Chris@366
|
89 set<shared_ptr<Vamp::PluginBase>> m_allAdapters;
|
Chris@263
|
90
|
Chris@0
|
91 // A plugin may have many outputs, so we can have more than one
|
Chris@0
|
92 // transform requested for a single plugin. The things we want to
|
Chris@0
|
93 // run in our process loop are plugins rather than their outputs,
|
Chris@0
|
94 // so we maintain a map from the plugins to the transforms desired
|
Chris@0
|
95 // of them and then iterate through this map
|
Chris@0
|
96 typedef map<Transform, vector<FeatureWriter *> > TransformWriterMap;
|
Chris@366
|
97 typedef map<shared_ptr<Vamp::Plugin>, TransformWriterMap> PluginMap;
|
Chris@0
|
98 PluginMap m_plugins;
|
Chris@108
|
99
|
Chris@109
|
100 // When we run plugins, we want to run them in a known order so as
|
Chris@109
|
101 // to get the same results on each run of Sonic Annotator with the
|
Chris@109
|
102 // same transforms. But if we just iterate through our PluginMap,
|
Chris@109
|
103 // we get them in an arbitrary order based on pointer
|
Chris@109
|
104 // address. This vector provides an underlying order for us. Note
|
Chris@109
|
105 // that the TransformWriterMap is consistently ordered (because
|
Chris@109
|
106 // the key is a Transform which has a proper ordering) so using
|
Chris@109
|
107 // this gives us a consistent order across the whole PluginMap
|
Chris@366
|
108 vector<shared_ptr<Vamp::Plugin>> m_orderedPlugins;
|
Chris@109
|
109
|
Chris@0
|
110 // And a map back from transforms to their plugins. Note that
|
Chris@366
|
111 // this is keyed by whole transform structure, not transform ID --
|
Chris@366
|
112 // two differently configured transforms with the same ID must use
|
Chris@366
|
113 // different plugin instances.
|
Chris@366
|
114 typedef map<Transform, shared_ptr<Vamp::Plugin>> TransformPluginMap;
|
Chris@0
|
115 TransformPluginMap m_transformPluginMap;
|
Chris@0
|
116
|
Chris@0
|
117 // Cache the plugin output descriptors, mapping from plugin to a
|
Chris@0
|
118 // map from output ID to output descriptor.
|
Chris@0
|
119 typedef map<string, Vamp::Plugin::OutputDescriptor> OutputMap;
|
Chris@366
|
120 typedef map<shared_ptr<Vamp::Plugin>, OutputMap> PluginOutputMap;
|
Chris@0
|
121 PluginOutputMap m_pluginOutputs;
|
Chris@0
|
122
|
Chris@0
|
123 // Map from plugin output identifier to plugin output index
|
Chris@0
|
124 typedef map<string, int> OutputIndexMap;
|
Chris@0
|
125 OutputIndexMap m_pluginOutputIndices;
|
Chris@0
|
126
|
Chris@0
|
127 typedef set<std::string> SummaryNameSet;
|
Chris@233
|
128 SummaryNameSet m_summaries; // requested on command line for all transforms
|
Chris@233
|
129 bool m_summariesOnly; // command line flag
|
Chris@0
|
130 Vamp::HostExt::PluginSummarisingAdapter::SegmentBoundaries m_boundaries;
|
Chris@0
|
131
|
Chris@106
|
132 AudioFileReader *prepareReader(QString audioSource);
|
Chris@106
|
133
|
Chris@106
|
134 void extractFeaturesFor(AudioFileReader *reader, QString audioSource);
|
Chris@106
|
135
|
Chris@366
|
136 void writeSummaries(QString audioSource,
|
Chris@366
|
137 std::shared_ptr<Vamp::Plugin>);
|
Chris@0
|
138
|
Chris@0
|
139 void writeFeatures(QString audioSource,
|
Chris@366
|
140 std::shared_ptr<Vamp::Plugin>,
|
Chris@0
|
141 const Vamp::Plugin::FeatureSet &,
|
Chris@0
|
142 Transform::SummaryType summaryType =
|
Chris@0
|
143 Transform::NoSummary);
|
Chris@31
|
144
|
Chris@31
|
145 void testOutputFiles(QString audioSource);
|
Chris@0
|
146 void finish();
|
Chris@0
|
147
|
Chris@0
|
148 int m_blockSize;
|
Chris@331
|
149 sv_samplerate_t m_defaultSampleRate;
|
Chris@331
|
150 sv_samplerate_t m_sampleRate;
|
Chris@0
|
151 int m_channels;
|
Chris@116
|
152 bool m_normalise;
|
Chris@45
|
153
|
Chris@45
|
154 QMap<QString, AudioFileReader *> m_readyReaders;
|
Chris@0
|
155 };
|
Chris@0
|
156
|
Chris@0
|
157 #endif
|