Coverage Report

Created: 2025-08-26 06:36

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