~ubuntu-branches/ubuntu/hoary/kdemultimedia/hoary

« back to all changes in this revision

Viewing changes to kmidi/sf2cfg.cpp

  • Committer: Bazaar Package Importer
  • Author(s): Martin Schulze
  • Date: 2003-01-22 15:00:51 UTC
  • Revision ID: james.westby@ubuntu.com-20030122150051-uihwkdoxf15mi1tn
Tags: upstream-2.2.2
ImportĀ upstreamĀ versionĀ 2.2.2

Show diffs side-by-side

added added

removed removed

Lines of Context:
 
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
 
8
 *
 
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.
 
13
 *
 
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.
 
18
 *
 
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
 *================================================================*/
 
23
 
 
24
#include <stdio.h>
 
25
#include <stdlib.h>
 
26
#include <string.h>
 
27
#include "config.h"
 
28
#include "sbk.h"
 
29
#include "sflayer.h"
 
30
 
 
31
static SFInfo sfinfo;
 
32
 
 
33
static char *getname(char *p);
 
34
static void print_sbk(SFInfo *sf, FILE *fout);
 
35
 
 
36
int main(int argc, char **argv)
 
37
{
 
38
        FILE *fp;
 
39
 
 
40
        if (argc < 2) {
 
41
                fprintf(stderr, "usage: sf2cfg SoundFontFile [> textfile]\n");
 
42
                exit(1);
 
43
        }
 
44
 
 
45
        if ((fp = fopen(argv[1], "r")) == NULL) {
 
46
                fprintf(stderr, "can't open SoundFont file %s\n", argv[1]);
 
47
                exit(1);
 
48
        }
 
49
 
 
50
        load_sbk(fp, &sfinfo);
 
51
        fclose(fp);
 
52
 
 
53
        fp = stdout;
 
54
        if (argc >= 3 && (fp = fopen(argv[2], "w")) == NULL) {
 
55
                fprintf(stderr, "can't open text file %s\n", argv[2]);
 
56
                exit(1);
 
57
        }
 
58
        print_sbk(&sfinfo, fp);
 
59
 
 
60
        fprintf(fp, "\nsf %s\n", argv[1]);
 
61
 
 
62
        return 0;
 
63
}
 
64
 
 
65
 
 
66
static char *getname(char *p)
 
67
{
 
68
        int i;
 
69
        static char buf[21];
 
70
        strncpy(buf, p, 20);
 
71
        buf[20] = 0;
 
72
        for (i = 19; i > 4 && buf[i]==' '; i--) {
 
73
          buf[i] = 0;
 
74
        }
 
75
        for (i = 0; buf[i]; i++) {
 
76
          if (buf[i] == ' ') buf[i] = '_';
 
77
          if (buf[i] == '#') buf[i] = '@';
 
78
        }
 
79
        return buf;
 
80
}
 
81
 
 
82
 
 
83
static void print_sbk(SFInfo *sf, FILE *fout)
 
84
{
 
85
    int i, bank, preset, lastpatch;
 
86
    int lastbank = -1;
 
87
    tpresethdr *ip;
 
88
    tinsthdr *tp;
 
89
 
 
90
    fprintf(fout, "#  ** SoundFont: %d %d\n", sf->version, sf->minorversion);
 
91
    fprintf(fout, "#  ** SampleData: %d %d\n", (int)sf->samplepos, (int)sf->samplesize);
 
92
 
 
93
    fprintf(fout, "#\n#  ** Presets: %d\n", sf->nrpresets-1);
 
94
 
 
95
    for (bank = 0; bank <= 128; bank++) {
 
96
      for (preset = 0; preset <= 127; preset++) {
 
97
      lastpatch = -1;
 
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;
 
102
            inst = -1;
 
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;
 
107
                        break;
 
108
                   }
 
109
            }
 
110
            if (inst < 0) continue;
 
111
            tp = sf->insthdr;
 
112
            if (bank != 128) {
 
113
                int realwaves = 0;
 
114
                if (bank != lastbank) {
 
115
                        fprintf(fout, "\nbank %d sf\n", bank);
 
116
                        lastbank = bank;
 
117
                }
 
118
                for (b = tp[inst].bagNdx; b < tp[inst+1].bagNdx; b++) {
 
119
                    sm_idx = -1;
 
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;
 
122
                    }
 
123
                    if (sm_idx >= 0 && sf->sampleinfo[sm_idx].sampletype < 0x8000) realwaves++;
 
124
                }
 
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;
 
128
                }
 
129
            }
 
130
            else {
 
131
                int keynote, c, dpreset;
 
132
                fprintf(fout, "\ndrumset %d sf\t%s\n", ip[i].preset, getname(ip[i].name));
 
133
 
 
134
                for (dpreset = 0; dpreset < 128; dpreset++)
 
135
                for (c = ip[i].bagNdx; c < ip[i+1].bagNdx; c++) {
 
136
                  inst = -1;
 
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;
 
140
                        break;
 
141
                   }
 
142
                  if (inst >= 0) for (b = tp[inst].bagNdx; b < tp[inst+1].bagNdx; b++) {
 
143
                    int hikeynote = -1;
 
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;
 
150
                        }
 
151
                    }
 
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 ));
 
159
                           lastpatch = dpreset;
 
160
                    }
 
161
                  }
 
162
                }
 
163
 
 
164
            }
 
165
        }
 
166
      }
 
167
    }
 
168
}