2 * stereo->mono downmixing
5 * $Id: audio.c,v 1.10 2003/08/01 22:38:04 karl Exp $
7 * Copyright (c) 2001 Michael Smith <msmith@labyrinth.net.au>
9 * This program is distributed under the terms of the GNU General
10 * Public License, version 2. You may use, modify, and redistribute
11 * it under the terms of this license. A copy should be included
28 #define MODULE "audio/"
31 downmix_state
*downmix_initialise(void) {
32 downmix_state
*state
= calloc(1, sizeof(downmix_state
));
34 LOG_INFO0("Enabling stereo->mono downmixing");
39 void downmix_clear(downmix_state
*s
) {
47 void downmix_buffer_float(downmix_state
*s
, float **buf
, int samples
)
51 if(samples
> s
->buflen
) {
52 void *tmp
= realloc(s
->buffer
, samples
* sizeof(float));
59 for(i
=0; i
< samples
; i
++) {
60 s
->buffer
[i
] = (buf
[0][i
] + buf
[1][i
])*0.5;
66 void downmix_buffer(downmix_state
*s
, signed char *buf
, int len
, int be
)
71 if(samples
> s
->buflen
) {
72 void *tmp
= realloc(s
->buffer
, samples
* sizeof(float));
80 for(i
=0; i
< samples
; i
++) {
81 s
->buffer
[i
] = (((buf
[4*i
]<<8) | (buf
[4*i
+ 1]&0xff)) +
82 ((buf
[4*i
+ 2]<<8) | (buf
[4*i
+ 3]&0xff)))/65536.f
;
86 for(i
=0; i
< samples
; i
++) {
87 s
->buffer
[i
] = (((buf
[4*i
+ 1]<<8) | (buf
[4*i
]&0xff)) +
88 ((buf
[4*i
+ 3]<<8) | (buf
[4*i
+ 2]&0xff)))/65536.f
;
93 resample_state
*resample_initialise(int channels
, int infreq
, int outfreq
)
95 resample_state
*state
= calloc(1, sizeof(resample_state
));
102 if (resampler_init(&state
->resampler
, channels
, outfreq
, infreq
, RES_END
)) {
103 LOG_ERROR0("Couldn't initialise resampler to specified frequency");
107 if ((state
->buffers
= calloc(channels
, sizeof(float *))) == NULL
)
109 if ((state
->convbuf
= calloc(channels
, sizeof(float *))) == NULL
)
113 while (0); /* not a loop */
117 LOG_ERROR0("Couldn't initialise resampler due to memory allocation failure");
118 resample_clear (state
);
121 state
->channels
= channels
;
123 LOG_INFO3("Initialised resampler for %d channels, from %d Hz to %d Hz",
124 channels
, infreq
, outfreq
);
129 void resample_clear(resample_state
*s
)
135 for(c
=0; c
<s
->channels
; c
++)
141 for(c
=0; c
<s
->channels
; c
++)
146 resampler_clear(&s
->resampler
);
151 void resample_buffer(resample_state
*s
, signed char *buf
, int buflen
, int be
)
154 buflen
/= 2*s
->channels
; /* bytes -> samples conversion */
156 if(s
->convbuflen
< buflen
) {
157 s
->convbuflen
= buflen
;
158 for(c
=0; c
< s
->channels
; c
++)
159 s
->convbuf
[c
] = realloc(s
->convbuf
[c
], buflen
* sizeof(float));
163 for(i
=0; i
< buflen
; i
++) {
164 for(c
=0; c
< s
->channels
; c
++) {
165 s
->convbuf
[c
][i
] = ((buf
[2*(i
*s
->channels
+ c
)]<<8) |
166 (0x00ff&(int)buf
[2*(i
*s
->channels
+ c
)+1]))/
172 for(i
=0; i
< buflen
; i
++) {
173 for(c
=0; c
< s
->channels
; c
++) {
174 s
->convbuf
[c
][i
] = ((buf
[2*(i
*s
->channels
+ c
) + 1]<<8) |
175 (0x00ff&(int)buf
[2*(i
*s
->channels
+ c
)]))/
181 resample_buffer_float(s
, s
->convbuf
, buflen
);
184 void resample_buffer_float(resample_state
*s
, float **buf
, int buflen
)
189 s
->buffill
= resampler_push_check(&s
->resampler
, buflen
);
190 if(s
->buffill
<= 0) {
191 LOG_ERROR1("Fatal reencoding error: resampler_push_check returned %d",
195 if(s
->bufsize
< s
->buffill
) {
196 s
->bufsize
= s
->buffill
;
197 for(c
=0; c
<s
->channels
; c
++)
198 s
->buffers
[c
] = realloc(s
->buffers
[c
], s
->bufsize
* sizeof(float));
201 if((res
= resampler_push(&s
->resampler
, s
->buffers
, (float const **)buf
, buflen
))
203 LOG_ERROR2("Internal error in resampling: returned number of samples %d"
204 ", expected %d", res
, s
->buffill
);
211 void resample_finish(resample_state
*s
)
218 ret
= resampler_drain(&s
->resampler
, s
->buffers
);
220 if(ret
> s
->bufsize
) {
221 LOG_ERROR0("Fatal error in resampler: buffers too small");