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