2 ** Copyright (C) 1999-2011 Erik de Castro Lopo <erikd@mega-nerd.com>
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.
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.
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.
30 #include "GSM610/gsm.h"
32 #define GSM610_BLOCKSIZE 33
33 #define GSM610_SAMPLES 160
35 typedef struct gsm610_tag
37 int blockcount
, samplecount
;
38 int samplesperblock
, blocksize
;
40 int (*decode_block
) (SF_PRIVATE
*psf
, struct gsm610_tag
*pgsm610
) ;
41 int (*encode_block
) (SF_PRIVATE
*psf
, struct gsm610_tag
*pgsm610
) ;
43 short samples
[WAV_W64_GSM610_SAMPLES
] ;
44 unsigned char block
[WAV_W64_GSM610_BLOCKSIZE
] ;
46 /* Damn I hate typedef-ed pointers; yes, gsm is a pointer type. */
50 static sf_count_t
gsm610_read_s (SF_PRIVATE
*psf
, short *ptr
, sf_count_t len
) ;
51 static sf_count_t
gsm610_read_i (SF_PRIVATE
*psf
, int *ptr
, sf_count_t len
) ;
52 static sf_count_t
gsm610_read_f (SF_PRIVATE
*psf
, float *ptr
, sf_count_t len
) ;
53 static sf_count_t
gsm610_read_d (SF_PRIVATE
*psf
, double *ptr
, sf_count_t len
) ;
55 static sf_count_t
gsm610_write_s (SF_PRIVATE
*psf
, const short *ptr
, sf_count_t len
) ;
56 static sf_count_t
gsm610_write_i (SF_PRIVATE
*psf
, const int *ptr
, sf_count_t len
) ;
57 static sf_count_t
gsm610_write_f (SF_PRIVATE
*psf
, const float *ptr
, sf_count_t len
) ;
58 static sf_count_t
gsm610_write_d (SF_PRIVATE
*psf
, const double *ptr
, sf_count_t len
) ;
60 static int gsm610_read_block (SF_PRIVATE
*psf
, GSM610_PRIVATE
*pgsm610
, short *ptr
, int len
) ;
61 static int gsm610_write_block (SF_PRIVATE
*psf
, GSM610_PRIVATE
*pgsm610
, const short *ptr
, int len
) ;
63 static int gsm610_decode_block (SF_PRIVATE
*psf
, GSM610_PRIVATE
*pgsm610
) ;
64 static int gsm610_encode_block (SF_PRIVATE
*psf
, GSM610_PRIVATE
*pgsm610
) ;
66 static int gsm610_wav_decode_block (SF_PRIVATE
*psf
, GSM610_PRIVATE
*pgsm610
) ;
67 static int gsm610_wav_encode_block (SF_PRIVATE
*psf
, GSM610_PRIVATE
*pgsm610
) ;
69 static sf_count_t
gsm610_seek (SF_PRIVATE
*psf
, int mode
, sf_count_t offset
) ;
71 static int gsm610_close (SF_PRIVATE
*psf
) ;
73 /*============================================================================================
74 ** WAV GSM610 initialisation function.
78 gsm610_init (SF_PRIVATE
*psf
)
79 { GSM610_PRIVATE
*pgsm610
;
82 if (psf
->codec_data
!= NULL
)
83 { psf_log_printf (psf
, "*** psf->codec_data is not NULL.\n") ;
87 if (psf
->file
.mode
== SFM_RDWR
)
88 return SFE_BAD_MODE_RW
;
90 psf
->sf
.seekable
= SF_FALSE
;
92 if ((pgsm610
= calloc (1, sizeof (GSM610_PRIVATE
))) == NULL
)
93 return SFE_MALLOC_FAILED
;
95 psf
->codec_data
= pgsm610
;
97 memset (pgsm610
, 0, sizeof (GSM610_PRIVATE
)) ;
99 /*============================================================
101 Need separate gsm_data structs for encode and decode.
103 ============================================================*/
105 if ((pgsm610
->gsm_data
= gsm_create ()) == NULL
)
106 return SFE_MALLOC_FAILED
;
108 switch (SF_CONTAINER (psf
->sf
.format
))
109 { case SF_FORMAT_WAV
:
110 case SF_FORMAT_WAVEX
:
112 gsm_option (pgsm610
->gsm_data
, GSM_OPT_WAV49
, &true_flag
) ;
114 pgsm610
->encode_block
= gsm610_wav_encode_block
;
115 pgsm610
->decode_block
= gsm610_wav_decode_block
;
117 pgsm610
->samplesperblock
= WAV_W64_GSM610_SAMPLES
;
118 pgsm610
->blocksize
= WAV_W64_GSM610_BLOCKSIZE
;
121 case SF_FORMAT_AIFF
:
123 pgsm610
->encode_block
= gsm610_encode_block
;
124 pgsm610
->decode_block
= gsm610_decode_block
;
126 pgsm610
->samplesperblock
= GSM610_SAMPLES
;
127 pgsm610
->blocksize
= GSM610_BLOCKSIZE
;
131 return SFE_INTERNAL
;
135 if (psf
->file
.mode
== SFM_READ
)
136 { if (psf
->datalength
% pgsm610
->blocksize
== 0)
137 pgsm610
->blocks
= psf
->datalength
/ pgsm610
->blocksize
;
138 else if (psf
->datalength
% pgsm610
->blocksize
== 1 && pgsm610
->blocksize
== GSM610_BLOCKSIZE
)
140 ** Weird AIFF specific case.
141 ** AIFF chunks must be at an even offset from the start of file and
142 ** GSM610_BLOCKSIZE is odd which can result in an odd length SSND
143 ** chunk. The SSND chunk then gets padded on write which means that
144 ** when it is read the datalength is too big by 1.
146 pgsm610
->blocks
= psf
->datalength
/ pgsm610
->blocksize
;
149 { psf_log_printf (psf
, "*** Warning : data chunk seems to be truncated.\n") ;
150 pgsm610
->blocks
= psf
->datalength
/ pgsm610
->blocksize
+ 1 ;
153 psf
->sf
.frames
= pgsm610
->samplesperblock
* pgsm610
->blocks
;
155 psf_fseek (psf
, psf
->dataoffset
, SEEK_SET
) ;
157 pgsm610
->decode_block (psf
, pgsm610
) ; /* Read first block. */
159 psf
->read_short
= gsm610_read_s
;
160 psf
->read_int
= gsm610_read_i
;
161 psf
->read_float
= gsm610_read_f
;
162 psf
->read_double
= gsm610_read_d
;
165 if (psf
->file
.mode
== SFM_WRITE
)
166 { pgsm610
->blockcount
= 0 ;
167 pgsm610
->samplecount
= 0 ;
169 psf
->write_short
= gsm610_write_s
;
170 psf
->write_int
= gsm610_write_i
;
171 psf
->write_float
= gsm610_write_f
;
172 psf
->write_double
= gsm610_write_d
;
175 psf
->codec_close
= gsm610_close
;
177 psf
->seek
= gsm610_seek
;
179 psf
->filelength
= psf_get_filelen (psf
) ;
180 psf
->datalength
= psf
->filelength
- psf
->dataoffset
;
185 /*============================================================================================
186 ** GSM 6.10 Read Functions.
190 gsm610_wav_decode_block (SF_PRIVATE
*psf
, GSM610_PRIVATE
*pgsm610
)
193 pgsm610
->blockcount
++ ;
194 pgsm610
->samplecount
= 0 ;
196 if (pgsm610
->blockcount
> pgsm610
->blocks
)
197 { memset (pgsm610
->samples
, 0, WAV_W64_GSM610_SAMPLES
* sizeof (short)) ;
201 if ((k
= psf_fread (pgsm610
->block
, 1, WAV_W64_GSM610_BLOCKSIZE
, psf
)) != WAV_W64_GSM610_BLOCKSIZE
)
202 psf_log_printf (psf
, "*** Warning : short read (%d != %d).\n", k
, WAV_W64_GSM610_BLOCKSIZE
) ;
204 if (gsm_decode (pgsm610
->gsm_data
, pgsm610
->block
, pgsm610
->samples
) < 0)
205 { psf_log_printf (psf
, "Error from WAV gsm_decode() on frame : %d\n", pgsm610
->blockcount
) ;
209 if (gsm_decode (pgsm610
->gsm_data
, pgsm610
->block
+ (WAV_W64_GSM610_BLOCKSIZE
+ 1) / 2, pgsm610
->samples
+ WAV_W64_GSM610_SAMPLES
/ 2) < 0)
210 { psf_log_printf (psf
, "Error from WAV gsm_decode() on frame : %d.5\n", pgsm610
->blockcount
) ;
215 } /* gsm610_wav_decode_block */
218 gsm610_decode_block (SF_PRIVATE
*psf
, GSM610_PRIVATE
*pgsm610
)
221 pgsm610
->blockcount
++ ;
222 pgsm610
->samplecount
= 0 ;
224 if (pgsm610
->blockcount
> pgsm610
->blocks
)
225 { memset (pgsm610
->samples
, 0, GSM610_SAMPLES
* sizeof (short)) ;
229 if ((k
= psf_fread (pgsm610
->block
, 1, GSM610_BLOCKSIZE
, psf
)) != GSM610_BLOCKSIZE
)
230 psf_log_printf (psf
, "*** Warning : short read (%d != %d).\n", k
, GSM610_BLOCKSIZE
) ;
232 if (gsm_decode (pgsm610
->gsm_data
, pgsm610
->block
, pgsm610
->samples
) < 0)
233 { psf_log_printf (psf
, "Error from standard gsm_decode() on frame : %d\n", pgsm610
->blockcount
) ;
238 } /* gsm610_decode_block */
241 gsm610_read_block (SF_PRIVATE
*psf
, GSM610_PRIVATE
*pgsm610
, short *ptr
, int len
)
242 { int count
, total
= 0, indx
= 0 ;
245 { if (pgsm610
->blockcount
>= pgsm610
->blocks
&& pgsm610
->samplecount
>= pgsm610
->samplesperblock
)
246 { memset (&(ptr
[indx
]), 0, (len
- indx
) * sizeof (short)) ;
250 if (pgsm610
->samplecount
>= pgsm610
->samplesperblock
)
251 pgsm610
->decode_block (psf
, pgsm610
) ;
253 count
= pgsm610
->samplesperblock
- pgsm610
->samplecount
;
254 count
= (len
- indx
> count
) ? count
: len
- indx
;
256 memcpy (&(ptr
[indx
]), &(pgsm610
->samples
[pgsm610
->samplecount
]), count
* sizeof (short)) ;
258 pgsm610
->samplecount
+= count
;
263 } /* gsm610_read_block */
266 gsm610_read_s (SF_PRIVATE
*psf
, short *ptr
, sf_count_t len
)
267 { GSM610_PRIVATE
*pgsm610
;
268 int readcount
, count
;
269 sf_count_t total
= 0 ;
271 if (psf
->codec_data
== NULL
)
273 pgsm610
= (GSM610_PRIVATE
*) psf
->codec_data
;
276 { readcount
= (len
> 0x10000000) ? 0x1000000 : (int) len
;
278 count
= gsm610_read_block (psf
, pgsm610
, ptr
, readcount
) ;
283 if (count
!= readcount
)
288 } /* gsm610_read_s */
291 gsm610_read_i (SF_PRIVATE
*psf
, int *ptr
, sf_count_t len
)
292 { GSM610_PRIVATE
*pgsm610
;
294 int k
, bufferlen
, readcount
= 0, count
;
295 sf_count_t total
= 0 ;
297 if (psf
->codec_data
== NULL
)
299 pgsm610
= (GSM610_PRIVATE
*) psf
->codec_data
;
302 bufferlen
= ARRAY_LEN (psf
->u
.sbuf
) ;
304 { readcount
= (len
>= bufferlen
) ? bufferlen
: len
;
305 count
= gsm610_read_block (psf
, pgsm610
, sptr
, readcount
) ;
306 for (k
= 0 ; k
< readcount
; k
++)
307 ptr
[total
+ k
] = sptr
[k
] << 16 ;
313 } /* gsm610_read_i */
316 gsm610_read_f (SF_PRIVATE
*psf
, float *ptr
, sf_count_t len
)
317 { GSM610_PRIVATE
*pgsm610
;
319 int k
, bufferlen
, readcount
= 0, count
;
320 sf_count_t total
= 0 ;
323 if (psf
->codec_data
== NULL
)
325 pgsm610
= (GSM610_PRIVATE
*) psf
->codec_data
;
327 normfact
= (psf
->norm_float
== SF_TRUE
) ? 1.0 / ((float) 0x8000) : 1.0 ;
330 bufferlen
= ARRAY_LEN (psf
->u
.sbuf
) ;
332 { readcount
= (len
>= bufferlen
) ? bufferlen
: len
;
333 count
= gsm610_read_block (psf
, pgsm610
, sptr
, readcount
) ;
334 for (k
= 0 ; k
< readcount
; k
++)
335 ptr
[total
+ k
] = normfact
* sptr
[k
] ;
341 } /* gsm610_read_f */
344 gsm610_read_d (SF_PRIVATE
*psf
, double *ptr
, sf_count_t len
)
345 { GSM610_PRIVATE
*pgsm610
;
347 int k
, bufferlen
, readcount
= 0, count
;
348 sf_count_t total
= 0 ;
351 normfact
= (psf
->norm_double
== SF_TRUE
) ? 1.0 / ((double) 0x8000) : 1.0 ;
353 if (psf
->codec_data
== NULL
)
355 pgsm610
= (GSM610_PRIVATE
*) psf
->codec_data
;
358 bufferlen
= ARRAY_LEN (psf
->u
.sbuf
) ;
360 { readcount
= (len
>= bufferlen
) ? bufferlen
: len
;
361 count
= gsm610_read_block (psf
, pgsm610
, sptr
, readcount
) ;
362 for (k
= 0 ; k
< readcount
; k
++)
363 ptr
[total
+ k
] = normfact
* sptr
[k
] ;
369 } /* gsm610_read_d */
372 gsm610_seek (SF_PRIVATE
*psf
, int UNUSED (mode
), sf_count_t offset
)
373 { GSM610_PRIVATE
*pgsm610
;
374 int newblock
, newsample
;
376 if (psf
->codec_data
== NULL
)
378 pgsm610
= (GSM610_PRIVATE
*) psf
->codec_data
;
380 if (psf
->dataoffset
< 0)
381 { psf
->error
= SFE_BAD_SEEK
;
382 return PSF_SEEK_ERROR
;
386 { int true_flag
= 1 ;
388 psf_fseek (psf
, psf
->dataoffset
, SEEK_SET
) ;
389 pgsm610
->blockcount
= 0 ;
391 gsm_init (pgsm610
->gsm_data
) ;
392 if ((SF_CONTAINER (psf
->sf
.format
)) == SF_FORMAT_WAV
||
393 (SF_CONTAINER (psf
->sf
.format
)) == SF_FORMAT_W64
)
394 gsm_option (pgsm610
->gsm_data
, GSM_OPT_WAV49
, &true_flag
) ;
396 pgsm610
->decode_block (psf
, pgsm610
) ;
397 pgsm610
->samplecount
= 0 ;
401 if (offset
< 0 || offset
> pgsm610
->blocks
* pgsm610
->samplesperblock
)
402 { psf
->error
= SFE_BAD_SEEK
;
403 return PSF_SEEK_ERROR
;
406 newblock
= offset
/ pgsm610
->samplesperblock
;
407 newsample
= offset
% pgsm610
->samplesperblock
;
409 if (psf
->file
.mode
== SFM_READ
)
410 { if (psf
->read_current
!= newblock
* pgsm610
->samplesperblock
+ newsample
)
411 { psf_fseek (psf
, psf
->dataoffset
+ newblock
* pgsm610
->samplesperblock
, SEEK_SET
) ;
412 pgsm610
->blockcount
= newblock
;
413 pgsm610
->decode_block (psf
, pgsm610
) ;
414 pgsm610
->samplecount
= newsample
;
417 return newblock
* pgsm610
->samplesperblock
+ newsample
;
420 /* What to do about write??? */
421 psf
->error
= SFE_BAD_SEEK
;
422 return PSF_SEEK_ERROR
;
425 /*==========================================================================================
426 ** GSM 6.10 Write Functions.
430 gsm610_encode_block (SF_PRIVATE
*psf
, GSM610_PRIVATE
*pgsm610
)
433 /* Encode the samples. */
434 gsm_encode (pgsm610
->gsm_data
, pgsm610
->samples
, pgsm610
->block
) ;
436 /* Write the block to disk. */
437 if ((k
= psf_fwrite (pgsm610
->block
, 1, GSM610_BLOCKSIZE
, psf
)) != GSM610_BLOCKSIZE
)
438 psf_log_printf (psf
, "*** Warning : short write (%d != %d).\n", k
, GSM610_BLOCKSIZE
) ;
440 pgsm610
->samplecount
= 0 ;
441 pgsm610
->blockcount
++ ;
443 /* Set samples to zero for next block. */
444 memset (pgsm610
->samples
, 0, WAV_W64_GSM610_SAMPLES
* sizeof (short)) ;
447 } /* gsm610_encode_block */
450 gsm610_wav_encode_block (SF_PRIVATE
*psf
, GSM610_PRIVATE
*pgsm610
)
453 /* Encode the samples. */
454 gsm_encode (pgsm610
->gsm_data
, pgsm610
->samples
, pgsm610
->block
) ;
455 gsm_encode (pgsm610
->gsm_data
, pgsm610
->samples
+WAV_W64_GSM610_SAMPLES
/2, pgsm610
->block
+WAV_W64_GSM610_BLOCKSIZE
/2) ;
457 /* Write the block to disk. */
458 if ((k
= psf_fwrite (pgsm610
->block
, 1, WAV_W64_GSM610_BLOCKSIZE
, psf
)) != WAV_W64_GSM610_BLOCKSIZE
)
459 psf_log_printf (psf
, "*** Warning : short write (%d != %d).\n", k
, WAV_W64_GSM610_BLOCKSIZE
) ;
461 pgsm610
->samplecount
= 0 ;
462 pgsm610
->blockcount
++ ;
464 /* Set samples to zero for next block. */
465 memset (pgsm610
->samples
, 0, WAV_W64_GSM610_SAMPLES
* sizeof (short)) ;
468 } /* gsm610_wav_encode_block */
471 gsm610_write_block (SF_PRIVATE
*psf
, GSM610_PRIVATE
*pgsm610
, const short *ptr
, int len
)
472 { int count
, total
= 0, indx
= 0 ;
475 { count
= pgsm610
->samplesperblock
- pgsm610
->samplecount
;
477 if (count
> len
- indx
)
480 memcpy (&(pgsm610
->samples
[pgsm610
->samplecount
]), &(ptr
[indx
]), count
* sizeof (short)) ;
482 pgsm610
->samplecount
+= count
;
485 if (pgsm610
->samplecount
>= pgsm610
->samplesperblock
)
486 pgsm610
->encode_block (psf
, pgsm610
) ;
490 } /* gsm610_write_block */
493 gsm610_write_s (SF_PRIVATE
*psf
, const short *ptr
, sf_count_t len
)
494 { GSM610_PRIVATE
*pgsm610
;
495 int writecount
, count
;
496 sf_count_t total
= 0 ;
498 if (psf
->codec_data
== NULL
)
500 pgsm610
= (GSM610_PRIVATE
*) psf
->codec_data
;
503 { writecount
= (len
> 0x10000000) ? 0x10000000 : (int) len
;
505 count
= gsm610_write_block (psf
, pgsm610
, ptr
, writecount
) ;
510 if (count
!= writecount
)
515 } /* gsm610_write_s */
518 gsm610_write_i (SF_PRIVATE
*psf
, const int *ptr
, sf_count_t len
)
519 { GSM610_PRIVATE
*pgsm610
;
521 int k
, bufferlen
, writecount
= 0, count
;
522 sf_count_t total
= 0 ;
524 if (psf
->codec_data
== NULL
)
526 pgsm610
= (GSM610_PRIVATE
*) psf
->codec_data
;
529 bufferlen
= ARRAY_LEN (psf
->u
.sbuf
) ;
531 { writecount
= (len
>= bufferlen
) ? bufferlen
: len
;
532 for (k
= 0 ; k
< writecount
; k
++)
533 sptr
[k
] = ptr
[total
+ k
] >> 16 ;
534 count
= gsm610_write_block (psf
, pgsm610
, sptr
, writecount
) ;
540 } /* gsm610_write_i */
543 gsm610_write_f (SF_PRIVATE
*psf
, const float *ptr
, sf_count_t len
)
544 { GSM610_PRIVATE
*pgsm610
;
546 int k
, bufferlen
, writecount
= 0, count
;
547 sf_count_t total
= 0 ;
550 if (psf
->codec_data
== NULL
)
552 pgsm610
= (GSM610_PRIVATE
*) psf
->codec_data
;
554 normfact
= (psf
->norm_float
== SF_TRUE
) ? (1.0 * 0x7FFF) : 1.0 ;
557 bufferlen
= ARRAY_LEN (psf
->u
.sbuf
) ;
559 { writecount
= (len
>= bufferlen
) ? bufferlen
: len
;
560 for (k
= 0 ; k
< writecount
; k
++)
561 sptr
[k
] = lrintf (normfact
* ptr
[total
+ k
]) ;
562 count
= gsm610_write_block (psf
, pgsm610
, sptr
, writecount
) ;
568 } /* gsm610_write_f */
571 gsm610_write_d (SF_PRIVATE
*psf
, const double *ptr
, sf_count_t len
)
572 { GSM610_PRIVATE
*pgsm610
;
574 int k
, bufferlen
, writecount
= 0, count
;
575 sf_count_t total
= 0 ;
578 if (psf
->codec_data
== NULL
)
580 pgsm610
= (GSM610_PRIVATE
*) psf
->codec_data
;
582 normfact
= (psf
->norm_double
== SF_TRUE
) ? (1.0 * 0x7FFF) : 1.0 ;
585 bufferlen
= ARRAY_LEN (psf
->u
.sbuf
) ;
587 { writecount
= (len
>= bufferlen
) ? bufferlen
: len
;
588 for (k
= 0 ; k
< writecount
; k
++)
589 sptr
[k
] = lrint (normfact
* ptr
[total
+ k
]) ;
590 count
= gsm610_write_block (psf
, pgsm610
, sptr
, writecount
) ;
596 } /* gsm610_write_d */
599 gsm610_close (SF_PRIVATE
*psf
)
600 { GSM610_PRIVATE
*pgsm610
;
602 if (psf
->codec_data
== NULL
)
605 pgsm610
= (GSM610_PRIVATE
*) psf
->codec_data
;
607 if (psf
->file
.mode
== SFM_WRITE
)
608 { /* If a block has been partially assembled, write it out
609 ** as the final block.
612 if (pgsm610
->samplecount
&& pgsm610
->samplecount
< pgsm610
->samplesperblock
)
613 pgsm610
->encode_block (psf
, pgsm610
) ;
616 if (pgsm610
->gsm_data
)
617 gsm_destroy (pgsm610
->gsm_data
) ;