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.
29 #include "G72x/g72x.h"
31 /* This struct is private to the G72x code. */
33 typedef struct g72x_state G72x_STATE
;
36 { /* Private data. Don't mess with it. */
37 struct g72x_state
* private ;
39 /* Public data. Read only. */
40 int blocksize
, samplesperblock
, bytesperblock
;
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
] ;
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
) ;
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
) ;
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
) ;
61 static sf_count_t
g72x_seek (SF_PRIVATE
*psf
, int mode
, sf_count_t offset
) ;
63 static int g72x_close (SF_PRIVATE
*psf
) ;
66 /*============================================================================================
67 ** WAV G721 Reader initialisation function.
71 g72x_init (SF_PRIVATE
* psf
)
72 { G72x_PRIVATE
*pg72x
;
73 int bitspersample
, bytesperblock
, codec
;
75 if (psf
->codec_data
!= NULL
)
76 { psf_log_printf (psf
, "*** psf->codec_data is not NULL.\n") ;
80 psf
->sf
.seekable
= SF_FALSE
;
82 if (psf
->sf
.channels
!= 1)
83 return SFE_G72X_NOT_MONO
;
85 if ((pg72x
= calloc (1, sizeof (G72x_PRIVATE
))) == NULL
)
86 return SFE_MALLOC_FAILED
;
88 psf
->codec_data
= (void*) pg72x
;
90 pg72x
->block_curr
= 0 ;
91 pg72x
->sample_curr
= 0 ;
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
;
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
;
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
;
112 default : return SFE_UNIMPLEMENTED
;
115 psf
->blockwidth
= psf
->bytewidth
= 1 ;
117 psf
->filelength
= psf_get_filelen (psf
) ;
118 if (psf
->filelength
< psf
->dataoffset
)
119 psf
->filelength
= psf
->dataoffset
;
121 psf
->datalength
= psf
->filelength
- psf
->dataoffset
;
122 if (psf
->dataend
> 0)
123 psf
->datalength
-= psf
->filelength
- psf
->dataend
;
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
;
130 pg72x
->bytesperblock
= bytesperblock
;
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
;
137 psf
->seek
= g72x_seek
;
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 ;
144 pg72x
->blocks_total
= psf
->datalength
/ pg72x
->blocksize
;
146 psf
->sf
.frames
= pg72x
->blocks_total
* pg72x
->samplesperblock
;
148 psf_g72x_decode_block (psf
, pg72x
) ;
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
;
155 pg72x
->bytesperblock
= bytesperblock
;
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
;
162 if (psf
->datalength
% pg72x
->blocksize
)
163 pg72x
->blocks_total
= (psf
->datalength
/ pg72x
->blocksize
) + 1 ;
165 pg72x
->blocks_total
= psf
->datalength
/ pg72x
->blocksize
;
167 if (psf
->datalength
> 0)
168 psf
->sf
.frames
= (8 * psf
->datalength
) / bitspersample
;
170 if ((psf
->sf
.frames
* bitspersample
) / 8 != psf
->datalength
)
171 psf_log_printf (psf
, "*** Warning : weird psf->datalength.\n") ;
174 psf
->codec_close
= g72x_close
;
179 /*============================================================================================
180 ** G721 Read Functions.
184 psf_g72x_decode_block (SF_PRIVATE
*psf
, G72x_PRIVATE
*pg72x
)
187 pg72x
->block_curr
++ ;
188 pg72x
->sample_curr
= 0 ;
190 if (pg72x
->block_curr
> pg72x
->blocks_total
)
191 { memset (pg72x
->samples
, 0, G72x_BLOCK_SIZE
* sizeof (short)) ;
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
) ;
198 pg72x
->blocksize
= k
;
199 g72x_decode_block (pg72x
->private, pg72x
->block
, pg72x
->samples
) ;
202 } /* psf_g72x_decode_block */
205 g72x_read_block (SF_PRIVATE
*psf
, G72x_PRIVATE
*pg72x
, short *ptr
, int len
)
206 { int count
, total
= 0, indx
= 0 ;
209 { if (pg72x
->block_curr
> pg72x
->blocks_total
)
210 { memset (&(ptr
[indx
]), 0, (len
- indx
) * sizeof (short)) ;
214 if (pg72x
->sample_curr
>= pg72x
->samplesperblock
)
215 psf_g72x_decode_block (psf
, pg72x
) ;
217 count
= pg72x
->samplesperblock
- pg72x
->sample_curr
;
218 count
= (len
- indx
> count
) ? count
: len
- indx
;
220 memcpy (&(ptr
[indx
]), &(pg72x
->samples
[pg72x
->sample_curr
]), count
* sizeof (short)) ;
222 pg72x
->sample_curr
+= count
;
227 } /* g72x_read_block */
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 ;
235 if (psf
->codec_data
== NULL
)
237 pg72x
= (G72x_PRIVATE
*) psf
->codec_data
;
240 { readcount
= (len
> 0x10000000) ? 0x10000000 : (int) len
;
242 count
= g72x_read_block (psf
, pg72x
, ptr
, readcount
) ;
247 if (count
!= readcount
)
255 g72x_read_i (SF_PRIVATE
*psf
, int *ptr
, sf_count_t len
)
256 { G72x_PRIVATE
*pg72x
;
258 int k
, bufferlen
, readcount
= 0, count
;
259 sf_count_t total
= 0 ;
261 if (psf
->codec_data
== NULL
)
263 pg72x
= (G72x_PRIVATE
*) psf
->codec_data
;
266 bufferlen
= SF_BUFFER_LEN
/ sizeof (short) ;
268 { readcount
= (len
>= bufferlen
) ? bufferlen
: len
;
269 count
= g72x_read_block (psf
, pg72x
, sptr
, readcount
) ;
271 for (k
= 0 ; k
< readcount
; k
++)
272 ptr
[total
+ k
] = sptr
[k
] << 16 ;
276 if (count
!= readcount
)
284 g72x_read_f (SF_PRIVATE
*psf
, float *ptr
, sf_count_t len
)
285 { G72x_PRIVATE
*pg72x
;
287 int k
, bufferlen
, readcount
= 0, count
;
288 sf_count_t total
= 0 ;
291 if (psf
->codec_data
== NULL
)
293 pg72x
= (G72x_PRIVATE
*) psf
->codec_data
;
295 normfact
= (psf
->norm_float
== SF_TRUE
) ? 1.0 / ((float) 0x8000) : 1.0 ;
298 bufferlen
= SF_BUFFER_LEN
/ sizeof (short) ;
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
] ;
307 if (count
!= readcount
)
315 g72x_read_d (SF_PRIVATE
*psf
, double *ptr
, sf_count_t len
)
316 { G72x_PRIVATE
*pg72x
;
318 int k
, bufferlen
, readcount
= 0, count
;
319 sf_count_t total
= 0 ;
322 if (psf
->codec_data
== NULL
)
324 pg72x
= (G72x_PRIVATE
*) psf
->codec_data
;
326 normfact
= (psf
->norm_double
== SF_TRUE
) ? 1.0 / ((double) 0x8000) : 1.0 ;
329 bufferlen
= SF_BUFFER_LEN
/ sizeof (short) ;
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
]) ;
338 if (count
!= readcount
)
346 g72x_seek (SF_PRIVATE
*psf
, int UNUSED (mode
), sf_count_t
UNUSED (offset
))
348 psf_log_printf (psf
, "seek unsupported\n") ;
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?
357 ** G72x_PRIVATE *pg72x ;
358 ** int newblock, newsample, sample_curr ;
360 ** if (psf->codec_data == NULL)
362 ** pg72x = (G72x_PRIVATE*) psf->codec_data ;
364 ** if (! (psf->datalength && psf->dataoffset))
365 ** { psf->error = SFE_BAD_SEEK ;
366 ** return PSF_SEEK_ERROR ;
369 ** sample_curr = (8 * psf->datalength) / G721_32_BITS_PER_SAMPLE ;
373 ** if (offset < 0 || offset > sample_curr)
374 ** { psf->error = SFE_BAD_SEEK ;
375 ** return PSF_SEEK_ERROR ;
377 ** newblock = offset / pg72x->samplesperblock ;
378 ** newsample = offset % pg72x->samplesperblock ;
382 ** if (psf->current + offset < 0 || psf->current + offset > sample_curr)
383 ** { psf->error = SFE_BAD_SEEK ;
384 ** return PSF_SEEK_ERROR ;
386 ** newblock = (8 * (psf->current + offset)) / pg72x->samplesperblock ;
387 ** newsample = (8 * (psf->current + offset)) % pg72x->samplesperblock ;
391 ** if (offset > 0 || sample_curr + offset < 0)
392 ** { psf->error = SFE_BAD_SEEK ;
393 ** return PSF_SEEK_ERROR ;
395 ** newblock = (sample_curr + offset) / pg72x->samplesperblock ;
396 ** newsample = (sample_curr + offset) % pg72x->samplesperblock ;
400 ** psf->error = SFE_BAD_SEEK ;
401 ** return PSF_SEEK_ERROR ;
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 ;
411 ** { /+* What to do about write??? *+/
412 ** psf->error = SFE_BAD_SEEK ;
413 ** return PSF_SEEK_ERROR ;
416 ** psf->current = newblock * pg72x->samplesperblock + newsample ;
417 ** return psf->current ;
422 /*==========================================================================================
423 ** G72x Write Functions.
427 psf_g72x_encode_block (SF_PRIVATE
*psf
, G72x_PRIVATE
*pg72x
)
430 /* Encode the samples. */
431 g72x_encode_block (pg72x
->private, pg72x
->samples
, pg72x
->block
) ;
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
) ;
437 pg72x
->sample_curr
= 0 ;
438 pg72x
->block_curr
++ ;
440 /* Set samples to zero for next block. */
441 memset (pg72x
->samples
, 0, G72x_BLOCK_SIZE
* sizeof (short)) ;
444 } /* psf_g72x_encode_block */
447 g72x_write_block (SF_PRIVATE
*psf
, G72x_PRIVATE
*pg72x
, const short *ptr
, int len
)
448 { int count
, total
= 0, indx
= 0 ;
451 { count
= pg72x
->samplesperblock
- pg72x
->sample_curr
;
453 if (count
> len
- indx
)
456 memcpy (&(pg72x
->samples
[pg72x
->sample_curr
]), &(ptr
[indx
]), count
* sizeof (short)) ;
458 pg72x
->sample_curr
+= count
;
461 if (pg72x
->sample_curr
>= pg72x
->samplesperblock
)
462 psf_g72x_encode_block (psf
, pg72x
) ;
466 } /* g72x_write_block */
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 ;
474 if (psf
->codec_data
== NULL
)
476 pg72x
= (G72x_PRIVATE
*) psf
->codec_data
;
479 { writecount
= (len
> 0x10000000) ? 0x10000000 : (int) len
;
481 count
= g72x_write_block (psf
, pg72x
, ptr
, writecount
) ;
485 if (count
!= writecount
)
493 g72x_write_i (SF_PRIVATE
*psf
, const int *ptr
, sf_count_t len
)
494 { G72x_PRIVATE
*pg72x
;
496 int k
, bufferlen
, writecount
= 0, count
;
497 sf_count_t total
= 0 ;
499 if (psf
->codec_data
== NULL
)
501 pg72x
= (G72x_PRIVATE
*) psf
->codec_data
;
504 bufferlen
= ((SF_BUFFER_LEN
/ psf
->blockwidth
) * psf
->blockwidth
) / sizeof (short) ;
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
) ;
513 if (count
!= writecount
)
520 g72x_write_f (SF_PRIVATE
*psf
, const float *ptr
, sf_count_t len
)
521 { G72x_PRIVATE
*pg72x
;
523 int k
, bufferlen
, writecount
= 0, count
;
524 sf_count_t total
= 0 ;
527 if (psf
->codec_data
== NULL
)
529 pg72x
= (G72x_PRIVATE
*) psf
->codec_data
;
531 normfact
= (psf
->norm_float
== SF_TRUE
) ? (1.0 * 0x8000) : 1.0 ;
534 bufferlen
= ((SF_BUFFER_LEN
/ psf
->blockwidth
) * psf
->blockwidth
) / sizeof (short) ;
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
) ;
543 if (count
!= writecount
)
551 g72x_write_d (SF_PRIVATE
*psf
, const double *ptr
, sf_count_t len
)
552 { G72x_PRIVATE
*pg72x
;
554 int k
, bufferlen
, writecount
= 0, count
;
555 sf_count_t total
= 0 ;
558 if (psf
->codec_data
== NULL
)
560 pg72x
= (G72x_PRIVATE
*) psf
->codec_data
;
562 normfact
= (psf
->norm_double
== SF_TRUE
) ? (1.0 * 0x8000) : 1.0 ;
565 bufferlen
= ((SF_BUFFER_LEN
/ psf
->blockwidth
) * psf
->blockwidth
) / sizeof (short) ;
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
) ;
574 if (count
!= writecount
)
582 g72x_close (SF_PRIVATE
*psf
)
583 { G72x_PRIVATE
*pg72x
;
585 pg72x
= (G72x_PRIVATE
*) psf
->codec_data
;
587 if (psf
->file
.mode
== SFM_WRITE
)
588 { /* If a block has been partially assembled, write it out
589 ** as the final block.
592 if (pg72x
->sample_curr
&& pg72x
->sample_curr
< G72x_BLOCK_SIZE
)
593 psf_g72x_encode_block (psf
, pg72x
) ;
595 if (psf
->write_header
)
596 psf
->write_header (psf
, SF_FALSE
) ;
599 /* Only free the pointer allocated by g72x_(reader|writer)_init. */
600 free (pg72x
->private) ;