Merged with trunk revision 600
[ardour.git] / libs / libsndfile / src / xi.c
1 /*
2 ** Copyright (C) 2003-2006 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 #include "sfconfig.h"
20
21 #include <stdio.h>
22 #include <stdlib.h>
23 #include <fcntl.h>
24 #include <string.h>
25 #include <ctype.h>
26
27 #include "sndfile.h"
28 #include "sfendian.h"
29 #include "common.h"
30 #include "float_cast.h"
31
32 #define MAX_XI_SAMPLES  16
33
34 /*------------------------------------------------------------------------------
35 ** Private static functions and tyepdefs.
36 */
37
38 typedef struct
39 {       /* Warning, this filename is NOT nul terminated. */
40         char    filename [22] ;
41         char    software [20] ;
42         char    sample_name [22] ;
43
44         int             loop_begin, loop_end ;
45         int             sample_flags ;
46
47         /* Data for encoder and decoder. */
48         short   last_16 ;
49 } XI_PRIVATE ;
50
51 static int      xi_close                (SF_PRIVATE *psf) ;
52 static int      xi_write_header (SF_PRIVATE *psf, int calc_length) ;
53 static int      xi_read_header  (SF_PRIVATE *psf) ;
54 static int      dpcm_init               (SF_PRIVATE *psf) ;
55
56
57 static sf_count_t       dpcm_seek (SF_PRIVATE *psf, int mode, sf_count_t offset) ;
58
59 /*------------------------------------------------------------------------------
60 ** Public function.
61 */
62
63 int
64 xi_open (SF_PRIVATE *psf)
65 {       XI_PRIVATE *pxi ;
66         int             subformat, error = 0 ;
67
68         if (psf->is_pipe)
69                 return SFE_XI_NO_PIPE ;
70
71         if (psf->fdata)
72                 pxi = psf->fdata ;
73         else if ((pxi = calloc (1, sizeof (XI_PRIVATE))) == NULL)
74                 return SFE_MALLOC_FAILED ;
75
76         psf->fdata = pxi ;
77
78         if (psf->mode == SFM_READ || (psf->mode == SFM_RDWR && psf->filelength > 0))
79         {       if ((error = xi_read_header (psf)))
80                         return error ;
81                 } ;
82
83         subformat = psf->sf.format & SF_FORMAT_SUBMASK ;
84
85         if (psf->mode == SFM_WRITE || psf->mode == SFM_RDWR)
86         {       if ((psf->sf.format & SF_FORMAT_TYPEMASK) != SF_FORMAT_XI)
87                         return  SFE_BAD_OPEN_FORMAT ;
88
89                 psf->endian = SF_ENDIAN_LITTLE ;
90                 psf->sf.channels = 1 ; /* Always mono */
91                 psf->sf.samplerate = 44100 ; /* Always */
92
93                 /* Set up default instrument and software name. */
94                 memcpy (pxi->filename, "Default Name            ", sizeof (pxi->filename)) ;
95                 memcpy (pxi->software, PACKAGE "-" VERSION "               ", sizeof (pxi->software)) ;
96
97                 memset (pxi->sample_name, 0, sizeof (pxi->sample_name)) ;
98                 LSF_SNPRINTF (pxi->sample_name, sizeof (pxi->sample_name), "%s", "Sample #1") ;
99
100                 pxi->sample_flags = (subformat == SF_FORMAT_DPCM_16) ? 16 : 0 ;
101
102                 if (xi_write_header (psf, SF_FALSE))
103                         return psf->error ;
104
105                 psf->write_header = xi_write_header ;
106                 } ;
107
108         psf->container_close = xi_close ;
109         psf->seek = dpcm_seek ;
110
111         psf->sf.seekable = SF_FALSE ;
112
113         psf->blockwidth = psf->bytewidth * psf->sf.channels ;
114
115         switch (subformat)
116         {       case SF_FORMAT_DPCM_8 :         /* 8-bit differential PCM. */
117                 case SF_FORMAT_DPCM_16 :        /* 16-bit differential PCM. */
118                                 error = dpcm_init (psf) ;
119                                 break ;
120
121                 default : break ;
122                 } ;
123
124         return error ;
125 } /* xi_open */
126
127 /*------------------------------------------------------------------------------
128 */
129
130 static int
131 xi_close        (SF_PRIVATE *psf)
132 {
133         psf = psf ;
134
135         return 0 ;
136 } /* xi_close */
137
138 /*==============================================================================
139 */
140
141 static sf_count_t dpcm_read_dsc2s (SF_PRIVATE *psf, short *ptr, sf_count_t len) ;
142 static sf_count_t dpcm_read_dsc2i (SF_PRIVATE *psf, int *ptr, sf_count_t len) ;
143 static sf_count_t dpcm_read_dsc2f (SF_PRIVATE *psf, float *ptr, sf_count_t len) ;
144 static sf_count_t dpcm_read_dsc2d (SF_PRIVATE *psf, double *ptr, sf_count_t len) ;
145
146 static sf_count_t dpcm_write_s2dsc (SF_PRIVATE *psf, const short *ptr, sf_count_t len) ;
147 static sf_count_t dpcm_write_i2dsc (SF_PRIVATE *psf, const int *ptr, sf_count_t len) ;
148 static sf_count_t dpcm_write_f2dsc (SF_PRIVATE *psf, const float *ptr, sf_count_t len) ;
149 static sf_count_t dpcm_write_d2dsc (SF_PRIVATE *psf, const double *ptr, sf_count_t len) ;
150
151 static sf_count_t dpcm_read_dles2s (SF_PRIVATE *psf, short *ptr, sf_count_t len) ;
152 static sf_count_t dpcm_read_dles2i (SF_PRIVATE *psf, int *ptr, sf_count_t len) ;
153 static sf_count_t dpcm_read_dles2f (SF_PRIVATE *psf, float *ptr, sf_count_t len) ;
154 static sf_count_t dpcm_read_dles2d (SF_PRIVATE *psf, double *ptr, sf_count_t len) ;
155
156 static sf_count_t dpcm_write_s2dles (SF_PRIVATE *psf, const short *ptr, sf_count_t len) ;
157 static sf_count_t dpcm_write_i2dles (SF_PRIVATE *psf, const int *ptr, sf_count_t len) ;
158 static sf_count_t dpcm_write_f2dles (SF_PRIVATE *psf, const float *ptr, sf_count_t len) ;
159 static sf_count_t dpcm_write_d2dles (SF_PRIVATE *psf, const double *ptr, sf_count_t len) ;
160
161 static int
162 dpcm_init (SF_PRIVATE *psf)
163 {       if (psf->bytewidth == 0 || psf->sf.channels == 0)
164                 return SFE_INTERNAL ;
165
166         psf->blockwidth = psf->bytewidth * psf->sf.channels ;
167
168         if (psf->mode == SFM_READ || psf->mode == SFM_RDWR)
169         {       switch (psf->bytewidth)
170                 {       case 1 :
171                                         psf->read_short         = dpcm_read_dsc2s ;
172                                         psf->read_int           = dpcm_read_dsc2i ;
173                                         psf->read_float         = dpcm_read_dsc2f ;
174                                         psf->read_double        = dpcm_read_dsc2d ;
175                                         break ;
176                         case 2 :
177                                         psf->read_short         = dpcm_read_dles2s ;
178                                         psf->read_int           = dpcm_read_dles2i ;
179                                         psf->read_float         = dpcm_read_dles2f ;
180                                         psf->read_double        = dpcm_read_dles2d ;
181                                         break ;
182                         default :
183                                 psf_log_printf (psf, "dpcm_init() returning SFE_UNIMPLEMENTED\n") ;
184                                 return SFE_UNIMPLEMENTED ;
185                         } ;
186                 } ;
187
188         if (psf->mode == SFM_WRITE || psf->mode == SFM_RDWR)
189         {       switch (psf->bytewidth)
190                 {       case 1 :
191                                         psf->write_short        = dpcm_write_s2dsc ;
192                                         psf->write_int          = dpcm_write_i2dsc ;
193                                         psf->write_float        = dpcm_write_f2dsc ;
194                                         psf->write_double       = dpcm_write_d2dsc ;
195                                         break ;
196                         case 2 :
197                                         psf->write_short        = dpcm_write_s2dles ;
198                                         psf->write_int          = dpcm_write_i2dles ;
199                                         psf->write_float        = dpcm_write_f2dles ;
200                                         psf->write_double       = dpcm_write_d2dles ;
201                                         break ;
202                         default :
203                                 psf_log_printf (psf, "dpcm_init() returning SFE_UNIMPLEMENTED\n") ;
204                                 return SFE_UNIMPLEMENTED ;
205                         } ;
206                 } ;
207
208         psf->filelength = psf_get_filelen (psf) ;
209         psf->datalength = (psf->dataend) ? psf->dataend - psf->dataoffset :
210                                                         psf->filelength - psf->dataoffset ;
211         psf->sf.frames = psf->datalength / psf->blockwidth ;
212
213         return 0 ;
214 } /* dpcm_init */
215
216 /*==============================================================================
217 */
218
219 static sf_count_t
220 dpcm_seek (SF_PRIVATE *psf, int mode, sf_count_t offset)
221 {       XI_PRIVATE      *pxi ;
222         int                     total, bufferlen, len ;
223
224         if ((pxi = psf->fdata) == NULL)
225                 return SFE_INTERNAL ;
226
227         if (psf->datalength < 0 || psf->dataoffset < 0)
228         {       psf->error = SFE_BAD_SEEK ;
229                 return  PSF_SEEK_ERROR ;
230                 } ;
231
232         if (offset == 0)
233         {       psf_fseek (psf, psf->dataoffset, SEEK_SET) ;
234                 pxi->last_16 = 0 ;
235                 return 0 ;
236                 } ;
237
238         if (offset < 0 || offset > psf->sf.frames)
239         {       psf->error = SFE_BAD_SEEK ;
240                 return  PSF_SEEK_ERROR ;
241                 } ;
242
243         if (mode != SFM_READ)
244         {       /* What to do about write??? */
245                 psf->error = SFE_BAD_SEEK ;
246                 return  PSF_SEEK_ERROR ;
247                 } ;
248
249         psf_fseek (psf, psf->dataoffset, SEEK_SET) ;
250
251         if ((psf->sf.format & SF_FORMAT_SUBMASK) == SF_FORMAT_DPCM_16)
252         {       total = offset ;
253                 bufferlen = ARRAY_LEN (psf->u.sbuf) ;
254                 while (total > 0)
255                 {       len = (total > bufferlen) ? bufferlen : total ;
256                         total -= dpcm_read_dles2s (psf, psf->u.sbuf, len) ;
257                         } ;
258                 }
259         else
260         {       total = offset ;
261                 bufferlen = ARRAY_LEN (psf->u.sbuf) ;
262                 while (total > 0)
263                 {       len = (total > bufferlen) ? bufferlen : total ;
264                         total -= dpcm_read_dsc2s (psf, psf->u.sbuf, len) ;
265                         } ;
266                 } ;
267
268         return offset ;
269 } /* dpcm_seek */
270
271
272 static int
273 xi_write_header (SF_PRIVATE *psf, int calc_length)
274 {       XI_PRIVATE      *pxi ;
275         sf_count_t      current ;
276         const char      *string ;
277
278         if ((pxi = psf->fdata) == NULL)
279                 return SFE_INTERNAL ;
280
281         calc_length = calc_length ; /* Avoid a compiler warning. */
282
283         current = psf_ftell (psf) ;
284
285         /* Reset the current header length to zero. */
286         psf->header [0] = 0 ;
287         psf->headindex = 0 ;
288         psf_fseek (psf, 0, SEEK_SET) ;
289
290         string = "Extended Instrument: " ;
291         psf_binheader_writef (psf, "b", string, strlen (string)) ;
292         psf_binheader_writef (psf, "b1", pxi->filename, sizeof (pxi->filename), 0x1A) ;
293
294         /* Write software version and two byte XI version. */
295         psf_binheader_writef (psf, "eb2", pxi->software, sizeof (pxi->software), (1 << 8) + 2) ;
296
297         /*
298         ** Jump note numbers (96), volume envelope (48), pan envelope (48),
299         ** volume points (1), pan points (1)
300         */
301         psf_binheader_writef (psf, "z", (size_t) (96 + 48 + 48 + 1 + 1)) ;
302
303         /* Jump volume loop (3 bytes), pan loop (3), envelope flags (3), vibrato (3)
304         ** fade out (2), 22 unknown bytes, and then write sample_count (2 bytes).
305         */
306         psf_binheader_writef (psf, "ez2z2", (size_t) (4 * 3), 0x1234, make_size_t (22), 1) ;
307
308         pxi->loop_begin = 0 ;
309         pxi->loop_end = 0 ;
310
311         psf_binheader_writef (psf, "et844", psf->sf.frames, pxi->loop_begin, pxi->loop_end) ;
312
313         /* volume, fine tune, flags, pan, note, namelen */
314         psf_binheader_writef (psf, "111111", 128, 0, pxi->sample_flags, 128, 0, strlen (pxi->sample_name)) ;
315
316         psf_binheader_writef (psf, "b", pxi->sample_name, sizeof (pxi->sample_name)) ;
317
318
319
320
321
322         /* Header construction complete so write it out. */
323         psf_fwrite (psf->header, psf->headindex, 1, psf) ;
324
325         if (psf->error)
326                 return psf->error ;
327
328         psf->dataoffset = psf->headindex ;
329
330         if (current > 0)
331                 psf_fseek (psf, current, SEEK_SET) ;
332
333         return psf->error ;
334 } /* xi_write_header */
335
336 static int
337 xi_read_header (SF_PRIVATE *psf)
338 {       char    buffer [64], name [32] ;
339         short   version, fade_out, sample_count ;
340         int             k, loop_begin, loop_end ;
341         int     sample_sizes [MAX_XI_SAMPLES] ;
342
343         psf_binheader_readf (psf, "pb", 0, buffer, 21) ;
344
345         memset (sample_sizes, 0, sizeof (sample_sizes)) ;
346
347         buffer [20] = 0 ;
348         if (strcmp (buffer, "Extended Instrument:") != 0)
349                 return SFE_XI_BAD_HEADER ;
350
351         memset (buffer, 0, sizeof (buffer)) ;
352         psf_binheader_readf (psf, "b", buffer, 23) ;
353
354         if (buffer [22] != 0x1A)
355                 return SFE_XI_BAD_HEADER ;
356
357         buffer [22] = 0 ;
358         psf_log_printf (psf, "Extended Instrument : %s\n", buffer) ;
359
360         psf_binheader_readf (psf, "be2", buffer, 20, &version) ;
361         buffer [19] = 0 ;
362         psf_log_printf (psf, "Software : %s\nVersion  : %d.%02d\n", buffer, version / 256, version % 256) ;
363
364         /* Jump note numbers (96), volume envelope (48), pan envelope (48),
365         ** volume points (1), pan points (1)
366         */
367         psf_binheader_readf (psf, "j", 96 + 48 + 48 + 1 + 1) ;
368
369         psf_binheader_readf (psf, "b", buffer, 12) ;
370         psf_log_printf (psf, "Volume Loop\n  sustain : %u\n  begin   : %u\n  end     : %u\n",
371                                                 buffer [0], buffer [1], buffer [2]) ;
372         psf_log_printf (psf, "Pan Loop\n  sustain : %u\n  begin   : %u\n  end     : %u\n",
373                                                 buffer [3], buffer [4], buffer [5]) ;
374         psf_log_printf (psf, "Envelope Flags\n  volume  : 0x%X\n  pan     : 0x%X\n",
375                                 buffer [6] & 0xFF, buffer [7] & 0xFF) ;
376
377         psf_log_printf (psf, "Vibrato\n  type    : %u\n  sweep   : %u\n  depth   : %u\n  rate    : %u\n",
378                                 buffer [8], buffer [9], buffer [10], buffer [11]) ;
379
380         /*
381         ** Read fade_out then jump reserved (2 bytes) and ???? (20 bytes) and
382         ** sample_count.
383         */
384         psf_binheader_readf (psf, "e2j2", &fade_out, 2 + 20, &sample_count) ;
385         psf_log_printf (psf, "Fade out  : %d\n", fade_out) ;
386
387         /* XI file can contain up to 16 samples. */
388         if (sample_count > MAX_XI_SAMPLES)
389                 return SFE_XI_EXCESS_SAMPLES ;
390
391         if (psf->instrument == NULL && (psf->instrument = psf_instrument_alloc ()) == NULL)
392                 return SFE_MALLOC_FAILED ;
393
394         /* Log all data for each sample. */
395         for (k = 0 ; k < sample_count ; k++)
396         {       psf_binheader_readf (psf, "e444", &(sample_sizes [k]), &loop_begin, &loop_end) ;
397
398                 /* Read 5 know bytes, 1 unknown byte and 22 name bytes. */
399                 psf_binheader_readf (psf, "bb", buffer, 6, name, 22) ;
400                 name [21] = 0 ;
401
402                 psf_log_printf (psf, "Sample #%d\n  name    : %s\n", k + 1, name) ;
403
404                 psf_log_printf (psf, "  size    : %d\n", sample_sizes [k]) ;
405
406
407
408                 psf_log_printf (psf, "  loop\n    begin : %d\n    end   : %d\n", loop_begin, loop_end) ;
409
410                 psf_log_printf (psf, "  volume  : %u\n  f. tune : %d\n  flags   : 0x%02X ",
411                                         buffer [0] & 0xFF, buffer [1] & 0xFF, buffer [2] & 0xFF) ;
412
413                 psf_log_printf (psf, " (") ;
414                 if (buffer [2] & 1)
415                         psf_log_printf (psf, " Loop") ;
416                 if (buffer [2] & 2)
417                         psf_log_printf (psf, " PingPong") ;
418                 psf_log_printf (psf, (buffer [2] & 16) ? " 16bit" : " 8bit") ;
419                 psf_log_printf (psf, " )\n") ;
420
421                 psf_log_printf (psf, "  pan     : %u\n  note    : %d\n  namelen : %d\n",
422                                         buffer [3] & 0xFF, buffer [4], buffer [5]) ;
423
424                 if (k != 0)
425                         continue ;
426
427                 if (buffer [2] & 16)
428                 {       psf->sf.format = SF_FORMAT_XI | SF_FORMAT_DPCM_16 ;
429                         psf->bytewidth = 2 ;
430                         }
431                 else
432                 {       psf->sf.format = SF_FORMAT_XI | SF_FORMAT_DPCM_8 ;
433                         psf->bytewidth = 1 ;
434                         } ;
435                 } ;
436
437         while (sample_count > 1 && sample_sizes [sample_count - 1] == 0)
438                 sample_count -- ;
439
440         /* Currently, we can only handle 1 sample per file. */
441
442         if (sample_count > 2)
443         {       psf_log_printf (psf, "*** Sample count is less than 16 but more than 1.\n") ;
444                 psf_log_printf (psf, "  sample count : %d    sample_sizes [%d] : %d\n",
445                                                 sample_count, sample_count - 1, sample_sizes [sample_count - 1]) ;
446                 return SFE_XI_EXCESS_SAMPLES ;
447                 } ;
448
449         psf->dataoffset = psf_fseek (psf, 0, SEEK_CUR) ;
450         psf_log_printf (psf, "Data Offset : %D\n", psf->dataoffset) ;
451
452         psf->datalength = sample_sizes [0] ;
453
454         if (psf->dataoffset + psf->datalength > psf->filelength)
455         {       psf_log_printf (psf, "*** File seems to be truncated. Should be at least %D bytes long.\n",
456                                 psf->dataoffset + sample_sizes [0]) ;
457                 psf->datalength = psf->filelength - psf->dataoffset ;
458                 } ;
459
460         if (psf_fseek (psf, psf->dataoffset, SEEK_SET) != psf->dataoffset)
461                 return SFE_BAD_SEEK ;
462
463         psf->endian = SF_ENDIAN_LITTLE ;
464         psf->sf.channels = 1 ; /* Always mono */
465         psf->sf.samplerate = 44100 ; /* Always */
466
467         psf->blockwidth = psf->sf.channels * psf->bytewidth ;
468
469         if (! psf->sf.frames && psf->blockwidth)
470                 psf->sf.frames = (psf->filelength - psf->dataoffset) / psf->blockwidth ;
471
472         psf->instrument->basenote = 0 ;
473         psf->instrument->gain = 1 ;
474         psf->instrument->velocity_lo = psf->instrument->key_lo = 0 ;
475         psf->instrument->velocity_hi = psf->instrument->key_hi = 127 ;
476
477         return 0 ;
478 } /* xi_read_header */
479
480 /*==============================================================================
481 */
482
483 static void dsc2s_array (XI_PRIVATE *pxi, signed char *src, int count, short *dest) ;
484 static void dsc2i_array (XI_PRIVATE *pxi, signed char *src, int count, int *dest) ;
485 static void dsc2f_array (XI_PRIVATE *pxi, signed char *src, int count, float *dest, float normfact) ;
486 static void dsc2d_array (XI_PRIVATE *pxi, signed char *src, int count, double *dest, double normfact) ;
487
488 static void dles2s_array (XI_PRIVATE *pxi, short *src, int count, short *dest) ;
489 static void dles2i_array (XI_PRIVATE *pxi, short *src, int count, int *dest) ;
490 static void dles2f_array (XI_PRIVATE *pxi, short *src, int count, float *dest, float normfact) ;
491 static void dles2d_array (XI_PRIVATE *pxi, short *src, int count, double *dest, double normfact) ;
492
493 static sf_count_t
494 dpcm_read_dsc2s (SF_PRIVATE *psf, short *ptr, sf_count_t len)
495 {       XI_PRIVATE      *pxi ;
496         int                     bufferlen, readcount ;
497         sf_count_t      total = 0 ;
498
499         if ((pxi = psf->fdata) == NULL)
500                 return 0 ;
501
502         bufferlen = ARRAY_LEN (psf->u.ucbuf) ;
503
504         while (len > 0)
505         {       if (len < bufferlen)
506                         bufferlen = (int) len ;
507                 readcount = psf_fread (psf->u.scbuf, sizeof (signed char), bufferlen, psf) ;
508                 dsc2s_array (pxi, psf->u.scbuf, readcount, ptr + total) ;
509                 total += readcount ;
510                 if (readcount < bufferlen)
511                         break ;
512                 len -= readcount ;
513                 } ;
514
515         return total ;
516 } /* dpcm_read_dsc2s */
517
518 static sf_count_t
519 dpcm_read_dsc2i (SF_PRIVATE *psf, int *ptr, sf_count_t len)
520 {       XI_PRIVATE      *pxi ;
521         int                     bufferlen, readcount ;
522         sf_count_t      total = 0 ;
523
524         if ((pxi = psf->fdata) == NULL)
525                 return 0 ;
526
527         bufferlen = ARRAY_LEN (psf->u.ucbuf) ;
528
529         while (len > 0)
530         {       if (len < bufferlen)
531                         bufferlen = (int) len ;
532                 readcount = psf_fread (psf->u.scbuf, sizeof (signed char), bufferlen, psf) ;
533                 dsc2i_array (pxi, psf->u.scbuf, readcount, ptr + total) ;
534                 total += readcount ;
535                 if (readcount < bufferlen)
536                         break ;
537                 len -= readcount ;
538                 } ;
539
540         return total ;
541 } /* dpcm_read_dsc2i */
542
543 static sf_count_t
544 dpcm_read_dsc2f (SF_PRIVATE *psf, float *ptr, sf_count_t len)
545 {       XI_PRIVATE      *pxi ;
546         int                     bufferlen, readcount ;
547         sf_count_t      total = 0 ;
548         float           normfact ;
549
550         if ((pxi = psf->fdata) == NULL)
551                 return 0 ;
552
553         normfact = (psf->norm_float == SF_TRUE) ? 1.0 / ((float) 0x80) : 1.0 ;
554
555         bufferlen = ARRAY_LEN (psf->u.ucbuf) ;
556
557         while (len > 0)
558         {       if (len < bufferlen)
559                         bufferlen = (int) len ;
560                 readcount = psf_fread (psf->u.scbuf, sizeof (signed char), bufferlen, psf) ;
561                 dsc2f_array (pxi, psf->u.scbuf, readcount, ptr + total, normfact) ;
562                 total += readcount ;
563                 if (readcount < bufferlen)
564                         break ;
565                 len -= readcount ;
566                 } ;
567
568         return total ;
569 } /* dpcm_read_dsc2f */
570
571 static sf_count_t
572 dpcm_read_dsc2d (SF_PRIVATE *psf, double *ptr, sf_count_t len)
573 {       XI_PRIVATE      *pxi ;
574         int                     bufferlen, readcount ;
575         sf_count_t      total = 0 ;
576         double          normfact ;
577
578         if ((pxi = psf->fdata) == NULL)
579                 return 0 ;
580
581         normfact = (psf->norm_double == SF_TRUE) ? 1.0 / ((double) 0x80) : 1.0 ;
582
583         bufferlen = ARRAY_LEN (psf->u.ucbuf) ;
584
585         while (len > 0)
586         {       if (len < bufferlen)
587                         bufferlen = (int) len ;
588                 readcount = psf_fread (psf->u.scbuf, sizeof (signed char), bufferlen, psf) ;
589                 dsc2d_array (pxi, psf->u.scbuf, readcount, ptr + total, normfact) ;
590                 total += readcount ;
591                 if (readcount < bufferlen)
592                         break ;
593                 len -= readcount ;
594                 } ;
595
596         return total ;
597 } /* dpcm_read_dsc2d */
598
599 /*------------------------------------------------------------------------------
600 */
601
602 static sf_count_t
603 dpcm_read_dles2s (SF_PRIVATE *psf, short *ptr, sf_count_t len)
604 {       XI_PRIVATE      *pxi ;
605         int                     bufferlen, readcount ;
606         sf_count_t      total = 0 ;
607
608         if ((pxi = psf->fdata) == NULL)
609                 return 0 ;
610
611         bufferlen = ARRAY_LEN (psf->u.sbuf) ;
612
613         while (len > 0)
614         {       if (len < bufferlen)
615                         bufferlen = (int) len ;
616                 readcount = psf_fread (psf->u.sbuf, sizeof (short), bufferlen, psf) ;
617                 dles2s_array (pxi, psf->u.sbuf, readcount, ptr + total) ;
618                 total += readcount ;
619                 if (readcount < bufferlen)
620                         break ;
621                 len -= readcount ;
622                 } ;
623
624         return total ;
625 } /* dpcm_read_dles2s */
626
627 static sf_count_t
628 dpcm_read_dles2i (SF_PRIVATE *psf, int *ptr, sf_count_t len)
629 {       XI_PRIVATE      *pxi ;
630         int                     bufferlen, readcount ;
631         sf_count_t      total = 0 ;
632
633         if ((pxi = psf->fdata) == NULL)
634                 return 0 ;
635
636         bufferlen = ARRAY_LEN (psf->u.sbuf) ;
637
638         while (len > 0)
639         {       if (len < bufferlen)
640                         bufferlen = (int) len ;
641                 readcount = psf_fread (psf->u.sbuf, sizeof (short), bufferlen, psf) ;
642                 dles2i_array (pxi, psf->u.sbuf, readcount, ptr + total) ;
643                 total += readcount ;
644                 if (readcount < bufferlen)
645                         break ;
646                 len -= readcount ;
647                 } ;
648
649         return total ;
650 } /* dpcm_read_dles2i */
651
652 static sf_count_t
653 dpcm_read_dles2f (SF_PRIVATE *psf, float *ptr, sf_count_t len)
654 {       XI_PRIVATE      *pxi ;
655         int                     bufferlen, readcount ;
656         sf_count_t      total = 0 ;
657         float           normfact ;
658
659         if ((pxi = psf->fdata) == NULL)
660                 return 0 ;
661
662         normfact = (psf->norm_float == SF_TRUE) ? 1.0 / ((float) 0x8000) : 1.0 ;
663
664         bufferlen = ARRAY_LEN (psf->u.sbuf) ;
665
666         while (len > 0)
667         {       if (len < bufferlen)
668                         bufferlen = (int) len ;
669                 readcount = psf_fread (psf->u.sbuf, sizeof (short), bufferlen, psf) ;
670                 dles2f_array (pxi, psf->u.sbuf, readcount, ptr + total, normfact) ;
671                 total += readcount ;
672                 if (readcount < bufferlen)
673                         break ;
674                 len -= readcount ;
675                 } ;
676
677         return total ;
678 } /* dpcm_read_dles2f */
679
680 static sf_count_t
681 dpcm_read_dles2d (SF_PRIVATE *psf, double *ptr, sf_count_t len)
682 {       XI_PRIVATE      *pxi ;
683         int                     bufferlen, readcount ;
684         sf_count_t      total = 0 ;
685         double          normfact ;
686
687         if ((pxi = psf->fdata) == NULL)
688                 return 0 ;
689
690         normfact = (psf->norm_double == SF_TRUE) ? 1.0 / ((double) 0x8000) : 1.0 ;
691
692         bufferlen = ARRAY_LEN (psf->u.sbuf) ;
693
694         while (len > 0)
695         {       if (len < bufferlen)
696                         bufferlen = (int) len ;
697                 readcount = psf_fread (psf->u.sbuf, sizeof (short), bufferlen, psf) ;
698                 dles2d_array (pxi, psf->u.sbuf, readcount, ptr + total, normfact) ;
699                 total += readcount ;
700                 if (readcount < bufferlen)
701                         break ;
702                 len -= readcount ;
703                 } ;
704
705         return total ;
706 } /* dpcm_read_dles2d */
707
708 /*==============================================================================
709 */
710
711 static void s2dsc_array (XI_PRIVATE *pxi, const short *src, signed char *dest, int count) ;
712 static void i2dsc_array (XI_PRIVATE *pxi, const int *src, signed char *dest, int count) ;
713 static void f2dsc_array (XI_PRIVATE *pxi, const float *src, signed char *dest, int count, float normfact) ;
714 static void d2dsc_array (XI_PRIVATE *pxi, const double *src, signed char *dest, int count, double normfact) ;
715
716 static void     s2dles_array (XI_PRIVATE *pxi, const short *src, short *dest, int count) ;
717 static void i2dles_array (XI_PRIVATE *pxi, const int *src, short *dest, int count) ;
718 static void f2dles_array (XI_PRIVATE *pxi, const float *src, short *dest, int count, float normfact) ;
719 static void d2dles_array (XI_PRIVATE *pxi, const double *src, short *dest, int count, double normfact) ;
720
721
722 static sf_count_t
723 dpcm_write_s2dsc (SF_PRIVATE *psf, const short *ptr, sf_count_t len)
724 {       XI_PRIVATE      *pxi ;
725         int                     bufferlen, writecount ;
726         sf_count_t      total = 0 ;
727
728         if ((pxi = psf->fdata) == NULL)
729                 return 0 ;
730
731         bufferlen = ARRAY_LEN (psf->u.ucbuf) ;
732
733         while (len > 0)
734         {       if (len < bufferlen)
735                         bufferlen = (int) len ;
736                 s2dsc_array (pxi, ptr + total, psf->u.scbuf, bufferlen) ;
737                 writecount = psf_fwrite (psf->u.scbuf, sizeof (signed char), bufferlen, psf) ;
738                 total += writecount ;
739                 if (writecount < bufferlen)
740                         break ;
741                 len -= writecount ;
742                 } ;
743
744         return total ;
745 } /* dpcm_write_s2dsc */
746
747 static sf_count_t
748 dpcm_write_i2dsc (SF_PRIVATE *psf, const int *ptr, sf_count_t len)
749 {       XI_PRIVATE      *pxi ;
750         int                     bufferlen, writecount ;
751         sf_count_t      total = 0 ;
752
753         if ((pxi = psf->fdata) == NULL)
754                 return 0 ;
755
756         bufferlen = ARRAY_LEN (psf->u.ucbuf) ;
757
758         while (len > 0)
759         {       if (len < bufferlen)
760                         bufferlen = (int) len ;
761                 i2dsc_array (pxi, ptr + total, psf->u.scbuf, bufferlen) ;
762                 writecount = psf_fwrite (psf->u.scbuf, sizeof (signed char), bufferlen, psf) ;
763                 total += writecount ;
764                 if (writecount < bufferlen)
765                         break ;
766                 len -= writecount ;
767                 } ;
768
769         return total ;
770 } /* dpcm_write_i2dsc */
771
772 static sf_count_t
773 dpcm_write_f2dsc (SF_PRIVATE *psf, const float *ptr, sf_count_t len)
774 {       XI_PRIVATE      *pxi ;
775         int                     bufferlen, writecount ;
776         sf_count_t      total = 0 ;
777         float           normfact ;
778
779         if ((pxi = psf->fdata) == NULL)
780                 return 0 ;
781
782         normfact = (psf->norm_float == SF_TRUE) ? (1.0 * 0x7F) : 1.0 ;
783
784         bufferlen = ARRAY_LEN (psf->u.ucbuf) ;
785
786         while (len > 0)
787         {       if (len < bufferlen)
788                         bufferlen = (int) len ;
789                 f2dsc_array (pxi, ptr + total, psf->u.scbuf, bufferlen, normfact) ;
790                 writecount = psf_fwrite (psf->u.scbuf, sizeof (signed char), bufferlen, psf) ;
791                 total += writecount ;
792                 if (writecount < bufferlen)
793                         break ;
794                 len -= writecount ;
795                 } ;
796
797         return total ;
798 } /* dpcm_write_f2dsc */
799
800 static sf_count_t
801 dpcm_write_d2dsc (SF_PRIVATE *psf, const double *ptr, sf_count_t len)
802 {       XI_PRIVATE      *pxi ;
803         int                     bufferlen, writecount ;
804         sf_count_t      total = 0 ;
805         double          normfact ;
806
807         if ((pxi = psf->fdata) == NULL)
808                 return 0 ;
809
810         normfact = (psf->norm_double == SF_TRUE) ? (1.0 * 0x7F) : 1.0 ;
811
812         bufferlen = ARRAY_LEN (psf->u.ucbuf) ;
813
814         while (len > 0)
815         {       if (len < bufferlen)
816                         bufferlen = (int) len ;
817                 d2dsc_array (pxi, ptr + total, psf->u.scbuf, bufferlen, normfact) ;
818                 writecount = psf_fwrite (psf->u.scbuf, sizeof (signed char), bufferlen, psf) ;
819                 total += writecount ;
820                 if (writecount < bufferlen)
821                         break ;
822                 len -= writecount ;
823                 } ;
824
825         return total ;
826 } /* dpcm_write_d2dsc */
827
828
829 static sf_count_t
830 dpcm_write_s2dles (SF_PRIVATE *psf, const short *ptr, sf_count_t len)
831 {       XI_PRIVATE      *pxi ;
832         int                     bufferlen, writecount ;
833         sf_count_t      total = 0 ;
834
835         if ((pxi = psf->fdata) == NULL)
836                 return 0 ;
837
838         bufferlen = ARRAY_LEN (psf->u.sbuf) ;
839
840         while (len > 0)
841         {       if (len < bufferlen)
842                         bufferlen = (int) len ;
843                 s2dles_array (pxi, ptr + total, psf->u.sbuf, bufferlen) ;
844                 writecount = psf_fwrite (psf->u.sbuf, sizeof (short), bufferlen, psf) ;
845                 total += writecount ;
846                 if (writecount < bufferlen)
847                         break ;
848                 len -= writecount ;
849                 } ;
850
851         return total ;
852 } /* dpcm_write_s2dles */
853
854 static sf_count_t
855 dpcm_write_i2dles (SF_PRIVATE *psf, const int *ptr, sf_count_t len)
856 {       XI_PRIVATE      *pxi ;
857         int                     bufferlen, writecount ;
858         sf_count_t      total = 0 ;
859
860         if ((pxi = psf->fdata) == NULL)
861                 return 0 ;
862
863         bufferlen = ARRAY_LEN (psf->u.sbuf) ;
864
865         while (len > 0)
866         {       if (len < bufferlen)
867                         bufferlen = (int) len ;
868                 i2dles_array (pxi, ptr + total, psf->u.sbuf, bufferlen) ;
869                 writecount = psf_fwrite (psf->u.sbuf, sizeof (short), bufferlen, psf) ;
870                 total += writecount ;
871                 if (writecount < bufferlen)
872                         break ;
873                 len -= writecount ;
874                 } ;
875
876         return total ;
877 } /* dpcm_write_i2dles */
878
879 static sf_count_t
880 dpcm_write_f2dles (SF_PRIVATE *psf, const float *ptr, sf_count_t len)
881 {       XI_PRIVATE      *pxi ;
882         int                     bufferlen, writecount ;
883         sf_count_t      total = 0 ;
884         float           normfact ;
885
886         if ((pxi = psf->fdata) == NULL)
887                 return 0 ;
888
889         normfact = (psf->norm_float == SF_TRUE) ? (1.0 * 0x7FFF) : 1.0 ;
890
891         bufferlen = ARRAY_LEN (psf->u.sbuf) ;
892
893         while (len > 0)
894         {       if (len < bufferlen)
895                         bufferlen = (int) len ;
896                 f2dles_array (pxi, ptr + total, psf->u.sbuf, bufferlen, normfact) ;
897                 writecount = psf_fwrite (psf->u.sbuf, sizeof (short), bufferlen, psf) ;
898                 total += writecount ;
899                 if (writecount < bufferlen)
900                         break ;
901                 len -= writecount ;
902                 } ;
903
904         return total ;
905 } /* dpcm_write_f2dles */
906
907 static sf_count_t
908 dpcm_write_d2dles (SF_PRIVATE *psf, const double *ptr, sf_count_t len)
909 {       XI_PRIVATE      *pxi ;
910         int                     bufferlen, writecount ;
911         sf_count_t      total = 0 ;
912         double          normfact ;
913
914         if ((pxi = psf->fdata) == NULL)
915                 return 0 ;
916
917         normfact = (psf->norm_double == SF_TRUE) ? (1.0 * 0x7FFF) : 1.0 ;
918
919         bufferlen = ARRAY_LEN (psf->u.sbuf) ;
920
921         while (len > 0)
922         {       if (len < bufferlen)
923                         bufferlen = (int) len ;
924                 d2dles_array (pxi, ptr + total, psf->u.sbuf, bufferlen, normfact) ;
925                 writecount = psf_fwrite (psf->u.sbuf, sizeof (short), bufferlen, psf) ;
926                 total += writecount ;
927                 if (writecount < bufferlen)
928                         break ;
929                 len -= writecount ;
930                 } ;
931
932         return total ;
933 } /* dpcm_write_d2dles */
934
935
936 /*==============================================================================
937 */
938
939 static void
940 dsc2s_array (XI_PRIVATE *pxi, signed char *src, int count, short *dest)
941 {       signed char     last_val ;
942         int                     k ;
943
944         last_val = pxi->last_16 >> 8 ;
945
946         for (k = 0 ; k < count ; k++)
947         {       last_val += src [k] ;
948                 dest [k] = last_val << 8 ;
949                 } ;
950
951         pxi->last_16 = last_val << 8 ;
952 } /* dsc2s_array */
953
954 static void
955 dsc2i_array (XI_PRIVATE *pxi, signed char *src, int count, int *dest)
956 {       signed char     last_val ;
957         int                     k ;
958
959         last_val = pxi->last_16 >> 8 ;
960
961         for (k = 0 ; k < count ; k++)
962         {       last_val += src [k] ;
963                 dest [k] = last_val << 24 ;
964                 } ;
965
966         pxi->last_16 = last_val << 8 ;
967 } /* dsc2i_array */
968
969 static void
970 dsc2f_array (XI_PRIVATE *pxi, signed char *src, int count, float *dest, float normfact)
971 {       signed char     last_val ;
972         int                     k ;
973
974         last_val = pxi->last_16 >> 8 ;
975
976         for (k = 0 ; k < count ; k++)
977         {       last_val += src [k] ;
978                 dest [k] = last_val * normfact ;
979                 } ;
980
981         pxi->last_16 = last_val << 8 ;
982 } /* dsc2f_array */
983
984 static void
985 dsc2d_array (XI_PRIVATE *pxi, signed char *src, int count, double *dest, double normfact)
986 {       signed char     last_val ;
987         int                     k ;
988
989         last_val = pxi->last_16 >> 8 ;
990
991         for (k = 0 ; k < count ; k++)
992         {       last_val += src [k] ;
993                 dest [k] = last_val * normfact ;
994                 } ;
995
996         pxi->last_16 = last_val << 8 ;
997 } /* dsc2d_array */
998
999 /*------------------------------------------------------------------------------
1000 */
1001
1002 static void
1003 s2dsc_array (XI_PRIVATE *pxi, const short *src, signed char *dest, int count)
1004 {       signed char     last_val, current ;
1005         int                     k ;
1006
1007         last_val = pxi->last_16 >> 8 ;
1008
1009         for (k = 0 ; k < count ; k++)
1010         {       current = src [k] >> 8 ;
1011                 dest [k] = current - last_val ;
1012                 last_val = current ;
1013                 } ;
1014
1015         pxi->last_16 = last_val << 8 ;
1016 } /* s2dsc_array */
1017
1018 static void
1019 i2dsc_array (XI_PRIVATE *pxi, const int *src, signed char *dest, int count)
1020 {       signed char     last_val, current ;
1021         int                     k ;
1022
1023         last_val = pxi->last_16 >> 8 ;
1024
1025         for (k = 0 ; k < count ; k++)
1026         {       current = src [k] >> 24 ;
1027                 dest [k] = current - last_val ;
1028                 last_val = current ;
1029                 } ;
1030
1031         pxi->last_16 = last_val << 8 ;
1032 } /* i2dsc_array */
1033
1034 static void
1035 f2dsc_array (XI_PRIVATE *pxi, const float *src, signed char *dest, int count, float normfact)
1036 {       signed char     last_val, current ;
1037         int                     k ;
1038
1039         last_val = pxi->last_16 >> 8 ;
1040
1041         for (k = 0 ; k < count ; k++)
1042         {       current = lrintf (src [k] * normfact) ;
1043                 dest [k] = current - last_val ;
1044                 last_val = current ;
1045                 } ;
1046
1047         pxi->last_16 = last_val << 8 ;
1048 } /* f2dsc_array */
1049
1050 static void
1051 d2dsc_array (XI_PRIVATE *pxi, const double *src, signed char *dest, int count, double normfact)
1052 {       signed char     last_val, current ;
1053         int                     k ;
1054
1055         last_val = pxi->last_16 >> 8 ;
1056
1057         for (k = 0 ; k < count ; k++)
1058         {       current = lrint (src [k] * normfact) ;
1059                 dest [k] = current - last_val ;
1060                 last_val = current ;
1061                 } ;
1062
1063         pxi->last_16 = last_val << 8 ;
1064 } /* d2dsc_array */
1065
1066 /*==============================================================================
1067 */
1068
1069 static void
1070 dles2s_array (XI_PRIVATE *pxi, short *src, int count, short *dest)
1071 {       short   last_val ;
1072         int             k ;
1073
1074         last_val = pxi->last_16 ;
1075
1076         for (k = 0 ; k < count ; k++)
1077         {       last_val += LES2H_SHORT (src [k]) ;
1078                 dest [k] = last_val ;
1079                 } ;
1080
1081         pxi->last_16 = last_val ;
1082 } /* dles2s_array */
1083
1084 static void
1085 dles2i_array (XI_PRIVATE *pxi, short *src, int count, int *dest)
1086 {       short   last_val ;
1087         int             k ;
1088
1089         last_val = pxi->last_16 ;
1090
1091         for (k = 0 ; k < count ; k++)
1092         {       last_val += LES2H_SHORT (src [k]) ;
1093                 dest [k] = last_val << 16 ;
1094                 } ;
1095
1096         pxi->last_16 = last_val ;
1097 } /* dles2i_array */
1098
1099 static void
1100 dles2f_array (XI_PRIVATE *pxi, short *src, int count, float *dest, float normfact)
1101 {       short   last_val ;
1102         int             k ;
1103
1104         last_val = pxi->last_16 ;
1105
1106         for (k = 0 ; k < count ; k++)
1107         {       last_val += LES2H_SHORT (src [k]) ;
1108                 dest [k] = last_val * normfact ;
1109                 } ;
1110
1111         pxi->last_16 = last_val ;
1112 } /* dles2f_array */
1113
1114 static void
1115 dles2d_array (XI_PRIVATE *pxi, short *src, int count, double *dest, double normfact)
1116 {       short   last_val ;
1117         int             k ;
1118
1119         last_val = pxi->last_16 ;
1120
1121         for (k = 0 ; k < count ; k++)
1122         {       last_val += LES2H_SHORT (src [k]) ;
1123                 dest [k] = last_val * normfact ;
1124                 } ;
1125
1126         pxi->last_16 = last_val ;
1127 } /* dles2d_array */
1128
1129 /*------------------------------------------------------------------------------
1130 */
1131
1132 static void
1133 s2dles_array (XI_PRIVATE *pxi, const short *src, short *dest, int count)
1134 {       short   diff, last_val ;
1135         int             k ;
1136
1137         last_val = pxi->last_16 ;
1138
1139         for (k = 0 ; k < count ; k++)
1140         {       diff = src [k] - last_val ;
1141                 dest [k] = LES2H_SHORT (diff) ;
1142                 last_val = src [k] ;
1143                 } ;
1144
1145         pxi->last_16 = last_val ;
1146 } /* s2dles_array */
1147
1148 static void
1149 i2dles_array (XI_PRIVATE *pxi, const int *src, short *dest, int count)
1150 {       short   diff, last_val ;
1151         int             k ;
1152
1153         last_val = pxi->last_16 ;
1154
1155         for (k = 0 ; k < count ; k++)
1156         {       diff = (src [k] >> 16) - last_val ;
1157                 dest [k] = LES2H_SHORT (diff) ;
1158                 last_val = src [k] >> 16 ;
1159                 } ;
1160
1161         pxi->last_16 = last_val ;
1162 } /* i2dles_array */
1163
1164 static void
1165 f2dles_array (XI_PRIVATE *pxi, const float *src, short *dest, int count, float normfact)
1166 {       short   diff, last_val, current ;
1167         int             k ;
1168
1169         last_val = pxi->last_16 ;
1170
1171         for (k = 0 ; k < count ; k++)
1172         {       current = lrintf (src [k] * normfact) ;
1173                 diff = current - last_val ;
1174                 dest [k] = LES2H_SHORT (diff) ;
1175                 last_val = current ;
1176                 } ;
1177
1178         pxi->last_16 = last_val ;
1179 } /* f2dles_array */
1180
1181 static void
1182 d2dles_array (XI_PRIVATE *pxi, const double *src, short *dest, int count, double normfact)
1183 {       short   diff, last_val, current ;
1184         int             k ;
1185
1186         last_val = pxi->last_16 ;
1187
1188         for (k = 0 ; k < count ; k++)
1189         {       current = lrint (src [k] * normfact) ;
1190                 diff = current - last_val ;
1191                 dest [k] = LES2H_SHORT (diff) ;
1192                 last_val = current ;
1193                 } ;
1194
1195         pxi->last_16 = last_val ;
1196 } /* d2dles_array */
1197
1198 /*
1199 ** Do not edit or modify anything in this comment block.
1200 ** The arch-tag line is a file identity tag for the GNU Arch 
1201 ** revision control system.
1202 **
1203 ** arch-tag: 1ab2dbe0-29af-4d80-9c6f-cb21b67521bc
1204 */