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.
33 * ## Example pipelines
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
55 #include "gsttwolamemp2enc.h"
56 #include "gst/gst-i18n-plugin.h"
58 GST_DEBUG_CATEGORY_STATIC (debug);
59 #define GST_CAT_DEFAULT debug
61 /* TwoLAME can do MPEG-1, MPEG-2 so it has 6 possible
62 * sample rates it supports */
63 static GstStaticPadTemplate gst_two_lame_sink_template =
64 GST_STATIC_PAD_TEMPLATE ("sink",
67 GST_STATIC_CAPS ("audio/x-raw, "
68 "format = (string) { " GST_AUDIO_NE (F32) ", " GST_AUDIO_NE (S16) " }, "
69 "layout = (string) interleaved, "
70 "rate = (int) { 16000, 22050, 24000, 32000, 44100, 48000 }, "
71 "channels = (int) 1; "
73 "format = (string) { " GST_AUDIO_NE (F32) ", " GST_AUDIO_NE (S16) " }, "
74 "layout = (string) interleaved, "
75 "rate = (int) { 16000, 22050, 24000, 32000, 44100, 48000 }, "
76 "channels = (int) 2," "channel-mask = (bitmask) 0x3")
79 static GstStaticPadTemplate gst_two_lame_src_template =
80 GST_STATIC_PAD_TEMPLATE ("src",
83 GST_STATIC_CAPS ("audio/mpeg, "
84 "mpegversion = (int) 1, "
86 "rate = (int) { 16000, 22050, 24000, 32000, 44100, 48000 }, "
87 "channels = (int) [ 1, 2 ]")
96 gboolean energy_level_extension;
98 gboolean error_protection;
104 gint vbr_max_bitrate;
106 gint quick_mode_count;
107 } gst_two_lame_default_settings;
109 /********** Define useful types for non-programmatic interfaces **********/
110 #define GST_TYPE_TWO_LAME_MODE (gst_two_lame_mode_get_type())
112 gst_two_lame_mode_get_type (void)
114 static GType two_lame_mode_type = 0;
115 static const GEnumValue two_lame_modes[] = {
116 {TWOLAME_AUTO_MODE, "Auto", "auto"},
117 {TWOLAME_STEREO, "Stereo", "stereo"},
118 {TWOLAME_JOINT_STEREO, "Joint Stereo", "joint"},
119 {TWOLAME_DUAL_CHANNEL, "Dual Channel", "dual"},
120 {TWOLAME_MONO, "Mono", "mono"},
124 if (!two_lame_mode_type) {
126 g_enum_register_static ("GstTwoLameMode", two_lame_modes);
128 return two_lame_mode_type;
131 #define GST_TYPE_TWO_LAME_PADDING (gst_two_lame_padding_get_type())
133 gst_two_lame_padding_get_type (void)
135 static GType two_lame_padding_type = 0;
136 static const GEnumValue two_lame_padding[] = {
137 {TWOLAME_PAD_NO, "No Padding", "never"},
138 {TWOLAME_PAD_ALL, "Always Pad", "always"},
142 if (!two_lame_padding_type) {
143 two_lame_padding_type =
144 g_enum_register_static ("GstTwoLamePadding", two_lame_padding);
146 return two_lame_padding_type;
149 #define GST_TYPE_TWO_LAME_EMPHASIS (gst_two_lame_emphasis_get_type())
151 gst_two_lame_emphasis_get_type (void)
153 static GType two_lame_emphasis_type = 0;
154 static const GEnumValue two_lame_emphasis[] = {
155 {TWOLAME_EMPHASIS_N, "No emphasis", "none"},
156 {TWOLAME_EMPHASIS_5, "50/15 ms", "5"},
157 {TWOLAME_EMPHASIS_C, "CCIT J.17", "ccit"},
161 if (!two_lame_emphasis_type) {
162 two_lame_emphasis_type =
163 g_enum_register_static ("GstTwoLameEmphasis", two_lame_emphasis);
166 return two_lame_emphasis_type;
169 /********** Standard stuff for signals and arguments **********/
178 ARG_ENERGY_LEVEL_EXTENSION,
180 ARG_ERROR_PROTECTION,
191 static gboolean gst_two_lame_start (GstAudioEncoder * enc);
192 static gboolean gst_two_lame_stop (GstAudioEncoder * enc);
193 static gboolean gst_two_lame_set_format (GstAudioEncoder * enc,
194 GstAudioInfo * info);
195 static GstFlowReturn gst_two_lame_handle_frame (GstAudioEncoder * enc,
197 static void gst_two_lame_flush (GstAudioEncoder * enc);
199 static void gst_two_lame_set_property (GObject * object, guint prop_id,
200 const GValue * value, GParamSpec * pspec);
201 static void gst_two_lame_get_property (GObject * object, guint prop_id,
202 GValue * value, GParamSpec * pspec);
203 static gboolean gst_two_lame_setup (GstTwoLame * twolame);
204 static gboolean two_lame_element_init (void);
206 G_DEFINE_TYPE (GstTwoLame, gst_two_lame, GST_TYPE_AUDIO_ENCODER);
207 GST_ELEMENT_REGISTER_DEFINE_WITH_CODE (twolamemp2enc, "twolamemp2enc",
208 GST_RANK_PRIMARY, GST_TYPE_TWO_LAME, two_lame_element_init (););
211 gst_two_lame_release_memory (GstTwoLame * twolame)
213 if (twolame->glopts) {
214 twolame_close (&twolame->glopts);
215 twolame->glopts = NULL;
220 gst_two_lame_finalize (GObject * obj)
222 gst_two_lame_release_memory (GST_TWO_LAME (obj));
224 G_OBJECT_CLASS (gst_two_lame_parent_class)->finalize (obj);
228 gst_two_lame_class_init (GstTwoLameClass * klass)
230 GObjectClass *gobject_class;
231 GstAudioEncoderClass *gstbase_class;
233 gobject_class = (GObjectClass *) klass;
234 gstbase_class = (GstAudioEncoderClass *) klass;
236 gobject_class->set_property = gst_two_lame_set_property;
237 gobject_class->get_property = gst_two_lame_get_property;
238 gobject_class->finalize = gst_two_lame_finalize;
240 gstbase_class->start = GST_DEBUG_FUNCPTR (gst_two_lame_start);
241 gstbase_class->stop = GST_DEBUG_FUNCPTR (gst_two_lame_stop);
242 gstbase_class->set_format = GST_DEBUG_FUNCPTR (gst_two_lame_set_format);
243 gstbase_class->handle_frame = GST_DEBUG_FUNCPTR (gst_two_lame_handle_frame);
244 gstbase_class->flush = GST_DEBUG_FUNCPTR (gst_two_lame_flush);
246 g_object_class_install_property (G_OBJECT_CLASS (klass), ARG_MODE,
247 g_param_spec_enum ("mode", "Mode", "Encoding mode",
248 GST_TYPE_TWO_LAME_MODE, gst_two_lame_default_settings.mode,
249 G_PARAM_READWRITE | G_PARAM_STATIC_STRINGS));
251 g_object_class_install_property (G_OBJECT_CLASS (klass), ARG_PSYMODEL,
252 g_param_spec_int ("psymodel", "Psychoacoustic Model",
253 "Psychoacoustic model used to encode the audio",
254 -1, 4, gst_two_lame_default_settings.psymodel,
255 G_PARAM_READWRITE | G_PARAM_STATIC_STRINGS));
257 g_object_class_install_property (G_OBJECT_CLASS (klass), ARG_BITRATE,
258 g_param_spec_int ("bitrate", "Bitrate (kb/s)",
259 "Bitrate in kbit/sec (8, 16, 24, 32, 40, 48, 56, 64, 80, 96, "
260 "112, 128, 144, 160, 192, 224, 256, 320, 384)",
261 8, 384, gst_two_lame_default_settings.bitrate,
262 G_PARAM_READWRITE | G_PARAM_STATIC_STRINGS));
264 g_object_class_install_property (G_OBJECT_CLASS (klass), ARG_PADDING,
265 g_param_spec_enum ("padding", "Padding", "Padding type",
266 GST_TYPE_TWO_LAME_PADDING, gst_two_lame_default_settings.padding,
267 G_PARAM_READWRITE | G_PARAM_STATIC_STRINGS));
269 g_object_class_install_property (G_OBJECT_CLASS (klass),
270 ARG_ENERGY_LEVEL_EXTENSION,
271 g_param_spec_boolean ("energy-level-extension", "Energy Level Extension",
272 "Write peak PCM level to each frame",
273 gst_two_lame_default_settings.energy_level_extension,
274 G_PARAM_READWRITE | G_PARAM_STATIC_STRINGS));
276 g_object_class_install_property (G_OBJECT_CLASS (klass), ARG_EMPHASIS,
277 g_param_spec_enum ("emphasis", "Emphasis",
278 "Pre-emphasis to apply to the decoded audio",
279 GST_TYPE_TWO_LAME_EMPHASIS, gst_two_lame_default_settings.emphasis,
280 G_PARAM_READWRITE | G_PARAM_STATIC_STRINGS));
282 g_object_class_install_property (G_OBJECT_CLASS (klass), ARG_ERROR_PROTECTION,
283 g_param_spec_boolean ("error-protection", "Error protection",
284 "Adds checksum to every frame",
285 gst_two_lame_default_settings.error_protection,
286 G_PARAM_READWRITE | G_PARAM_STATIC_STRINGS));
288 g_object_class_install_property (G_OBJECT_CLASS (klass), ARG_COPYRIGHT,
289 g_param_spec_boolean ("copyright", "Copyright", "Mark as copyright",
290 gst_two_lame_default_settings.copyright,
291 G_PARAM_READWRITE | G_PARAM_STATIC_STRINGS));
293 g_object_class_install_property (G_OBJECT_CLASS (klass), ARG_ORIGINAL,
294 g_param_spec_boolean ("original", "Original", "Mark as original",
295 gst_two_lame_default_settings.original,
296 G_PARAM_READWRITE | G_PARAM_STATIC_STRINGS));
298 g_object_class_install_property (G_OBJECT_CLASS (klass), ARG_VBR,
299 g_param_spec_boolean ("vbr", "VBR", "Enable variable bitrate mode",
300 gst_two_lame_default_settings.vbr,
301 G_PARAM_READWRITE | G_PARAM_STATIC_STRINGS));
303 g_object_class_install_property (G_OBJECT_CLASS (klass), ARG_VBR_LEVEL,
304 g_param_spec_float ("vbr-level", "VBR Level", "VBR Level",
305 -10.0, 10.0, gst_two_lame_default_settings.vbr_level,
306 G_PARAM_READWRITE | G_PARAM_STATIC_STRINGS));
308 g_object_class_install_property (G_OBJECT_CLASS (klass), ARG_ATH_LEVEL,
309 g_param_spec_float ("ath-level", "ATH Level", "ATH Level in dB",
310 -G_MAXFLOAT, G_MAXFLOAT, gst_two_lame_default_settings.ath_level,
311 G_PARAM_READWRITE | G_PARAM_STATIC_STRINGS));
313 g_object_class_install_property (G_OBJECT_CLASS (klass), ARG_VBR_MAX_BITRATE,
314 g_param_spec_int ("vbr-max-bitrate", "VBR max bitrate",
315 "Specify maximum VBR bitrate (0=off, 8, 16, 24, 32, 40, 48, 56, 64, 80, 96, "
316 "112, 128, 144, 160, 192, 224, 256, 320, 384)",
317 0, 384, gst_two_lame_default_settings.vbr_max_bitrate,
318 G_PARAM_READWRITE | G_PARAM_STATIC_STRINGS));
320 g_object_class_install_property (G_OBJECT_CLASS (klass), ARG_QUICK_MODE,
321 g_param_spec_boolean ("quick-mode", "Quick mode",
322 "Calculate Psymodel every frames",
323 gst_two_lame_default_settings.quick_mode,
324 G_PARAM_READWRITE | G_PARAM_STATIC_STRINGS));
326 g_object_class_install_property (G_OBJECT_CLASS (klass), ARG_QUICK_MODE_COUNT,
327 g_param_spec_int ("quick-mode-count", "Quick mode count",
328 "Calculate Psymodel every n frames",
329 0, G_MAXINT, gst_two_lame_default_settings.quick_mode_count,
330 G_PARAM_READWRITE | G_PARAM_STATIC_STRINGS));
332 gst_element_class_add_static_pad_template (GST_ELEMENT_CLASS (klass),
333 &gst_two_lame_src_template);
334 gst_element_class_add_static_pad_template (GST_ELEMENT_CLASS (klass),
335 &gst_two_lame_sink_template);
337 gst_element_class_set_static_metadata (GST_ELEMENT_CLASS (klass),
338 "TwoLAME mp2 encoder", "Codec/Encoder/Audio",
339 "High-quality free MP2 encoder",
340 "Sebastian Dröge <sebastian.droege@collabora.co.uk>");
342 gst_type_mark_as_plugin_api (GST_TYPE_TWO_LAME_MODE, 0);
343 gst_type_mark_as_plugin_api (GST_TYPE_TWO_LAME_PADDING, 0);
344 gst_type_mark_as_plugin_api (GST_TYPE_TWO_LAME_EMPHASIS, 0);
348 gst_two_lame_set_format (GstAudioEncoder * enc, GstAudioInfo * info)
355 twolame = GST_TWO_LAME (enc);
357 /* parameters already parsed for us */
358 twolame->samplerate = GST_AUDIO_INFO_RATE (info);
359 twolame->num_channels = GST_AUDIO_INFO_CHANNELS (info);
360 twolame->float_input = !GST_AUDIO_INFO_IS_INTEGER (info);
362 /* but we might be asked to reconfigure, so reset */
363 gst_two_lame_release_memory (twolame);
365 GST_DEBUG_OBJECT (twolame, "setting up twolame");
366 if (!gst_two_lame_setup (twolame))
369 out_samplerate = twolame_get_out_samplerate (twolame->glopts);
370 if (out_samplerate == 0)
371 goto zero_output_rate;
373 if (out_samplerate != twolame->samplerate) {
374 GST_WARNING_OBJECT (twolame,
375 "output samplerate %d is different from incoming samplerate %d",
376 out_samplerate, twolame->samplerate);
379 version = twolame_get_version (twolame->glopts);
380 if (version == TWOLAME_MPEG2)
386 gst_caps_new_simple ("audio/mpeg",
387 "mpegversion", G_TYPE_INT, 1,
388 "mpegaudioversion", G_TYPE_INT, version,
389 "layer", G_TYPE_INT, 2,
390 "channels", G_TYPE_INT,
391 twolame->mode == TWOLAME_MONO ? 1 : twolame->num_channels, "rate",
392 G_TYPE_INT, out_samplerate, NULL);
394 /* and use these caps */
395 gst_audio_encoder_set_output_format (GST_AUDIO_ENCODER (twolame), othercaps);
396 gst_caps_unref (othercaps);
398 /* report needs to base class:
399 * hand one frame at a time, if we are pretty sure what a frame is */
400 if (out_samplerate == twolame->samplerate) {
401 gst_audio_encoder_set_frame_samples_min (enc, 1152);
402 gst_audio_encoder_set_frame_samples_max (enc, 1152);
403 gst_audio_encoder_set_frame_max (enc, 1);
410 GST_ELEMENT_ERROR (twolame, LIBRARY, SETTINGS, (NULL),
411 ("TwoLAME decided on a zero sample rate"));
416 GST_ELEMENT_ERROR (twolame, LIBRARY, SETTINGS,
417 (_("Failed to configure TwoLAME encoder. Check your encoding parameters.")), (NULL));
423 gst_two_lame_init (GstTwoLame * twolame)
425 GST_DEBUG_OBJECT (twolame, "starting initialization");
427 GST_PAD_SET_ACCEPT_TEMPLATE (GST_AUDIO_ENCODER_SINK_PAD (twolame));
429 twolame->mode = gst_two_lame_default_settings.mode;
430 twolame->psymodel = gst_two_lame_default_settings.psymodel;
431 twolame->bitrate = gst_two_lame_default_settings.bitrate;
432 twolame->padding = gst_two_lame_default_settings.padding;
433 twolame->energy_level_extension =
434 gst_two_lame_default_settings.energy_level_extension;
435 twolame->emphasis = gst_two_lame_default_settings.emphasis;
436 twolame->error_protection = gst_two_lame_default_settings.error_protection;
437 twolame->copyright = gst_two_lame_default_settings.copyright;
438 twolame->original = gst_two_lame_default_settings.original;
439 twolame->vbr = gst_two_lame_default_settings.vbr;
440 twolame->vbr_level = gst_two_lame_default_settings.vbr_level;
441 twolame->ath_level = gst_two_lame_default_settings.ath_level;
442 twolame->vbr_max_bitrate = gst_two_lame_default_settings.vbr_max_bitrate;
443 twolame->quick_mode = gst_two_lame_default_settings.quick_mode;
444 twolame->quick_mode_count = gst_two_lame_default_settings.quick_mode_count;
446 GST_DEBUG_OBJECT (twolame, "done initializing");
450 gst_two_lame_start (GstAudioEncoder * enc)
452 GstTwoLame *twolame = GST_TWO_LAME (enc);
454 GST_DEBUG_OBJECT (twolame, "start");
459 gst_two_lame_stop (GstAudioEncoder * enc)
461 GstTwoLame *twolame = GST_TWO_LAME (enc);
463 GST_DEBUG_OBJECT (twolame, "stop");
465 gst_two_lame_release_memory (twolame);
469 /* <php-emulation-mode>three underscores for ___rate is really really really
470 * private as opposed to one underscore<php-emulation-mode> */
471 /* call this MACRO outside of the NULL state so that we have a higher chance
472 * of actually having a pipeline and bus to get the message through */
474 #define CHECK_AND_FIXUP_BITRATE(obj,param,rate) \
476 gint ___rate = rate; \
477 gint maxrate = 320; \
478 gint multiplier = 64; \
480 maxrate = 64; multiplier = 8; \
481 if ((rate % 8) != 0) ___rate = GST_ROUND_UP_8 (rate); \
482 } else if (rate <= 144) { \
483 maxrate = 144; multiplier = 16; \
484 if ((rate % 16) != 0) ___rate = GST_ROUND_UP_16 (rate); \
485 } else if (rate <= 256) { \
486 maxrate = 256; multiplier = 32; \
487 if ((rate % 32) != 0) ___rate = GST_ROUND_UP_32 (rate); \
488 } else if (rate <= 384) { \
489 maxrate = 384; multiplier = 64; \
490 if ((rate % 64) != 0) ___rate = GST_ROUND_UP_64 (rate); \
492 if (___rate != rate) { \
493 GST_ELEMENT_WARNING (obj, LIBRARY, SETTINGS, \
494 (_("The requested bitrate %d kbit/s for property '%s' " \
496 "The bitrate was changed to %d kbit/s."), rate, \
498 ("A bitrate below %d should be a multiple of %d.", \
499 maxrate, multiplier)); \
505 gst_two_lame_set_property (GObject * object, guint prop_id,
506 const GValue * value, GParamSpec * pspec)
508 GstTwoLame *twolame = GST_TWO_LAME (object);
512 twolame->mode = g_value_get_enum (value);
515 twolame->psymodel = g_value_get_int (value);
518 twolame->bitrate = g_value_get_int (value);
521 twolame->padding = g_value_get_enum (value);
523 case ARG_ENERGY_LEVEL_EXTENSION:
524 twolame->energy_level_extension = g_value_get_boolean (value);
527 twolame->emphasis = g_value_get_enum (value);
529 case ARG_ERROR_PROTECTION:
530 twolame->error_protection = g_value_get_boolean (value);
533 twolame->copyright = g_value_get_boolean (value);
536 twolame->original = g_value_get_boolean (value);
539 twolame->vbr = g_value_get_boolean (value);
542 twolame->vbr_level = g_value_get_float (value);
545 twolame->ath_level = g_value_get_float (value);
547 case ARG_VBR_MAX_BITRATE:
548 twolame->vbr_max_bitrate = g_value_get_int (value);
551 twolame->quick_mode = g_value_get_boolean (value);
553 case ARG_QUICK_MODE_COUNT:
554 twolame->quick_mode_count = g_value_get_int (value);
557 G_OBJECT_WARN_INVALID_PROPERTY_ID (object, prop_id, pspec);
563 gst_two_lame_get_property (GObject * object, guint prop_id, GValue * value,
566 GstTwoLame *twolame = GST_TWO_LAME (object);
570 g_value_set_enum (value, twolame->mode);
573 g_value_set_int (value, twolame->psymodel);
576 g_value_set_int (value, twolame->bitrate);
579 g_value_set_enum (value, twolame->padding);
581 case ARG_ENERGY_LEVEL_EXTENSION:
582 g_value_set_boolean (value, twolame->energy_level_extension);
585 g_value_set_enum (value, twolame->emphasis);
587 case ARG_ERROR_PROTECTION:
588 g_value_set_boolean (value, twolame->error_protection);
591 g_value_set_boolean (value, twolame->copyright);
594 g_value_set_boolean (value, twolame->original);
597 g_value_set_boolean (value, twolame->vbr);
600 g_value_set_float (value, twolame->vbr_level);
603 g_value_set_float (value, twolame->ath_level);
605 case ARG_VBR_MAX_BITRATE:
606 g_value_set_int (value, twolame->vbr_max_bitrate);
609 g_value_set_boolean (value, twolame->quick_mode);
611 case ARG_QUICK_MODE_COUNT:
612 g_value_set_int (value, twolame->quick_mode_count);
615 G_OBJECT_WARN_INVALID_PROPERTY_ID (object, prop_id, pspec);
621 gst_two_lame_flush_full (GstTwoLame * lame, gboolean push)
626 GstFlowReturn result = GST_FLOW_OK;
631 buf = gst_buffer_new_and_alloc (16384);
632 gst_buffer_map (buf, &map, GST_MAP_WRITE);
633 size = twolame_encode_flush (lame->glopts, map.data, 16384);
634 gst_buffer_unmap (buf, &map);
636 if (size > 0 && push) {
637 gst_buffer_set_size (buf, size);
638 GST_DEBUG_OBJECT (lame, "pushing final packet of %u bytes", size);
639 result = gst_audio_encoder_finish_frame (GST_AUDIO_ENCODER (lame), buf, -1);
641 GST_DEBUG_OBJECT (lame, "no final packet (size=%d, push=%d)", size, push);
642 gst_buffer_unref (buf);
643 result = GST_FLOW_OK;
649 gst_two_lame_flush (GstAudioEncoder * enc)
651 gst_two_lame_flush_full (GST_TWO_LAME (enc), FALSE);
655 gst_two_lame_handle_frame (GstAudioEncoder * enc, GstBuffer * buf)
658 gint mp3_buffer_size, mp3_size;
660 GstFlowReturn result;
662 GstMapInfo map, mp3_map;
664 twolame = GST_TWO_LAME (enc);
666 /* squeeze remaining and push */
667 if (G_UNLIKELY (buf == NULL))
668 return gst_two_lame_flush_full (twolame, TRUE);
670 gst_buffer_map (buf, &map, GST_MAP_READ);
672 if (twolame->float_input)
673 num_samples = map.size / 4;
675 num_samples = map.size / 2;
677 /* allocate space for output */
678 mp3_buffer_size = 1.25 * num_samples + 16384;
679 mp3_buf = gst_buffer_new_and_alloc (mp3_buffer_size);
680 gst_buffer_map (mp3_buf, &mp3_map, GST_MAP_WRITE);
682 if (twolame->num_channels == 1) {
683 if (twolame->float_input)
684 mp3_size = twolame_encode_buffer_float32 (twolame->glopts,
686 (float *) map.data, num_samples, mp3_map.data, mp3_buffer_size);
688 mp3_size = twolame_encode_buffer (twolame->glopts,
689 (short int *) map.data,
690 (short int *) map.data, num_samples, mp3_map.data, mp3_buffer_size);
692 if (twolame->float_input)
693 mp3_size = twolame_encode_buffer_float32_interleaved (twolame->glopts,
695 num_samples / twolame->num_channels, mp3_map.data, mp3_buffer_size);
697 mp3_size = twolame_encode_buffer_interleaved (twolame->glopts,
698 (short int *) map.data,
699 num_samples / twolame->num_channels, mp3_map.data, mp3_buffer_size);
702 GST_LOG_OBJECT (twolame, "encoded %" G_GSIZE_FORMAT " bytes of audio "
703 "to %d bytes of mp3", map.size, mp3_size);
705 gst_buffer_unmap (buf, &map);
706 gst_buffer_unmap (mp3_buf, &mp3_map);
709 gst_buffer_set_size (mp3_buf, mp3_size);
710 result = gst_audio_encoder_finish_frame (enc, mp3_buf, -1);
714 g_warning ("error %d", mp3_size);
716 gst_buffer_unref (mp3_buf);
717 result = GST_FLOW_OK;
723 /* set up the encoder state */
725 gst_two_lame_setup (GstTwoLame * twolame)
728 #define CHECK_ERROR(command) G_STMT_START {\
729 if ((command) < 0) { \
730 GST_ERROR_OBJECT (twolame, "setup failed: " G_STRINGIFY (command)); \
736 GstCaps *allowed_caps;
738 GST_DEBUG_OBJECT (twolame, "starting setup");
740 /* check if we're already setup; if we are, we might want to check
741 * if this initialization is compatible with the previous one */
743 if (twolame->setup) {
744 GST_WARNING_OBJECT (twolame, "already setup");
745 twolame->setup = FALSE;
748 twolame->glopts = twolame_init ();
750 if (twolame->glopts == NULL)
753 /* copy the parameters over */
754 twolame_set_in_samplerate (twolame->glopts, twolame->samplerate);
756 /* let twolame choose default samplerate unless outgoing sample rate is fixed */
757 allowed_caps = gst_pad_get_allowed_caps (GST_AUDIO_ENCODER_SRC_PAD (twolame));
759 if (allowed_caps != NULL) {
760 GstStructure *structure;
763 structure = gst_caps_get_structure (allowed_caps, 0);
765 if (gst_structure_get_int (structure, "rate", &samplerate)) {
766 GST_DEBUG_OBJECT (twolame,
767 "Setting sample rate to %d as fixed in src caps", samplerate);
768 twolame_set_out_samplerate (twolame->glopts, samplerate);
770 GST_DEBUG_OBJECT (twolame, "Letting twolame choose sample rate");
771 twolame_set_out_samplerate (twolame->glopts, 0);
773 gst_caps_unref (allowed_caps);
776 GST_DEBUG_OBJECT (twolame,
777 "No peer yet, letting twolame choose sample rate");
778 twolame_set_out_samplerate (twolame->glopts, 0);
781 /* force mono encoding if we only have one channel */
782 if (twolame->num_channels == 1)
785 /* Fix bitrates and MPEG version */
787 CHECK_ERROR (twolame_set_num_channels (twolame->glopts,
788 twolame->num_channels));
790 CHECK_ERROR (twolame_set_mode (twolame->glopts, twolame->mode));
791 CHECK_ERROR (twolame_set_psymodel (twolame->glopts, twolame->psymodel));
792 CHECK_AND_FIXUP_BITRATE (twolame, "bitrate", twolame->bitrate);
793 CHECK_ERROR (twolame_set_bitrate (twolame->glopts, twolame->bitrate));
794 CHECK_ERROR (twolame_set_padding (twolame->glopts, twolame->padding));
795 CHECK_ERROR (twolame_set_energy_levels (twolame->glopts,
796 twolame->energy_level_extension));
797 CHECK_ERROR (twolame_set_emphasis (twolame->glopts, twolame->emphasis));
798 CHECK_ERROR (twolame_set_error_protection (twolame->glopts,
799 twolame->error_protection));
800 CHECK_ERROR (twolame_set_copyright (twolame->glopts, twolame->copyright));
801 CHECK_ERROR (twolame_set_original (twolame->glopts, twolame->original));
802 CHECK_ERROR (twolame_set_VBR (twolame->glopts, twolame->vbr));
803 CHECK_ERROR (twolame_set_VBR_level (twolame->glopts, twolame->vbr_level));
804 CHECK_ERROR (twolame_set_ATH_level (twolame->glopts, twolame->ath_level));
805 CHECK_AND_FIXUP_BITRATE (twolame, "vbr-max-bitrate",
806 twolame->vbr_max_bitrate);
807 CHECK_ERROR (twolame_set_VBR_max_bitrate_kbps (twolame->glopts,
808 twolame->vbr_max_bitrate));
809 CHECK_ERROR (twolame_set_quick_mode (twolame->glopts, twolame->quick_mode));
810 CHECK_ERROR (twolame_set_quick_count (twolame->glopts,
811 twolame->quick_mode_count));
813 /* initialize the twolame encoder */
814 if ((retval = twolame_init_params (twolame->glopts)) >= 0) {
815 twolame->setup = TRUE;
816 /* FIXME: it would be nice to print out the mode here */
817 GST_INFO ("twolame encoder setup (%d kbit/s, %d Hz, %d channels)",
818 twolame->bitrate, twolame->samplerate, twolame->num_channels);
820 GST_ERROR_OBJECT (twolame, "twolame_init_params returned %d", retval);
823 GST_DEBUG_OBJECT (twolame, "done with setup");
825 return twolame->setup;
830 gst_two_lame_get_default_settings (void)
832 twolame_options *glopts = NULL;
834 glopts = twolame_init ();
835 if (glopts == NULL) {
836 GST_ERROR ("Couldn't initialize TwoLAME");
840 twolame_set_num_channels (glopts, 2);
841 twolame_set_in_samplerate (glopts, 44100);
843 if (twolame_init_params (glopts) != 0) {
844 GST_ERROR ("Couldn't set default parameters");
848 gst_two_lame_default_settings.mode = TWOLAME_JOINT_STEREO; /* twolame_get_mode (glopts); */
849 gst_two_lame_default_settings.psymodel = twolame_get_psymodel (glopts);
850 gst_two_lame_default_settings.bitrate = twolame_get_bitrate (glopts);
851 gst_two_lame_default_settings.padding = twolame_get_padding (glopts);
852 gst_two_lame_default_settings.energy_level_extension =
853 twolame_get_energy_levels (glopts);
854 gst_two_lame_default_settings.emphasis = twolame_get_emphasis (glopts);
855 gst_two_lame_default_settings.error_protection =
856 twolame_get_error_protection (glopts);
857 gst_two_lame_default_settings.copyright = twolame_get_copyright (glopts);
858 gst_two_lame_default_settings.original = twolame_get_original (glopts);
859 gst_two_lame_default_settings.vbr = twolame_get_VBR (glopts);
860 gst_two_lame_default_settings.vbr_level = twolame_get_VBR_level (glopts);
861 gst_two_lame_default_settings.ath_level = twolame_get_ATH_level (glopts);
862 gst_two_lame_default_settings.vbr_max_bitrate =
863 twolame_get_VBR_max_bitrate_kbps (glopts);
864 gst_two_lame_default_settings.quick_mode = twolame_get_quick_mode (glopts);
865 gst_two_lame_default_settings.quick_mode_count =
866 twolame_get_quick_count (glopts);
868 twolame_close (&glopts);
874 two_lame_element_init (void)
876 GST_DEBUG_CATEGORY_INIT (debug, "twolame", 0, "twolame mp2 encoder");
878 if (!gst_two_lame_get_default_settings ())
882 GST_DEBUG ("binding text domain %s to locale dir %s", GETTEXT_PACKAGE,
884 bindtextdomain (GETTEXT_PACKAGE, LOCALEDIR);
885 bind_textdomain_codeset (GETTEXT_PACKAGE, "UTF-8");
886 #endif /* ENABLE_NLS */
891 plugin_init (GstPlugin * plugin)
893 return GST_ELEMENT_REGISTER (twolamemp2enc, plugin);
896 GST_PLUGIN_DEFINE (GST_VERSION_MAJOR,
899 "Encode MP2s with TwoLAME",
900 plugin_init, VERSION, "LGPL", GST_PACKAGE_NAME, GST_PACKAGE_ORIGIN);