1
/*================================================================
2
* sbk2cfg -- extracts info from sf2/sbk font and constructs
3
* a TiMidity cfg file. Greg Lee, lee@hawaii.edu, 5/98.
4
* The code is adapted from "sbktext" by Takashi Iwai, which contained
5
* the following notice:
6
*================================================================
7
* Copyright (C) 1996,1997 Takashi Iwai
9
* This program is free software; you can redistribute it and/or modify
10
* it under the terms of the GNU General Public License as published by
11
* the Free Software Foundation; either version 2 of the License, or
12
* (at your option) any later version.
14
* This program is distributed in the hope that it will be useful,
15
* but WITHOUT ANY WARRANTY; without even the implied warranty of
16
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
17
* GNU General Public License for more details.
19
* You should have received a copy of the GNU General Public License
20
* along with this program; if not, write to the Free Software
21
* Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
22
*================================================================*/
33
static char *getname(char *p);
34
static void print_sbk(SFInfo *sf, FILE *fout);
36
int main(int argc, char **argv)
41
fprintf(stderr, "usage: sf2cfg SoundFontFile [> textfile]\n");
45
if ((fp = fopen(argv[1], "r")) == NULL) {
46
fprintf(stderr, "can't open SoundFont file %s\n", argv[1]);
50
load_sbk(fp, &sfinfo);
54
if (argc >= 3 && (fp = fopen(argv[2], "w")) == NULL) {
55
fprintf(stderr, "can't open text file %s\n", argv[2]);
58
print_sbk(&sfinfo, fp);
60
fprintf(fp, "\nsf %s\n", argv[1]);
66
static char *getname(char *p)
72
for (i = 19; i > 4 && buf[i]==' '; i--) {
75
for (i = 0; buf[i]; i++) {
76
if (buf[i] == ' ') buf[i] = '_';
77
if (buf[i] == '#') buf[i] = '@';
83
static void print_sbk(SFInfo *sf, FILE *fout)
85
int i, bank, preset, lastpatch;
90
fprintf(fout, "# ** SoundFont: %d %d\n", sf->version, sf->minorversion);
91
fprintf(fout, "# ** SampleData: %d %d\n", (int)sf->samplepos, (int)sf->samplesize);
93
fprintf(fout, "#\n# ** Presets: %d\n", sf->nrpresets-1);
95
for (bank = 0; bank <= 128; bank++) {
96
for (preset = 0; preset <= 127; preset++) {
98
for (i = 0, ip = sf->presethdr; i < sf->nrpresets-1; i++) {
99
int b, g, inst, sm_idx;
100
if (ip[i].bank != bank) continue;
101
if (ip[i].preset != preset) continue;
103
for (b = ip[i].bagNdx; b < ip[i+1].bagNdx; b++) {
104
for (g = sf->presetbag[b]; g < sf->presetbag[b+1]; g++)
105
if (sf->presetgen[g].oper == SF_instrument) {
106
inst = sf->presetgen[g].amount;
110
if (inst < 0) continue;
114
if (bank != lastbank) {
115
fprintf(fout, "\nbank %d sf\n", bank);
118
for (b = tp[inst].bagNdx; b < tp[inst+1].bagNdx; b++) {
120
for (g = sf->instbag[b]; g < sf->instbag[b+1]; g++) {
121
if (sf->instgen[g].oper == SF_sampleId) sm_idx = sf->instgen[g].amount;
123
if (sm_idx >= 0 && sf->sampleinfo[sm_idx].sampletype < 0x8000) realwaves++;
125
if (realwaves && ip[i].preset != lastpatch) {
126
fprintf(fout, "\t%3d %s\n", ip[i].preset, getname(ip[i].name));
127
lastpatch = ip[i].preset;
131
int keynote, c, dpreset;
132
fprintf(fout, "\ndrumset %d sf\t%s\n", ip[i].preset, getname(ip[i].name));
134
for (dpreset = 0; dpreset < 128; dpreset++)
135
for (c = ip[i].bagNdx; c < ip[i+1].bagNdx; c++) {
137
for (g = sf->presetbag[c]; g < sf->presetbag[c+1]; g++)
138
if (sf->presetgen[g].oper == SF_instrument) {
139
inst = sf->presetgen[g].amount;
142
if (inst >= 0) for (b = tp[inst].bagNdx; b < tp[inst+1].bagNdx; b++) {
144
sm_idx = keynote = -1;
145
for (g = sf->instbag[b]; g < sf->instbag[b+1]; g++) {
146
if (sf->instgen[g].oper == SF_sampleId) sm_idx = sf->instgen[g].amount;
147
else if (sf->instgen[g].oper == SF_keyRange) {
148
keynote = sf->instgen[g].amount & 0xff;
149
hikeynote = (sf->instgen[g].amount >> 8) & 0xff;
152
if (sm_idx < 0) continue;
153
if (sf->sampleinfo[sm_idx].sampletype >= 0x8000) continue;
154
/*if (keynote != dpreset) continue;*/
155
if (dpreset < keynote) continue;
156
if (dpreset > hikeynote) continue;
157
if (sm_idx >= 0 && keynote >= 0 && dpreset != lastpatch) {
158
fprintf(fout, "\t%3d %s\n", dpreset, getname( sf->samplenames[sm_idx].name ));