1 /*
2 * Schism Tracker - a cross-platform Impulse Tracker clone
3 * copyright (c) 2003-2005 Storlek <storlek@rigelseven.com>
4 * copyright (c) 2005-2008 Mrs. Brisby <mrs.brisby@nimh.org>
5 * copyright (c) 2009 Storlek & Mrs. Brisby
6 * copyright (c) 2010-2012 Storlek
7 * URL: http://schismtracker.org/
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., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
22 */
23 #define NEED_BYTESWAP
24 #include "headers.h"
25 #include "fmt.h"
26
27 #include "it.h"
28 #include "song.h"
29 #include "sndfile.h"
30
31 #include <string.h>
32 #include <stdlib.h>
33 #include <stdint.h>
34
35 /* --------------------------------------------------------------------- */
36
37 #pragma pack(push, 1)
38 struct GF1PatchHeader {
39 uint8_t sig[8]; // "GF1PATCH"
40 uint8_t ver[4]; // "100\0" or "110\0"
41 uint8_t id[10]; // "ID#000002\0"
42 char desc[60]; // Discription (in ASCII) [sic]
43 uint8_t insnum; // To some patch makers, 0 means 1 [what?]
44 uint8_t voicenum; // Voices (Always 14?)
45 uint8_t channum; // Channels
46 uint16_t waveforms;
47 uint16_t mastervol; // 0-127 [then why is it 16-bit? ugh]
48 uint32_t datasize;
49 uint8_t reserved1[36];
50 uint16_t insID; // Instrument ID [0..0xFFFF] [?]
51 char insname[16]; // Instrument name (in ASCII)
52 uint32_t inssize; // Instrument size
53 uint8_t layers;
54 uint8_t reserved2[40];
55 uint8_t layerduplicate;
56 uint8_t layer;
57 uint32_t layersize;
58 uint8_t smpnum;
59 uint8_t reserved3[40];
60 };
61
62 struct GF1PatchSampleHeader {
63 char wavename[7]; // Wave name (in ASCII)
64 uint8_t fractions; // bits 0-3 loop start frac / 4-7 loop end frac
65 uint32_t samplesize; // Sample data size (s)
66 uint32_t loopstart;
67 uint32_t loopend;
68 uint16_t samplerate;
69 uint32_t lofreq; // Low frequency
70 uint32_t hifreq; // High frequency
71 uint32_t rtfreq; // Root frequency
72 uint16_t tune; // Tune (Always 1, not used anymore)
73 uint8_t panning; // Panning (L=0 -> R=15)
74 uint8_t envelopes[12];
75 uint8_t trem_speed, trem_rate, trem_depth;
76 uint8_t vib_speed, vib_rate, vib_depth;
77 uint8_t smpmode; // bit mask: 16, unsigned, loop, pingpong, reverse, sustain, envelope, clamped release
78 uint16_t scalefreq; // Scale frequency
79 uint16_t scalefac; // Scale factor [0..2048] (1024 is normal)
80 uint8_t reserved[36];
81 };
82 #pragma pack(pop)
83
84 /* --------------------------------------------------------------------- */
85
gusfreq(unsigned int freq)86 static int gusfreq(unsigned int freq)
87 {
88 unsigned int scale_table[109] = {
89 /*C-0..B-*/
90 /* Octave 0 */ 16351, 17323, 18354, 19445, 20601, 21826,
91 23124, 24499, 25956, 27500, 29135, 30867,
92 /* Octave 1 */ 32703, 34647, 36708, 38890, 41203, 43653,
93 46249, 48999, 51913, 54999, 58270, 61735,
94 /* Octave 2 */ 65406, 69295, 73416, 77781, 82406, 87306,
95 92498, 97998, 103826, 109999, 116540, 123470,
96 /* Octave 3 */ 130812, 138591, 146832, 155563, 164813, 174614,
97 184997, 195997, 207652, 219999, 233081, 246941,
98 /* Octave 4 */ 261625, 277182, 293664, 311126, 329627, 349228,
99 369994, 391995, 415304, 440000, 466163, 493883,
100 /* Octave 5 */ 523251, 554365, 587329, 622254, 659255, 698456,
101 739989, 783991, 830609, 880000, 932328, 987767,
102 /* Octave 6 */ 1046503, 1108731, 1174660, 1244509, 1318511, 1396914,
103 1479979, 1567983, 1661220, 1760002, 1864657, 1975536,
104 /* Octave 7 */ 2093007, 2217464, 2349321, 2489019, 2637024, 2793830,
105 2959960, 3135968, 3322443, 3520006, 3729316, 3951073,
106 /* Octave 8 */ 4186073, 4434930, 4698645, 4978041, 5274051, 5587663,
107 5919922, 6271939, 6644889, 7040015, 7458636, 7902150,
108 0xFFFFFFFF,
109 };
110 int no;
111
112 for (no = 0; scale_table[no] != 0xFFFFFFFF; no++) {
113 if (scale_table[no] <= freq && scale_table[no + 1] >= freq) {
114 return no - 12;
115 }
116 }
117
118 return 4 * 12;
119 }
120
121 /* --------------------------------------------------------------------- */
122
fmt_pat_read_info(dmoz_file_t * file,const uint8_t * data,size_t length)123 int fmt_pat_read_info(dmoz_file_t *file, const uint8_t *data, size_t length)
124 {
125 const struct GF1PatchHeader *header = (const struct GF1PatchHeader *) data;
126
127 if ((length <= sizeof(struct GF1PatchHeader))
128 || (memcmp(header->sig, "GF1PATCH", 8) != 0)
129 || (memcmp(header->ver, "110\0", 4) != 0 && memcmp(header->ver, "100\0", 4) != 0)
130 || (memcmp(header->id, "ID#000002\0", 10) != 0)) {
131 return 0;
132 }
133 file->description = "Gravis Patch File";
134 file->title = strn_dup(header->insname, 16);
135 file->type = TYPE_INST_OTHER;
136 return 1;
137 }
138
139
fmt_pat_load_instrument(const uint8_t * data,size_t length,int slot)140 int fmt_pat_load_instrument(const uint8_t *data, size_t length, int slot)
141 {
142 struct GF1PatchHeader header;
143 struct GF1PatchSampleHeader gfsamp;
144 struct instrumentloader ii;
145 song_instrument_t *g;
146 song_sample_t *smp;
147 unsigned int pos, rs;
148 int lo, hi, tmp, i, nsamp, n;
149
150 if (length < sizeof(header) || !slot) return 0;
151 memcpy(&header, data, sizeof(header));
152 if ((memcmp(header.sig, "GF1PATCH", 8) != 0)
153 || (memcmp(header.ver, "110\0", 4) != 0 && memcmp(header.ver, "100\0", 4) != 0)
154 || (memcmp(header.id, "ID#000002\0", 10) != 0)) {
155 return 0;
156 }
157
158 header.waveforms = bswapLE16(header.waveforms);
159 header.mastervol = bswapLE16(header.mastervol);
160 header.datasize = bswapLE32(header.datasize);
161 header.insID = bswapLE16(header.insID);
162 header.inssize = bswapLE32(header.inssize);
163 header.layersize = bswapLE32(header.layersize);
164
165 g = instrument_loader_init(&ii, slot);
166 memcpy(g->name, header.insname, 16);
167 g->name[15] = '\0';
168
169 nsamp = CLAMP(header.smpnum, 1, 16);
170 pos = sizeof(header);
171 for (i = 0; i < 120; i++) {
172 g->sample_map[i] = 0;
173 g->note_map[i] = i + 1;
174 }
175 for (i = 0; i < nsamp; i++) {
176 memcpy(&gfsamp, data + pos, sizeof(gfsamp));
177 pos += sizeof(gfsamp);
178
179 n = instrument_loader_sample(&ii, i + 1) - 1;
180 smp = song_get_sample(n);
181
182 gfsamp.samplesize = bswapLE32(gfsamp.samplesize);
183 gfsamp.loopstart = bswapLE32(gfsamp.loopstart);
184 gfsamp.loopend = bswapLE32(gfsamp.loopend);
185 gfsamp.samplerate = bswapLE16(gfsamp.samplerate);
186 gfsamp.lofreq = bswapLE32(gfsamp.lofreq);
187 gfsamp.hifreq = bswapLE32(gfsamp.hifreq);
188 gfsamp.rtfreq = bswapLE32(gfsamp.rtfreq);
189 gfsamp.tune = bswapLE16(gfsamp.tune);
190 gfsamp.scalefreq = bswapLE16(gfsamp.scalefac);
191
192 lo = CLAMP(gusfreq(gfsamp.lofreq), 0, 95);
193 hi = CLAMP(gusfreq(gfsamp.hifreq), 0, 95);
194 if (lo > hi) {
195 tmp = lo;
196 lo = hi;
197 hi = tmp;
198 }
199 for (; lo < hi; lo++) {
200 g->sample_map[lo + 12] = n;
201 }
202
203 if (gfsamp.smpmode & 1) {
204 gfsamp.samplesize >>= 1;
205 gfsamp.loopstart >>= 1;
206 gfsamp.loopend >>= 1;
207 }
208 smp->length = gfsamp.samplesize;
209 smp->loop_start = smp->sustain_start = gfsamp.loopstart;
210 smp->loop_end = smp->sustain_end = gfsamp.loopend;
211 smp->c5speed = gfsamp.samplerate;
212
213 smp->flags = 0;
214 rs = SF_M | SF_LE; // channels; endianness
215 rs |= (gfsamp.smpmode & 1) ? SF_16 : SF_8; // bit width
216 rs |= (gfsamp.smpmode & 2) ? SF_PCMU : SF_PCMS; // encoding
217 if (gfsamp.smpmode & 32) {
218 if (gfsamp.smpmode & 4)
219 smp->flags |= CHN_SUSTAINLOOP;
220 if (gfsamp.smpmode & 8)
221 smp->flags |= CHN_PINGPONGSUSTAIN;
222 } else {
223 if (gfsamp.smpmode & 4)
224 smp->flags |= CHN_LOOP;
225 if (gfsamp.smpmode & 8)
226 smp->flags |= CHN_PINGPONGLOOP;
227 }
228 memcpy(smp->filename, gfsamp.wavename, 7);
229 smp->filename[8] = '\0';
230 strcpy(smp->name, smp->filename);
231 smp->vib_speed = gfsamp.vib_speed;
232 smp->vib_rate = gfsamp.vib_rate;
233 smp->vib_depth = gfsamp.vib_depth;
234
235 pos += csf_read_sample(current_song->samples + n, rs, data + pos, length - pos);
236 }
237 return 1;
238 }
239
240