99729d34125735d45469d2566d4c2491a852c0d5
[Faustine.git] / interpretor / libsndfile-1.0.25 / src / g72x.c
1 /*
2 ** Copyright (C) 1999-2011 Erik de Castro Lopo <erikd@mega-nerd.com>
3 **
4 ** This program is free software; you can redistribute it and/or modify
5 ** it under the terms of the GNU Lesser General Public License as published by
6 ** the Free Software Foundation; either version 2.1 of the License, or
7 ** (at your option) any later version.
8 **
9 ** This program is distributed in the hope that it will be useful,
10 ** but WITHOUT ANY WARRANTY; without even the implied warranty of
11 ** MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
12 ** GNU Lesser General Public License for more details.
13 **
14 ** You should have received a copy of the GNU Lesser General Public License
15 ** along with this program; if not, write to the Free Software
16 ** Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA.
17 */
18
19 #include "sfconfig.h"
20
21 #include <stdio.h>
22 #include <stdlib.h>
23 #include <string.h>
24 #include <math.h>
25
26 #include "sndfile.h"
27 #include "sfendian.h"
28 #include "common.h"
29 #include "G72x/g72x.h"
30
31 /* This struct is private to the G72x code. */
32 struct g72x_state ;
33 typedef struct g72x_state G72x_STATE ;
34
35 typedef struct
36 { /* Private data. Don't mess with it. */
37 struct g72x_state * private ;
38
39 /* Public data. Read only. */
40 int blocksize, samplesperblock, bytesperblock ;
41
42 /* Public data. Read and write. */
43 int blocks_total, block_curr, sample_curr ;
44 unsigned char block [G72x_BLOCK_SIZE] ;
45 short samples [G72x_BLOCK_SIZE] ;
46 } G72x_PRIVATE ;
47
48 static int psf_g72x_decode_block (SF_PRIVATE *psf, G72x_PRIVATE *pg72x) ;
49 static int psf_g72x_encode_block (SF_PRIVATE *psf, G72x_PRIVATE *pg72x) ;
50
51 static sf_count_t g72x_read_s (SF_PRIVATE *psf, short *ptr, sf_count_t len) ;
52 static sf_count_t g72x_read_i (SF_PRIVATE *psf, int *ptr, sf_count_t len) ;
53 static sf_count_t g72x_read_f (SF_PRIVATE *psf, float *ptr, sf_count_t len) ;
54 static sf_count_t g72x_read_d (SF_PRIVATE *psf, double *ptr, sf_count_t len) ;
55
56 static sf_count_t g72x_write_s (SF_PRIVATE *psf, const short *ptr, sf_count_t len) ;
57 static sf_count_t g72x_write_i (SF_PRIVATE *psf, const int *ptr, sf_count_t len) ;
58 static sf_count_t g72x_write_f (SF_PRIVATE *psf, const float *ptr, sf_count_t len) ;
59 static sf_count_t g72x_write_d (SF_PRIVATE *psf, const double *ptr, sf_count_t len) ;
60
61 static sf_count_t g72x_seek (SF_PRIVATE *psf, int mode, sf_count_t offset) ;
62
63 static int g72x_close (SF_PRIVATE *psf) ;
64
65
66 /*============================================================================================
67 ** WAV G721 Reader initialisation function.
68 */
69
70 int
71 g72x_init (SF_PRIVATE * psf)
72 { G72x_PRIVATE *pg72x ;
73 int bitspersample, bytesperblock, codec ;
74
75 if (psf->codec_data != NULL)
76 { psf_log_printf (psf, "*** psf->codec_data is not NULL.\n") ;
77 return SFE_INTERNAL ;
78 } ;
79
80 psf->sf.seekable = SF_FALSE ;
81
82 if (psf->sf.channels != 1)
83 return SFE_G72X_NOT_MONO ;
84
85 if ((pg72x = calloc (1, sizeof (G72x_PRIVATE))) == NULL)
86 return SFE_MALLOC_FAILED ;
87
88 psf->codec_data = (void*) pg72x ;
89
90 pg72x->block_curr = 0 ;
91 pg72x->sample_curr = 0 ;
92
93 switch (SF_CODEC (psf->sf.format))
94 { case SF_FORMAT_G721_32 :
95 codec = G721_32_BITS_PER_SAMPLE ;
96 bytesperblock = G721_32_BYTES_PER_BLOCK ;
97 bitspersample = G721_32_BITS_PER_SAMPLE ;
98 break ;
99
100 case SF_FORMAT_G723_24:
101 codec = G723_24_BITS_PER_SAMPLE ;
102 bytesperblock = G723_24_BYTES_PER_BLOCK ;
103 bitspersample = G723_24_BITS_PER_SAMPLE ;
104 break ;
105
106 case SF_FORMAT_G723_40:
107 codec = G723_40_BITS_PER_SAMPLE ;
108 bytesperblock = G723_40_BYTES_PER_BLOCK ;
109 bitspersample = G723_40_BITS_PER_SAMPLE ;
110 break ;
111
112 default : return SFE_UNIMPLEMENTED ;
113 } ;
114
115 psf->blockwidth = psf->bytewidth = 1 ;
116
117 psf->filelength = psf_get_filelen (psf) ;
118 if (psf->filelength < psf->dataoffset)
119 psf->filelength = psf->dataoffset ;
120
121 psf->datalength = psf->filelength - psf->dataoffset ;
122 if (psf->dataend > 0)
123 psf->datalength -= psf->filelength - psf->dataend ;
124
125 if (psf->file.mode == SFM_READ)
126 { pg72x->private = g72x_reader_init (codec, &(pg72x->blocksize), &(pg72x->samplesperblock)) ;
127 if (pg72x->private == NULL)
128 return SFE_MALLOC_FAILED ;
129
130 pg72x->bytesperblock = bytesperblock ;
131
132 psf->read_short = g72x_read_s ;
133 psf->read_int = g72x_read_i ;
134 psf->read_float = g72x_read_f ;
135 psf->read_double = g72x_read_d ;
136
137 psf->seek = g72x_seek ;
138
139 if (psf->datalength % pg72x->blocksize)
140 { psf_log_printf (psf, "*** Odd psf->datalength (%D) should be a multiple of %d\n", psf->datalength, pg72x->blocksize) ;
141 pg72x->blocks_total = (psf->datalength / pg72x->blocksize) + 1 ;
142 }
143 else
144 pg72x->blocks_total = psf->datalength / pg72x->blocksize ;
145
146 psf->sf.frames = pg72x->blocks_total * pg72x->samplesperblock ;
147
148 psf_g72x_decode_block (psf, pg72x) ;
149 }
150 else if (psf->file.mode == SFM_WRITE)
151 { pg72x->private = g72x_writer_init (codec, &(pg72x->blocksize), &(pg72x->samplesperblock)) ;
152 if (pg72x->private == NULL)
153 return SFE_MALLOC_FAILED ;
154
155 pg72x->bytesperblock = bytesperblock ;
156
157 psf->write_short = g72x_write_s ;
158 psf->write_int = g72x_write_i ;
159 psf->write_float = g72x_write_f ;
160 psf->write_double = g72x_write_d ;
161
162 if (psf->datalength % pg72x->blocksize)
163 pg72x->blocks_total = (psf->datalength / pg72x->blocksize) + 1 ;
164 else
165 pg72x->blocks_total = psf->datalength / pg72x->blocksize ;
166
167 if (psf->datalength > 0)
168 psf->sf.frames = (8 * psf->datalength) / bitspersample ;
169
170 if ((psf->sf.frames * bitspersample) / 8 != psf->datalength)
171 psf_log_printf (psf, "*** Warning : weird psf->datalength.\n") ;
172 } ;
173
174 psf->codec_close = g72x_close ;
175
176 return 0 ;
177 } /* g72x_init */
178
179 /*============================================================================================
180 ** G721 Read Functions.
181 */
182
183 static int
184 psf_g72x_decode_block (SF_PRIVATE *psf, G72x_PRIVATE *pg72x)
185 { int k ;
186
187 pg72x->block_curr ++ ;
188 pg72x->sample_curr = 0 ;
189
190 if (pg72x->block_curr > pg72x->blocks_total)
191 { memset (pg72x->samples, 0, G72x_BLOCK_SIZE * sizeof (short)) ;
192 return 1 ;
193 } ;
194
195 if ((k = psf_fread (pg72x->block, 1, pg72x->bytesperblock, psf)) != pg72x->bytesperblock)
196 psf_log_printf (psf, "*** Warning : short read (%d != %d).\n", k, pg72x->bytesperblock) ;
197
198 pg72x->blocksize = k ;
199 g72x_decode_block (pg72x->private, pg72x->block, pg72x->samples) ;
200
201 return 1 ;
202 } /* psf_g72x_decode_block */
203
204 static int
205 g72x_read_block (SF_PRIVATE *psf, G72x_PRIVATE *pg72x, short *ptr, int len)
206 { int count, total = 0, indx = 0 ;
207
208 while (indx < len)
209 { if (pg72x->block_curr > pg72x->blocks_total)
210 { memset (&(ptr [indx]), 0, (len - indx) * sizeof (short)) ;
211 return total ;
212 } ;
213
214 if (pg72x->sample_curr >= pg72x->samplesperblock)
215 psf_g72x_decode_block (psf, pg72x) ;
216
217 count = pg72x->samplesperblock - pg72x->sample_curr ;
218 count = (len - indx > count) ? count : len - indx ;
219
220 memcpy (&(ptr [indx]), &(pg72x->samples [pg72x->sample_curr]), count * sizeof (short)) ;
221 indx += count ;
222 pg72x->sample_curr += count ;
223 total = indx ;
224 } ;
225
226 return total ;
227 } /* g72x_read_block */
228
229 static sf_count_t
230 g72x_read_s (SF_PRIVATE *psf, short *ptr, sf_count_t len)
231 { G72x_PRIVATE *pg72x ;
232 int readcount, count ;
233 sf_count_t total = 0 ;
234
235 if (psf->codec_data == NULL)
236 return 0 ;
237 pg72x = (G72x_PRIVATE*) psf->codec_data ;
238
239 while (len > 0)
240 { readcount = (len > 0x10000000) ? 0x10000000 : (int) len ;
241
242 count = g72x_read_block (psf, pg72x, ptr, readcount) ;
243
244 total += count ;
245 len -= count ;
246
247 if (count != readcount)
248 break ;
249 } ;
250
251 return total ;
252 } /* g72x_read_s */
253
254 static sf_count_t
255 g72x_read_i (SF_PRIVATE *psf, int *ptr, sf_count_t len)
256 { G72x_PRIVATE *pg72x ;
257 short *sptr ;
258 int k, bufferlen, readcount = 0, count ;
259 sf_count_t total = 0 ;
260
261 if (psf->codec_data == NULL)
262 return 0 ;
263 pg72x = (G72x_PRIVATE*) psf->codec_data ;
264
265 sptr = psf->u.sbuf ;
266 bufferlen = SF_BUFFER_LEN / sizeof (short) ;
267 while (len > 0)
268 { readcount = (len >= bufferlen) ? bufferlen : len ;
269 count = g72x_read_block (psf, pg72x, sptr, readcount) ;
270
271 for (k = 0 ; k < readcount ; k++)
272 ptr [total + k] = sptr [k] << 16 ;
273
274 total += count ;
275 len -= readcount ;
276 if (count != readcount)
277 break ;
278 } ;
279
280 return total ;
281 } /* g72x_read_i */
282
283 static sf_count_t
284 g72x_read_f (SF_PRIVATE *psf, float *ptr, sf_count_t len)
285 { G72x_PRIVATE *pg72x ;
286 short *sptr ;
287 int k, bufferlen, readcount = 0, count ;
288 sf_count_t total = 0 ;
289 float normfact ;
290
291 if (psf->codec_data == NULL)
292 return 0 ;
293 pg72x = (G72x_PRIVATE*) psf->codec_data ;
294
295 normfact = (psf->norm_float == SF_TRUE) ? 1.0 / ((float) 0x8000) : 1.0 ;
296
297 sptr = psf->u.sbuf ;
298 bufferlen = SF_BUFFER_LEN / sizeof (short) ;
299 while (len > 0)
300 { readcount = (len >= bufferlen) ? bufferlen : len ;
301 count = g72x_read_block (psf, pg72x, sptr, readcount) ;
302 for (k = 0 ; k < readcount ; k++)
303 ptr [total + k] = normfact * sptr [k] ;
304
305 total += count ;
306 len -= readcount ;
307 if (count != readcount)
308 break ;
309 } ;
310
311 return total ;
312 } /* g72x_read_f */
313
314 static sf_count_t
315 g72x_read_d (SF_PRIVATE *psf, double *ptr, sf_count_t len)
316 { G72x_PRIVATE *pg72x ;
317 short *sptr ;
318 int k, bufferlen, readcount = 0, count ;
319 sf_count_t total = 0 ;
320 double normfact ;
321
322 if (psf->codec_data == NULL)
323 return 0 ;
324 pg72x = (G72x_PRIVATE*) psf->codec_data ;
325
326 normfact = (psf->norm_double == SF_TRUE) ? 1.0 / ((double) 0x8000) : 1.0 ;
327
328 sptr = psf->u.sbuf ;
329 bufferlen = SF_BUFFER_LEN / sizeof (short) ;
330 while (len > 0)
331 { readcount = (len >= bufferlen) ? bufferlen : len ;
332 count = g72x_read_block (psf, pg72x, sptr, readcount) ;
333 for (k = 0 ; k < readcount ; k++)
334 ptr [total + k] = normfact * (double) (sptr [k]) ;
335
336 total += count ;
337 len -= readcount ;
338 if (count != readcount)
339 break ;
340 } ;
341
342 return total ;
343 } /* g72x_read_d */
344
345 static sf_count_t
346 g72x_seek (SF_PRIVATE *psf, int UNUSED (mode), sf_count_t UNUSED (offset))
347 {
348 psf_log_printf (psf, "seek unsupported\n") ;
349
350 /* No simple solution. To do properly, would need to seek
351 ** to start of file and decode everything up to seek position.
352 ** Maybe implement SEEK_SET to 0 only?
353 */
354 return 0 ;
355
356 /*
357 ** G72x_PRIVATE *pg72x ;
358 ** int newblock, newsample, sample_curr ;
359 **
360 ** if (psf->codec_data == NULL)
361 ** return 0 ;
362 ** pg72x = (G72x_PRIVATE*) psf->codec_data ;
363 **
364 ** if (! (psf->datalength && psf->dataoffset))
365 ** { psf->error = SFE_BAD_SEEK ;
366 ** return PSF_SEEK_ERROR ;
367 ** } ;
368 **
369 ** sample_curr = (8 * psf->datalength) / G721_32_BITS_PER_SAMPLE ;
370 **
371 ** switch (whence)
372 ** { case SEEK_SET :
373 ** if (offset < 0 || offset > sample_curr)
374 ** { psf->error = SFE_BAD_SEEK ;
375 ** return PSF_SEEK_ERROR ;
376 ** } ;
377 ** newblock = offset / pg72x->samplesperblock ;
378 ** newsample = offset % pg72x->samplesperblock ;
379 ** break ;
380 **
381 ** case SEEK_CUR :
382 ** if (psf->current + offset < 0 || psf->current + offset > sample_curr)
383 ** { psf->error = SFE_BAD_SEEK ;
384 ** return PSF_SEEK_ERROR ;
385 ** } ;
386 ** newblock = (8 * (psf->current + offset)) / pg72x->samplesperblock ;
387 ** newsample = (8 * (psf->current + offset)) % pg72x->samplesperblock ;
388 ** break ;
389 **
390 ** case SEEK_END :
391 ** if (offset > 0 || sample_curr + offset < 0)
392 ** { psf->error = SFE_BAD_SEEK ;
393 ** return PSF_SEEK_ERROR ;
394 ** } ;
395 ** newblock = (sample_curr + offset) / pg72x->samplesperblock ;
396 ** newsample = (sample_curr + offset) % pg72x->samplesperblock ;
397 ** break ;
398 **
399 ** default :
400 ** psf->error = SFE_BAD_SEEK ;
401 ** return PSF_SEEK_ERROR ;
402 ** } ;
403 **
404 ** if (psf->file.mode == SFM_READ)
405 ** { psf_fseek (psf, psf->dataoffset + newblock * pg72x->blocksize, SEEK_SET) ;
406 ** pg72x->block_curr = newblock ;
407 ** psf_g72x_decode_block (psf, pg72x) ;
408 ** pg72x->sample_curr = newsample ;
409 ** }
410 ** else
411 ** { /+* What to do about write??? *+/
412 ** psf->error = SFE_BAD_SEEK ;
413 ** return PSF_SEEK_ERROR ;
414 ** } ;
415 **
416 ** psf->current = newblock * pg72x->samplesperblock + newsample ;
417 ** return psf->current ;
418 **
419 */
420 } /* g72x_seek */
421
422 /*==========================================================================================
423 ** G72x Write Functions.
424 */
425
426 static int
427 psf_g72x_encode_block (SF_PRIVATE *psf, G72x_PRIVATE *pg72x)
428 { int k ;
429
430 /* Encode the samples. */
431 g72x_encode_block (pg72x->private, pg72x->samples, pg72x->block) ;
432
433 /* Write the block to disk. */
434 if ((k = psf_fwrite (pg72x->block, 1, pg72x->blocksize, psf)) != pg72x->blocksize)
435 psf_log_printf (psf, "*** Warning : short write (%d != %d).\n", k, pg72x->blocksize) ;
436
437 pg72x->sample_curr = 0 ;
438 pg72x->block_curr ++ ;
439
440 /* Set samples to zero for next block. */
441 memset (pg72x->samples, 0, G72x_BLOCK_SIZE * sizeof (short)) ;
442
443 return 1 ;
444 } /* psf_g72x_encode_block */
445
446 static int
447 g72x_write_block (SF_PRIVATE *psf, G72x_PRIVATE *pg72x, const short *ptr, int len)
448 { int count, total = 0, indx = 0 ;
449
450 while (indx < len)
451 { count = pg72x->samplesperblock - pg72x->sample_curr ;
452
453 if (count > len - indx)
454 count = len - indx ;
455
456 memcpy (&(pg72x->samples [pg72x->sample_curr]), &(ptr [indx]), count * sizeof (short)) ;
457 indx += count ;
458 pg72x->sample_curr += count ;
459 total = indx ;
460
461 if (pg72x->sample_curr >= pg72x->samplesperblock)
462 psf_g72x_encode_block (psf, pg72x) ;
463 } ;
464
465 return total ;
466 } /* g72x_write_block */
467
468 static sf_count_t
469 g72x_write_s (SF_PRIVATE *psf, const short *ptr, sf_count_t len)
470 { G72x_PRIVATE *pg72x ;
471 int writecount, count ;
472 sf_count_t total = 0 ;
473
474 if (psf->codec_data == NULL)
475 return 0 ;
476 pg72x = (G72x_PRIVATE*) psf->codec_data ;
477
478 while (len > 0)
479 { writecount = (len > 0x10000000) ? 0x10000000 : (int) len ;
480
481 count = g72x_write_block (psf, pg72x, ptr, writecount) ;
482
483 total += count ;
484 len -= count ;
485 if (count != writecount)
486 break ;
487 } ;
488
489 return total ;
490 } /* g72x_write_s */
491
492 static sf_count_t
493 g72x_write_i (SF_PRIVATE *psf, const int *ptr, sf_count_t len)
494 { G72x_PRIVATE *pg72x ;
495 short *sptr ;
496 int k, bufferlen, writecount = 0, count ;
497 sf_count_t total = 0 ;
498
499 if (psf->codec_data == NULL)
500 return 0 ;
501 pg72x = (G72x_PRIVATE*) psf->codec_data ;
502
503 sptr = psf->u.sbuf ;
504 bufferlen = ((SF_BUFFER_LEN / psf->blockwidth) * psf->blockwidth) / sizeof (short) ;
505 while (len > 0)
506 { writecount = (len >= bufferlen) ? bufferlen : len ;
507 for (k = 0 ; k < writecount ; k++)
508 sptr [k] = ptr [total + k] >> 16 ;
509 count = g72x_write_block (psf, pg72x, sptr, writecount) ;
510
511 total += count ;
512 len -= writecount ;
513 if (count != writecount)
514 break ;
515 } ;
516 return total ;
517 } /* g72x_write_i */
518
519 static sf_count_t
520 g72x_write_f (SF_PRIVATE *psf, const float *ptr, sf_count_t len)
521 { G72x_PRIVATE *pg72x ;
522 short *sptr ;
523 int k, bufferlen, writecount = 0, count ;
524 sf_count_t total = 0 ;
525 float normfact ;
526
527 if (psf->codec_data == NULL)
528 return 0 ;
529 pg72x = (G72x_PRIVATE*) psf->codec_data ;
530
531 normfact = (psf->norm_float == SF_TRUE) ? (1.0 * 0x8000) : 1.0 ;
532
533 sptr = psf->u.sbuf ;
534 bufferlen = ((SF_BUFFER_LEN / psf->blockwidth) * psf->blockwidth) / sizeof (short) ;
535 while (len > 0)
536 { writecount = (len >= bufferlen) ? bufferlen : len ;
537 for (k = 0 ; k < writecount ; k++)
538 sptr [k] = lrintf (normfact * ptr [total + k]) ;
539 count = g72x_write_block (psf, pg72x, sptr, writecount) ;
540
541 total += count ;
542 len -= writecount ;
543 if (count != writecount)
544 break ;
545 } ;
546
547 return total ;
548 } /* g72x_write_f */
549
550 static sf_count_t
551 g72x_write_d (SF_PRIVATE *psf, const double *ptr, sf_count_t len)
552 { G72x_PRIVATE *pg72x ;
553 short *sptr ;
554 int k, bufferlen, writecount = 0, count ;
555 sf_count_t total = 0 ;
556 double normfact ;
557
558 if (psf->codec_data == NULL)
559 return 0 ;
560 pg72x = (G72x_PRIVATE*) psf->codec_data ;
561
562 normfact = (psf->norm_double == SF_TRUE) ? (1.0 * 0x8000) : 1.0 ;
563
564 sptr = psf->u.sbuf ;
565 bufferlen = ((SF_BUFFER_LEN / psf->blockwidth) * psf->blockwidth) / sizeof (short) ;
566 while (len > 0)
567 { writecount = (len >= bufferlen) ? bufferlen : len ;
568 for (k = 0 ; k < writecount ; k++)
569 sptr [k] = lrint (normfact * ptr [total + k]) ;
570 count = g72x_write_block (psf, pg72x, sptr, writecount) ;
571
572 total += count ;
573 len -= writecount ;
574 if (count != writecount)
575 break ;
576 } ;
577
578 return total ;
579 } /* g72x_write_d */
580
581 static int
582 g72x_close (SF_PRIVATE *psf)
583 { G72x_PRIVATE *pg72x ;
584
585 pg72x = (G72x_PRIVATE*) psf->codec_data ;
586
587 if (psf->file.mode == SFM_WRITE)
588 { /* If a block has been partially assembled, write it out
589 ** as the final block.
590 */
591
592 if (pg72x->sample_curr && pg72x->sample_curr < G72x_BLOCK_SIZE)
593 psf_g72x_encode_block (psf, pg72x) ;
594
595 if (psf->write_header)
596 psf->write_header (psf, SF_FALSE) ;
597 } ;
598
599 /* Only free the pointer allocated by g72x_(reader|writer)_init. */
600 free (pg72x->private) ;
601
602 return 0 ;
603 } /* g72x_close */
604