Chris@137
|
1 /* -*- c-basic-offset: 4 indent-tabs-mode: nil -*- vi:set ts=8 sts=4 sw=4: */
|
Chris@137
|
2
|
Chris@137
|
3 /*
|
Chris@137
|
4 Sonic Annotator
|
Chris@137
|
5 A utility for batch feature extraction from audio files.
|
Chris@137
|
6 Mark Levy, Chris Sutton and Chris Cannam, Queen Mary, University of London.
|
Chris@137
|
7 Copyright 2007-2014 QMUL.
|
Chris@137
|
8
|
Chris@137
|
9 This program is free software; you can redistribute it and/or
|
Chris@137
|
10 modify it under the terms of the GNU General Public License as
|
Chris@137
|
11 published by the Free Software Foundation; either version 2 of the
|
Chris@137
|
12 License, or (at your option) any later version. See the file
|
Chris@137
|
13 COPYING included with this distribution for more information.
|
Chris@137
|
14 */
|
Chris@137
|
15
|
Chris@137
|
16 #include "MIDIFeatureWriter.h"
|
Chris@137
|
17
|
Chris@137
|
18 using namespace std;
|
Chris@137
|
19 using Vamp::Plugin;
|
Chris@137
|
20 using Vamp::PluginBase;
|
Chris@137
|
21
|
Chris@137
|
22 #include "base/Exceptions.h"
|
Chris@137
|
23 #include "data/fileio/MIDIFileWriter.h"
|
Chris@137
|
24
|
Chris@137
|
25 MIDIFeatureWriter::MIDIFeatureWriter() :
|
Chris@137
|
26 FileFeatureWriter(SupportOneFilePerTrackTransform |
|
Chris@137
|
27 SupportOneFilePerTrack |
|
Chris@137
|
28 SupportOneFileTotal,
|
Chris@137
|
29 "mid")
|
Chris@137
|
30 {
|
Chris@137
|
31 }
|
Chris@137
|
32
|
Chris@137
|
33 MIDIFeatureWriter::~MIDIFeatureWriter()
|
Chris@137
|
34 {
|
Chris@137
|
35 }
|
Chris@137
|
36
|
Chris@137
|
37 MIDIFeatureWriter::ParameterList
|
Chris@137
|
38 MIDIFeatureWriter::getSupportedParameters() const
|
Chris@137
|
39 {
|
Chris@137
|
40 ParameterList pl = FileFeatureWriter::getSupportedParameters();
|
Chris@137
|
41 return pl;
|
Chris@137
|
42 }
|
Chris@137
|
43
|
Chris@137
|
44 void
|
Chris@137
|
45 MIDIFeatureWriter::setParameters(map<string, string> ¶ms)
|
Chris@137
|
46 {
|
Chris@137
|
47 FileFeatureWriter::setParameters(params);
|
Chris@137
|
48 }
|
Chris@137
|
49
|
Chris@137
|
50 void
|
Chris@137
|
51 MIDIFeatureWriter::setTrackMetadata(QString, TrackMetadata)
|
Chris@137
|
52 {
|
Chris@137
|
53 cerr << "MIDIFeatureWriter::setTrackMetadata: not supported (yet?)" << endl;
|
Chris@137
|
54 }
|
Chris@137
|
55
|
Chris@137
|
56 void
|
Chris@137
|
57 MIDIFeatureWriter::write(QString trackId,
|
Chris@137
|
58 const Transform &transform,
|
Chris@137
|
59 const Plugin::OutputDescriptor& output,
|
Chris@137
|
60 const Plugin::FeatureList& features,
|
Chris@137
|
61 std::string summaryType)
|
Chris@137
|
62 {
|
Chris@140
|
63 QString transformId = transform.getIdentifier();
|
Chris@140
|
64
|
Chris@140
|
65 QString filename = getOutputFilename(trackId, transformId);
|
Chris@137
|
66 if (filename == "") {
|
Chris@140
|
67 throw FailedToOpenOutputStream(trackId, transformId);
|
Chris@137
|
68 }
|
Chris@137
|
69
|
Chris@140
|
70 if (m_rates.find(filename) == m_rates.end()) {
|
Chris@140
|
71 // If the output is FixedSampleRate, we draw the sample rate
|
Chris@140
|
72 // from the output descriptor; otherwise from the transform
|
Chris@140
|
73 float sampleRate;
|
Chris@140
|
74 if (output.sampleType == Plugin::OutputDescriptor::FixedSampleRate) {
|
Chris@140
|
75 sampleRate = output.sampleRate;
|
Chris@140
|
76 } else {
|
Chris@140
|
77 sampleRate = transform.getSampleRate();
|
Chris@140
|
78 }
|
Chris@140
|
79 m_rates[filename] = sampleRate;
|
Chris@140
|
80 }
|
Chris@140
|
81
|
Chris@140
|
82 if (m_fileTransforms[filename].find(transformId) ==
|
Chris@140
|
83 m_fileTransforms[filename].end()) {
|
Chris@140
|
84
|
Chris@140
|
85 // This transform is new to the file, give it a channel number
|
Chris@140
|
86
|
Chris@140
|
87 int channel = m_nextChannels[filename];
|
Chris@140
|
88 m_nextChannels[filename] = channel + 1;
|
Chris@140
|
89
|
Chris@140
|
90 m_fileTransforms[filename].insert(transformId);
|
Chris@140
|
91 m_channels[transformId] = channel;
|
Chris@140
|
92 }
|
Chris@140
|
93
|
Chris@140
|
94 NoteList notes = m_notes[filename];
|
Chris@140
|
95
|
Chris@140
|
96
|
Chris@140
|
97
|
Chris@140
|
98 m_notes[filename] = notes;
|
Chris@137
|
99 }
|
Chris@137
|
100
|
Chris@137
|
101 void
|
Chris@137
|
102 MIDIFeatureWriter::finish()
|
Chris@137
|
103 {
|
Chris@137
|
104 for (NoteMap::const_iterator i = m_notes.begin(); i != m_notes.end(); ++i) {
|
Chris@137
|
105
|
Chris@137
|
106 QString filename = i->first;
|
Chris@137
|
107 NoteList notes = i->second;
|
Chris@137
|
108 float rate = m_rates[filename];
|
Chris@137
|
109
|
Chris@137
|
110 TrivialNoteExportable exportable(notes);
|
Chris@137
|
111
|
Chris@137
|
112 {
|
Chris@137
|
113 MIDIFileWriter writer(filename, &exportable, rate);
|
Chris@137
|
114 if (!writer.isOK()) {
|
Chris@137
|
115 cerr << "ERROR: Failed to create MIDI writer: "
|
Chris@137
|
116 << writer.getError() << endl;
|
Chris@137
|
117 throw FileOperationFailed(filename, "create MIDI writer");
|
Chris@137
|
118 }
|
Chris@137
|
119 writer.write();
|
Chris@137
|
120 }
|
Chris@137
|
121 }
|
Chris@137
|
122 }
|
Chris@137
|
123
|