1 /*
2 ** Copyright (C) 1999-2020 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 <string.h>
24 #include <math.h>
25
26 #include "sndfile.h"
27 #include "sfendian.h"
28 #include "common.h"
29
30 typedef struct IMA_ADPCM_PRIVATE_tag
31 { int (*decode_block) (SF_PRIVATE *psf, struct IMA_ADPCM_PRIVATE_tag *pima) ;
32 int (*encode_block) (SF_PRIVATE *psf, struct IMA_ADPCM_PRIVATE_tag *pima) ;
33
34 int channels, blocksize, samplesperblock, blocks ;
35 int blockcount, samplecount ;
36 int previous [2] ;
37 int stepindx [2] ;
38 unsigned char *block ;
39 short *samples ;
40 short data [] ; /* ISO C99 struct flexible array. */
41 } IMA_ADPCM_PRIVATE ;
42
43 /*============================================================================================
44 ** Predefined IMA ADPCM data.
45 */
46
47 static int ima_indx_adjust [16] =
48 { -1, -1, -1, -1, /* +0 - +3, decrease the step size */
49 +2, +4, +6, +8, /* +4 - +7, increase the step size */
50 -1, -1, -1, -1, /* -0 - -3, decrease the step size */
51 +2, +4, +6, +8, /* -4 - -7, increase the step size */
52 } ;
53
54 static int ima_step_size [89] =
55 { 7, 8, 9, 10, 11, 12, 13, 14, 16, 17, 19, 21, 23, 25, 28, 31, 34, 37, 41, 45,
56 50, 55, 60, 66, 73, 80, 88, 97, 107, 118, 130, 143, 157, 173, 190, 209, 230,
57 253, 279, 307, 337, 371, 408, 449, 494, 544, 598, 658, 724, 796, 876, 963,
58 1060, 1166, 1282, 1411, 1552, 1707, 1878, 2066, 2272, 2499, 2749, 3024, 3327,
59 3660, 4026, 4428, 4871, 5358, 5894, 6484, 7132, 7845, 8630, 9493, 10442,
60 11487, 12635, 13899, 15289, 16818, 18500, 20350, 22385, 24623, 27086, 29794,
61 32767
62 } ;
63
64 static int ima_reader_init (SF_PRIVATE *psf, int blockalign, int samplesperblock) ;
65 static int ima_writer_init (SF_PRIVATE *psf, int blockalign) ;
66
67 static int ima_read_block (SF_PRIVATE *psf, IMA_ADPCM_PRIVATE *pima, short *ptr, int len) ;
68 static int ima_write_block (SF_PRIVATE *psf, IMA_ADPCM_PRIVATE *pima, const short *ptr, int len) ;
69
70 static sf_count_t ima_read_s (SF_PRIVATE *psf, short *ptr, sf_count_t len) ;
71 static sf_count_t ima_read_i (SF_PRIVATE *psf, int *ptr, sf_count_t len) ;
72 static sf_count_t ima_read_f (SF_PRIVATE *psf, float *ptr, sf_count_t len) ;
73 static sf_count_t ima_read_d (SF_PRIVATE *psf, double *ptr, sf_count_t len) ;
74
75 static sf_count_t ima_write_s (SF_PRIVATE *psf, const short *ptr, sf_count_t len) ;
76 static sf_count_t ima_write_i (SF_PRIVATE *psf, const int *ptr, sf_count_t len) ;
77 static sf_count_t ima_write_f (SF_PRIVATE *psf, const float *ptr, sf_count_t len) ;
78 static sf_count_t ima_write_d (SF_PRIVATE *psf, const double *ptr, sf_count_t len) ;
79
80 static sf_count_t aiff_ima_seek (SF_PRIVATE *psf, int mode, sf_count_t offset) ;
81 static sf_count_t wavlike_ima_seek (SF_PRIVATE *psf, int mode, sf_count_t offset) ;
82
83 static int ima_close (SF_PRIVATE *psf) ;
84
85 static int wavlike_ima_decode_block (SF_PRIVATE *psf, IMA_ADPCM_PRIVATE *pima) ;
86 static int wavlike_ima_encode_block (SF_PRIVATE *psf, IMA_ADPCM_PRIVATE *pima) ;
87
88 /*-static int aiff_ima_reader_init (SF_PRIVATE *psf, int blockalign, int samplesperblock) ;-*/
89 static int aiff_ima_decode_block (SF_PRIVATE *psf, IMA_ADPCM_PRIVATE *pima) ;
90 static int aiff_ima_encode_block (SF_PRIVATE *psf, IMA_ADPCM_PRIVATE *pima) ;
91
92
93 static inline int
clamp_ima_step_index(int indx)94 clamp_ima_step_index (int indx)
95 { if (indx < 0)
96 return 0 ;
97 if (indx >= ARRAY_LEN (ima_step_size))
98 return ARRAY_LEN (ima_step_size) - 1 ;
99
100 return indx ;
101 } /* clamp_ima_step_index */
102
103 /*============================================================================================
104 ** IMA ADPCM Reader initialisation function.
105 */
106
107 int
wavlike_ima_init(SF_PRIVATE * psf,int blockalign,int samplesperblock)108 wavlike_ima_init (SF_PRIVATE *psf, int blockalign, int samplesperblock)
109 { int error ;
110
111 if (psf->codec_data != NULL)
112 { psf_log_printf (psf, "*** psf->codec_data is not NULL.\n") ;
113 return SFE_INTERNAL ;
114 } ;
115
116 if (psf->file.mode == SFM_RDWR)
117 return SFE_BAD_MODE_RW ;
118
119 if (psf->file.mode == SFM_READ)
120 if ((error = ima_reader_init (psf, blockalign, samplesperblock)))
121 return error ;
122
123 if (psf->file.mode == SFM_WRITE)
124 if ((error = ima_writer_init (psf, blockalign)))
125 return error ;
126
127 psf->codec_close = ima_close ;
128 psf->seek = wavlike_ima_seek ;
129
130 return 0 ;
131 } /* wavlike_ima_init */
132
133 int
aiff_ima_init(SF_PRIVATE * psf,int blockalign,int samplesperblock)134 aiff_ima_init (SF_PRIVATE *psf, int blockalign, int samplesperblock)
135 { int error ;
136
137 if (psf->file.mode == SFM_RDWR)
138 return SFE_BAD_MODE_RW ;
139
140 if (psf->file.mode == SFM_READ)
141 if ((error = ima_reader_init (psf, blockalign, samplesperblock)))
142 return error ;
143
144 if (psf->file.mode == SFM_WRITE)
145 if ((error = ima_writer_init (psf, blockalign)))
146 return error ;
147
148 psf->codec_close = ima_close ;
149 psf->seek = aiff_ima_seek ;
150
151 return 0 ;
152 } /* aiff_ima_init */
153
154 static int
ima_close(SF_PRIVATE * psf)155 ima_close (SF_PRIVATE *psf)
156 { IMA_ADPCM_PRIVATE *pima ;
157
158 pima = (IMA_ADPCM_PRIVATE*) psf->codec_data ;
159
160 if (psf->file.mode == SFM_WRITE)
161 { /* If a block has been partially assembled, write it out
162 ** as the final block.
163 */
164 if (pima->samplecount && pima->samplecount < pima->samplesperblock)
165 pima->encode_block (psf, pima) ;
166
167 psf->sf.frames = pima->samplesperblock * pima->blockcount / psf->sf.channels ;
168 } ;
169
170 return 0 ;
171 } /* ima_close */
172
173 /*============================================================================================
174 ** IMA ADPCM Read Functions.
175 */
176
177 static int
ima_reader_init(SF_PRIVATE * psf,int blockalign,int samplesperblock)178 ima_reader_init (SF_PRIVATE *psf, int blockalign, int samplesperblock)
179 { IMA_ADPCM_PRIVATE *pima ;
180 int pimasize, count ;
181
182 if (psf->file.mode != SFM_READ)
183 return SFE_BAD_MODE_RW ;
184
185 pimasize = sizeof (IMA_ADPCM_PRIVATE) + blockalign * psf->sf.channels + 3 * psf->sf.channels * samplesperblock ;
186
187 if (! (pima = calloc (1, pimasize)))
188 return SFE_MALLOC_FAILED ;
189
190 psf->codec_data = (void*) pima ;
191
192 pima->samples = pima->data ;
193 pima->block = (unsigned char*) (pima->data + samplesperblock * psf->sf.channels) ;
194
195 pima->channels = psf->sf.channels ;
196 pima->blocksize = blockalign ;
197 pima->samplesperblock = samplesperblock ;
198
199 psf->filelength = psf_get_filelen (psf) ;
200 psf->datalength = (psf->dataend) ? psf->dataend - psf->dataoffset :
201 psf->filelength - psf->dataoffset ;
202
203 if (pima->blocksize <= 0)
204 { psf_log_printf (psf, "*** Error : pima->blocksize should be > 0.\n") ;
205 return SFE_INTERNAL ;
206 } ;
207
208 if (pima->samplesperblock <= 0)
209 { psf_log_printf (psf, "*** Error : pima->samplesperblock should be > 0.\n") ;
210 return SFE_INTERNAL ;
211 } ;
212
213 if (psf->datalength % pima->blocksize)
214 pima->blocks = psf->datalength / pima->blocksize + 1 ;
215 else
216 pima->blocks = psf->datalength / pima->blocksize ;
217
218 switch (SF_CONTAINER (psf->sf.format))
219 { case SF_FORMAT_WAV :
220 case SF_FORMAT_W64 :
221 count = 2 * (pima->blocksize - 4 * pima->channels) / pima->channels + 1 ;
222
223 if (pima->samplesperblock != count)
224 { psf_log_printf (psf, "*** Error : samplesperblock should be %d.\n", count) ;
225 return SFE_INTERNAL ;
226 } ;
227
228 pima->decode_block = wavlike_ima_decode_block ;
229
230 psf->sf.frames = pima->samplesperblock * pima->blocks ;
231 break ;
232
233 case SF_FORMAT_AIFF :
234 psf_log_printf (psf, "still need to check block count\n") ;
235 pima->decode_block = aiff_ima_decode_block ;
236 psf->sf.frames = pima->samplesperblock * pima->blocks / pima->channels ;
237 break ;
238
239 default :
240 psf_log_printf (psf, "ima_reader_init: bad psf->sf.format\n") ;
241 return SFE_INTERNAL ;
242 } ;
243
244 pima->decode_block (psf, pima) ; /* Read first block. */
245
246 psf->read_short = ima_read_s ;
247 psf->read_int = ima_read_i ;
248 psf->read_float = ima_read_f ;
249 psf->read_double = ima_read_d ;
250
251 return 0 ;
252 } /* ima_reader_init */
253
254 static int
aiff_ima_decode_block(SF_PRIVATE * psf,IMA_ADPCM_PRIVATE * pima)255 aiff_ima_decode_block (SF_PRIVATE *psf, IMA_ADPCM_PRIVATE *pima)
256 { unsigned char *blockdata ;
257 int chan, k, diff, bytecode, predictor ;
258 short step, stepindx, *sampledata ;
259
260 static int count = 0 ;
261 count ++ ;
262
263 pima->blockcount += pima->channels ;
264 pima->samplecount = 0 ;
265
266 if (pima->blockcount > pima->blocks)
267 { memset (pima->samples, 0, pima->samplesperblock * pima->channels * sizeof (short)) ;
268 return 1 ;
269 } ;
270
271 if ((k = psf_fread (pima->block, 1, pima->blocksize * pima->channels, psf)) != pima->blocksize * pima->channels)
272 psf_log_printf (psf, "*** Warning : short read (%d != %d).\n", k, pima->blocksize) ;
273
274 /* Read and check the block header. */
275 for (chan = 0 ; chan < pima->channels ; chan++)
276 { blockdata = pima->block + chan * 34 ;
277 sampledata = pima->samples + chan ;
278
279 /* Sign-extend from 16 bits to 32. */
280 predictor = (int) ((short) ((blockdata [0] << 8) | (blockdata [1] & 0x80))) ;
281
282 stepindx = blockdata [1] & 0x7F ;
283 stepindx = clamp_ima_step_index (stepindx) ;
284
285 /*
286 ** Pull apart the packed 4 bit samples and store them in their
287 ** correct sample positions.
288 */
289 for (k = 0 ; k < pima->blocksize - 2 ; k++)
290 { bytecode = blockdata [k + 2] ;
291 sampledata [pima->channels * (2 * k + 0)] = bytecode & 0xF ;
292 sampledata [pima->channels * (2 * k + 1)] = (bytecode >> 4) & 0xF ;
293 } ;
294
295 /* Decode the encoded 4 bit samples. */
296 for (k = 0 ; k < pima->samplesperblock ; k ++)
297 { step = ima_step_size [stepindx] ;
298
299 bytecode = pima->samples [pima->channels * k + chan] ;
300
301 stepindx += ima_indx_adjust [bytecode] ;
302 stepindx = clamp_ima_step_index (stepindx) ;
303
304 diff = step >> 3 ;
305 if (bytecode & 1) diff += step >> 2 ;
306 if (bytecode & 2) diff += step >> 1 ;
307 if (bytecode & 4) diff += step ;
308 if (bytecode & 8) diff = -diff ;
309
310 predictor += diff ;
311 if (predictor < -32768)
312 predictor = -32768 ;
313 else if (predictor > 32767)
314 predictor = 32767 ;
315
316 pima->samples [pima->channels * k + chan] = predictor ;
317 } ;
318 } ;
319
320 return 1 ;
321 } /* aiff_ima_decode_block */
322
323 static int
aiff_ima_encode_block(SF_PRIVATE * psf,IMA_ADPCM_PRIVATE * pima)324 aiff_ima_encode_block (SF_PRIVATE *psf, IMA_ADPCM_PRIVATE *pima)
325 { int chan, k, step, diff, vpdiff, blockindx, indx ;
326 short bytecode, mask ;
327
328 k = 0 ;
329 for (chan = 0 ; chan < pima->channels ; chan ++)
330 { blockindx = chan * pima->blocksize ;
331 /* Encode the block header. */
332 pima->block [blockindx++] = (pima->previous [chan] >> 8) & 0xFF ;
333 pima->block [blockindx++] = (pima->previous [chan] & 0x80) + (pima->stepindx [chan] & 0x7F) ;
334
335 /* Encode the samples as 4 bit. */
336 for (indx = chan ; indx < pima->samplesperblock * pima->channels ; indx += pima->channels)
337 { diff = pima->samples [indx] - pima->previous [chan] ;
338
339 bytecode = 0 ;
340 step = ima_step_size [pima->stepindx [chan]] ;
341 vpdiff = step >> 3 ;
342 if (diff < 0)
343 { bytecode = 8 ;
344 diff = -diff ;
345 } ;
346 mask = 4 ;
347 while (mask)
348 { if (diff >= step)
349 { bytecode |= mask ;
350 diff -= step ;
351 vpdiff += step ;
352 } ;
353 step >>= 1 ;
354 mask >>= 1 ;
355 } ;
356
357 if (bytecode & 8)
358 vpdiff = -vpdiff ;
359 pima->previous [chan] += vpdiff ;
360
361 if (pima->previous [chan] > 32767)
362 pima->previous [chan] = 32767 ;
363 else if (pima->previous [chan] < -32768)
364 pima->previous [chan] = -32768 ;
365
366 pima->stepindx [chan] += ima_indx_adjust [bytecode] ;
367
368 pima->stepindx [chan] = clamp_ima_step_index (pima->stepindx [chan]) ;
369 pima->block [blockindx] = (bytecode << (4 * k)) | pima->block [blockindx] ;
370 blockindx += k ;
371 k = 1 - k ;
372 } ;
373 } ;
374
375 /* Write the block to disk. */
376 if ((k = psf_fwrite (pima->block, 1, pima->channels * pima->blocksize, psf)) != pima->channels * pima->blocksize)
377 psf_log_printf (psf, "*** Warning : short write (%d != %d).\n", k, pima->channels * pima->blocksize) ;
378
379 memset (pima->block, 0, pima->channels * pima->blocksize) ;
380 pima->samplecount = 0 ;
381 pima->blockcount ++ ;
382
383 return 1 ;
384 } /* aiff_ima_encode_block */
385
386 static int
wavlike_ima_decode_block(SF_PRIVATE * psf,IMA_ADPCM_PRIVATE * pima)387 wavlike_ima_decode_block (SF_PRIVATE *psf, IMA_ADPCM_PRIVATE *pima)
388 { int chan, k, predictor, blockindx, indx, indxstart, diff ;
389 short step, bytecode, stepindx [2] ;
390
391 pima->blockcount ++ ;
392 pima->samplecount = 0 ;
393
394 if (pima->blockcount > pima->blocks)
395 { memset (pima->samples, 0, pima->samplesperblock * pima->channels * sizeof (short)) ;
396 return 1 ;
397 } ;
398
399 if ((k = psf_fread (pima->block, 1, pima->blocksize, psf)) != pima->blocksize)
400 psf_log_printf (psf, "*** Warning : short read (%d != %d).\n", k, pima->blocksize) ;
401
402 /* Read and check the block header. */
403
404 for (chan = 0 ; chan < pima->channels ; chan++)
405 { predictor = pima->block [chan*4] | (pima->block [chan*4+1] << 8) ;
406 if (predictor & 0x8000)
407 predictor -= 0x10000 ;
408
409 stepindx [chan] = pima->block [chan*4+2] ;
410 stepindx [chan] = clamp_ima_step_index (stepindx [chan]) ;
411
412
413 if (pima->block [chan*4+3] != 0)
414 psf_log_printf (psf, "IMA ADPCM synchronisation error.\n") ;
415
416 pima->samples [chan] = predictor ;
417 } ;
418
419 /*
420 ** Pull apart the packed 4 bit samples and store them in their
421 ** correct sample positions.
422 */
423
424 blockindx = 4 * pima->channels ;
425
426 indxstart = pima->channels ;
427 while (blockindx < pima->blocksize)
428 { for (chan = 0 ; chan < pima->channels ; chan++)
429 { indx = indxstart + chan ;
430 for (k = 0 ; k < 4 ; k++)
431 { bytecode = pima->block [blockindx++] ;
432 pima->samples [indx] = bytecode & 0x0F ;
433 indx += pima->channels ;
434 pima->samples [indx] = (bytecode >> 4) & 0x0F ;
435 indx += pima->channels ;
436 } ;
437 } ;
438 indxstart += 8 * pima->channels ;
439 } ;
440
441 /* Decode the encoded 4 bit samples. */
442
443 for (k = pima->channels ; k < (pima->samplesperblock * pima->channels) ; k ++)
444 { chan = (pima->channels > 1) ? (k % 2) : 0 ;
445
446 bytecode = pima->samples [k] & 0xF ;
447
448 step = ima_step_size [stepindx [chan]] ;
449 predictor = pima->samples [k - pima->channels] ;
450
451 diff = step >> 3 ;
452 if (bytecode & 1)
453 diff += step >> 2 ;
454 if (bytecode & 2)
455 diff += step >> 1 ;
456 if (bytecode & 4)
457 diff += step ;
458 if (bytecode & 8)
459 diff = -diff ;
460
461 predictor += diff ;
462
463 if (predictor > 32767)
464 predictor = 32767 ;
465 else if (predictor < -32768)
466 predictor = -32768 ;
467
468 stepindx [chan] += ima_indx_adjust [bytecode] ;
469 stepindx [chan] = clamp_ima_step_index (stepindx [chan]) ;
470
471 pima->samples [k] = predictor ;
472 } ;
473
474 return 1 ;
475 } /* wavlike_ima_decode_block */
476
477 static int
wavlike_ima_encode_block(SF_PRIVATE * psf,IMA_ADPCM_PRIVATE * pima)478 wavlike_ima_encode_block (SF_PRIVATE *psf, IMA_ADPCM_PRIVATE *pima)
479 { int chan, k, step, diff, vpdiff, blockindx, indx, indxstart ;
480 short bytecode, mask ;
481
482 /* Encode the block header. */
483 for (chan = 0 ; chan < pima->channels ; chan++)
484 { pima->block [chan*4] = pima->samples [chan] & 0xFF ;
485 pima->block [chan*4+1] = (pima->samples [chan] >> 8) & 0xFF ;
486
487 pima->block [chan*4+2] = pima->stepindx [chan] ;
488 pima->block [chan*4+3] = 0 ;
489
490 pima->previous [chan] = pima->samples [chan] ;
491 } ;
492
493 /* Encode the samples as 4 bit. */
494
495 for (k = pima->channels ; k < (pima->samplesperblock * pima->channels) ; k ++)
496 { chan = (pima->channels > 1) ? (k % 2) : 0 ;
497
498 diff = pima->samples [k] - pima->previous [chan] ;
499
500 bytecode = 0 ;
501 step = ima_step_size [pima->stepindx [chan]] ;
502 vpdiff = step >> 3 ;
503 if (diff < 0)
504 { bytecode = 8 ;
505 diff = -diff ;
506 } ;
507 mask = 4 ;
508 while (mask)
509 { if (diff >= step)
510 { bytecode |= mask ;
511 diff -= step ;
512 vpdiff += step ;
513 } ;
514 step >>= 1 ;
515 mask >>= 1 ;
516 } ;
517
518 if (bytecode & 8)
519 pima->previous [chan] -= vpdiff ;
520 else
521 pima->previous [chan] += vpdiff ;
522
523 if (pima->previous [chan] > 32767)
524 pima->previous [chan] = 32767 ;
525 else if (pima->previous [chan] < -32768)
526 pima->previous [chan] = -32768 ;
527
528 pima->stepindx [chan] += ima_indx_adjust [bytecode] ;
529 pima->stepindx [chan] = clamp_ima_step_index (pima->stepindx [chan]) ;
530
531 pima->samples [k] = bytecode ;
532 } ;
533
534 /* Pack the 4 bit encoded samples. */
535
536 blockindx = 4 * pima->channels ;
537
538 indxstart = pima->channels ;
539 while (blockindx < pima->blocksize)
540 { for (chan = 0 ; chan < pima->channels ; chan++)
541 { indx = indxstart + chan ;
542 for (k = 0 ; k < 4 ; k++)
543 { pima->block [blockindx] = pima->samples [indx] & 0x0F ;
544 indx += pima->channels ;
545 pima->block [blockindx] |= (pima->samples [indx] << 4) & 0xF0 ;
546 indx += pima->channels ;
547 blockindx ++ ;
548 } ;
549 } ;
550 indxstart += 8 * pima->channels ;
551 } ;
552
553 /* Write the block to disk. */
554
555 if ((k = psf_fwrite (pima->block, 1, pima->blocksize, psf)) != pima->blocksize)
556 psf_log_printf (psf, "*** Warning : short write (%d != %d).\n", k, pima->blocksize) ;
557
558 memset (pima->samples, 0, pima->samplesperblock * sizeof (short)) ;
559 pima->samplecount = 0 ;
560 pima->blockcount ++ ;
561
562 return 1 ;
563 } /* wavlike_ima_encode_block */
564
565 static int
ima_read_block(SF_PRIVATE * psf,IMA_ADPCM_PRIVATE * pima,short * ptr,int len)566 ima_read_block (SF_PRIVATE *psf, IMA_ADPCM_PRIVATE *pima, short *ptr, int len)
567 { int count, total = 0, indx = 0 ;
568
569 while (indx < len)
570 { if (pima->blockcount >= pima->blocks && pima->samplecount >= pima->samplesperblock)
571 { memset (&(ptr [indx]), 0, (size_t) ((len - indx) * sizeof (short))) ;
572 return total ;
573 } ;
574
575 if (pima->samplecount >= pima->samplesperblock)
576 pima->decode_block (psf, pima) ;
577
578 count = (pima->samplesperblock - pima->samplecount) * pima->channels ;
579 count = (len - indx > count) ? count : len - indx ;
580
581 memcpy (&(ptr [indx]), &(pima->samples [pima->samplecount * pima->channels]), count * sizeof (short)) ;
582 indx += count ;
583 pima->samplecount += count / pima->channels ;
584 total = indx ;
585 } ;
586
587 return total ;
588 } /* ima_read_block */
589
590 static sf_count_t
ima_read_s(SF_PRIVATE * psf,short * ptr,sf_count_t len)591 ima_read_s (SF_PRIVATE *psf, short *ptr, sf_count_t len)
592 { IMA_ADPCM_PRIVATE *pima ;
593 int readcount, count ;
594 sf_count_t total = 0 ;
595
596 if (! psf->codec_data)
597 return 0 ;
598 pima = (IMA_ADPCM_PRIVATE*) psf->codec_data ;
599
600 while (len > 0)
601 { readcount = (len > 0x10000000) ? 0x10000000 : (int) len ;
602
603 count = ima_read_block (psf, pima, ptr, readcount) ;
604
605 total += count ;
606 len -= count ;
607 if (count != readcount)
608 break ;
609 } ;
610
611 return total ;
612 } /* ima_read_s */
613
614 static sf_count_t
ima_read_i(SF_PRIVATE * psf,int * ptr,sf_count_t len)615 ima_read_i (SF_PRIVATE *psf, int *ptr, sf_count_t len)
616 { IMA_ADPCM_PRIVATE *pima ;
617 BUF_UNION ubuf ;
618 short *sptr ;
619 int k, bufferlen, readcount, count ;
620 sf_count_t total = 0 ;
621
622 if (! psf->codec_data)
623 return 0 ;
624 pima = (IMA_ADPCM_PRIVATE*) psf->codec_data ;
625
626 sptr = ubuf.sbuf ;
627 bufferlen = ARRAY_LEN (ubuf.sbuf) ;
628 while (len > 0)
629 { readcount = (len >= bufferlen) ? bufferlen : (int) len ;
630 count = ima_read_block (psf, pima, sptr, readcount) ;
631 for (k = 0 ; k < readcount ; k++)
632 ptr [total + k] = arith_shift_left (sptr [k], 16) ;
633 total += count ;
634 len -= readcount ;
635 if (count != readcount)
636 break ;
637 } ;
638
639 return total ;
640 } /* ima_read_i */
641
642 static sf_count_t
ima_read_f(SF_PRIVATE * psf,float * ptr,sf_count_t len)643 ima_read_f (SF_PRIVATE *psf, float *ptr, sf_count_t len)
644 { IMA_ADPCM_PRIVATE *pima ;
645 BUF_UNION ubuf ;
646 short *sptr ;
647 int k, bufferlen, readcount, count ;
648 sf_count_t total = 0 ;
649 float normfact ;
650
651 if (! psf->codec_data)
652 return 0 ;
653 pima = (IMA_ADPCM_PRIVATE*) psf->codec_data ;
654
655 normfact = (psf->norm_float == SF_TRUE) ? 1.0 / ((float) 0x8000) : 1.0 ;
656
657 sptr = ubuf.sbuf ;
658 bufferlen = ARRAY_LEN (ubuf.sbuf) ;
659 while (len > 0)
660 { readcount = (len >= bufferlen) ? bufferlen : (int) len ;
661 count = ima_read_block (psf, pima, sptr, readcount) ;
662 for (k = 0 ; k < readcount ; k++)
663 ptr [total + k] = normfact * (float) (sptr [k]) ;
664 total += count ;
665 len -= readcount ;
666 if (count != readcount)
667 break ;
668 } ;
669
670 return total ;
671 } /* ima_read_f */
672
673 static sf_count_t
ima_read_d(SF_PRIVATE * psf,double * ptr,sf_count_t len)674 ima_read_d (SF_PRIVATE *psf, double *ptr, sf_count_t len)
675 { IMA_ADPCM_PRIVATE *pima ;
676 BUF_UNION ubuf ;
677 short *sptr ;
678 int k, bufferlen, readcount, count ;
679 sf_count_t total = 0 ;
680 double normfact ;
681
682 if (! psf->codec_data)
683 return 0 ;
684 pima = (IMA_ADPCM_PRIVATE*) psf->codec_data ;
685
686 normfact = (psf->norm_double == SF_TRUE) ? 1.0 / ((double) 0x8000) : 1.0 ;
687
688 sptr = ubuf.sbuf ;
689 bufferlen = ARRAY_LEN (ubuf.sbuf) ;
690 while (len > 0)
691 { readcount = (len >= bufferlen) ? bufferlen : (int) len ;
692 count = ima_read_block (psf, pima, sptr, readcount) ;
693 for (k = 0 ; k < readcount ; k++)
694 ptr [total + k] = normfact * (double) (sptr [k]) ;
695 total += count ;
696 len -= readcount ;
697 if (count != readcount)
698 break ;
699 } ;
700
701 return total ;
702 } /* ima_read_d */
703
704 static sf_count_t
aiff_ima_seek(SF_PRIVATE * psf,int mode,sf_count_t offset)705 aiff_ima_seek (SF_PRIVATE *psf, int mode, sf_count_t offset)
706 { IMA_ADPCM_PRIVATE *pima ;
707 int newblock, newsample, newblockaiff ;
708
709 if (! psf->codec_data)
710 return 0 ;
711 pima = (IMA_ADPCM_PRIVATE*) psf->codec_data ;
712
713 if (psf->datalength < 0 || psf->dataoffset < 0)
714 { psf->error = SFE_BAD_SEEK ;
715 return PSF_SEEK_ERROR ;
716 } ;
717
718 if (offset == 0)
719 { psf_fseek (psf, psf->dataoffset, SEEK_SET) ;
720 pima->blockcount = 0 ;
721 pima->decode_block (psf, pima) ;
722 pima->samplecount = 0 ;
723 return 0 ;
724 } ;
725
726 if (offset < 0 || offset > pima->blocks * pima->samplesperblock)
727 { psf->error = SFE_BAD_SEEK ;
728 return PSF_SEEK_ERROR ;
729 } ;
730
731 newblock = offset / pima->samplesperblock ;
732 newsample = offset % pima->samplesperblock ;
733 newblockaiff = newblock * psf->sf.channels ;
734
735 if (mode == SFM_READ)
736 { psf_fseek (psf, psf->dataoffset + newblockaiff * pima->blocksize, SEEK_SET) ;
737 pima->blockcount = newblockaiff ;
738 pima->decode_block (psf, pima) ;
739 pima->samplecount = newsample ;
740 }
741 else
742 { /* What to do about write??? */
743 psf->error = SFE_BAD_SEEK ;
744 return PSF_SEEK_ERROR ;
745 } ;
746
747 return newblock * pima->samplesperblock + newsample ;
748 } /* aiff_ima_seek */
749
750 static sf_count_t
wavlike_ima_seek(SF_PRIVATE * psf,int mode,sf_count_t offset)751 wavlike_ima_seek (SF_PRIVATE *psf, int mode, sf_count_t offset)
752 { IMA_ADPCM_PRIVATE *pima ;
753 int newblock, newsample ;
754
755 if (! psf->codec_data)
756 return 0 ;
757 pima = (IMA_ADPCM_PRIVATE*) psf->codec_data ;
758
759 if (psf->datalength < 0 || psf->dataoffset < 0)
760 { psf->error = SFE_BAD_SEEK ;
761 return PSF_SEEK_ERROR ;
762 } ;
763
764 if (offset == 0)
765 { psf_fseek (psf, psf->dataoffset, SEEK_SET) ;
766 pima->blockcount = 0 ;
767 if (!pima->decode_block)
768 return PSF_SEEK_ERROR ;
769
770 pima->decode_block (psf, pima) ;
771 pima->samplecount = 0 ;
772 return 0 ;
773 } ;
774
775 if (offset < 0 || offset > pima->blocks * pima->samplesperblock)
776 { psf->error = SFE_BAD_SEEK ;
777 return PSF_SEEK_ERROR ;
778 } ;
779
780 newblock = offset / pima->samplesperblock ;
781 newsample = offset % pima->samplesperblock ;
782
783 if (mode == SFM_READ)
784 { psf_fseek (psf, psf->dataoffset + newblock * pima->blocksize, SEEK_SET) ;
785 pima->blockcount = newblock ;
786 pima->decode_block (psf, pima) ;
787 pima->samplecount = newsample ;
788 }
789 else
790 { /* What to do about write??? */
791 psf->error = SFE_BAD_SEEK ;
792 return PSF_SEEK_ERROR ;
793 } ;
794
795 return newblock * pima->samplesperblock + newsample ;
796 } /* wavlike_ima_seek */
797
798 /*==========================================================================================
799 ** IMA ADPCM Write Functions.
800 */
801
802 static int
ima_writer_init(SF_PRIVATE * psf,int blockalign)803 ima_writer_init (SF_PRIVATE *psf, int blockalign)
804 { IMA_ADPCM_PRIVATE *pima ;
805 int samplesperblock ;
806 unsigned int pimasize ;
807
808 if (psf->file.mode != SFM_WRITE)
809 return SFE_BAD_MODE_RW ;
810
811 switch (SF_CONTAINER (psf->sf.format))
812 { case SF_FORMAT_WAV :
813 case SF_FORMAT_W64 :
814 samplesperblock = 2 * (blockalign - 4 * psf->sf.channels) / psf->sf.channels + 1 ;
815 break ;
816
817 case SF_FORMAT_AIFF :
818 samplesperblock = 2 * ((blockalign - 2) * psf->sf.channels) / psf->sf.channels ;
819 break ;
820
821 default :
822 psf_log_printf (psf, "ima_reader_init: bad psf->sf.format\n") ;
823 return SFE_INTERNAL ;
824 } ;
825
826 pimasize = sizeof (IMA_ADPCM_PRIVATE) + blockalign + 3 * psf->sf.channels * samplesperblock ;
827
828 if ((pima = calloc (1, pimasize)) == NULL)
829 return SFE_MALLOC_FAILED ;
830
831 psf->codec_data = (void*) pima ;
832
833 pima->channels = psf->sf.channels ;
834 pima->blocksize = blockalign ;
835 pima->samplesperblock = samplesperblock ;
836
837 pima->block = (unsigned char*) pima->data ;
838 pima->samples = (short*) (pima->data + blockalign) ;
839
840 pima->samplecount = 0 ;
841
842 switch (SF_CONTAINER (psf->sf.format))
843 { case SF_FORMAT_WAV :
844 case SF_FORMAT_W64 :
845 pima->encode_block = wavlike_ima_encode_block ;
846 break ;
847
848 case SF_FORMAT_AIFF :
849 pima->encode_block = aiff_ima_encode_block ;
850 break ;
851
852 default :
853 psf_log_printf (psf, "ima_reader_init: bad psf->sf.format\n") ;
854 return SFE_INTERNAL ;
855 } ;
856
857 psf->write_short = ima_write_s ;
858 psf->write_int = ima_write_i ;
859 psf->write_float = ima_write_f ;
860 psf->write_double = ima_write_d ;
861
862 return 0 ;
863 } /* ima_writer_init */
864
865 /*==========================================================================================
866 */
867
868 static int
ima_write_block(SF_PRIVATE * psf,IMA_ADPCM_PRIVATE * pima,const short * ptr,int len)869 ima_write_block (SF_PRIVATE *psf, IMA_ADPCM_PRIVATE *pima, const short *ptr, int len)
870 { int count, total = 0, indx = 0 ;
871
872 while (indx < len)
873 { count = (pima->samplesperblock - pima->samplecount) * pima->channels ;
874
875 if (count > len - indx)
876 count = len - indx ;
877
878 memcpy (&(pima->samples [pima->samplecount * pima->channels]), &(ptr [total]), count * sizeof (short)) ;
879 indx += count ;
880 pima->samplecount += count / pima->channels ;
881 total = indx ;
882
883 if (pima->samplecount >= pima->samplesperblock)
884 pima->encode_block (psf, pima) ;
885 } ;
886
887 return total ;
888 } /* ima_write_block */
889
890 static sf_count_t
ima_write_s(SF_PRIVATE * psf,const short * ptr,sf_count_t len)891 ima_write_s (SF_PRIVATE *psf, const short *ptr, sf_count_t len)
892 { IMA_ADPCM_PRIVATE *pima ;
893 int writecount, count ;
894 sf_count_t total = 0 ;
895
896 if (! psf->codec_data)
897 return 0 ;
898 pima = (IMA_ADPCM_PRIVATE*) psf->codec_data ;
899
900 while (len)
901 { writecount = (len > 0x10000000) ? 0x10000000 : (int) len ;
902
903 count = ima_write_block (psf, pima, ptr, writecount) ;
904
905 total += count ;
906 len -= count ;
907 if (count != writecount)
908 break ;
909 } ;
910
911 return total ;
912 } /* ima_write_s */
913
914 static sf_count_t
ima_write_i(SF_PRIVATE * psf,const int * ptr,sf_count_t len)915 ima_write_i (SF_PRIVATE *psf, const int *ptr, sf_count_t len)
916 { IMA_ADPCM_PRIVATE *pima ;
917 BUF_UNION ubuf ;
918 short *sptr ;
919 int k, bufferlen, writecount, count ;
920 sf_count_t total = 0 ;
921
922 if (! psf->codec_data)
923 return 0 ;
924 pima = (IMA_ADPCM_PRIVATE*) psf->codec_data ;
925
926 sptr = ubuf.sbuf ;
927 bufferlen = ARRAY_LEN (ubuf.sbuf) ;
928 while (len > 0)
929 { writecount = (len >= bufferlen) ? bufferlen : (int) len ;
930 for (k = 0 ; k < writecount ; k++)
931 sptr [k] = ptr [total + k] >> 16 ;
932 count = ima_write_block (psf, pima, sptr, writecount) ;
933 total += count ;
934 len -= writecount ;
935 if (count != writecount)
936 break ;
937 } ;
938
939 return total ;
940 } /* ima_write_i */
941
942 static sf_count_t
ima_write_f(SF_PRIVATE * psf,const float * ptr,sf_count_t len)943 ima_write_f (SF_PRIVATE *psf, const float *ptr, sf_count_t len)
944 { IMA_ADPCM_PRIVATE *pima ;
945 BUF_UNION ubuf ;
946 short *sptr ;
947 int k, bufferlen, writecount, count ;
948 sf_count_t total = 0 ;
949 float normfact ;
950
951 if (! psf->codec_data)
952 return 0 ;
953 pima = (IMA_ADPCM_PRIVATE*) psf->codec_data ;
954
955 normfact = (psf->norm_float == SF_TRUE) ? (1.0 * 0x7FFF) : 1.0 ;
956
957 sptr = ubuf.sbuf ;
958 bufferlen = ARRAY_LEN (ubuf.sbuf) ;
959 while (len > 0)
960 { writecount = (len >= bufferlen) ? bufferlen : (int) len ;
961 for (k = 0 ; k < writecount ; k++)
962 sptr [k] = psf_lrintf (normfact * ptr [total + k]) ;
963 count = ima_write_block (psf, pima, sptr, writecount) ;
964 total += count ;
965 len -= writecount ;
966 if (count != writecount)
967 break ;
968 } ;
969
970 return total ;
971 } /* ima_write_f */
972
973 static sf_count_t
ima_write_d(SF_PRIVATE * psf,const double * ptr,sf_count_t len)974 ima_write_d (SF_PRIVATE *psf, const double *ptr, sf_count_t len)
975 { IMA_ADPCM_PRIVATE *pima ;
976 BUF_UNION ubuf ;
977 short *sptr ;
978 int k, bufferlen, writecount, count ;
979 sf_count_t total = 0 ;
980 double normfact ;
981
982 if (! psf->codec_data)
983 return 0 ;
984 pima = (IMA_ADPCM_PRIVATE*) psf->codec_data ;
985
986 normfact = (psf->norm_double == SF_TRUE) ? (1.0 * 0x7FFF) : 1.0 ;
987
988 sptr = ubuf.sbuf ;
989 bufferlen = ARRAY_LEN (ubuf.sbuf) ;
990 while (len > 0)
991 { writecount = (len >= bufferlen) ? bufferlen : (int) len ;
992 for (k = 0 ; k < writecount ; k++)
993 sptr [k] = psf_lrint (normfact * ptr [total + k]) ;
994 count = ima_write_block (psf, pima, sptr, writecount) ;
995 total += count ;
996 len -= writecount ;
997 if (count != writecount)
998 break ;
999 } ;
1000
1001 return total ;
1002 } /* ima_write_d */
1003
1004