2 * Copyright (C) 2003-2010 The Music Player Daemon Project
3 * http://www.musicpd.org
5 * This program is free software; you can redistribute it and/or modify
6 * it under the terms of the GNU General Public License as published by
7 * the Free Software Foundation; either version 2 of the License, or
8 * (at your option) any later version.
10 * This program is distributed in the hope that it will be useful,
11 * but WITHOUT ANY WARRANTY; without even the implied warranty of
12 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
13 * GNU General Public License for more details.
15 * You should have received a copy of the GNU General Public License along
16 * with this program; if not, write to the Free Software Foundation, Inc.,
17 * 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA.
21 #include "encoder_api.h"
22 #include "encoder_plugin.h"
23 #include "audio_format.h"
25 #include <lame/lame.h>
30 struct encoder encoder
;
32 struct audio_format audio_format
;
36 lame_global_flags
*gfp
;
38 unsigned char buffer
[32768];
42 extern const struct encoder_plugin lame_encoder_plugin
;
45 lame_encoder_quark(void)
47 return g_quark_from_static_string("lame_encoder");
51 lame_encoder_configure(struct lame_encoder
*encoder
,
52 const struct config_param
*param
, GError
**error
)
57 value
= config_get_block_string(param
, "quality", NULL
);
59 /* a quality was configured (VBR) */
61 encoder
->quality
= g_ascii_strtod(value
, &endptr
);
63 if (*endptr
!= '\0' || encoder
->quality
< -1.0 ||
64 encoder
->quality
> 10.0) {
65 g_set_error(error
, lame_encoder_quark(), 0,
66 "quality \"%s\" is not a number in the "
67 "range -1 to 10, line %i",
72 if (config_get_block_string(param
, "bitrate", NULL
) != NULL
) {
73 g_set_error(error
, lame_encoder_quark(), 0,
74 "quality and bitrate are "
75 "both defined (line %i)",
80 /* a bit rate was configured */
82 value
= config_get_block_string(param
, "bitrate", NULL
);
84 g_set_error(error
, lame_encoder_quark(), 0,
85 "neither bitrate nor quality defined "
91 encoder
->quality
= -2.0;
92 encoder
->bitrate
= g_ascii_strtoll(value
, &endptr
, 10);
94 if (*endptr
!= '\0' || encoder
->bitrate
<= 0) {
95 g_set_error(error
, lame_encoder_quark(), 0,
96 "bitrate at line %i should be a positive integer",
105 static struct encoder
*
106 lame_encoder_init(const struct config_param
*param
, GError
**error
)
108 struct lame_encoder
*encoder
;
110 encoder
= g_new(struct lame_encoder
, 1);
111 encoder_struct_init(&encoder
->encoder
, &lame_encoder_plugin
);
113 /* load configuration from "param" */
114 if (!lame_encoder_configure(encoder
, param
, error
)) {
115 /* configuration has failed, roll back and return error */
120 return &encoder
->encoder
;
124 lame_encoder_finish(struct encoder
*_encoder
)
126 struct lame_encoder
*encoder
= (struct lame_encoder
*)_encoder
;
128 /* the real liblame cleanup was already performed by
129 lame_encoder_close(), so no real work here */
134 lame_encoder_setup(struct lame_encoder
*encoder
, GError
**error
)
136 if (encoder
->quality
>= -1.0) {
137 /* a quality was configured (VBR) */
139 if (0 != lame_set_VBR(encoder
->gfp
, vbr_rh
)) {
140 g_set_error(error
, lame_encoder_quark(), 0,
141 "error setting lame VBR mode");
144 if (0 != lame_set_VBR_q(encoder
->gfp
, encoder
->quality
)) {
145 g_set_error(error
, lame_encoder_quark(), 0,
146 "error setting lame VBR quality");
150 /* a bit rate was configured */
152 if (0 != lame_set_brate(encoder
->gfp
, encoder
->bitrate
)) {
153 g_set_error(error
, lame_encoder_quark(), 0,
154 "error setting lame bitrate");
159 if (0 != lame_set_num_channels(encoder
->gfp
,
160 encoder
->audio_format
.channels
)) {
161 g_set_error(error
, lame_encoder_quark(), 0,
162 "error setting lame num channels");
166 if (0 != lame_set_in_samplerate(encoder
->gfp
,
167 encoder
->audio_format
.sample_rate
)) {
168 g_set_error(error
, lame_encoder_quark(), 0,
169 "error setting lame sample rate");
173 if (0 > lame_init_params(encoder
->gfp
)) {
174 g_set_error(error
, lame_encoder_quark(), 0,
175 "error initializing lame params");
183 lame_encoder_open(struct encoder
*_encoder
, struct audio_format
*audio_format
,
186 struct lame_encoder
*encoder
= (struct lame_encoder
*)_encoder
;
188 audio_format
->format
= SAMPLE_FORMAT_S16
;
189 audio_format
->channels
= 2;
191 encoder
->audio_format
= *audio_format
;
193 encoder
->gfp
= lame_init();
194 if (encoder
->gfp
== NULL
) {
195 g_set_error(error
, lame_encoder_quark(), 0,
196 "lame_init() failed");
200 if (!lame_encoder_setup(encoder
, error
)) {
201 lame_close(encoder
->gfp
);
205 encoder
->buffer_length
= 0;
211 lame_encoder_close(struct encoder
*_encoder
)
213 struct lame_encoder
*encoder
= (struct lame_encoder
*)_encoder
;
215 lame_close(encoder
->gfp
);
219 lame_encoder_write(struct encoder
*_encoder
,
220 const void *data
, size_t length
,
221 G_GNUC_UNUSED GError
**error
)
223 struct lame_encoder
*encoder
= (struct lame_encoder
*)_encoder
;
226 const int16_t *src
= (const int16_t*)data
;
230 assert(encoder
->buffer_length
== 0);
233 length
/ audio_format_frame_size(&encoder
->audio_format
);
234 left
= g_malloc(sizeof(left
[0]) * num_frames
);
235 right
= g_malloc(sizeof(right
[0]) * num_frames
);
237 /* this is for only 16-bit audio */
239 for (i
= 0; i
< num_frames
; i
++) {
244 bytes_out
= lame_encode_buffer_float(encoder
->gfp
, left
, right
,
245 num_frames
, encoder
->buffer
,
246 sizeof(encoder
->buffer
));
252 g_set_error(error
, lame_encoder_quark(), 0,
253 "lame encoder failed");
257 encoder
->buffer_length
= (size_t)bytes_out
;
262 lame_encoder_read(struct encoder
*_encoder
, void *dest
, size_t length
)
264 struct lame_encoder
*encoder
= (struct lame_encoder
*)_encoder
;
266 if (length
> encoder
->buffer_length
)
267 length
= encoder
->buffer_length
;
269 memcpy(dest
, encoder
->buffer
, length
);
271 encoder
->buffer_length
-= length
;
272 memmove(encoder
->buffer
, encoder
->buffer
+ length
,
273 encoder
->buffer_length
);
279 lame_encoder_get_mime_type(G_GNUC_UNUSED
struct encoder
*_encoder
)
284 const struct encoder_plugin lame_encoder_plugin
= {
286 .init
= lame_encoder_init
,
287 .finish
= lame_encoder_finish
,
288 .open
= lame_encoder_open
,
289 .close
= lame_encoder_close
,
290 .write
= lame_encoder_write
,
291 .read
= lame_encoder_read
,
292 .get_mime_type
= lame_encoder_get_mime_type
,