• Home
  • Line#
  • Scopes#
  • Navigate#
  • Raw
  • Download
1 /*
2 ** Copyright (C) 2002-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 /*------------------------------------------------------------------------------
33 */
34 
35 #define	SDS_DATA_OFFSET				0x15
36 #define SDS_BLOCK_SIZE				127
37 
38 #define SDS_AUDIO_BYTES_PER_BLOCK	120
39 
40 #define SDS_3BYTE_TO_INT_DECODE(x) (((x) & 0x7F) | (((x) & 0x7F00) >> 1) | (((x) & 0x7F0000) >> 2))
41 #define SDS_INT_TO_3BYTE_ENCODE(x) (((x) & 0x7F) | (((x) << 1) & 0x7F00) | (((x) << 2) & 0x7F0000))
42 
43 /*------------------------------------------------------------------------------
44 ** Typedefs.
45 */
46 
47 typedef struct tag_SDS_PRIVATE
48 {	int bitwidth, frames ;
49 	int	samplesperblock, total_blocks ;
50 
51 	int (*reader) (SF_PRIVATE *psf, struct tag_SDS_PRIVATE *psds) ;
52 	int (*writer) (SF_PRIVATE *psf, struct tag_SDS_PRIVATE *psds) ;
53 
54 	int read_block, read_count ;
55 	unsigned char read_data [SDS_BLOCK_SIZE] ;
56 	int	read_samples [SDS_BLOCK_SIZE / 2] ; /* Maximum samples per block */
57 
58 	int write_block, write_count ;
59 	int total_written ;
60 	unsigned char write_data [SDS_BLOCK_SIZE] ;
61 	int	write_samples [SDS_BLOCK_SIZE / 2] ; /* Maximum samples per block */
62 } SDS_PRIVATE ;
63 
64 /*------------------------------------------------------------------------------
65 ** Private static functions.
66 */
67 
68 static int	sds_close	(SF_PRIVATE *psf) ;
69 
70 static int	sds_write_header (SF_PRIVATE *psf, int calc_length) ;
71 static int	sds_read_header (SF_PRIVATE *psf, SDS_PRIVATE *psds) ;
72 
73 static int	sds_init (SF_PRIVATE *psf, SDS_PRIVATE *psds) ;
74 
75 static sf_count_t sds_read_s (SF_PRIVATE *psf, short *ptr, sf_count_t len) ;
76 static sf_count_t sds_read_i (SF_PRIVATE *psf, int *ptr, sf_count_t len) ;
77 static sf_count_t sds_read_f (SF_PRIVATE *psf, float *ptr, sf_count_t len) ;
78 static sf_count_t sds_read_d (SF_PRIVATE *psf, double *ptr, sf_count_t len) ;
79 
80 static sf_count_t sds_write_s (SF_PRIVATE *psf, const short *ptr, sf_count_t len) ;
81 static sf_count_t sds_write_i (SF_PRIVATE *psf, const int *ptr, sf_count_t len) ;
82 static sf_count_t sds_write_f (SF_PRIVATE *psf, const float *ptr, sf_count_t len) ;
83 static sf_count_t sds_write_d (SF_PRIVATE *psf, const double *ptr, sf_count_t len) ;
84 
85 static sf_count_t sds_seek (SF_PRIVATE *psf, int mode, sf_count_t offset) ;
86 static int sds_byterate (SF_PRIVATE * psf) ;
87 
88 static int sds_2byte_read (SF_PRIVATE *psf, SDS_PRIVATE *psds) ;
89 static int sds_3byte_read (SF_PRIVATE *psf, SDS_PRIVATE *psds) ;
90 static int sds_4byte_read (SF_PRIVATE *psf, SDS_PRIVATE *psds) ;
91 
92 static int sds_read (SF_PRIVATE *psf, SDS_PRIVATE *psds, int *iptr, int readcount) ;
93 
94 static int sds_2byte_write (SF_PRIVATE *psf, SDS_PRIVATE *psds) ;
95 static int sds_3byte_write (SF_PRIVATE *psf, SDS_PRIVATE *psds) ;
96 static int sds_4byte_write (SF_PRIVATE *psf, SDS_PRIVATE *psds) ;
97 
98 static int sds_write (SF_PRIVATE *psf, SDS_PRIVATE *psds, const int *iptr, int writecount) ;
99 
100 /*------------------------------------------------------------------------------
101 ** Public function.
102 */
103 
104 int
sds_open(SF_PRIVATE * psf)105 sds_open	(SF_PRIVATE *psf)
106 {	SDS_PRIVATE	*psds ;
107 	int			error = 0 ;
108 
109 	/* Hmmmm, need this here to pass update_header_test. */
110 	psf->sf.frames = 0 ;
111 
112 	if (! (psds = calloc (1, sizeof (SDS_PRIVATE))))
113 		return SFE_MALLOC_FAILED ;
114 	psf->codec_data = psds ;
115 
116 	if (psf->file.mode == SFM_READ || (psf->file.mode == SFM_RDWR && psf->filelength > 0))
117 	{	if ((error = sds_read_header (psf, psds)))
118 			return error ;
119 		} ;
120 
121 	if ((SF_CONTAINER (psf->sf.format)) != SF_FORMAT_SDS)
122 		return	SFE_BAD_OPEN_FORMAT ;
123 
124 	if (psf->file.mode == SFM_WRITE || psf->file.mode == SFM_RDWR)
125 	{	if (sds_write_header (psf, SF_FALSE))
126 			return psf->error ;
127 
128 		psf->write_header = sds_write_header ;
129 
130 		psf_fseek (psf, SDS_DATA_OFFSET, SEEK_SET) ;
131 		} ;
132 
133 	if ((error = sds_init (psf, psds)) != 0)
134 		return error ;
135 
136 	psf->container_close = sds_close ;
137 	psf->seek = sds_seek ;
138 	psf->byterate = sds_byterate ;
139 
140 	psf->blockwidth = 0 ;
141 
142 	return error ;
143 } /* sds_open */
144 
145 /*------------------------------------------------------------------------------
146 */
147 
148 static int
sds_close(SF_PRIVATE * psf)149 sds_close	(SF_PRIVATE *psf)
150 {
151 	if (psf->file.mode == SFM_WRITE || psf->file.mode == SFM_RDWR)
152 	{	SDS_PRIVATE *psds ;
153 
154 		if ((psds = (SDS_PRIVATE *) psf->codec_data) == NULL)
155 		{	psf_log_printf (psf, "*** Bad psf->codec_data ptr.\n") ;
156 			return SFE_INTERNAL ;
157 			} ;
158 
159 		if (psds->write_count > 0)
160 		{	memset (&(psds->write_data [psds->write_count]), 0, (psds->samplesperblock - psds->write_count) * sizeof (int)) ;
161 			psds->writer (psf, psds) ;
162 			} ;
163 
164 		sds_write_header (psf, SF_TRUE) ;
165 		} ;
166 
167 	return 0 ;
168 } /* sds_close */
169 
170 static int
sds_init(SF_PRIVATE * psf,SDS_PRIVATE * psds)171 sds_init (SF_PRIVATE *psf, SDS_PRIVATE *psds)
172 {
173 	if (psds->bitwidth < 8 || psds->bitwidth > 28)
174 		return (psf->error = SFE_SDS_BAD_BIT_WIDTH) ;
175 
176 	if (psds->bitwidth < 14)
177 	{	psds->reader = sds_2byte_read ;
178 		psds->writer = sds_2byte_write ;
179 		psds->samplesperblock = SDS_AUDIO_BYTES_PER_BLOCK / 2 ;
180 		}
181 	else if (psds->bitwidth < 21)
182 	{	psds->reader = sds_3byte_read ;
183 		psds->writer = sds_3byte_write ;
184 		psds->samplesperblock = SDS_AUDIO_BYTES_PER_BLOCK / 3 ;
185 		}
186 	else
187 	{	psds->reader = sds_4byte_read ;
188 		psds->writer = sds_4byte_write ;
189 		psds->samplesperblock = SDS_AUDIO_BYTES_PER_BLOCK / 4 ;
190 		} ;
191 
192 	if (psf->file.mode == SFM_READ || psf->file.mode == SFM_RDWR)
193 	{	psf->read_short		= sds_read_s ;
194 		psf->read_int		= sds_read_i ;
195 		psf->read_float		= sds_read_f ;
196 		psf->read_double	= sds_read_d ;
197 
198 		/* Read first block. */
199 		psds->reader (psf, psds) ;
200 		} ;
201 
202 	if (psf->file.mode == SFM_WRITE || psf->file.mode == SFM_RDWR)
203 	{	psf->write_short	= sds_write_s ;
204 		psf->write_int		= sds_write_i ;
205 		psf->write_float	= sds_write_f ;
206 		psf->write_double	= sds_write_d ;
207 		} ;
208 
209 	return 0 ;
210 } /* sds_init */
211 
212 static int
sds_read_header(SF_PRIVATE * psf,SDS_PRIVATE * psds)213 sds_read_header (SF_PRIVATE *psf, SDS_PRIVATE *psds)
214 {	unsigned char	channel, bitwidth, loop_type, byte ;
215 	unsigned short	sample_no, marker ;
216 	unsigned int	samp_period, data_length, sustain_loop_start, sustain_loop_end ;
217 	int		bytesread, blockcount ;
218 
219 	/* Set position to start of file to begin reading header. */
220 	bytesread = psf_binheader_readf (psf, "pE211", 0, &marker, &channel, &byte) ;
221 
222 	if (marker != 0xF07E || byte != 0x01)
223 		return SFE_SDS_NOT_SDS ;
224 
225 	bytesread += psf_binheader_readf (psf, "e2", &sample_no) ;
226 	sample_no = SDS_3BYTE_TO_INT_DECODE (sample_no) ;
227 
228 	psf_log_printf (psf, "Midi Sample Dump Standard (.sds)\nF07E\n"
229 						" Midi Channel  : %d\n Sample Number : %d\n",
230 						channel, sample_no) ;
231 
232 	bytesread += psf_binheader_readf (psf, "e13", &bitwidth, &samp_period) ;
233 
234 	samp_period = SDS_3BYTE_TO_INT_DECODE (samp_period) ;
235 
236 	psds->bitwidth = bitwidth ;
237 
238 	if (psds->bitwidth > 1)
239 		psf_log_printf (psf, " Bit Width     : %d\n", psds->bitwidth) ;
240 	else
241 	{	psf_log_printf (psf, " Bit Width     : %d (should be > 1)\n", psds->bitwidth) ;
242 		return SFE_SDS_BAD_BIT_WIDTH ;
243 		} ;
244 
245 	if (samp_period > 0)
246 	{	psf->sf.samplerate = 1000000000 / samp_period ;
247 
248 		psf_log_printf (psf, " Sample Period : %d\n"
249 							" Sample Rate   : %d\n",
250 							samp_period, psf->sf.samplerate) ;
251 		}
252 	else
253 	{	psf->sf.samplerate = 16000 ;
254 
255 		psf_log_printf (psf, " Sample Period : %d (should be > 0)\n"
256 							" Sample Rate   : %d (guessed)\n",
257 							samp_period, psf->sf.samplerate) ;
258 		} ;
259 
260 	bytesread += psf_binheader_readf (psf, "e3331", &data_length, &sustain_loop_start, &sustain_loop_end, &loop_type) ;
261 
262 	data_length = SDS_3BYTE_TO_INT_DECODE (data_length) ;
263 
264 	psf->sf.frames = psds->frames = data_length ;
265 
266 	sustain_loop_start = SDS_3BYTE_TO_INT_DECODE (sustain_loop_start) ;
267 	sustain_loop_end = SDS_3BYTE_TO_INT_DECODE (sustain_loop_end) ;
268 
269 	psf_log_printf (psf, 	" Sustain Loop\n"
270 							"     Start     : %d\n"
271 							"     End       : %d\n"
272 							"     Loop Type : %d\n",
273 			sustain_loop_start, sustain_loop_end, loop_type) ;
274 
275 	psf->dataoffset = SDS_DATA_OFFSET ;
276 	psf->datalength = psf->filelength - psf->dataoffset ;
277 
278 	bytesread += psf_binheader_readf (psf, "1", &byte) ;
279 	if (byte != 0xF7)
280 		psf_log_printf (psf, "bad end : %X\n", byte & 0xFF) ;
281 
282 	for (blockcount = 0 ; bytesread < psf->filelength ; blockcount++)
283 	{
284 		bytesread += psf_fread (&marker, 1, 2, psf) ;
285 
286 		if (marker == 0)
287 			break ;
288 
289 		psf_fseek (psf, SDS_BLOCK_SIZE - 2, SEEK_CUR) ;
290 		bytesread += SDS_BLOCK_SIZE - 2 ;
291 		} ;
292 
293 	psf_log_printf (psf, "\nBlocks         : %d\n", blockcount) ;
294 	psds->total_blocks = blockcount ;
295 
296 	psds->samplesperblock = SDS_AUDIO_BYTES_PER_BLOCK / ((psds->bitwidth + 6) / 7) ;
297 	psf_log_printf (psf, "Samples/Block  : %d\n", psds->samplesperblock) ;
298 
299 	psf_log_printf (psf, "Frames         : %d\n", blockcount * psds->samplesperblock) ;
300 
301 	/* Always Mono */
302 	psf->sf.channels = 1 ;
303 	psf->sf.sections = 1 ;
304 
305 	/*
306 	** Lie to the user about PCM bit width. Always round up to
307 	** the next multiple of 8.
308 	*/
309 	switch ((psds->bitwidth + 7) / 8)
310 	{	case 1 :
311 			psf->sf.format = SF_FORMAT_SDS | SF_FORMAT_PCM_S8 ;
312 			break ;
313 
314 		case 2 :
315 			psf->sf.format = SF_FORMAT_SDS | SF_FORMAT_PCM_16 ;
316 			break ;
317 
318 		case 3 :
319 			psf->sf.format = SF_FORMAT_SDS | SF_FORMAT_PCM_24 ;
320 			break ;
321 
322 		case 4 :
323 			psf->sf.format = SF_FORMAT_SDS | SF_FORMAT_PCM_32 ;
324 			break ;
325 
326 		default :
327 			psf_log_printf (psf, "*** Weird byte width (%d)\n", (psds->bitwidth + 7) / 8) ;
328 			return SFE_SDS_BAD_BIT_WIDTH ;
329 		} ;
330 
331 	psf_fseek (psf, SDS_DATA_OFFSET, SEEK_SET) ;
332 
333 	return 0 ;
334 } /* sds_read_header */
335 
336 static int
sds_write_header(SF_PRIVATE * psf,int calc_length)337 sds_write_header (SF_PRIVATE *psf, int calc_length)
338 {	SDS_PRIVATE *psds ;
339 	sf_count_t	current ;
340 	int samp_period, data_length, sustain_loop_start, sustain_loop_end ;
341 	unsigned char loop_type = 0 ;
342 
343 	if ((psds = (SDS_PRIVATE *) psf->codec_data) == NULL)
344 	{	psf_log_printf (psf, "*** Bad psf->codec_data ptr.\n") ;
345 		return SFE_INTERNAL ;
346 		} ;
347 
348 	if (psf->pipeoffset > 0)
349 		return 0 ;
350 
351 	current = psf_ftell (psf) ;
352 
353 	if (calc_length)
354 		psf->sf.frames = psds->total_written ;
355 
356 	if (psds->write_count > 0)
357 	{	int current_count = psds->write_count ;
358 		int current_block = psds->write_block ;
359 
360 		psds->writer (psf, psds) ;
361 
362 		psf_fseek (psf, -1 * SDS_BLOCK_SIZE, SEEK_CUR) ;
363 
364 		psds->write_count = current_count ;
365 		psds->write_block = current_block ;
366 		} ;
367 
368 	/* Reset the current header length to zero. */
369 	psf->header.ptr [0] = 0 ;
370 	psf->header.indx = 0 ;
371 
372 	if (psf->is_pipe == SF_FALSE)
373 		psf_fseek (psf, 0, SEEK_SET) ;
374 
375 	psf_binheader_writef (psf, "E211", BHW2 (0xF07E), BHW1 (0), BHW1 (1)) ;
376 
377 	switch (SF_CODEC (psf->sf.format))
378 	{	case SF_FORMAT_PCM_S8 :
379 				psds->bitwidth = 8 ;
380 				break ;
381 		case SF_FORMAT_PCM_16 :
382 				psds->bitwidth = 16 ;
383 				break ;
384 		case SF_FORMAT_PCM_24 :
385 				psds->bitwidth = 24 ;
386 				break ;
387 		default:
388 			return SFE_SDS_BAD_BIT_WIDTH ;
389 		} ;
390 
391 	samp_period = SDS_INT_TO_3BYTE_ENCODE (1000000000 / psf->sf.samplerate) ;
392 
393 	psf_binheader_writef (psf, "e213", BHW2 (0), BHW1 (psds->bitwidth), BHW3 (samp_period)) ;
394 
395 	data_length			= SDS_INT_TO_3BYTE_ENCODE (psds->total_written) ;
396 	sustain_loop_start	= SDS_INT_TO_3BYTE_ENCODE (0) ;
397 	sustain_loop_end	= SDS_INT_TO_3BYTE_ENCODE (0) ;
398 
399 	psf_binheader_writef (psf, "e33311", BHW3 (data_length), BHW3 (sustain_loop_start), BHW3 (sustain_loop_end), BHW1 (loop_type), BHW1 (0xF7)) ;
400 
401 	/* Header construction complete so write it out. */
402 	psf_fwrite (psf->header.ptr, psf->header.indx, 1, psf) ;
403 
404 	if (psf->error)
405 		return psf->error ;
406 
407 	psf->dataoffset = psf->header.indx ;
408 	psf->datalength = psds->write_block * SDS_BLOCK_SIZE ;
409 
410 	if (current > 0)
411 		psf_fseek (psf, current, SEEK_SET) ;
412 
413 	return psf->error ;
414 } /* sds_write_header */
415 
416 
417 /*------------------------------------------------------------------------------
418 */
419 
420 static int
sds_2byte_read(SF_PRIVATE * psf,SDS_PRIVATE * psds)421 sds_2byte_read (SF_PRIVATE *psf, SDS_PRIVATE *psds)
422 {	unsigned char *ucptr, checksum ;
423 	unsigned int sample ;
424 	int 	k ;
425 
426 	psds->read_block ++ ;
427 	psds->read_count = 0 ;
428 
429 	if (psds->read_block * psds->samplesperblock > psds->frames)
430 	{	memset (psds->read_samples, 0, psds->samplesperblock * sizeof (int)) ;
431 		return 1 ;
432 		} ;
433 
434 	if ((k = psf_fread (psds->read_data, 1, SDS_BLOCK_SIZE, psf)) != SDS_BLOCK_SIZE)
435 		psf_log_printf (psf, "*** Warning : short read (%d != %d).\n", k, SDS_BLOCK_SIZE) ;
436 
437 	if (psds->read_data [0] != 0xF0)
438 	{	printf ("Error A : %02X\n", psds->read_data [0] & 0xFF) ;
439 		} ;
440 
441 	checksum = psds->read_data [1] ;
442 	if (checksum != 0x7E)
443 	{	printf ("Error 1 : %02X\n", checksum & 0xFF) ;
444 		}
445 
446 	for (k = 2 ; k <= SDS_BLOCK_SIZE - 3 ; k ++)
447 		checksum ^= psds->read_data [k] ;
448 
449 	checksum &= 0x7F ;
450 
451 	if (checksum != psds->read_data [SDS_BLOCK_SIZE - 2])
452 	{	psf_log_printf (psf, "Block %d : checksum is %02X should be %02X\n", psds->read_data [4], checksum, psds->read_data [SDS_BLOCK_SIZE - 2]) ;
453 		} ;
454 
455 	ucptr = psds->read_data + 5 ;
456 	for (k = 0 ; k < 120 ; k += 2)
457 	{	sample = arith_shift_left (ucptr [k], 25) + arith_shift_left (ucptr [k + 1], 18) ;
458 		psds->read_samples [k / 2] = (int) (sample - 0x80000000) ;
459 		} ;
460 
461 	return 1 ;
462 } /* sds_2byte_read */
463 
464 static int
sds_3byte_read(SF_PRIVATE * psf,SDS_PRIVATE * psds)465 sds_3byte_read (SF_PRIVATE *psf, SDS_PRIVATE *psds)
466 {	unsigned char *ucptr, checksum ;
467 	unsigned int sample ;
468 	int 	k ;
469 
470 	psds->read_block ++ ;
471 	psds->read_count = 0 ;
472 
473 	if (psds->read_block * psds->samplesperblock > psds->frames)
474 	{	memset (psds->read_samples, 0, psds->samplesperblock * sizeof (int)) ;
475 		return 1 ;
476 		} ;
477 
478 	if ((k = psf_fread (psds->read_data, 1, SDS_BLOCK_SIZE, psf)) != SDS_BLOCK_SIZE)
479 		psf_log_printf (psf, "*** Warning : short read (%d != %d).\n", k, SDS_BLOCK_SIZE) ;
480 
481 	if (psds->read_data [0] != 0xF0)
482 	{	printf ("Error A : %02X\n", psds->read_data [0] & 0xFF) ;
483 		} ;
484 
485 	checksum = psds->read_data [1] ;
486 	if (checksum != 0x7E)
487 	{	printf ("Error 1 : %02X\n", checksum & 0xFF) ;
488 		}
489 
490 	for (k = 2 ; k <= SDS_BLOCK_SIZE - 3 ; k ++)
491 		checksum ^= psds->read_data [k] ;
492 
493 	checksum &= 0x7F ;
494 
495 	if (checksum != psds->read_data [SDS_BLOCK_SIZE - 2])
496 	{	psf_log_printf (psf, "Block %d : checksum is %02X should be %02X\n", psds->read_data [4], checksum, psds->read_data [SDS_BLOCK_SIZE - 2]) ;
497 		} ;
498 
499 	ucptr = psds->read_data + 5 ;
500 	for (k = 0 ; k < 120 ; k += 3)
501 	{	sample = (((uint32_t) ucptr [k]) << 25) + (ucptr [k + 1] << 18) + (ucptr [k + 2] << 11) ;
502 		psds->read_samples [k / 3] = (int) (sample - 0x80000000) ;
503 		} ;
504 
505 	return 1 ;
506 } /* sds_3byte_read */
507 
508 static int
sds_4byte_read(SF_PRIVATE * psf,SDS_PRIVATE * psds)509 sds_4byte_read (SF_PRIVATE *psf, SDS_PRIVATE *psds)
510 {	unsigned char *ucptr, checksum ;
511 	uint32_t sample ;
512 	int 	k ;
513 
514 	psds->read_block ++ ;
515 	psds->read_count = 0 ;
516 
517 	if (psds->read_block * psds->samplesperblock > psds->frames)
518 	{	memset (psds->read_samples, 0, psds->samplesperblock * sizeof (int)) ;
519 		return 1 ;
520 		} ;
521 
522 	if ((k = psf_fread (psds->read_data, 1, SDS_BLOCK_SIZE, psf)) != SDS_BLOCK_SIZE)
523 		psf_log_printf (psf, "*** Warning : short read (%d != %d).\n", k, SDS_BLOCK_SIZE) ;
524 
525 	if (psds->read_data [0] != 0xF0)
526 	{	printf ("Error A : %02X\n", psds->read_data [0] & 0xFF) ;
527 		} ;
528 
529 	checksum = psds->read_data [1] ;
530 	if (checksum != 0x7E)
531 	{	printf ("Error 1 : %02X\n", checksum & 0xFF) ;
532 		}
533 
534 	for (k = 2 ; k <= SDS_BLOCK_SIZE - 3 ; k ++)
535 		checksum ^= psds->read_data [k] ;
536 
537 	checksum &= 0x7F ;
538 
539 	if (checksum != psds->read_data [SDS_BLOCK_SIZE - 2])
540 	{	psf_log_printf (psf, "Block %d : checksum is %02X should be %02X\n", psds->read_data [4], checksum, psds->read_data [SDS_BLOCK_SIZE - 2]) ;
541 		} ;
542 
543 	ucptr = psds->read_data + 5 ;
544 	for (k = 0 ; k < 120 ; k += 4)
545 	{	sample = (((uint32_t) ucptr [k]) << 25) + (ucptr [k + 1] << 18) + (ucptr [k + 2] << 11) + (ucptr [k + 3] << 4) ;
546 		psds->read_samples [k / 4] = (int) (sample - 0x80000000) ;
547 		} ;
548 
549 	return 1 ;
550 } /* sds_4byte_read */
551 
552 
553 static sf_count_t
sds_read_s(SF_PRIVATE * psf,short * ptr,sf_count_t len)554 sds_read_s (SF_PRIVATE *psf, short *ptr, sf_count_t len)
555 {	BUF_UNION	ubuf ;
556 	SDS_PRIVATE	*psds ;
557 	int			*iptr ;
558 	int			k, bufferlen, readcount, count ;
559 	sf_count_t	total = 0 ;
560 
561 	if (psf->codec_data == NULL)
562 		return 0 ;
563 	psds = (SDS_PRIVATE*) psf->codec_data ;
564 
565 	iptr = ubuf.ibuf ;
566 	bufferlen = ARRAY_LEN (ubuf.ibuf) ;
567 	while (len > 0)
568 	{	readcount = (len >= bufferlen) ? bufferlen : len ;
569 		count = sds_read (psf, psds, iptr, readcount) ;
570 		for (k = 0 ; k < readcount ; k++)
571 			ptr [total + k] = iptr [k] >> 16 ;
572 		total += count ;
573 		len -= readcount ;
574 		} ;
575 
576 	return total ;
577 } /* sds_read_s */
578 
579 static sf_count_t
sds_read_i(SF_PRIVATE * psf,int * ptr,sf_count_t len)580 sds_read_i (SF_PRIVATE *psf, int *ptr, sf_count_t len)
581 {	SDS_PRIVATE *psds ;
582 	int			total ;
583 
584 	if (psf->codec_data == NULL)
585 		return 0 ;
586 	psds = (SDS_PRIVATE*) psf->codec_data ;
587 
588 	total = sds_read (psf, psds, ptr, len) ;
589 
590 	return total ;
591 } /* sds_read_i */
592 
593 static sf_count_t
sds_read_f(SF_PRIVATE * psf,float * ptr,sf_count_t len)594 sds_read_f (SF_PRIVATE *psf, float *ptr, sf_count_t len)
595 {	BUF_UNION	ubuf ;
596 	SDS_PRIVATE	*psds ;
597 	int			*iptr ;
598 	int			k, bufferlen, readcount, count ;
599 	sf_count_t	total = 0 ;
600 	float		normfact ;
601 
602 	if (psf->codec_data == NULL)
603 		return 0 ;
604 	psds = (SDS_PRIVATE*) psf->codec_data ;
605 
606 	if (psf->norm_float == SF_TRUE)
607 		normfact = 1.0 / 0x80000000 ;
608 	else
609 		normfact = 1.0 / (1 << psds->bitwidth) ;
610 
611 	iptr = ubuf.ibuf ;
612 	bufferlen = ARRAY_LEN (ubuf.ibuf) ;
613 	while (len > 0)
614 	{	readcount = (len >= bufferlen) ? bufferlen : len ;
615 		count = sds_read (psf, psds, iptr, readcount) ;
616 		for (k = 0 ; k < readcount ; k++)
617 			ptr [total + k] = normfact * iptr [k] ;
618 		total += count ;
619 		len -= readcount ;
620 		} ;
621 
622 	return total ;
623 } /* sds_read_f */
624 
625 static sf_count_t
sds_read_d(SF_PRIVATE * psf,double * ptr,sf_count_t len)626 sds_read_d (SF_PRIVATE *psf, double *ptr, sf_count_t len)
627 {	BUF_UNION	ubuf ;
628 	SDS_PRIVATE	*psds ;
629 	int			*iptr ;
630 	int			k, bufferlen, readcount, count ;
631 	sf_count_t	total = 0 ;
632 	double		normfact ;
633 
634 	if (psf->codec_data == NULL)
635 		return 0 ;
636 	psds = (SDS_PRIVATE*) psf->codec_data ;
637 
638 	if (psf->norm_double == SF_TRUE)
639 		normfact = 1.0 / 0x80000000 ;
640 	else
641 		normfact = 1.0 / (1 << psds->bitwidth) ;
642 
643 	iptr = ubuf.ibuf ;
644 	bufferlen = ARRAY_LEN (ubuf.ibuf) ;
645 	while (len > 0)
646 	{	readcount = (len >= bufferlen) ? bufferlen : len ;
647 		count = sds_read (psf, psds, iptr, readcount) ;
648 		for (k = 0 ; k < readcount ; k++)
649 			ptr [total + k] = normfact * iptr [k] ;
650 		total += count ;
651 		len -= readcount ;
652 		} ;
653 
654 	return total ;
655 } /* sds_read_d */
656 
657 static int
sds_read(SF_PRIVATE * psf,SDS_PRIVATE * psds,int * ptr,int len)658 sds_read (SF_PRIVATE *psf, SDS_PRIVATE *psds, int *ptr, int len)
659 {	int	count, total = 0 ;
660 
661 	while (total < len)
662 	{	if (psds->read_block * psds->samplesperblock >= psds->frames)
663 		{	memset (&(ptr [total]), 0, (len - total) * sizeof (int)) ;
664 			return total ;
665 			} ;
666 
667 		if (psds->read_count >= psds->samplesperblock)
668 			psds->reader (psf, psds) ;
669 
670 		count = (psds->samplesperblock - psds->read_count) ;
671 		count = (len - total > count) ? count : len - total ;
672 
673 		memcpy (&(ptr [total]), &(psds->read_samples [psds->read_count]), count * sizeof (int)) ;
674 		total += count ;
675 		psds->read_count += count ;
676 		} ;
677 
678 	return total ;
679 } /* sds_read */
680 
681 /*==============================================================================
682 */
683 
684 static sf_count_t
sds_seek(SF_PRIVATE * psf,int mode,sf_count_t seek_from_start)685 sds_seek (SF_PRIVATE *psf, int mode, sf_count_t seek_from_start)
686 {	SDS_PRIVATE	*psds ;
687 	sf_count_t	file_offset ;
688 	int			newblock, newsample ;
689 
690 	if ((psds = psf->codec_data) == NULL)
691 	{	psf->error = SFE_INTERNAL ;
692 		return PSF_SEEK_ERROR ;
693 		} ;
694 
695 	if (psf->datalength < 0 || psf->dataoffset < 0)
696 	{	psf->error = SFE_BAD_SEEK ;
697 		return PSF_SEEK_ERROR ;
698 		} ;
699 
700 	if (seek_from_start < 0 || seek_from_start > psf->sf.frames)
701 	{	psf->error = SFE_BAD_SEEK ;
702 		return PSF_SEEK_ERROR ;
703 		} ;
704 
705 	if (mode == SFM_READ && psds->write_count > 0)
706 		psds->writer (psf, psds) ;
707 
708 	newblock = seek_from_start / psds->samplesperblock ;
709 	newsample = seek_from_start % psds->samplesperblock ;
710 
711 	switch (mode)
712 	{	case SFM_READ :
713 			if (newblock > psds->total_blocks)
714 			{	psf->error = SFE_BAD_SEEK ;
715 				return PSF_SEEK_ERROR ;
716 				} ;
717 
718 			file_offset = psf->dataoffset + newblock * SDS_BLOCK_SIZE ;
719 
720 			if (psf_fseek (psf, file_offset, SEEK_SET) != file_offset)
721 			{	psf->error = SFE_SEEK_FAILED ;
722 				return PSF_SEEK_ERROR ;
723 				} ;
724 
725 			psds->read_block = newblock ;
726 			psds->reader (psf, psds) ;
727 			psds->read_count = newsample ;
728 			break ;
729 
730 		case SFM_WRITE :
731 			if (newblock > psds->total_blocks)
732 			{	psf->error = SFE_BAD_SEEK ;
733 				return PSF_SEEK_ERROR ;
734 				} ;
735 
736 			file_offset = psf->dataoffset + newblock * SDS_BLOCK_SIZE ;
737 
738 			if (psf_fseek (psf, file_offset, SEEK_SET) != file_offset)
739 			{	psf->error = SFE_SEEK_FAILED ;
740 				return PSF_SEEK_ERROR ;
741 				} ;
742 
743 			psds->write_block = newblock ;
744 			psds->reader (psf, psds) ;
745 			psds->write_count = newsample ;
746 			break ;
747 
748 		default :
749 			psf->error = SFE_BAD_SEEK ;
750 			return PSF_SEEK_ERROR ;
751 			break ;
752 		} ;
753 
754 	return seek_from_start ;
755 } /* sds_seek */
756 
757 static int
sds_byterate(SF_PRIVATE * psf)758 sds_byterate (SF_PRIVATE * psf)
759 {
760 	if (psf->file.mode == SFM_READ)
761 		return (psf->datalength * psf->sf.samplerate) / psf->sf.frames ;
762 
763 	return -1 ;
764 } /* sds_byterate */
765 
766 /*==============================================================================
767 */
768 
769 static int
sds_2byte_write(SF_PRIVATE * psf,SDS_PRIVATE * psds)770 sds_2byte_write (SF_PRIVATE *psf, SDS_PRIVATE *psds)
771 {	unsigned char *ucptr, checksum ;
772 	unsigned int sample ;
773 	int 	k ;
774 
775 	psds->write_data [0] = 0xF0 ;
776 	psds->write_data [1] = 0x7E ;
777 	psds->write_data [2] = 0 ;							/* Channel number */
778 	psds->write_data [3] = 2 ;
779 	psds->write_data [4] = psds->write_block & 0x7F ;	/* Packet number */
780 
781 	ucptr = psds->write_data + 5 ;
782 	for (k = 0 ; k < 120 ; k += 2)
783 	{	sample = psds->write_samples [k / 2] ;
784 		sample += 0x80000000 ;
785 		ucptr [k] = (sample >> 25) & 0x7F ;
786 		ucptr [k + 1] = (sample >> 18) & 0x7F ;
787 		} ;
788 
789 	checksum = psds->write_data [1] ;
790 	for (k = 2 ; k <= SDS_BLOCK_SIZE - 3 ; k ++)
791 		checksum ^= psds->write_data [k] ;
792 	checksum &= 0x7F ;
793 
794 	psds->write_data [SDS_BLOCK_SIZE - 2] = checksum ;
795 	psds->write_data [SDS_BLOCK_SIZE - 1] = 0xF7 ;
796 
797 	if ((k = psf_fwrite (psds->write_data, 1, SDS_BLOCK_SIZE, psf)) != SDS_BLOCK_SIZE)
798 		psf_log_printf (psf, "*** Warning : psf_fwrite (%d != %d).\n", k, SDS_BLOCK_SIZE) ;
799 
800 	psds->write_block ++ ;
801 	psds->write_count = 0 ;
802 
803 	if (psds->write_block > psds->total_blocks)
804 		psds->total_blocks = psds->write_block ;
805 	psds->frames = psds->total_blocks * psds->samplesperblock ;
806 
807 	return 1 ;
808 } /* sds_2byte_write */
809 
810 static int
sds_3byte_write(SF_PRIVATE * psf,SDS_PRIVATE * psds)811 sds_3byte_write (SF_PRIVATE *psf, SDS_PRIVATE *psds)
812 {	unsigned char *ucptr, checksum ;
813 	unsigned int sample ;
814 	int 	k ;
815 
816 	psds->write_data [0] = 0xF0 ;
817 	psds->write_data [1] = 0x7E ;
818 	psds->write_data [2] = 0 ;							/* Channel number */
819 	psds->write_data [3] = 2 ;
820 	psds->write_data [4] = psds->write_block & 0x7F ;	/* Packet number */
821 
822 	ucptr = psds->write_data + 5 ;
823 	for (k = 0 ; k < 120 ; k += 3)
824 	{	sample = psds->write_samples [k / 3] ;
825 		sample += 0x80000000 ;
826 		ucptr [k] = (sample >> 25) & 0x7F ;
827 		ucptr [k + 1] = (sample >> 18) & 0x7F ;
828 		ucptr [k + 2] = (sample >> 11) & 0x7F ;
829 		} ;
830 
831 	checksum = psds->write_data [1] ;
832 	for (k = 2 ; k <= SDS_BLOCK_SIZE - 3 ; k ++)
833 		checksum ^= psds->write_data [k] ;
834 	checksum &= 0x7F ;
835 
836 	psds->write_data [SDS_BLOCK_SIZE - 2] = checksum ;
837 	psds->write_data [SDS_BLOCK_SIZE - 1] = 0xF7 ;
838 
839 	if ((k = psf_fwrite (psds->write_data, 1, SDS_BLOCK_SIZE, psf)) != SDS_BLOCK_SIZE)
840 		psf_log_printf (psf, "*** Warning : psf_fwrite (%d != %d).\n", k, SDS_BLOCK_SIZE) ;
841 
842 	psds->write_block ++ ;
843 	psds->write_count = 0 ;
844 
845 	if (psds->write_block > psds->total_blocks)
846 		psds->total_blocks = psds->write_block ;
847 	psds->frames = psds->total_blocks * psds->samplesperblock ;
848 
849 	return 1 ;
850 } /* sds_3byte_write */
851 
852 static int
sds_4byte_write(SF_PRIVATE * psf,SDS_PRIVATE * psds)853 sds_4byte_write (SF_PRIVATE *psf, SDS_PRIVATE *psds)
854 {	unsigned char *ucptr, checksum ;
855 	unsigned int sample ;
856 	int 	k ;
857 
858 	psds->write_data [0] = 0xF0 ;
859 	psds->write_data [1] = 0x7E ;
860 	psds->write_data [2] = 0 ;							/* Channel number */
861 	psds->write_data [3] = 2 ;
862 	psds->write_data [4] = psds->write_block & 0x7F ;	/* Packet number */
863 
864 	ucptr = psds->write_data + 5 ;
865 	for (k = 0 ; k < 120 ; k += 4)
866 	{	sample = psds->write_samples [k / 4] ;
867 		sample += 0x80000000 ;
868 		ucptr [k] = (sample >> 25) & 0x7F ;
869 		ucptr [k + 1] = (sample >> 18) & 0x7F ;
870 		ucptr [k + 2] = (sample >> 11) & 0x7F ;
871 		ucptr [k + 3] = (sample >> 4) & 0x7F ;
872 		} ;
873 
874 	checksum = psds->write_data [1] ;
875 	for (k = 2 ; k <= SDS_BLOCK_SIZE - 3 ; k ++)
876 		checksum ^= psds->write_data [k] ;
877 	checksum &= 0x7F ;
878 
879 	psds->write_data [SDS_BLOCK_SIZE - 2] = checksum ;
880 	psds->write_data [SDS_BLOCK_SIZE - 1] = 0xF7 ;
881 
882 	if ((k = psf_fwrite (psds->write_data, 1, SDS_BLOCK_SIZE, psf)) != SDS_BLOCK_SIZE)
883 		psf_log_printf (psf, "*** Warning : psf_fwrite (%d != %d).\n", k, SDS_BLOCK_SIZE) ;
884 
885 	psds->write_block ++ ;
886 	psds->write_count = 0 ;
887 
888 	if (psds->write_block > psds->total_blocks)
889 		psds->total_blocks = psds->write_block ;
890 	psds->frames = psds->total_blocks * psds->samplesperblock ;
891 
892 	return 1 ;
893 } /* sds_4byte_write */
894 
895 static sf_count_t
sds_write_s(SF_PRIVATE * psf,const short * ptr,sf_count_t len)896 sds_write_s (SF_PRIVATE *psf, const short *ptr, sf_count_t len)
897 {	BUF_UNION	ubuf ;
898 	SDS_PRIVATE	*psds ;
899 	int			*iptr ;
900 	int			k, bufferlen, writecount, count ;
901 	sf_count_t	total = 0 ;
902 
903 	if (psf->codec_data == NULL)
904 		return 0 ;
905 	psds = (SDS_PRIVATE*) psf->codec_data ;
906 	psds->total_written += len ;
907 
908 	iptr = ubuf.ibuf ;
909 	bufferlen = ARRAY_LEN (ubuf.ibuf) ;
910 	while (len > 0)
911 	{	writecount = (len >= bufferlen) ? bufferlen : len ;
912 		for (k = 0 ; k < writecount ; k++)
913 			iptr [k] = arith_shift_left (ptr [total + k], 16) ;
914 		count = sds_write (psf, psds, iptr, writecount) ;
915 		total += count ;
916 		len -= writecount ;
917 		} ;
918 
919 	return total ;
920 } /* sds_write_s */
921 
922 static sf_count_t
sds_write_i(SF_PRIVATE * psf,const int * ptr,sf_count_t len)923 sds_write_i (SF_PRIVATE *psf, const int *ptr, sf_count_t len)
924 {	SDS_PRIVATE *psds ;
925 	int			total ;
926 
927 	if (psf->codec_data == NULL)
928 		return 0 ;
929 	psds = (SDS_PRIVATE*) psf->codec_data ;
930 	psds->total_written += len ;
931 
932 	total = sds_write (psf, psds, ptr, len) ;
933 
934 	return total ;
935 } /* sds_write_i */
936 
937 static sf_count_t
sds_write_f(SF_PRIVATE * psf,const float * ptr,sf_count_t len)938 sds_write_f (SF_PRIVATE *psf, const float *ptr, sf_count_t len)
939 {	BUF_UNION	ubuf ;
940 	SDS_PRIVATE	*psds ;
941 	int			*iptr ;
942 	int			k, bufferlen, writecount, count ;
943 	sf_count_t	total = 0 ;
944 	float		normfact ;
945 
946 	if (psf->codec_data == NULL)
947 		return 0 ;
948 	psds = (SDS_PRIVATE*) psf->codec_data ;
949 	psds->total_written += len ;
950 
951 	if (psf->norm_float == SF_TRUE)
952 		normfact = 1.0 * 0x80000000 ;
953 	else
954 		normfact = 1.0 * (1 << psds->bitwidth) ;
955 
956 	iptr = ubuf.ibuf ;
957 	bufferlen = ARRAY_LEN (ubuf.ibuf) ;
958 	while (len > 0)
959 	{	writecount = (len >= bufferlen) ? bufferlen : len ;
960 		for (k = 0 ; k < writecount ; k++)
961 			iptr [k] = normfact * ptr [total + k] ;
962 		count = sds_write (psf, psds, iptr, writecount) ;
963 		total += count ;
964 		len -= writecount ;
965 		} ;
966 
967 	return total ;
968 } /* sds_write_f */
969 
970 static sf_count_t
sds_write_d(SF_PRIVATE * psf,const double * ptr,sf_count_t len)971 sds_write_d (SF_PRIVATE *psf, const double *ptr, sf_count_t len)
972 {	BUF_UNION	ubuf ;
973 	SDS_PRIVATE	*psds ;
974 	int			*iptr ;
975 	int			k, bufferlen, writecount, count ;
976 	sf_count_t	total = 0 ;
977 	double		normfact ;
978 
979 	if (psf->codec_data == NULL)
980 		return 0 ;
981 	psds = (SDS_PRIVATE*) psf->codec_data ;
982 	psds->total_written += len ;
983 
984 	if (psf->norm_double == SF_TRUE)
985 		normfact = 1.0 * 0x80000000 ;
986 	else
987 		normfact = 1.0 * (1 << psds->bitwidth) ;
988 
989 	iptr = ubuf.ibuf ;
990 	bufferlen = ARRAY_LEN (ubuf.ibuf) ;
991 	while (len > 0)
992 	{	writecount = (len >= bufferlen) ? bufferlen : len ;
993 		for (k = 0 ; k < writecount ; k++)
994 			iptr [k] = normfact * ptr [total + k] ;
995 		count = sds_write (psf, psds, iptr, writecount) ;
996 		total += count ;
997 		len -= writecount ;
998 		} ;
999 
1000 	return total ;
1001 } /* sds_write_d */
1002 
1003 static int
sds_write(SF_PRIVATE * psf,SDS_PRIVATE * psds,const int * ptr,int len)1004 sds_write (SF_PRIVATE *psf, SDS_PRIVATE *psds, const int *ptr, int len)
1005 {	int	count, total = 0 ;
1006 
1007 	while (total < len)
1008 	{	count = psds->samplesperblock - psds->write_count ;
1009 		if (count > len - total)
1010 			count = len - total ;
1011 
1012 		memcpy (&(psds->write_samples [psds->write_count]), &(ptr [total]), count * sizeof (int)) ;
1013 		total += count ;
1014 		psds->write_count += count ;
1015 
1016 		if (psds->write_count >= psds->samplesperblock)
1017 			psds->writer (psf, psds) ;
1018 		} ;
1019 
1020 	return total ;
1021 } /* sds_write */
1022 
1023