Merge branch 'libsndfile'
[Faustine.git] / interpretor / lib / src / libsndfile-1.0.25 / src / txw.c
1 /*
2 ** Copyright (C) 2002-2011 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
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
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
126 txw_read_header (SF_PRIVATE *psf)
127 { TXW_HEADER txwh ;
128 const char *strptr ;
129
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) ;
133
134 if (memcmp (psf->u.cbuf, "LM8953\0\0\0\0\0\0\0\0\0\0", 16) != 0)
135 return ERROR_666 ;
136
137 psf_log_printf (psf, "Read only : Yamaha TX-16 Sampler (.txw)\nLM8953\n") ;
138
139 /* Jump 6 bytes (dummp_aeg), read format, read sample rate. */
140 psf_binheader_readf (psf, "j11", 6, &txwh.format, &txwh.srate) ;
141
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 ;
148
149 switch (txwh.format)
150 { case TXW_LOOPED :
151 strptr = "looped" ;
152 break ;
153
154 case TXW_NO_LOOP :
155 strptr = "non-looped" ;
156 break ;
157
158 default :
159 psf_log_printf (psf, " Format : 0x%02x => ?????\n", txwh.format) ;
160 return ERROR_666 ;
161 } ;
162
163 psf_log_printf (psf, " Format : 0x%02X => %s\n", txwh.format, strptr) ;
164
165 strptr = NULL ;
166
167 switch (txwh.srate)
168 { case 1 :
169 psf->sf.samplerate = 33333 ;
170 break ;
171
172 case 2 :
173 psf->sf.samplerate = 50000 ;
174 break ;
175
176 case 3 :
177 psf->sf.samplerate = 16667 ;
178 break ;
179
180 default :
181 /* This is ugly and braindead. */
182 txwh.srhash = ((txwh.sr2 & 0xFE) << 8) | (txwh.sr3 & 0xFE) ;
183 switch (txwh.srhash)
184 { case ((0x6 << 8) | 0x52) :
185 psf->sf.samplerate = 33333 ;
186 break ;
187
188 case ((0x10 << 8) | 0x52) :
189 psf->sf.samplerate = 50000 ;
190 break ;
191
192 case ((0xF6 << 8) | 0x52) :
193 psf->sf.samplerate = 166667 ;
194 break ;
195
196 default :
197 strptr = " Sample Rate : Unknown : forcing to 33333\n" ;
198 psf->sf.samplerate = 33333 ;
199 break ;
200 } ;
201 } ;
202
203
204 if (strptr)
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) ;
208 else
209 psf_log_printf (psf, " Sample Rate : %d => %d\n", txwh.srate, psf->sf.samplerate) ;
210
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) ;
214 } ;
215
216 psf->dataoffset = TXW_DATA_OFFSET ;
217 psf->datalength = psf->filelength - TXW_DATA_OFFSET ;
218 psf->sf.frames = 2 * psf->datalength / 3 ;
219
220
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)) ;
224
225 if (txwh.attacklen + txwh.repeatlen > psf->sf.frames)
226 psf_log_printf (psf, "*** File has been truncated.\n") ;
227
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 ;
232
233 return 0 ;
234 } /* txw_read_header */
235
236 static sf_count_t
237 txw_read_s (SF_PRIVATE *psf, short *ptr, sf_count_t len)
238 { unsigned char *ucptr ;
239 short sample ;
240 int k, bufferlen, readcount, count ;
241 sf_count_t total = 0 ;
242
243 bufferlen = sizeof (psf->u.cbuf) / 3 ;
244 bufferlen -= (bufferlen & 1) ;
245 while (len > 0)
246 { readcount = (len >= bufferlen) ? bufferlen : len ;
247 count = psf_fread (psf->u.cbuf, 3, readcount, psf) ;
248
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 ;
255 ucptr += 3 ;
256 } ;
257
258 total += count ;
259 len -= readcount ;
260 } ;
261
262 return total ;
263 } /* txw_read_s */
264
265 static sf_count_t
266 txw_read_i (SF_PRIVATE *psf, int *ptr, sf_count_t len)
267 { unsigned char *ucptr ;
268 short sample ;
269 int k, bufferlen, readcount, count ;
270 sf_count_t total = 0 ;
271
272 bufferlen = sizeof (psf->u.cbuf) / 3 ;
273 bufferlen -= (bufferlen & 1) ;
274 while (len > 0)
275 { readcount = (len >= bufferlen) ? bufferlen : len ;
276 count = psf_fread (psf->u.cbuf, 3, readcount, psf) ;
277
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 ;
284 ucptr += 3 ;
285 } ;
286
287 total += count ;
288 len -= readcount ;
289 } ;
290
291 return total ;
292 } /* txw_read_i */
293
294 static sf_count_t
295 txw_read_f (SF_PRIVATE *psf, float *ptr, sf_count_t len)
296 { unsigned char *ucptr ;
297 short sample ;
298 int k, bufferlen, readcount, count ;
299 sf_count_t total = 0 ;
300 float normfact ;
301
302 if (psf->norm_float == SF_TRUE)
303 normfact = 1.0 / 0x8000 ;
304 else
305 normfact = 1.0 / 0x10 ;
306
307 bufferlen = sizeof (psf->u.cbuf) / 3 ;
308 bufferlen -= (bufferlen & 1) ;
309 while (len > 0)
310 { readcount = (len >= bufferlen) ? bufferlen : len ;
311 count = psf_fread (psf->u.cbuf, 3, readcount, psf) ;
312
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 ;
319 ucptr += 3 ;
320 } ;
321
322 total += count ;
323 len -= readcount ;
324 } ;
325
326 return total ;
327 } /* txw_read_f */
328
329 static sf_count_t
330 txw_read_d (SF_PRIVATE *psf, double *ptr, sf_count_t len)
331 { unsigned char *ucptr ;
332 short sample ;
333 int k, bufferlen, readcount, count ;
334 sf_count_t total = 0 ;
335 double normfact ;
336
337 if (psf->norm_double == SF_TRUE)
338 normfact = 1.0 / 0x8000 ;
339 else
340 normfact = 1.0 / 0x10 ;
341
342 bufferlen = sizeof (psf->u.cbuf) / 3 ;
343 bufferlen -= (bufferlen & 1) ;
344 while (len > 0)
345 { readcount = (len >= bufferlen) ? bufferlen : len ;
346 count = psf_fread (psf->u.cbuf, 3, readcount, psf) ;
347
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 ;
354 ucptr += 3 ;
355 } ;
356
357 total += count ;
358 len -= readcount ;
359 } ;
360
361 return total ;
362 } /* txw_read_d */
363
364 static sf_count_t
365 txw_seek (SF_PRIVATE *psf, int mode, sf_count_t offset)
366 { if (psf && mode)
367 return offset ;
368
369 return 0 ;
370 } /* txw_seek */
371
372 #endif