14 #include "libaf/af_format.h"
15 #include "libmpdemux/mp3_hdr.h"
18 #include <lame/lame.h>
20 lame_global_flags
*lame
;
21 static int lame_param_quality
=0; // best
22 static int lame_param_algqual
=5; // same as old default
23 static int lame_param_vbr
=vbr_default
;
24 static int lame_param_mode
=-1; // unset
25 static int lame_param_padding
=-1; // unset
26 static int lame_param_br
=-1; // unset
27 static int lame_param_ratio
=-1; // unset
28 static float lame_param_scale
=-1; // unset
29 static int lame_param_lowpassfreq
= 0; //auto
30 static int lame_param_highpassfreq
= 0; //auto
31 static int lame_param_free_format
= 0; //disabled
32 static int lame_param_br_min
= 0; //not specified
33 static int lame_param_br_max
= 0; //not specified
35 #ifdef HAVE_MP3LAME_PRESET
36 int lame_param_fast
=0; // unset
37 static char* lame_param_preset
=NULL
; // unset
38 static int lame_presets_set( lame_t gfp
, int fast
, int cbr
, const char* preset_name
);
39 static void lame_presets_longinfo_dm ( FILE* msgfp
);
43 m_option_t lameopts_conf
[]={
44 {"q", &lame_param_quality
, CONF_TYPE_INT
, CONF_RANGE
, 0, 9, NULL
},
45 {"aq", &lame_param_algqual
, CONF_TYPE_INT
, CONF_RANGE
, 0, 9, NULL
},
46 {"vbr", &lame_param_vbr
, CONF_TYPE_INT
, CONF_RANGE
, 0, vbr_max_indicator
, NULL
},
47 {"cbr", &lame_param_vbr
, CONF_TYPE_FLAG
, 0, 0, 0, NULL
},
48 {"abr", &lame_param_vbr
, CONF_TYPE_FLAG
, 0, 0, vbr_abr
, NULL
},
49 {"mode", &lame_param_mode
, CONF_TYPE_INT
, CONF_RANGE
, 0, MAX_INDICATOR
, NULL
},
50 {"padding", &lame_param_padding
, CONF_TYPE_INT
, CONF_RANGE
, 0, PAD_MAX_INDICATOR
, NULL
},
51 {"br", &lame_param_br
, CONF_TYPE_INT
, CONF_RANGE
, 0, 1024, NULL
},
52 {"ratio", &lame_param_ratio
, CONF_TYPE_INT
, CONF_RANGE
, 0, 100, NULL
},
53 {"vol", &lame_param_scale
, CONF_TYPE_FLOAT
, CONF_RANGE
, 0, 10, NULL
},
54 {"lowpassfreq",&lame_param_lowpassfreq
, CONF_TYPE_INT
, CONF_RANGE
, -1, 48000,0},
55 {"highpassfreq",&lame_param_highpassfreq
, CONF_TYPE_INT
, CONF_RANGE
, -1, 48000,0},
56 {"nofree", &lame_param_free_format
, CONF_TYPE_FLAG
, 0, 0, 0, NULL
},
57 {"free", &lame_param_free_format
, CONF_TYPE_FLAG
, 0, 0, 1, NULL
},
58 {"br_min", &lame_param_br_min
, CONF_TYPE_INT
, CONF_RANGE
, 0, 1024, NULL
},
59 {"br_max", &lame_param_br_max
, CONF_TYPE_INT
, CONF_RANGE
, 0, 1024, NULL
},
60 #ifdef HAVE_MP3LAME_PRESET
61 {"fast", &lame_param_fast
, CONF_TYPE_FLAG
, 0, 0, 1, NULL
},
62 {"preset", &lame_param_preset
, CONF_TYPE_STRING
, 0, 0, 0, NULL
},
64 {"fast", "MPlayer was built without -lameopts fast support (requires libmp3lame >=3.92).\n", CONF_TYPE_PRINT
, CONF_NOCFG
, 0, 0, NULL
},
65 {"preset", "MPlayer was built without -lameopts preset support (requires libmp3lame >=3.92).\n", CONF_TYPE_PRINT
, CONF_NOCFG
, 0, 0, NULL
},
67 {"help", MSGTR_MEncoderMP3LameHelp
, CONF_TYPE_PRINT
, CONF_NOCFG
, 0, 0, NULL
},
68 {NULL
, NULL
, 0, 0, 0, 0, NULL
}
74 static int bind_lame(audio_encoder_t
*encoder
, muxer_stream_t
*mux_a
)
76 mp_msg(MSGT_FIXME
, MSGL_FIXME
, MSGTR_MP3AudioSelected
);
77 mux_a
->h
.dwSampleSize
=0; // VBR
78 mux_a
->h
.dwRate
=encoder
->params
.sample_rate
;
79 mux_a
->h
.dwScale
=encoder
->params
.samples_per_frame
; // samples/frame
80 if(sizeof(MPEGLAYER3WAVEFORMAT
)!=30) mp_msg(MSGT_MENCODER
,MSGL_WARN
,MSGTR_MP3WaveFormatSizeNot30
,sizeof(MPEGLAYER3WAVEFORMAT
));
81 mux_a
->wf
=malloc(sizeof(MPEGLAYER3WAVEFORMAT
)); // should be 30
82 mux_a
->wf
->wFormatTag
=0x55; // MP3
83 mux_a
->wf
->nChannels
= (lame_param_mode
<0) ? encoder
->params
.channels
: ((lame_param_mode
==3) ? 1 : 2);
84 mux_a
->wf
->nSamplesPerSec
=mux_a
->h
.dwRate
;
86 mux_a
->wf
->nAvgBytesPerSec
=lame_param_br
* 125;
88 mux_a
->wf
->nAvgBytesPerSec
=192000/8; // FIXME!
89 mux_a
->wf
->nBlockAlign
=encoder
->params
.samples_per_frame
; // required for l3codeca.acm + WMP 6.4
90 mux_a
->wf
->wBitsPerSample
=0; //16;
91 // from NaNdub: (requires for l3codeca.acm)
93 ((MPEGLAYER3WAVEFORMAT
*)(mux_a
->wf
))->wID
=1;
94 ((MPEGLAYER3WAVEFORMAT
*)(mux_a
->wf
))->fdwFlags
=2;
95 ((MPEGLAYER3WAVEFORMAT
*)(mux_a
->wf
))->nBlockSize
=encoder
->params
.samples_per_frame
; // ???
96 ((MPEGLAYER3WAVEFORMAT
*)(mux_a
->wf
))->nFramesPerBlock
=1;
97 ((MPEGLAYER3WAVEFORMAT
*)(mux_a
->wf
))->nCodecDelay
=0;
99 encoder
->input_format
= AF_FORMAT_S16_LE
;
100 encoder
->min_buffer_size
= 4608;
101 encoder
->max_buffer_size
= mux_a
->h
.dwRate
* mux_a
->wf
->nChannels
* 2;
106 #define min(a, b) ((a) <= (b) ? (a) : (b))
108 static int get_frame_size(audio_encoder_t
*encoder
)
111 if(encoder
->stream
->buffer_len
< 4)
113 sz
= mp_decode_mp3_header(encoder
->stream
->buffer
);
119 static int encode_lame(audio_encoder_t
*encoder
, uint8_t *dest
, void *src
, int len
, int max_size
)
122 if(encoder
->params
.channels
== 1)
123 n
= lame_encode_buffer(lame
, (short *)src
, (short *)src
, len
/2, dest
, max_size
);
125 n
= lame_encode_buffer_interleaved(lame
,(short *)src
, len
/4, dest
, max_size
);
127 return (n
< 0 ? 0 : n
);
131 static int close_lame(audio_encoder_t
*encoder
)
136 static void fixup(audio_encoder_t
*encoder
)
138 // fixup CBR mp3 audio header:
139 if(!lame_param_vbr
) {
140 encoder
->stream
->h
.dwSampleSize
=1;
141 ((MPEGLAYER3WAVEFORMAT
*)(encoder
->stream
->wf
))->nBlockSize
=
142 (encoder
->stream
->size
+(encoder
->stream
->h
.dwLength
>>1))/encoder
->stream
->h
.dwLength
;
143 encoder
->stream
->h
.dwLength
=encoder
->stream
->size
;
144 encoder
->stream
->h
.dwRate
=encoder
->stream
->wf
->nAvgBytesPerSec
;
145 encoder
->stream
->h
.dwScale
=1;
146 encoder
->stream
->wf
->nBlockAlign
=1;
147 mp_msg(MSGT_FIXME
, MSGL_FIXME
, MSGTR_CBRAudioByterate
,
148 encoder
->stream
->h
.dwRate
,((MPEGLAYER3WAVEFORMAT
*)(encoder
->stream
->wf
))->nBlockSize
);
152 int mpae_init_lame(audio_encoder_t
*encoder
)
154 encoder
->params
.bitrate
= lame_param_br
* 125;
155 encoder
->params
.samples_per_frame
= encoder
->params
.sample_rate
< 32000 ? 576 : 1152;
156 encoder
->decode_buffer_size
= 2304;
159 lame_set_bWriteVbrTag(lame
,0);
160 lame_set_in_samplerate(lame
,encoder
->params
.sample_rate
);
161 //lame_set_in_samplerate(lame,sh_audio->samplerate); // if resampling done by lame
162 lame_set_num_channels(lame
,encoder
->params
.channels
);
163 lame_set_out_samplerate(lame
,encoder
->params
.sample_rate
);
164 lame_set_quality(lame
,lame_param_algqual
); // 0 = best q
165 if(lame_param_free_format
) lame_set_free_format(lame
,1);
166 if(lame_param_vbr
){ // VBR:
167 lame_set_VBR(lame
,lame_param_vbr
); // vbr mode
168 lame_set_VBR_q(lame
,lame_param_quality
); // 0 = best vbr q 5=~128k
169 if(lame_param_br
>0) lame_set_VBR_mean_bitrate_kbps(lame
,lame_param_br
);
170 if(lame_param_br_min
>0) lame_set_VBR_min_bitrate_kbps(lame
,lame_param_br_min
);
171 if(lame_param_br_max
>0) lame_set_VBR_max_bitrate_kbps(lame
,lame_param_br_max
);
173 if(lame_param_br
>0) lame_set_brate(lame
,lame_param_br
);
175 if(lame_param_mode
>=0) lame_set_mode(lame
,lame_param_mode
); // j-st
176 if(lame_param_ratio
>0) lame_set_compression_ratio(lame
,lame_param_ratio
);
177 if(lame_param_scale
>0) {
178 mp_msg(MSGT_FIXME
, MSGL_FIXME
, MSGTR_SettingAudioInputGain
, lame_param_scale
);
179 lame_set_scale(lame
,lame_param_scale
);
181 if(lame_param_lowpassfreq
>=-1) lame_set_lowpassfreq(lame
,lame_param_lowpassfreq
);
182 if(lame_param_highpassfreq
>=-1) lame_set_highpassfreq(lame
,lame_param_highpassfreq
);
183 #ifdef HAVE_MP3LAME_PRESET
184 if(lame_param_preset
!= NULL
) {
185 mp_msg(MSGT_FIXME
, MSGL_FIXME
, MSGTR_LamePresetEquals
,lame_param_preset
);
186 if(lame_presets_set(lame
,lame_param_fast
, (lame_param_vbr
==0), lame_param_preset
) < 0)
190 if(lame_init_params(lame
) == -1) {
191 mp_msg(MSGT_MENCODER
, MSGL_FATAL
, MSGTR_LameCantInit
);
194 if( mp_msg_test(MSGT_MENCODER
,MSGL_V
) ) {
195 lame_print_config(lame
);
196 lame_print_internals(lame
);
199 encoder
->bind
= bind_lame
;
200 encoder
->get_frame_size
= get_frame_size
;
201 encoder
->encode
= encode_lame
;
202 encoder
->fixup
= fixup
;
203 encoder
->close
= close_lame
;
207 #ifdef HAVE_MP3LAME_PRESET
209 taken out of presets_set in lame-3.93.1/frontend/parse.c and modified */
210 static int lame_presets_set( lame_t gfp
, int fast
, int cbr
, const char* preset_name
)
214 if (strcmp(preset_name
, "help") == 0) {
215 mp_msg(MSGT_FIXME
, MSGL_FIXME
, MSGTR_LameVersion
, get_lame_version(), get_lame_url());
216 lame_presets_longinfo_dm(stderr
);
220 //aliases for compatibility with old presets
222 if (strcmp(preset_name
, "phone") == 0) {
226 if ( (strcmp(preset_name
, "phon+") == 0) ||
227 (strcmp(preset_name
, "lw") == 0) ||
228 (strcmp(preset_name
, "mw-eu") == 0) ||
229 (strcmp(preset_name
, "sw") == 0)) {
233 if (strcmp(preset_name
, "mw-us") == 0) {
237 if (strcmp(preset_name
, "voice") == 0) {
241 if (strcmp(preset_name
, "fm") == 0) {
244 if ( (strcmp(preset_name
, "radio") == 0) ||
245 (strcmp(preset_name
, "tape") == 0)) {
248 if (strcmp(preset_name
, "hifi") == 0) {
251 if (strcmp(preset_name
, "cd") == 0) {
254 if (strcmp(preset_name
, "studio") == 0) {
258 #ifdef HAVE_MP3LAME_PRESET_MEDIUM
259 if (strcmp(preset_name
, "medium") == 0) {
261 lame_set_preset(gfp
, MEDIUM_FAST
);
263 lame_set_preset(gfp
, MEDIUM
);
269 if (strcmp(preset_name
, "standard") == 0) {
271 lame_set_preset(gfp
, STANDARD_FAST
);
273 lame_set_preset(gfp
, STANDARD
);
278 else if (strcmp(preset_name
, "extreme") == 0){
280 lame_set_preset(gfp
, EXTREME_FAST
);
282 lame_set_preset(gfp
, EXTREME
);
287 else if (((strcmp(preset_name
, "insane") == 0) ||
288 (strcmp(preset_name
, "320" ) == 0)) && (fast
< 1)) {
290 lame_set_preset(gfp
, INSANE
);
295 // Generic ABR Preset
296 if (((atoi(preset_name
)) > 0) && (fast
< 1)) {
297 if ((atoi(preset_name
)) >= 8 && (atoi(preset_name
)) <= 320){
298 lame_set_preset(gfp
, atoi(preset_name
));
301 lame_set_VBR(gfp
, vbr_off
);
304 lame_set_mode(gfp
, MONO
);
311 mp_msg(MSGT_FIXME
, MSGL_FIXME
, MSGTR_LameVersion
, get_lame_version(), get_lame_url());
312 mp_msg(MSGT_FIXME
, MSGL_FIXME
, MSGTR_InvalidBitrateForLamePreset
);
317 mp_msg(MSGT_FIXME
, MSGL_FIXME
, MSGTR_LameVersion
, get_lame_version(), get_lame_url());
318 mp_msg(MSGT_FIXME
, MSGL_FIXME
, MSGTR_InvalidLamePresetOptions
);
323 #ifdef HAVE_MP3LAME_PRESET
324 /* lame_presets_longinfo_dm
325 taken out of presets_longinfo_dm in lame-3.93.1/frontend/parse.c and modified */
326 static void lame_presets_longinfo_dm ( FILE* msgfp
)
328 mp_msg(MSGT_FIXME
, MSGL_FIXME
, MSGTR_LamePresetsLongInfo
);