2 * Copyright (C) <1999> Erik Walthinsen <omega@cse.ogi.edu>
3 * Copyright (C) <2004> Wim Taymans <wim@fluendo.com>
4 * Copyright (C) <2005> Thomas Vander Stichele <thomas at apestaart dot org>
5 * Copyright (C) <2008> Sebastian Dröge <sebastian.droege@collabora.co.uk>
7 * This library is free software; you can redistribute it and/or
8 * modify it under the terms of the GNU Library General Public
9 * License as published by the Free Software Foundation; either
10 * version 2 of the License, or (at your option) any later version.
12 * This library is distributed in the hope that it will be useful,
13 * but WITHOUT ANY WARRANTY; without even the implied warranty of
14 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
15 * Library General Public License for more details.
17 * You should have received a copy of the GNU Library General Public
18 * License along with this library; if not, write to the
19 * Free Software Foundation, Inc., 51 Franklin St, Fifth Floor,
20 * Boston, MA 02110-1301, USA.
24 * Based on the lame element.
28 * SECTION:element-twolame
29 * @see_also: mad, lame
31 * This element encodes raw integer audio into an MPEG-1 layer 2 (MP2) stream.
34 * <title>Example pipelines</title>
36 * gst-launch-1.0 -v audiotestsrc wave=sine num-buffers=100 ! audioconvert ! twolame ! filesink location=sine.mp2
37 * ]| Encode a test sine signal to MP2.
39 * gst-launch-1.0 -v alsasrc ! audioconvert ! twolame bitrate=192 ! filesink location=alsasrc.mp2
40 * ]| Record from a sound card using ALSA and encode to MP2
42 * gst-launch-1.0 -v filesrc location=music.wav ! decodebin ! audioconvert ! audioresample ! twolame bitrate=192 ! id3v2mux ! filesink location=music.mp2
43 * ]| Transcode from a .wav file to MP2 (the id3v2mux element is optional)
45 * gst-launch-1.0 -v cdda://5 ! audioconvert ! twolame bitrate=192 ! filesink location=track5.mp2
46 * ]| Encode Audio CD track 5 to MP2
56 #include "gsttwolamemp2enc.h"
57 #include "gst/gst-i18n-plugin.h"
59 GST_DEBUG_CATEGORY_STATIC (debug);
60 #define GST_CAT_DEFAULT debug
62 /* TwoLAME can do MPEG-1, MPEG-2 so it has 6 possible
63 * sample rates it supports */
64 static GstStaticPadTemplate gst_two_lame_sink_template =
65 GST_STATIC_PAD_TEMPLATE ("sink",
68 GST_STATIC_CAPS ("audio/x-raw, "
69 "format = (string) { " GST_AUDIO_NE (F32) ", " GST_AUDIO_NE (S16) " }, "
70 "layout = (string) interleaved, "
71 "rate = (int) { 16000, 22050, 24000, 32000, 44100, 48000 }, "
72 "channels = (int) 1; "
74 "format = (string) { " GST_AUDIO_NE (F32) ", " GST_AUDIO_NE (S16) " }, "
75 "layout = (string) interleaved, "
76 "rate = (int) { 16000, 22050, 24000, 32000, 44100, 48000 }, "
77 "channels = (int) 2," "channel-mask = (bitmask) 0x3")
80 static GstStaticPadTemplate gst_two_lame_src_template =
81 GST_STATIC_PAD_TEMPLATE ("src",
84 GST_STATIC_CAPS ("audio/mpeg, "
85 "mpegversion = (int) 1, "
87 "rate = (int) { 16000, 22050, 24000, 32000, 44100, 48000 }, "
88 "channels = (int) [ 1, 2 ]")
97 gboolean energy_level_extension;
99 gboolean error_protection;
105 gint vbr_max_bitrate;
107 gint quick_mode_count;
108 } gst_two_lame_default_settings;
110 /********** Define useful types for non-programmatic interfaces **********/
111 #define GST_TYPE_TWO_LAME_MODE (gst_two_lame_mode_get_type())
113 gst_two_lame_mode_get_type (void)
115 static GType two_lame_mode_type = 0;
116 static const GEnumValue two_lame_modes[] = {
117 {TWOLAME_AUTO_MODE, "Auto", "auto"},
118 {TWOLAME_STEREO, "Stereo", "stereo"},
119 {TWOLAME_JOINT_STEREO, "Joint Stereo", "joint"},
120 {TWOLAME_DUAL_CHANNEL, "Dual Channel", "dual"},
121 {TWOLAME_MONO, "Mono", "mono"},
125 if (!two_lame_mode_type) {
127 g_enum_register_static ("GstTwoLameMode", two_lame_modes);
129 return two_lame_mode_type;
132 #define GST_TYPE_TWO_LAME_PADDING (gst_two_lame_padding_get_type())
134 gst_two_lame_padding_get_type (void)
136 static GType two_lame_padding_type = 0;
137 static const GEnumValue two_lame_padding[] = {
138 {TWOLAME_PAD_NO, "No Padding", "never"},
139 {TWOLAME_PAD_ALL, "Always Pad", "always"},
143 if (!two_lame_padding_type) {
144 two_lame_padding_type =
145 g_enum_register_static ("GstTwoLamePadding", two_lame_padding);
147 return two_lame_padding_type;
150 #define GST_TYPE_TWO_LAME_EMPHASIS (gst_two_lame_emphasis_get_type())
152 gst_two_lame_emphasis_get_type (void)
154 static GType two_lame_emphasis_type = 0;
155 static const GEnumValue two_lame_emphasis[] = {
156 {TWOLAME_EMPHASIS_N, "No emphasis", "none"},
157 {TWOLAME_EMPHASIS_5, "50/15 ms", "5"},
158 {TWOLAME_EMPHASIS_C, "CCIT J.17", "ccit"},
162 if (!two_lame_emphasis_type) {
163 two_lame_emphasis_type =
164 g_enum_register_static ("GstTwoLameEmphasis", two_lame_emphasis);
167 return two_lame_emphasis_type;
170 /********** Standard stuff for signals and arguments **********/
179 ARG_ENERGY_LEVEL_EXTENSION,
181 ARG_ERROR_PROTECTION,
192 static gboolean gst_two_lame_start (GstAudioEncoder * enc);
193 static gboolean gst_two_lame_stop (GstAudioEncoder * enc);
194 static gboolean gst_two_lame_set_format (GstAudioEncoder * enc,
195 GstAudioInfo * info);
196 static GstFlowReturn gst_two_lame_handle_frame (GstAudioEncoder * enc,
198 static void gst_two_lame_flush (GstAudioEncoder * enc);
200 static void gst_two_lame_set_property (GObject * object, guint prop_id,
201 const GValue * value, GParamSpec * pspec);
202 static void gst_two_lame_get_property (GObject * object, guint prop_id,
203 GValue * value, GParamSpec * pspec);
204 static gboolean gst_two_lame_setup (GstTwoLame * twolame);
206 G_DEFINE_TYPE (GstTwoLame, gst_two_lame, GST_TYPE_AUDIO_ENCODER);
209 gst_two_lame_release_memory (GstTwoLame * twolame)
211 if (twolame->glopts) {
212 twolame_close (&twolame->glopts);
213 twolame->glopts = NULL;
218 gst_two_lame_finalize (GObject * obj)
220 gst_two_lame_release_memory (GST_TWO_LAME (obj));
222 G_OBJECT_CLASS (gst_two_lame_parent_class)->finalize (obj);
226 gst_two_lame_class_init (GstTwoLameClass * klass)
228 GObjectClass *gobject_class;
229 GstAudioEncoderClass *gstbase_class;
231 gobject_class = (GObjectClass *) klass;
232 gstbase_class = (GstAudioEncoderClass *) klass;
234 gobject_class->set_property = gst_two_lame_set_property;
235 gobject_class->get_property = gst_two_lame_get_property;
236 gobject_class->finalize = gst_two_lame_finalize;
238 gstbase_class->start = GST_DEBUG_FUNCPTR (gst_two_lame_start);
239 gstbase_class->stop = GST_DEBUG_FUNCPTR (gst_two_lame_stop);
240 gstbase_class->set_format = GST_DEBUG_FUNCPTR (gst_two_lame_set_format);
241 gstbase_class->handle_frame = GST_DEBUG_FUNCPTR (gst_two_lame_handle_frame);
242 gstbase_class->flush = GST_DEBUG_FUNCPTR (gst_two_lame_flush);
244 g_object_class_install_property (G_OBJECT_CLASS (klass), ARG_MODE,
245 g_param_spec_enum ("mode", "Mode", "Encoding mode",
246 GST_TYPE_TWO_LAME_MODE, gst_two_lame_default_settings.mode,
247 G_PARAM_READWRITE | G_PARAM_STATIC_STRINGS));
249 g_object_class_install_property (G_OBJECT_CLASS (klass), ARG_PSYMODEL,
250 g_param_spec_int ("psymodel", "Psychoacoustic Model",
251 "Psychoacoustic model used to encode the audio",
252 -1, 4, gst_two_lame_default_settings.psymodel,
253 G_PARAM_READWRITE | G_PARAM_STATIC_STRINGS));
255 g_object_class_install_property (G_OBJECT_CLASS (klass), ARG_BITRATE,
256 g_param_spec_int ("bitrate", "Bitrate (kb/s)",
257 "Bitrate in kbit/sec (8, 16, 24, 32, 40, 48, 56, 64, 80, 96, "
258 "112, 128, 144, 160, 192, 224, 256, 320, 384)",
259 8, 384, gst_two_lame_default_settings.bitrate,
260 G_PARAM_READWRITE | G_PARAM_STATIC_STRINGS));
262 g_object_class_install_property (G_OBJECT_CLASS (klass), ARG_PADDING,
263 g_param_spec_enum ("padding", "Padding", "Padding type",
264 GST_TYPE_TWO_LAME_PADDING, gst_two_lame_default_settings.padding,
265 G_PARAM_READWRITE | G_PARAM_STATIC_STRINGS));
267 g_object_class_install_property (G_OBJECT_CLASS (klass),
268 ARG_ENERGY_LEVEL_EXTENSION,
269 g_param_spec_boolean ("energy-level-extension", "Energy Level Extension",
270 "Write peak PCM level to each frame",
271 gst_two_lame_default_settings.energy_level_extension,
272 G_PARAM_READWRITE | G_PARAM_STATIC_STRINGS));
274 g_object_class_install_property (G_OBJECT_CLASS (klass), ARG_EMPHASIS,
275 g_param_spec_enum ("emphasis", "Emphasis",
276 "Pre-emphasis to apply to the decoded audio",
277 GST_TYPE_TWO_LAME_EMPHASIS, gst_two_lame_default_settings.emphasis,
278 G_PARAM_READWRITE | G_PARAM_STATIC_STRINGS));
280 g_object_class_install_property (G_OBJECT_CLASS (klass), ARG_ERROR_PROTECTION,
281 g_param_spec_boolean ("error-protection", "Error protection",
282 "Adds checksum to every frame",
283 gst_two_lame_default_settings.error_protection,
284 G_PARAM_READWRITE | G_PARAM_STATIC_STRINGS));
286 g_object_class_install_property (G_OBJECT_CLASS (klass), ARG_COPYRIGHT,
287 g_param_spec_boolean ("copyright", "Copyright", "Mark as copyright",
288 gst_two_lame_default_settings.copyright,
289 G_PARAM_READWRITE | G_PARAM_STATIC_STRINGS));
291 g_object_class_install_property (G_OBJECT_CLASS (klass), ARG_ORIGINAL,
292 g_param_spec_boolean ("original", "Original", "Mark as original",
293 gst_two_lame_default_settings.original,
294 G_PARAM_READWRITE | G_PARAM_STATIC_STRINGS));
296 g_object_class_install_property (G_OBJECT_CLASS (klass), ARG_VBR,
297 g_param_spec_boolean ("vbr", "VBR", "Enable variable bitrate mode",
298 gst_two_lame_default_settings.vbr,
299 G_PARAM_READWRITE | G_PARAM_STATIC_STRINGS));
301 g_object_class_install_property (G_OBJECT_CLASS (klass), ARG_VBR_LEVEL,
302 g_param_spec_float ("vbr-level", "VBR Level", "VBR Level",
303 -10.0, 10.0, gst_two_lame_default_settings.vbr_level,
304 G_PARAM_READWRITE | G_PARAM_STATIC_STRINGS));
306 g_object_class_install_property (G_OBJECT_CLASS (klass), ARG_ATH_LEVEL,
307 g_param_spec_float ("ath-level", "ATH Level", "ATH Level in dB",
308 -G_MAXFLOAT, G_MAXFLOAT, gst_two_lame_default_settings.ath_level,
309 G_PARAM_READWRITE | G_PARAM_STATIC_STRINGS));
311 g_object_class_install_property (G_OBJECT_CLASS (klass), ARG_VBR_MAX_BITRATE,
312 g_param_spec_int ("vbr-max-bitrate", "VBR max bitrate",
313 "Specify maximum VBR bitrate (0=off, 8, 16, 24, 32, 40, 48, 56, 64, 80, 96, "
314 "112, 128, 144, 160, 192, 224, 256, 320, 384)",
315 0, 384, gst_two_lame_default_settings.vbr_max_bitrate,
316 G_PARAM_READWRITE | G_PARAM_STATIC_STRINGS));
318 g_object_class_install_property (G_OBJECT_CLASS (klass), ARG_QUICK_MODE,
319 g_param_spec_boolean ("quick-mode", "Quick mode",
320 "Calculate Psymodel every frames",
321 gst_two_lame_default_settings.quick_mode,
322 G_PARAM_READWRITE | G_PARAM_STATIC_STRINGS));
324 g_object_class_install_property (G_OBJECT_CLASS (klass), ARG_QUICK_MODE_COUNT,
325 g_param_spec_int ("quick-mode-count", "Quick mode count",
326 "Calculate Psymodel every n frames",
327 0, G_MAXINT, gst_two_lame_default_settings.quick_mode_count,
328 G_PARAM_READWRITE | G_PARAM_STATIC_STRINGS));
330 gst_element_class_add_static_pad_template (GST_ELEMENT_CLASS (klass),
331 &gst_two_lame_src_template);
332 gst_element_class_add_static_pad_template (GST_ELEMENT_CLASS (klass),
333 &gst_two_lame_sink_template);
335 gst_element_class_set_static_metadata (GST_ELEMENT_CLASS (klass),
336 "TwoLAME mp2 encoder", "Codec/Encoder/Audio",
337 "High-quality free MP2 encoder",
338 "Sebastian Dröge <sebastian.droege@collabora.co.uk>");
342 gst_two_lame_set_format (GstAudioEncoder * enc, GstAudioInfo * info)
349 twolame = GST_TWO_LAME (enc);
351 /* parameters already parsed for us */
352 twolame->samplerate = GST_AUDIO_INFO_RATE (info);
353 twolame->num_channels = GST_AUDIO_INFO_CHANNELS (info);
354 twolame->float_input = !GST_AUDIO_INFO_IS_INTEGER (info);
356 /* but we might be asked to reconfigure, so reset */
357 gst_two_lame_release_memory (twolame);
359 GST_DEBUG_OBJECT (twolame, "setting up twolame");
360 if (!gst_two_lame_setup (twolame))
363 out_samplerate = twolame_get_out_samplerate (twolame->glopts);
364 if (out_samplerate == 0)
365 goto zero_output_rate;
367 if (out_samplerate != twolame->samplerate) {
368 GST_WARNING_OBJECT (twolame,
369 "output samplerate %d is different from incoming samplerate %d",
370 out_samplerate, twolame->samplerate);
373 version = twolame_get_version (twolame->glopts);
374 if (version == TWOLAME_MPEG2)
380 gst_caps_new_simple ("audio/mpeg",
381 "mpegversion", G_TYPE_INT, 1,
382 "mpegaudioversion", G_TYPE_INT, version,
383 "layer", G_TYPE_INT, 2,
384 "channels", G_TYPE_INT,
385 twolame->mode == TWOLAME_MONO ? 1 : twolame->num_channels, "rate",
386 G_TYPE_INT, out_samplerate, NULL);
388 /* and use these caps */
389 gst_audio_encoder_set_output_format (GST_AUDIO_ENCODER (twolame), othercaps);
390 gst_caps_unref (othercaps);
392 /* report needs to base class:
393 * hand one frame at a time, if we are pretty sure what a frame is */
394 if (out_samplerate == twolame->samplerate) {
395 gst_audio_encoder_set_frame_samples_min (enc, 1152);
396 gst_audio_encoder_set_frame_samples_max (enc, 1152);
397 gst_audio_encoder_set_frame_max (enc, 1);
404 GST_ELEMENT_ERROR (twolame, LIBRARY, SETTINGS, (NULL),
405 ("TwoLAME decided on a zero sample rate"));
410 GST_ELEMENT_ERROR (twolame, LIBRARY, SETTINGS,
411 (_("Failed to configure TwoLAME encoder. Check your encoding parameters.")), (NULL));
417 gst_two_lame_init (GstTwoLame * twolame)
419 GST_DEBUG_OBJECT (twolame, "starting initialization");
421 GST_PAD_SET_ACCEPT_TEMPLATE (GST_AUDIO_ENCODER_SINK_PAD (twolame));
423 twolame->mode = gst_two_lame_default_settings.mode;
424 twolame->psymodel = gst_two_lame_default_settings.psymodel;
425 twolame->bitrate = gst_two_lame_default_settings.bitrate;
426 twolame->padding = gst_two_lame_default_settings.padding;
427 twolame->energy_level_extension =
428 gst_two_lame_default_settings.energy_level_extension;
429 twolame->emphasis = gst_two_lame_default_settings.emphasis;
430 twolame->error_protection = gst_two_lame_default_settings.error_protection;
431 twolame->copyright = gst_two_lame_default_settings.copyright;
432 twolame->original = gst_two_lame_default_settings.original;
433 twolame->vbr = gst_two_lame_default_settings.vbr;
434 twolame->vbr_level = gst_two_lame_default_settings.vbr_level;
435 twolame->ath_level = gst_two_lame_default_settings.ath_level;
436 twolame->vbr_max_bitrate = gst_two_lame_default_settings.vbr_max_bitrate;
437 twolame->quick_mode = gst_two_lame_default_settings.quick_mode;
438 twolame->quick_mode_count = gst_two_lame_default_settings.quick_mode_count;
440 GST_DEBUG_OBJECT (twolame, "done initializing");
444 gst_two_lame_start (GstAudioEncoder * enc)
446 GstTwoLame *twolame = GST_TWO_LAME (enc);
448 GST_DEBUG_OBJECT (twolame, "start");
453 gst_two_lame_stop (GstAudioEncoder * enc)
455 GstTwoLame *twolame = GST_TWO_LAME (enc);
457 GST_DEBUG_OBJECT (twolame, "stop");
459 gst_two_lame_release_memory (twolame);
463 /* <php-emulation-mode>three underscores for ___rate is really really really
464 * private as opposed to one underscore<php-emulation-mode> */
465 /* call this MACRO outside of the NULL state so that we have a higher chance
466 * of actually having a pipeline and bus to get the message through */
468 #define CHECK_AND_FIXUP_BITRATE(obj,param,rate) \
470 gint ___rate = rate; \
471 gint maxrate = 320; \
472 gint multiplier = 64; \
474 maxrate = 64; multiplier = 8; \
475 if ((rate % 8) != 0) ___rate = GST_ROUND_UP_8 (rate); \
476 } else if (rate <= 144) { \
477 maxrate = 144; multiplier = 16; \
478 if ((rate % 16) != 0) ___rate = GST_ROUND_UP_16 (rate); \
479 } else if (rate <= 256) { \
480 maxrate = 256; multiplier = 32; \
481 if ((rate % 32) != 0) ___rate = GST_ROUND_UP_32 (rate); \
482 } else if (rate <= 384) { \
483 maxrate = 384; multiplier = 64; \
484 if ((rate % 64) != 0) ___rate = GST_ROUND_UP_64 (rate); \
486 if (___rate != rate) { \
487 GST_ELEMENT_WARNING (obj, LIBRARY, SETTINGS, \
488 (_("The requested bitrate %d kbit/s for property '%s' " \
490 "The bitrate was changed to %d kbit/s."), rate, \
492 ("A bitrate below %d should be a multiple of %d.", \
493 maxrate, multiplier)); \
499 gst_two_lame_set_property (GObject * object, guint prop_id,
500 const GValue * value, GParamSpec * pspec)
502 GstTwoLame *twolame = GST_TWO_LAME (object);
506 twolame->mode = g_value_get_enum (value);
509 twolame->psymodel = g_value_get_int (value);
512 twolame->bitrate = g_value_get_int (value);
515 twolame->padding = g_value_get_enum (value);
517 case ARG_ENERGY_LEVEL_EXTENSION:
518 twolame->energy_level_extension = g_value_get_boolean (value);
521 twolame->emphasis = g_value_get_enum (value);
523 case ARG_ERROR_PROTECTION:
524 twolame->error_protection = g_value_get_boolean (value);
527 twolame->copyright = g_value_get_boolean (value);
530 twolame->original = g_value_get_boolean (value);
533 twolame->vbr = g_value_get_boolean (value);
536 twolame->vbr_level = g_value_get_float (value);
539 twolame->ath_level = g_value_get_float (value);
541 case ARG_VBR_MAX_BITRATE:
542 twolame->vbr_max_bitrate = g_value_get_int (value);
545 twolame->quick_mode = g_value_get_boolean (value);
547 case ARG_QUICK_MODE_COUNT:
548 twolame->quick_mode_count = g_value_get_int (value);
551 G_OBJECT_WARN_INVALID_PROPERTY_ID (object, prop_id, pspec);
557 gst_two_lame_get_property (GObject * object, guint prop_id, GValue * value,
560 GstTwoLame *twolame = GST_TWO_LAME (object);
564 g_value_set_enum (value, twolame->mode);
567 g_value_set_int (value, twolame->psymodel);
570 g_value_set_int (value, twolame->bitrate);
573 g_value_set_enum (value, twolame->padding);
575 case ARG_ENERGY_LEVEL_EXTENSION:
576 g_value_set_boolean (value, twolame->energy_level_extension);
579 g_value_set_enum (value, twolame->emphasis);
581 case ARG_ERROR_PROTECTION:
582 g_value_set_boolean (value, twolame->error_protection);
585 g_value_set_boolean (value, twolame->copyright);
588 g_value_set_boolean (value, twolame->original);
591 g_value_set_boolean (value, twolame->vbr);
594 g_value_set_float (value, twolame->vbr_level);
597 g_value_set_float (value, twolame->ath_level);
599 case ARG_VBR_MAX_BITRATE:
600 g_value_set_int (value, twolame->vbr_max_bitrate);
603 g_value_set_boolean (value, twolame->quick_mode);
605 case ARG_QUICK_MODE_COUNT:
606 g_value_set_int (value, twolame->quick_mode_count);
609 G_OBJECT_WARN_INVALID_PROPERTY_ID (object, prop_id, pspec);
615 gst_two_lame_flush_full (GstTwoLame * lame, gboolean push)
620 GstFlowReturn result = GST_FLOW_OK;
625 buf = gst_buffer_new_and_alloc (16384);
626 gst_buffer_map (buf, &map, GST_MAP_WRITE);
627 size = twolame_encode_flush (lame->glopts, map.data, 16384);
628 gst_buffer_unmap (buf, &map);
630 if (size > 0 && push) {
631 gst_buffer_set_size (buf, size);
632 GST_DEBUG_OBJECT (lame, "pushing final packet of %u bytes", size);
633 result = gst_audio_encoder_finish_frame (GST_AUDIO_ENCODER (lame), buf, -1);
635 GST_DEBUG_OBJECT (lame, "no final packet (size=%d, push=%d)", size, push);
636 gst_buffer_unref (buf);
637 result = GST_FLOW_OK;
643 gst_two_lame_flush (GstAudioEncoder * enc)
645 gst_two_lame_flush_full (GST_TWO_LAME (enc), FALSE);
649 gst_two_lame_handle_frame (GstAudioEncoder * enc, GstBuffer * buf)
652 gint mp3_buffer_size, mp3_size;
654 GstFlowReturn result;
656 GstMapInfo map, mp3_map;
658 twolame = GST_TWO_LAME (enc);
660 /* squeeze remaining and push */
661 if (G_UNLIKELY (buf == NULL))
662 return gst_two_lame_flush_full (twolame, TRUE);
664 gst_buffer_map (buf, &map, GST_MAP_READ);
666 if (twolame->float_input)
667 num_samples = map.size / 4;
669 num_samples = map.size / 2;
671 /* allocate space for output */
672 mp3_buffer_size = 1.25 * num_samples + 16384;
673 mp3_buf = gst_buffer_new_and_alloc (mp3_buffer_size);
674 gst_buffer_map (mp3_buf, &mp3_map, GST_MAP_WRITE);
676 if (twolame->num_channels == 1) {
677 if (twolame->float_input)
678 mp3_size = twolame_encode_buffer_float32 (twolame->glopts,
680 (float *) map.data, num_samples, mp3_map.data, mp3_buffer_size);
682 mp3_size = twolame_encode_buffer (twolame->glopts,
683 (short int *) map.data,
684 (short int *) map.data, num_samples, mp3_map.data, mp3_buffer_size);
686 if (twolame->float_input)
687 mp3_size = twolame_encode_buffer_float32_interleaved (twolame->glopts,
689 num_samples / twolame->num_channels, mp3_map.data, mp3_buffer_size);
691 mp3_size = twolame_encode_buffer_interleaved (twolame->glopts,
692 (short int *) map.data,
693 num_samples / twolame->num_channels, mp3_map.data, mp3_buffer_size);
696 GST_LOG_OBJECT (twolame, "encoded %" G_GSIZE_FORMAT " bytes of audio "
697 "to %d bytes of mp3", map.size, mp3_size);
699 gst_buffer_unmap (buf, &map);
700 gst_buffer_unmap (mp3_buf, &mp3_map);
703 gst_buffer_set_size (mp3_buf, mp3_size);
704 result = gst_audio_encoder_finish_frame (enc, mp3_buf, -1);
708 g_warning ("error %d", mp3_size);
710 gst_buffer_unref (mp3_buf);
711 result = GST_FLOW_OK;
717 /* set up the encoder state */
719 gst_two_lame_setup (GstTwoLame * twolame)
722 #define CHECK_ERROR(command) G_STMT_START {\
723 if ((command) < 0) { \
724 GST_ERROR_OBJECT (twolame, "setup failed: " G_STRINGIFY (command)); \
730 GstCaps *allowed_caps;
732 GST_DEBUG_OBJECT (twolame, "starting setup");
734 /* check if we're already setup; if we are, we might want to check
735 * if this initialization is compatible with the previous one */
737 if (twolame->setup) {
738 GST_WARNING_OBJECT (twolame, "already setup");
739 twolame->setup = FALSE;
742 twolame->glopts = twolame_init ();
744 if (twolame->glopts == NULL)
747 /* copy the parameters over */
748 twolame_set_in_samplerate (twolame->glopts, twolame->samplerate);
750 /* let twolame choose default samplerate unless outgoing sample rate is fixed */
751 allowed_caps = gst_pad_get_allowed_caps (GST_AUDIO_ENCODER_SRC_PAD (twolame));
753 if (allowed_caps != NULL) {
754 GstStructure *structure;
757 structure = gst_caps_get_structure (allowed_caps, 0);
759 if (gst_structure_get_int (structure, "rate", &samplerate)) {
760 GST_DEBUG_OBJECT (twolame,
761 "Setting sample rate to %d as fixed in src caps", samplerate);
762 twolame_set_out_samplerate (twolame->glopts, samplerate);
764 GST_DEBUG_OBJECT (twolame, "Letting twolame choose sample rate");
765 twolame_set_out_samplerate (twolame->glopts, 0);
767 gst_caps_unref (allowed_caps);
770 GST_DEBUG_OBJECT (twolame,
771 "No peer yet, letting twolame choose sample rate");
772 twolame_set_out_samplerate (twolame->glopts, 0);
775 /* force mono encoding if we only have one channel */
776 if (twolame->num_channels == 1)
779 /* Fix bitrates and MPEG version */
781 CHECK_ERROR (twolame_set_num_channels (twolame->glopts,
782 twolame->num_channels));
784 CHECK_ERROR (twolame_set_mode (twolame->glopts, twolame->mode));
785 CHECK_ERROR (twolame_set_psymodel (twolame->glopts, twolame->psymodel));
786 CHECK_AND_FIXUP_BITRATE (twolame, "bitrate", twolame->bitrate);
787 CHECK_ERROR (twolame_set_bitrate (twolame->glopts, twolame->bitrate));
788 CHECK_ERROR (twolame_set_padding (twolame->glopts, twolame->padding));
789 CHECK_ERROR (twolame_set_energy_levels (twolame->glopts,
790 twolame->energy_level_extension));
791 CHECK_ERROR (twolame_set_emphasis (twolame->glopts, twolame->emphasis));
792 CHECK_ERROR (twolame_set_error_protection (twolame->glopts,
793 twolame->error_protection));
794 CHECK_ERROR (twolame_set_copyright (twolame->glopts, twolame->copyright));
795 CHECK_ERROR (twolame_set_original (twolame->glopts, twolame->original));
796 CHECK_ERROR (twolame_set_VBR (twolame->glopts, twolame->vbr));
797 CHECK_ERROR (twolame_set_VBR_level (twolame->glopts, twolame->vbr_level));
798 CHECK_ERROR (twolame_set_ATH_level (twolame->glopts, twolame->ath_level));
799 CHECK_AND_FIXUP_BITRATE (twolame, "vbr-max-bitrate",
800 twolame->vbr_max_bitrate);
801 CHECK_ERROR (twolame_set_VBR_max_bitrate_kbps (twolame->glopts,
802 twolame->vbr_max_bitrate));
803 CHECK_ERROR (twolame_set_quick_mode (twolame->glopts, twolame->quick_mode));
804 CHECK_ERROR (twolame_set_quick_count (twolame->glopts,
805 twolame->quick_mode_count));
807 /* initialize the twolame encoder */
808 if ((retval = twolame_init_params (twolame->glopts)) >= 0) {
809 twolame->setup = TRUE;
810 /* FIXME: it would be nice to print out the mode here */
811 GST_INFO ("twolame encoder setup (%d kbit/s, %d Hz, %d channels)",
812 twolame->bitrate, twolame->samplerate, twolame->num_channels);
814 GST_ERROR_OBJECT (twolame, "twolame_init_params returned %d", retval);
817 GST_DEBUG_OBJECT (twolame, "done with setup");
819 return twolame->setup;
824 gst_two_lame_get_default_settings (void)
826 twolame_options *glopts = NULL;
828 glopts = twolame_init ();
829 if (glopts == NULL) {
830 GST_ERROR ("Couldn't initialize TwoLAME");
834 twolame_set_num_channels (glopts, 2);
835 twolame_set_in_samplerate (glopts, 44100);
837 if (twolame_init_params (glopts) != 0) {
838 GST_ERROR ("Couldn't set default parameters");
842 gst_two_lame_default_settings.mode = TWOLAME_JOINT_STEREO; /* twolame_get_mode (glopts); */
843 gst_two_lame_default_settings.psymodel = twolame_get_psymodel (glopts);
844 gst_two_lame_default_settings.bitrate = twolame_get_bitrate (glopts);
845 gst_two_lame_default_settings.padding = twolame_get_padding (glopts);
846 gst_two_lame_default_settings.energy_level_extension =
847 twolame_get_energy_levels (glopts);
848 gst_two_lame_default_settings.emphasis = twolame_get_emphasis (glopts);
849 gst_two_lame_default_settings.error_protection =
850 twolame_get_error_protection (glopts);
851 gst_two_lame_default_settings.copyright = twolame_get_copyright (glopts);
852 gst_two_lame_default_settings.original = twolame_get_original (glopts);
853 gst_two_lame_default_settings.vbr = twolame_get_VBR (glopts);
854 gst_two_lame_default_settings.vbr_level = twolame_get_VBR_level (glopts);
855 gst_two_lame_default_settings.ath_level = twolame_get_ATH_level (glopts);
856 gst_two_lame_default_settings.vbr_max_bitrate =
857 twolame_get_VBR_max_bitrate_kbps (glopts);
858 gst_two_lame_default_settings.quick_mode = twolame_get_quick_mode (glopts);
859 gst_two_lame_default_settings.quick_mode_count =
860 twolame_get_quick_count (glopts);
862 twolame_close (&glopts);
868 plugin_init (GstPlugin * plugin)
870 GST_DEBUG_CATEGORY_INIT (debug, "twolame", 0, "twolame mp2 encoder");
872 if (!gst_two_lame_get_default_settings ())
876 GST_DEBUG ("binding text domain %s to locale dir %s", GETTEXT_PACKAGE,
878 bindtextdomain (GETTEXT_PACKAGE, LOCALEDIR);
879 bind_textdomain_codeset (GETTEXT_PACKAGE, "UTF-8");
880 #endif /* ENABLE_NLS */
882 if (!gst_element_register (plugin, "twolamemp2enc", GST_RANK_PRIMARY,
889 GST_PLUGIN_DEFINE (GST_VERSION_MAJOR,
892 "Encode MP2s with TwoLAME",
893 plugin_init, VERSION, "LGPL", GST_PACKAGE_NAME, GST_PACKAGE_ORIGIN);