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