2 * Copyright (C) 2013 nu774
3 * For conditions of distribution and use, see copyright notice in COPYING
13 #include "pcm_reader.h"
15 typedef struct pcm_sint16_converter_t
{
16 pcm_reader_vtbl_t
*vtbl
;
18 pcm_sample_description_t format
;
21 } pcm_sint16_converter_t
;
23 static inline pcm_reader_t
*get_source(pcm_reader_t
*reader
)
25 return ((pcm_sint16_converter_t
*)reader
)->src
;
29 pcm_sample_description_t
*get_format(pcm_reader_t
*reader
)
31 return &((pcm_sint16_converter_t
*)reader
)->format
;
34 static int64_t get_length(pcm_reader_t
*reader
)
36 return pcm_get_length(get_source(reader
));
39 static int64_t get_position(pcm_reader_t
*reader
)
41 return pcm_get_position(get_source(reader
));
44 static int read_frames(pcm_reader_t
*reader
, void *buffer
, unsigned nframes
)
46 pcm_sint16_converter_t
*self
= (pcm_sint16_converter_t
*)reader
;
47 const pcm_sample_description_t
*sfmt
= pcm_get_format(self
->src
);
48 unsigned bytes
= nframes
* sfmt
->bytes_per_frame
;
50 if (self
->capacity
< bytes
) {
51 void *p
= realloc(self
->pivot
, bytes
);
54 self
->capacity
= bytes
;
56 nframes
= pcm_read_frames(self
->src
, self
->pivot
, nframes
);
57 if (pcm_convert_to_native_sint16(sfmt
, self
->pivot
, nframes
, buffer
) < 0)
62 static void teardown(pcm_reader_t
**reader
)
64 pcm_sint16_converter_t
*self
= (pcm_sint16_converter_t
*)*reader
;
65 pcm_teardown(&self
->src
);
71 static pcm_reader_vtbl_t my_vtable
= {
72 get_format
, get_length
, get_position
, read_frames
, teardown
75 pcm_reader_t
*pcm_open_sint16_converter(pcm_reader_t
*reader
)
77 pcm_sint16_converter_t
*self
= 0;
78 pcm_sample_description_t
*fmt
;
80 if ((self
= calloc(1, sizeof(pcm_sint16_converter_t
))) == 0)
83 self
->vtbl
= &my_vtable
;
84 memcpy(&self
->format
, pcm_get_format(reader
), sizeof(self
->format
));
87 fmt
->sample_type
= PCM_TYPE_SINT_BE
;
89 fmt
->sample_type
= PCM_TYPE_SINT
;
91 fmt
->bits_per_channel
= 16;
92 fmt
->bytes_per_frame
= 2 * fmt
->channels_per_frame
;
93 return (pcm_reader_t
*)self
;