1 /*
2 ** Copyright (C) 2002-2012 Erik de Castro Lopo <erikd@mega-nerd.com>
3 **
4 ** This program is free software; you can redistribute it and/or modify
5 ** it under the terms of the GNU Lesser General Public License as published by
6 ** the Free Software Foundation; either version 2.1 of the License, or
7 ** (at your option) any later version.
8 **
9 ** This program is distributed in the hope that it will be useful,
10 ** but WITHOUT ANY WARRANTY; without even the implied warranty of
11 ** MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
12 ** GNU Lesser General Public License for more details.
13 **
14 ** You should have received a copy of the GNU Lesser General Public License
15 ** along with this program; if not, write to the Free Software
16 ** Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA.
17 */
18
19 /*===========================================================================
20 ** Yamaha TX16 Sampler Files.
21 **
22 ** This header parser was written using information from the SoX source code
23 ** and trial and error experimentation. The code here however is all original.
24 */
25
26 #include "sfconfig.h"
27
28 #include <stdio.h>
29 #include <fcntl.h>
30 #include <string.h>
31 #include <ctype.h>
32
33 #include "sndfile.h"
34 #include "sfendian.h"
35 #include "common.h"
36
37 #if (ENABLE_EXPERIMENTAL_CODE == 0)
38
39 int
txw_open(SF_PRIVATE * psf)40 txw_open (SF_PRIVATE *psf)
41 { if (psf)
42 return SFE_UNIMPLEMENTED ;
43 return 0 ;
44 } /* txw_open */
45
46 #else
47
48 /*------------------------------------------------------------------------------
49 ** Markers.
50 */
51
52 #define TXW_DATA_OFFSET 32
53
54 #define TXW_LOOPED 0x49
55 #define TXW_NO_LOOP 0xC9
56
57 /*------------------------------------------------------------------------------
58 ** Private static functions.
59 */
60
61 static int txw_read_header (SF_PRIVATE *psf) ;
62
63 static sf_count_t txw_read_s (SF_PRIVATE *psf, short *ptr, sf_count_t len) ;
64 static sf_count_t txw_read_i (SF_PRIVATE *psf, int *ptr, sf_count_t len) ;
65 static sf_count_t txw_read_f (SF_PRIVATE *psf, float *ptr, sf_count_t len) ;
66 static sf_count_t txw_read_d (SF_PRIVATE *psf, double *ptr, sf_count_t len) ;
67
68 static sf_count_t txw_seek (SF_PRIVATE *psf, int mode, sf_count_t offset) ;
69
70 /*------------------------------------------------------------------------------
71 ** Public functions.
72 */
73
74 /*
75 * ftp://ftp.t0.or.at/pub/sound/tx16w/samples.yamaha
76 * ftp://ftp.t0.or.at/pub/sound/tx16w/faq/tx16w.tec
77 * http://www.t0.or.at/~mpakesch/tx16w/
78 *
79 * from tx16w.c sox 12.15: (7-Oct-98) (Mark Lakata and Leigh Smith)
80 * char filetype[6] "LM8953"
81 * nulls[10],
82 * dummy_aeg[6]
83 * format 0x49 = looped, 0xC9 = non-looped
84 * sample_rate 1 = 33 kHz, 2 = 50 kHz, 3 = 16 kHz
85 * atc_length[3] if sample rate 0, [2]&0xfe = 6: 33kHz, 0x10:50, 0xf6: 16,
86 * depending on [5] but to heck with it
87 * rpt_length[3] (these are for looped samples, attack and loop lengths)
88 * unused[2]
89 */
90
91 typedef struct
92 { unsigned char format, srate, sr2, sr3 ;
93 unsigned short srhash ;
94 unsigned int attacklen, repeatlen ;
95 } TXW_HEADER ;
96
97 #define ERROR_666 666
98
99 int
txw_open(SF_PRIVATE * psf)100 txw_open (SF_PRIVATE *psf)
101 { int error ;
102
103 if (psf->file.mode != SFM_READ)
104 return SFE_UNIMPLEMENTED ;
105
106 if ((error = txw_read_header (psf)))
107 return error ;
108
109 if (psf_fseek (psf, psf->dataoffset, SEEK_SET) != psf->dataoffset)
110 return SFE_BAD_SEEK ;
111
112 psf->read_short = txw_read_s ;
113 psf->read_int = txw_read_i ;
114 psf->read_float = txw_read_f ;
115 psf->read_double = txw_read_d ;
116
117 psf->seek = txw_seek ;
118
119 return 0 ;
120 } /* txw_open */
121
122 /*------------------------------------------------------------------------------
123 */
124
125 static int
txw_read_header(SF_PRIVATE * psf)126 txw_read_header (SF_PRIVATE *psf)
127 { BUF_UNION ubuf ;
128 TXW_HEADER txwh ;
129 const char *strptr ;
130
131 memset (&txwh, 0, sizeof (txwh)) ;
132 memset (ubuf.cbuf, 0, sizeof (ubuf.cbuf)) ;
133 psf_binheader_readf (psf, "pb", 0, ubuf.cbuf, 16) ;
134
135 if (memcmp (ubuf.cbuf, "LM8953\0\0\0\0\0\0\0\0\0\0", 16) != 0)
136 return ERROR_666 ;
137
138 psf_log_printf (psf, "Read only : Yamaha TX-16 Sampler (.txw)\nLM8953\n") ;
139
140 /* Jump 6 bytes (dummp_aeg), read format, read sample rate. */
141 psf_binheader_readf (psf, "j11", 6, &txwh.format, &txwh.srate) ;
142
143 /* 8 bytes (atc_length[3], rpt_length[3], unused[2]). */
144 psf_binheader_readf (psf, "e33j", &txwh.attacklen, &txwh.repeatlen, 2) ;
145 txwh.sr2 = (txwh.attacklen >> 16) & 0xFE ;
146 txwh.sr3 = (txwh.repeatlen >> 16) & 0xFE ;
147 txwh.attacklen &= 0x1FFFF ;
148 txwh.repeatlen &= 0x1FFFF ;
149
150 switch (txwh.format)
151 { case TXW_LOOPED :
152 strptr = "looped" ;
153 break ;
154
155 case TXW_NO_LOOP :
156 strptr = "non-looped" ;
157 break ;
158
159 default :
160 psf_log_printf (psf, " Format : 0x%02x => ?????\n", txwh.format) ;
161 return ERROR_666 ;
162 } ;
163
164 psf_log_printf (psf, " Format : 0x%02X => %s\n", txwh.format, strptr) ;
165
166 strptr = NULL ;
167
168 switch (txwh.srate)
169 { case 1 :
170 psf->sf.samplerate = 33333 ;
171 break ;
172
173 case 2 :
174 psf->sf.samplerate = 50000 ;
175 break ;
176
177 case 3 :
178 psf->sf.samplerate = 16667 ;
179 break ;
180
181 default :
182 /* This is ugly and braindead. */
183 txwh.srhash = ((txwh.sr2 & 0xFE) << 8) | (txwh.sr3 & 0xFE) ;
184 switch (txwh.srhash)
185 { case ((0x6 << 8) | 0x52) :
186 psf->sf.samplerate = 33333 ;
187 break ;
188
189 case ((0x10 << 8) | 0x52) :
190 psf->sf.samplerate = 50000 ;
191 break ;
192
193 case ((0xF6 << 8) | 0x52) :
194 psf->sf.samplerate = 166667 ;
195 break ;
196
197 default :
198 strptr = " Sample Rate : Unknown : forcing to 33333\n" ;
199 psf->sf.samplerate = 33333 ;
200 break ;
201 } ;
202 } ;
203
204
205 if (strptr)
206 psf_log_printf (psf, strptr) ;
207 else if (txwh.srhash)
208 psf_log_printf (psf, " Sample Rate : %d (0x%X) => %d\n", txwh.srate, txwh.srhash, psf->sf.samplerate) ;
209 else
210 psf_log_printf (psf, " Sample Rate : %d => %d\n", txwh.srate, psf->sf.samplerate) ;
211
212 if (txwh.format == TXW_LOOPED)
213 { psf_log_printf (psf, " Attack Len : %d\n", txwh.attacklen) ;
214 psf_log_printf (psf, " Repeat Len : %d\n", txwh.repeatlen) ;
215 } ;
216
217 psf->dataoffset = TXW_DATA_OFFSET ;
218 psf->datalength = psf->filelength - TXW_DATA_OFFSET ;
219 psf->sf.frames = 2 * psf->datalength / 3 ;
220
221
222 if (psf->datalength % 3 == 1)
223 psf_log_printf (psf, "*** File seems to be truncated, %d extra bytes.\n",
224 (int) (psf->datalength % 3)) ;
225
226 if (txwh.attacklen + txwh.repeatlen > psf->sf.frames)
227 psf_log_printf (psf, "*** File has been truncated.\n") ;
228
229 psf->sf.format = SF_FORMAT_TXW | SF_FORMAT_PCM_16 ;
230 psf->sf.channels = 1 ;
231 psf->sf.sections = 1 ;
232 psf->sf.seekable = SF_TRUE ;
233
234 return 0 ;
235 } /* txw_read_header */
236
237 static sf_count_t
txw_read_s(SF_PRIVATE * psf,short * ptr,sf_count_t len)238 txw_read_s (SF_PRIVATE *psf, short *ptr, sf_count_t len)
239 { BUF_UNION ubuf ;
240 unsigned char *ucptr ;
241 short sample ;
242 int k, bufferlen, readcount, count ;
243 sf_count_t total = 0 ;
244
245 bufferlen = sizeof (ubuf.cbuf) / 3 ;
246 bufferlen -= (bufferlen & 1) ;
247 while (len > 0)
248 { readcount = (len >= bufferlen) ? bufferlen : len ;
249 count = psf_fread (ubuf.cbuf, 3, readcount, psf) ;
250
251 ucptr = ubuf.ucbuf ;
252 for (k = 0 ; k < readcount ; k += 2)
253 { sample = (ucptr [0] << 8) | (ucptr [1] & 0xF0) ;
254 ptr [total + k] = sample ;
255 sample = (ucptr [2] << 8) | ((ucptr [1] & 0xF) << 4) ;
256 ptr [total + k + 1] = sample ;
257 ucptr += 3 ;
258 } ;
259
260 total += count ;
261 len -= readcount ;
262 } ;
263
264 return total ;
265 } /* txw_read_s */
266
267 static sf_count_t
txw_read_i(SF_PRIVATE * psf,int * ptr,sf_count_t len)268 txw_read_i (SF_PRIVATE *psf, int *ptr, sf_count_t len)
269 { BUF_UNION ubuf ;
270 unsigned char *ucptr ;
271 short sample ;
272 int k, bufferlen, readcount, count ;
273 sf_count_t total = 0 ;
274
275 bufferlen = sizeof (ubuf.cbuf) / 3 ;
276 bufferlen -= (bufferlen & 1) ;
277 while (len > 0)
278 { readcount = (len >= bufferlen) ? bufferlen : len ;
279 count = psf_fread (ubuf.cbuf, 3, readcount, psf) ;
280
281 ucptr = ubuf.ucbuf ;
282 for (k = 0 ; k < readcount ; k += 2)
283 { sample = (ucptr [0] << 8) | (ucptr [1] & 0xF0) ;
284 ptr [total + k] = sample << 16 ;
285 sample = (ucptr [2] << 8) | ((ucptr [1] & 0xF) << 4) ;
286 ptr [total + k + 1] = sample << 16 ;
287 ucptr += 3 ;
288 } ;
289
290 total += count ;
291 len -= readcount ;
292 } ;
293
294 return total ;
295 } /* txw_read_i */
296
297 static sf_count_t
txw_read_f(SF_PRIVATE * psf,float * ptr,sf_count_t len)298 txw_read_f (SF_PRIVATE *psf, float *ptr, sf_count_t len)
299 { BUF_UNION ubuf ;
300 unsigned char *ucptr ;
301 short sample ;
302 int k, bufferlen, readcount, count ;
303 sf_count_t total = 0 ;
304 float normfact ;
305
306 if (psf->norm_float == SF_TRUE)
307 normfact = 1.0 / 0x8000 ;
308 else
309 normfact = 1.0 / 0x10 ;
310
311 bufferlen = sizeof (ubuf.cbuf) / 3 ;
312 bufferlen -= (bufferlen & 1) ;
313 while (len > 0)
314 { readcount = (len >= bufferlen) ? bufferlen : len ;
315 count = psf_fread (ubuf.cbuf, 3, readcount, psf) ;
316
317 ucptr = ubuf.ucbuf ;
318 for (k = 0 ; k < readcount ; k += 2)
319 { sample = (ucptr [0] << 8) | (ucptr [1] & 0xF0) ;
320 ptr [total + k] = normfact * sample ;
321 sample = (ucptr [2] << 8) | ((ucptr [1] & 0xF) << 4) ;
322 ptr [total + k + 1] = normfact * sample ;
323 ucptr += 3 ;
324 } ;
325
326 total += count ;
327 len -= readcount ;
328 } ;
329
330 return total ;
331 } /* txw_read_f */
332
333 static sf_count_t
txw_read_d(SF_PRIVATE * psf,double * ptr,sf_count_t len)334 txw_read_d (SF_PRIVATE *psf, double *ptr, sf_count_t len)
335 { BUF_UNION ubuf ;
336 unsigned char *ucptr ;
337 short sample ;
338 int k, bufferlen, readcount, count ;
339 sf_count_t total = 0 ;
340 double normfact ;
341
342 if (psf->norm_double == SF_TRUE)
343 normfact = 1.0 / 0x8000 ;
344 else
345 normfact = 1.0 / 0x10 ;
346
347 bufferlen = sizeof (ubuf.cbuf) / 3 ;
348 bufferlen -= (bufferlen & 1) ;
349 while (len > 0)
350 { readcount = (len >= bufferlen) ? bufferlen : len ;
351 count = psf_fread (ubuf.cbuf, 3, readcount, psf) ;
352
353 ucptr = ubuf.ucbuf ;
354 for (k = 0 ; k < readcount ; k += 2)
355 { sample = (ucptr [0] << 8) | (ucptr [1] & 0xF0) ;
356 ptr [total + k] = normfact * sample ;
357 sample = (ucptr [2] << 8) | ((ucptr [1] & 0xF) << 4) ;
358 ptr [total + k + 1] = normfact * sample ;
359 ucptr += 3 ;
360 } ;
361
362 total += count ;
363 len -= readcount ;
364 } ;
365
366 return total ;
367 } /* txw_read_d */
368
369 static sf_count_t
txw_seek(SF_PRIVATE * psf,int mode,sf_count_t offset)370 txw_seek (SF_PRIVATE *psf, int mode, sf_count_t offset)
371 { if (psf && mode)
372 return offset ;
373
374 return 0 ;
375 } /* txw_seek */
376
377 #endif
378