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_float_converter_t
{
16 pcm_reader_vtbl_t
*vtbl
;
18 pcm_sample_description_t format
;
19 } pcm_float_converter_t
;
21 static inline pcm_reader_t
*get_source(pcm_reader_t
*reader
)
23 return ((pcm_float_converter_t
*)reader
)->src
;
27 pcm_sample_description_t
*get_format(pcm_reader_t
*reader
)
29 return &((pcm_float_converter_t
*)reader
)->format
;
32 static int64_t get_length(pcm_reader_t
*reader
)
34 return pcm_get_length(get_source(reader
));
37 static int64_t get_position(pcm_reader_t
*reader
)
39 return pcm_get_position(get_source(reader
));
42 static int read_frames(pcm_reader_t
*reader
, void *buffer
, unsigned nframes
)
45 pcm_float_converter_t
*self
= (pcm_float_converter_t
*)reader
;
46 const pcm_sample_description_t
*sfmt
= pcm_get_format(self
->src
);
47 nframes
= pcm_read_frames(self
->src
, buffer
, nframes
);
48 if (!(sfmt
->sample_type
& PCM_TYPE_FLOAT
)) {
51 unsigned i
, count
= nframes
* sfmt
->channels_per_frame
;
52 for (i
= 0; i
< count
; ++i
)
53 op
[i
] = ip
[i
] / 2147483648.0f
;
58 static void teardown(pcm_reader_t
**reader
)
60 pcm_float_converter_t
*self
= (pcm_float_converter_t
*)*reader
;
61 pcm_teardown(&self
->src
);
66 static pcm_reader_vtbl_t my_vtable
= {
67 get_format
, get_length
, get_position
, read_frames
, teardown
70 pcm_reader_t
*pcm_open_float_converter(pcm_reader_t
*reader
)
72 pcm_float_converter_t
*self
= 0;
73 pcm_sample_description_t
*fmt
;
75 if ((self
= calloc(1, sizeof(pcm_float_converter_t
))) == 0)
78 self
->vtbl
= &my_vtable
;
79 memcpy(&self
->format
, pcm_get_format(reader
), sizeof(self
->format
));
81 fmt
->bits_per_channel
= 32;
82 fmt
->sample_type
= PCM_TYPE_FLOAT
;
83 fmt
->bytes_per_frame
= 4 * fmt
->channels_per_frame
;
84 return (pcm_reader_t
*)self
;