9 #include "pcm_reader.h"
11 typedef struct pcm_sint16_converter_t
{
12 pcm_reader_vtbl_t
*vtbl
;
14 pcm_sample_description_t format
;
17 } pcm_sint16_converter_t
;
19 static inline pcm_reader_t
*get_source(pcm_reader_t
*reader
)
21 return ((pcm_sint16_converter_t
*)reader
)->src
;
25 pcm_sample_description_t
*get_format(pcm_reader_t
*reader
)
27 return &((pcm_sint16_converter_t
*)reader
)->format
;
30 static int64_t get_length(pcm_reader_t
*reader
)
32 return pcm_get_length(get_source(reader
));
35 static int64_t get_position(pcm_reader_t
*reader
)
37 return pcm_get_position(get_source(reader
));
40 static int read_frames(pcm_reader_t
*reader
, void *buffer
, unsigned nframes
)
42 pcm_sint16_converter_t
*self
= (pcm_sint16_converter_t
*)reader
;
43 const pcm_sample_description_t
*sfmt
= pcm_get_format(self
->src
);
44 unsigned bytes
= nframes
* sfmt
->bytes_per_frame
;
46 if (self
->capacity
< bytes
) {
47 void *p
= realloc(self
->pivot
, bytes
);
50 self
->capacity
= bytes
;
52 nframes
= pcm_read_frames(self
->src
, self
->pivot
, nframes
);
53 if (pcm_convert_to_native_sint16(sfmt
, self
->pivot
, nframes
, buffer
) < 0)
58 static void teardown(pcm_reader_t
**reader
)
60 pcm_sint16_converter_t
*self
= (pcm_sint16_converter_t
*)*reader
;
61 pcm_teardown(&self
->src
);
67 static pcm_reader_vtbl_t my_vtable
= {
68 get_format
, get_length
, get_position
, read_frames
, teardown
71 pcm_reader_t
*pcm_open_sint16_converter(pcm_reader_t
*reader
)
73 pcm_sint16_converter_t
*self
= 0;
74 pcm_sample_description_t
*fmt
;
76 if ((self
= calloc(1, sizeof(pcm_sint16_converter_t
))) == 0)
79 self
->vtbl
= &my_vtable
;
80 memcpy(&self
->format
, pcm_get_format(reader
), sizeof(self
->format
));
83 fmt
->sample_type
= PCM_TYPE_SINT_BE
;
85 fmt
->sample_type
= PCM_TYPE_SINT
;
87 fmt
->bits_per_channel
= 16;
88 fmt
->bytes_per_frame
= 2 * fmt
->channels_per_frame
;
89 return (pcm_reader_t
*)self
;