2 ** Copyright (C) 2002-2011 Erik de Castro Lopo <erikd@mega-nerd.com>
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.
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.
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.
19 /*===========================================================================
20 ** Yamaha TX16 Sampler Files.
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.
37 #if (ENABLE_EXPERIMENTAL_CODE == 0)
40 txw_open (SF_PRIVATE
*psf
)
42 return SFE_UNIMPLEMENTED
;
48 /*------------------------------------------------------------------------------
52 #define TXW_DATA_OFFSET 32
54 #define TXW_LOOPED 0x49
55 #define TXW_NO_LOOP 0xC9
57 /*------------------------------------------------------------------------------
58 ** Private static functions.
61 static int txw_read_header (SF_PRIVATE
*psf
) ;
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
) ;
68 static sf_count_t
txw_seek (SF_PRIVATE
*psf
, int mode
, sf_count_t offset
) ;
70 /*------------------------------------------------------------------------------
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/
79 * from tx16w.c sox 12.15: (7-Oct-98) (Mark Lakata and Leigh Smith)
80 * char filetype[6] "LM8953"
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)
92 { unsigned char format
, srate
, sr2
, sr3
;
93 unsigned short srhash
;
94 unsigned int attacklen
, repeatlen
;
100 txw_open (SF_PRIVATE
*psf
)
103 if (psf
->file
.mode
!= SFM_READ
)
104 return SFE_UNIMPLEMENTED
;
106 if ((error
= txw_read_header (psf
)))
109 if (psf_fseek (psf
, psf
->dataoffset
, SEEK_SET
) != psf
->dataoffset
)
110 return SFE_BAD_SEEK
;
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
;
117 psf
->seek
= txw_seek
;
122 /*------------------------------------------------------------------------------
126 txw_read_header (SF_PRIVATE
*psf
)
130 memset (&txwh
, 0, sizeof (txwh
)) ;
131 memset (psf
->u
.cbuf
, 0, sizeof (psf
->u
.cbuf
)) ;
132 psf_binheader_readf (psf
, "pb", 0, psf
->u
.cbuf
, 16) ;
134 if (memcmp (psf
->u
.cbuf
, "LM8953\0\0\0\0\0\0\0\0\0\0", 16) != 0)
137 psf_log_printf (psf
, "Read only : Yamaha TX-16 Sampler (.txw)\nLM8953\n") ;
139 /* Jump 6 bytes (dummp_aeg), read format, read sample rate. */
140 psf_binheader_readf (psf
, "j11", 6, &txwh
.format
, &txwh
.srate
) ;
142 /* 8 bytes (atc_length[3], rpt_length[3], unused[2]). */
143 psf_binheader_readf (psf
, "e33j", &txwh
.attacklen
, &txwh
.repeatlen
, 2) ;
144 txwh
.sr2
= (txwh
.attacklen
>> 16) & 0xFE ;
145 txwh
.sr3
= (txwh
.repeatlen
>> 16) & 0xFE ;
146 txwh
.attacklen
&= 0x1FFFF ;
147 txwh
.repeatlen
&= 0x1FFFF ;
155 strptr
= "non-looped" ;
159 psf_log_printf (psf
, " Format : 0x%02x => ?????\n", txwh
.format
) ;
163 psf_log_printf (psf
, " Format : 0x%02X => %s\n", txwh
.format
, strptr
) ;
169 psf
->sf
.samplerate
= 33333 ;
173 psf
->sf
.samplerate
= 50000 ;
177 psf
->sf
.samplerate
= 16667 ;
181 /* This is ugly and braindead. */
182 txwh
.srhash
= ((txwh
.sr2
& 0xFE) << 8) | (txwh
.sr3
& 0xFE) ;
184 { case ((0x6 << 8) | 0x52) :
185 psf
->sf
.samplerate
= 33333 ;
188 case ((0x10 << 8) | 0x52) :
189 psf
->sf
.samplerate
= 50000 ;
192 case ((0xF6 << 8) | 0x52) :
193 psf
->sf
.samplerate
= 166667 ;
197 strptr
= " Sample Rate : Unknown : forcing to 33333\n" ;
198 psf
->sf
.samplerate
= 33333 ;
205 psf_log_printf (psf
, strptr
) ;
206 else if (txwh
.srhash
)
207 psf_log_printf (psf
, " Sample Rate : %d (0x%X) => %d\n", txwh
.srate
, txwh
.srhash
, psf
->sf
.samplerate
) ;
209 psf_log_printf (psf
, " Sample Rate : %d => %d\n", txwh
.srate
, psf
->sf
.samplerate
) ;
211 if (txwh
.format
== TXW_LOOPED
)
212 { psf_log_printf (psf
, " Attack Len : %d\n", txwh
.attacklen
) ;
213 psf_log_printf (psf
, " Repeat Len : %d\n", txwh
.repeatlen
) ;
216 psf
->dataoffset
= TXW_DATA_OFFSET
;
217 psf
->datalength
= psf
->filelength
- TXW_DATA_OFFSET
;
218 psf
->sf
.frames
= 2 * psf
->datalength
/ 3 ;
221 if (psf
->datalength
% 3 == 1)
222 psf_log_printf (psf
, "*** File seems to be truncated, %d extra bytes.\n",
223 (int) (psf
->datalength
% 3)) ;
225 if (txwh
.attacklen
+ txwh
.repeatlen
> psf
->sf
.frames
)
226 psf_log_printf (psf
, "*** File has been truncated.\n") ;
228 psf
->sf
.format
= SF_FORMAT_TXW
| SF_FORMAT_PCM_16
;
229 psf
->sf
.channels
= 1 ;
230 psf
->sf
.sections
= 1 ;
231 psf
->sf
.seekable
= SF_TRUE
;
234 } /* txw_read_header */
237 txw_read_s (SF_PRIVATE
*psf
, short *ptr
, sf_count_t len
)
238 { unsigned char *ucptr
;
240 int k
, bufferlen
, readcount
, count
;
241 sf_count_t total
= 0 ;
243 bufferlen
= sizeof (psf
->u
.cbuf
) / 3 ;
244 bufferlen
-= (bufferlen
& 1) ;
246 { readcount
= (len
>= bufferlen
) ? bufferlen
: len
;
247 count
= psf_fread (psf
->u
.cbuf
, 3, readcount
, psf
) ;
249 ucptr
= psf
->u
.ucbuf
;
250 for (k
= 0 ; k
< readcount
; k
+= 2)
251 { sample
= (ucptr
[0] << 8) | (ucptr
[1] & 0xF0) ;
252 ptr
[total
+ k
] = sample
;
253 sample
= (ucptr
[2] << 8) | ((ucptr
[1] & 0xF) << 4) ;
254 ptr
[total
+ k
+ 1] = sample
;
266 txw_read_i (SF_PRIVATE
*psf
, int *ptr
, sf_count_t len
)
267 { unsigned char *ucptr
;
269 int k
, bufferlen
, readcount
, count
;
270 sf_count_t total
= 0 ;
272 bufferlen
= sizeof (psf
->u
.cbuf
) / 3 ;
273 bufferlen
-= (bufferlen
& 1) ;
275 { readcount
= (len
>= bufferlen
) ? bufferlen
: len
;
276 count
= psf_fread (psf
->u
.cbuf
, 3, readcount
, psf
) ;
278 ucptr
= psf
->u
.ucbuf
;
279 for (k
= 0 ; k
< readcount
; k
+= 2)
280 { sample
= (ucptr
[0] << 8) | (ucptr
[1] & 0xF0) ;
281 ptr
[total
+ k
] = sample
<< 16 ;
282 sample
= (ucptr
[2] << 8) | ((ucptr
[1] & 0xF) << 4) ;
283 ptr
[total
+ k
+ 1] = sample
<< 16 ;
295 txw_read_f (SF_PRIVATE
*psf
, float *ptr
, sf_count_t len
)
296 { unsigned char *ucptr
;
298 int k
, bufferlen
, readcount
, count
;
299 sf_count_t total
= 0 ;
302 if (psf
->norm_float
== SF_TRUE
)
303 normfact
= 1.0 / 0x8000 ;
305 normfact
= 1.0 / 0x10 ;
307 bufferlen
= sizeof (psf
->u
.cbuf
) / 3 ;
308 bufferlen
-= (bufferlen
& 1) ;
310 { readcount
= (len
>= bufferlen
) ? bufferlen
: len
;
311 count
= psf_fread (psf
->u
.cbuf
, 3, readcount
, psf
) ;
313 ucptr
= psf
->u
.ucbuf
;
314 for (k
= 0 ; k
< readcount
; k
+= 2)
315 { sample
= (ucptr
[0] << 8) | (ucptr
[1] & 0xF0) ;
316 ptr
[total
+ k
] = normfact
* sample
;
317 sample
= (ucptr
[2] << 8) | ((ucptr
[1] & 0xF) << 4) ;
318 ptr
[total
+ k
+ 1] = normfact
* sample
;
330 txw_read_d (SF_PRIVATE
*psf
, double *ptr
, sf_count_t len
)
331 { unsigned char *ucptr
;
333 int k
, bufferlen
, readcount
, count
;
334 sf_count_t total
= 0 ;
337 if (psf
->norm_double
== SF_TRUE
)
338 normfact
= 1.0 / 0x8000 ;
340 normfact
= 1.0 / 0x10 ;
342 bufferlen
= sizeof (psf
->u
.cbuf
) / 3 ;
343 bufferlen
-= (bufferlen
& 1) ;
345 { readcount
= (len
>= bufferlen
) ? bufferlen
: len
;
346 count
= psf_fread (psf
->u
.cbuf
, 3, readcount
, psf
) ;
348 ucptr
= psf
->u
.ucbuf
;
349 for (k
= 0 ; k
< readcount
; k
+= 2)
350 { sample
= (ucptr
[0] << 8) | (ucptr
[1] & 0xF0) ;
351 ptr
[total
+ k
] = normfact
* sample
;
352 sample
= (ucptr
[2] << 8) | ((ucptr
[1] & 0xF) << 4) ;
353 ptr
[total
+ k
+ 1] = normfact
* sample
;
365 txw_seek (SF_PRIVATE
*psf
, int mode
, sf_count_t offset
)