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