/[svn]/libgig/trunk/src/sf2dump.cpp
ViewVC logotype

Contents of /libgig/trunk/src/sf2dump.cpp

Parent Directory Parent Directory | Revision Log Revision Log


Revision 2204 - (show annotations) (download)
Mon Jul 11 17:23:54 2011 UTC (12 years, 8 months ago) by iliev
File size: 12864 byte(s)
* sf2: some fixes to sf2dump
* sf2: ToSeconds(), ToPermilles(), ToHz() are now exposed to the C++ API

1 /***************************************************************************
2 * *
3 * libgig - C++ cross-platform Gigasampler format file access library *
4 * *
5 * Copyright (C) 2003-2009 by Christian Schoenebeck *
6 * <cuse@users.sourceforge.net> *
7 * Copyright (C) 2009 by Grigor Iliev <grigor@grigoriliev.com> *
8 * *
9 * This program is part of libsf2. *
10 * *
11 * This program is free software; you can redistribute it and/or modify *
12 * it under the terms of the GNU General Public License as published by *
13 * the Free Software Foundation; either version 2 of the License, or *
14 * (at your option) any later version. *
15 * *
16 * This program is distributed in the hope that it will be useful, *
17 * but WITHOUT ANY WARRANTY; without even the implied warranty of *
18 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the *
19 * GNU General Public License for more details. *
20 * *
21 * You should have received a copy of the GNU General Public License *
22 * along with this program; if not, write to the Free Software *
23 * Foundation, Inc., 59 Temple Place, Suite 330, Boston, *
24 * MA 02111-1307 USA *
25 ***************************************************************************/
26
27 #ifdef HAVE_CONFIG_H
28 #include <config.h>
29 #endif
30
31 #include <iostream>
32 #include <cstdlib>
33 #include <string>
34 #include <sstream>
35
36 #include "SF.h"
37 #include "helper.h"
38
39 using namespace std;
40
41 string Revision();
42 void PrintVersion();
43 void PrintSamples(sf2::File* sf);
44 void PrintInstruments(sf2::File* sf);
45 void PrintPeresets(sf2::File* sf);
46 void PrintRegion(int idx, sf2::Region* reg);
47 void PrintModulatorItem(sf2::ModulatorItem* mod);
48 void PrintModulator(sf2::Modulator& mod);
49 void PrintUsage();
50 void PrintSfInfo(sf2::File* sf);
51
52 string GetControllerType(sf2::Modulator& mod);
53 string GetControllerSource(sf2::Modulator& mod);
54 string GetSampleType(uint16_t type);
55
56 template<class T> inline string GetValue(T val) {
57 if (val == sf2::NONE) return "NONE";
58 return ToString(val);
59 }
60
61 int main(int argc, char *argv[])
62 {
63 if (argc <= 1) {
64 PrintUsage();
65 return EXIT_FAILURE;
66 }
67 if (argv[1][0] == '-') {
68 switch (argv[1][1]) {
69 case 'v':
70 PrintVersion();
71 return EXIT_SUCCESS;
72 }
73 }
74 FILE* hFile = fopen(argv[1], "r");
75 if (!hFile) {
76 cout << "Invalid file argument!" << endl << endl;
77 void PrintUsage();
78 return EXIT_FAILURE;
79 }
80 fclose(hFile);
81 try {
82 RIFF::File* riff = new RIFF::File(argv[1]);
83 sf2::File* sf = new sf2::File(riff);
84 PrintSfInfo(sf);
85 PrintSamples(sf);
86 cout << endl;
87 PrintInstruments(sf);
88 PrintPeresets(sf);
89 delete sf;
90 delete riff;
91 }
92 catch (RIFF::Exception e) {
93 e.PrintMessage();
94 return EXIT_FAILURE;
95 }
96 catch (...) {
97 cout << "Unknown exception while trying to parse file." << endl;
98 return EXIT_FAILURE;
99 }
100
101 return EXIT_SUCCESS;
102 }
103
104 void PrintSfInfo(sf2::File* sf) {
105 cout << "File info:" << endl;
106 cout << "\tVersion: " << sf->pInfo->pVer->Major << "." << sf->pInfo->pVer->Minor << endl;
107 cout << "\tBank Name: " << sf->pInfo->BankName << endl;
108 cout << "\tSound Engine: " << sf->pInfo->SoundEngine << endl;
109 cout << "\tSound ROM Name: " << sf->pInfo->RomName << endl;
110 cout << "\tSound ROM Version: " << sf->pInfo->pRomVer->Major << "." << sf->pInfo->pRomVer->Minor << endl;
111 cout << "\tCreation Date: " << sf->pInfo->CreationDate << endl;
112 cout << "\tEngineers: " << sf->pInfo->Engineers << endl;
113 cout << "\tProduct: " << sf->pInfo->Product << endl;
114 cout << "\tCopyright: " << sf->pInfo->Copyright << endl;
115 cout << "\tComments: " << sf->pInfo->Comments << endl;
116 cout << "\tSoftware: " << sf->pInfo->Software << endl << endl;
117 }
118
119 void PrintSamples(sf2::File* sf) {
120 cout << "Samples (" << sf->GetSampleCount() << "): " << endl;
121 for (int i = 0; i < sf->GetSampleCount(); i++) {
122 sf2::Sample* s = sf->GetSample(i);
123 cout << "\t" << s->Name << " (Depth: " << ((s->GetFrameSize() / s->GetChannelCount()) * 8);
124 cout << ", SampleRate: " << s->SampleRate;
125 cout << ", Pitch: " << ((int)s->OriginalPitch);
126 cout << ", Pitch Correction: " << ((int)s->PitchCorrection )<< endl;
127 cout << "\t\tStart: " << s->Start << ", End: " << s->End;
128 cout << ", Start Loop: " << s->StartLoop << ", End Loop: " << s->EndLoop << endl;
129 cout << "\t\tSample Type: " << GetSampleType(s->SampleType) << ", Sample Link: " << s->SampleLink << ")" << endl;
130 }
131 }
132
133 void PrintInstruments(sf2::File* sf) {
134 cout << "Instruments (" << sf->GetInstrumentCount() << "): " << endl;
135 for (int i = 0; i < sf->GetInstrumentCount(); i++) {
136 sf2::Instrument* instr = sf->GetInstrument(i);
137 cout << "\t" << instr->Name << " (";
138 cout << "Instrument bag: " << instr->InstBagNdx << ")" << endl;
139 cout << "\t Regions (" << instr->GetRegionCount() << ")" << endl;
140
141 if (instr->pGlobalRegion) PrintRegion(-1, instr->pGlobalRegion);
142
143 for (int j = 0; j < instr->GetRegionCount(); j++) {
144 PrintRegion(j, instr->GetRegion(j));
145 }
146 cout << endl;
147 }
148 }
149
150 void PrintPeresets(sf2::File* sf) {
151 cout << "Presets (" << sf->GetPresetCount() << "): " << endl;
152 for (int i = 0; i < sf->GetPresetCount(); i++) { /* exclude the terminal header - EOP */
153 sf2::Preset* p = sf->GetPreset(i);
154 cout << "\t" << p->Name << " (Preset: " << p->PresetNum << ", Bank: " << p->Bank;
155 cout << ", Preset bag: " << p->PresetBagNdx << ")" << endl;
156
157 if (p->pGlobalRegion) PrintRegion(-1, p->pGlobalRegion);
158
159 for (int j = 0; j < p->GetRegionCount(); j++) {
160 PrintRegion(j, p->GetRegion(j));
161 }
162 cout << endl;
163 }
164 }
165
166 void PrintRegion(int idx, sf2::Region* reg) {
167 if (idx == -1) cout << "\t\tGlobal Region " << endl;
168 else cout << "\t\tRegion " << idx << endl;
169 sf2::Sample* s = reg->GetSample();
170 if (s != NULL) {
171 cout << "\t\t Sample: " << s->Name << ", Fine Tune: " << reg->fineTune;
172 if (reg->coarseTune) cout << ", Coarse Tune: " << reg->coarseTune;
173 if (reg->overridingRootKey != -1) cout << ", Overriding Root Key: " << reg->overridingRootKey;
174 if (reg->HasLoop) {
175 cout << ", Loop Start: " << reg->LoopStart << ", Loop End: " << reg->LoopEnd;
176 }
177 cout << endl;
178 }
179 cout << "\t\t Key range=";
180 if (reg->loKey == ::sf2::NONE && reg->hiKey == ::sf2::NONE) cout << "None";
181 else cout << reg->loKey << "-" << reg->hiKey;
182 cout << ", Velocity range=";
183 if (reg->minVel == ::sf2::NONE && reg->maxVel == ::sf2::NONE) cout << "None";
184 else cout << reg->minVel << "-" << reg->maxVel;
185
186 if (reg->exclusiveClass) cout << ", Exclusive group=" << reg->exclusiveClass;
187 cout << endl;
188
189 if (reg->pInstrument != NULL) {
190 cout << "\t\t Instrument: " << reg->pInstrument->Name << endl;
191 }
192
193 cout << "\t\t\tEG1PreAttackDelay=" << GetValue(reg->GetEG1PreAttackDelay());
194 cout << "s, EG1Attack=" << GetValue(reg->GetEG1Attack());
195 cout << "s, EG1Hold=" << GetValue(reg->GetEG1Hold()) << "s, EG1Decay=";
196 cout << GetValue(reg->GetEG1Decay()) << "s, EG1Sustain=" << GetValue(reg->GetEG1Sustain());
197 cout << "permille, EG1Release=" << GetValue(reg->GetEG1Release()) << "s" << endl;
198
199 cout << "\t\t\tEG2PreAttackDelay=" << GetValue(reg->GetEG2PreAttackDelay());
200 cout << "s, EG2Attack=" << GetValue(reg->GetEG2Attack());
201 cout << "s, EG2Hold=" << GetValue(reg->GetEG2Hold()) << "s, EG2Decay=";
202 cout << GetValue(reg->GetEG2Decay()) << "s, EG2Sustain=";
203 cout << GetValue(reg->GetEG2Sustain()) << "permille, EG2Release=";
204 cout << GetValue(reg->GetEG2Release()) << "s" << endl;
205
206 cout << "\t\t Modulation LFO: Delay=" << ::sf2::ToSeconds(reg->delayModLfo) << "s, Frequency=";
207 cout << ::sf2::ToHz(reg->freqModLfo) << "Hz, LFO to Volume=" << (reg->modLfoToVolume / 10) << "dB";
208 cout << ", LFO to Filter Cutoff=" << reg->modLfoToFilterFc;
209 cout << ", LFO to Pitch=" << reg->modLfoToPitch << endl;
210
211 cout << "\t\t Vibrato LFO: Delay=" << ::sf2::ToSeconds(reg->delayVibLfo) << "s, Frequency=";
212 cout << ::sf2::ToHz(reg->freqVibLfo) << "Hz, LFO to Pitch=" << reg->vibLfoToPitch << endl;
213
214 cout << "\t\t\tModulators (" << reg->modulators.size() << ")" << endl;
215
216 for (int i = 0; i < reg->modulators.size(); i++) {
217 cout << "\t\t\tModulator " << i << endl;
218 PrintModulatorItem(&reg->modulators[i]);
219 }
220 }
221
222 void PrintModulatorItem(sf2::ModulatorItem* mod) {
223 cout << "\t\t\t ModSrcOper" << endl;
224 PrintModulator(mod->ModSrcOper);
225
226 cout << "\t\t\t ModAmtSrcOper" << endl;
227 PrintModulator(mod->ModAmtSrcOper);
228 cout << "\t\t\t Amount: " << mod->ModAmount << endl;
229
230 if (mod->ModDestOper & (1 << 15)) {
231 cout << "\t\t\t ModDestOper: " << (mod->ModDestOper ^ (1 << 15)) << endl;
232 } else {
233 cout << "\t\t\t ModDestOper: " << mod->ModDestOper << endl;
234 }
235 }
236
237 void PrintModulator(sf2::Modulator& mod) {
238 cout << "\t\t\t\tController Type: " << GetControllerType(mod) << endl;
239 cout << "\t\t\t\tController Source: " << GetControllerSource(mod) << endl;
240 cout << "\t\t\t\tDirection: ";
241 cout << (mod.Direction ? "max -> min" : "min -> max") << endl;
242 cout << "\t\t\t\tPolarity: ";
243 cout << (mod.Polarity ? "Bipolar" : "Unipolar") << endl;
244 }
245
246 string GetControllerType(sf2::Modulator& mod) {
247 string s;
248 switch(mod.Type) {
249 case sf2::Modulator::LINEAR:
250 s = "Linear"; break;
251 case sf2::Modulator::CONCAVE:
252 s = "Concave"; break;
253 case sf2::Modulator::CONVEX:
254 s = "Convex"; break;
255 case sf2::Modulator::SWITCH:
256 s = "Switch"; break;
257 }
258
259 return s;
260 }
261
262 string GetControllerSource(sf2::Modulator& mod) {
263 if (mod.MidiPalete) {
264 stringstream ss;
265 ss << "MIDI controller " << mod.Index;
266 return ss.str();
267 }
268
269 string s;
270 switch(mod.Index) {
271 case sf2::Modulator::NO_CONTROLLER:
272 s = "No controller"; break;
273 case sf2::Modulator::NOTE_ON_VELOCITY:
274 s = "Note-On Velocity"; break;
275 case sf2::Modulator::NOTE_ON_KEY_NUMBER:
276 s = "Note-On Key Number"; break;
277 case sf2::Modulator::POLY_PRESSURE:
278 s = "Poly Pressure"; break;
279 case sf2::Modulator::CHANNEL_PRESSURE:
280 s = "Channel Pressure"; break;
281 case sf2::Modulator::PITCH_WHEEL:
282 s = "Pitch Wheel"; break;
283 case sf2::Modulator::PITCH_WHEEL_SENSITIVITY:
284 s = "Pitch Wheel Sensitivity"; break;
285 case sf2::Modulator::LINK:
286 s = "Link"; break;
287 default: s = "Unknown controller source";
288 }
289
290 return s;
291 }
292
293 string Revision() {
294 string s = "$Revision: 1.3 $";
295 return s.substr(11, s.size() - 13); // cut dollar signs, spaces and CVS macro keyword
296 }
297
298 void PrintVersion() {
299 cout << "sf2dump revision " << Revision() << endl;
300 cout << "using " << sf2::libraryName() << " " << sf2::libraryVersion() << endl;
301 }
302
303 void PrintUsage() {
304 cout << "sf2dump - parses SF2 files and prints out the content." << endl;
305 cout << endl;
306 cout << "Usage: sf2dump [-v] FILE" << endl;
307 cout << endl;
308 cout << " -v Print version and exit." << endl;
309 cout << endl;
310 }
311
312 string GetSampleType(uint16_t type) {
313 switch(type) {
314 case sf2::Sample::MONO_SAMPLE : return "Mono Sample";
315 case sf2::Sample::RIGHT_SAMPLE : return "Right Sample";
316 case sf2::Sample::LEFT_SAMPLE : return "Left Sample";
317 case sf2::Sample::LINKED_SAMPLE : return "Linked Sample";
318 case sf2::Sample::ROM_MONO_SAMPLE : return "ROM Mono Sample";
319 case sf2::Sample::ROM_RIGHT_SAMPLE : return "ROM Right Sample";
320 case sf2::Sample::ROM_LEFT_SAMPLE : return "ROM Left Sample";
321 case sf2::Sample::ROM_LINKED_SAMPLE : return "ROM Linked Sample";
322 default: return "Unknown";
323 }
324 }

  ViewVC Help
Powered by ViewVC