diff options
Diffstat (limited to 'ext/flite')
-rw-r--r-- | ext/flite/gstflitetestsrc.c | 180 |
1 files changed, 136 insertions, 44 deletions
diff --git a/ext/flite/gstflitetestsrc.c b/ext/flite/gstflitetestsrc.c index 716d73601..1e3381c7f 100644 --- a/ext/flite/gstflitetestsrc.c +++ b/ext/flite/gstflitetestsrc.c @@ -25,7 +25,7 @@ #include <gst/gst.h> #include <gst/base/gstbasesrc.h> #include <gst/base/gstadapter.h> -#include <gst/audio/multichannel.h> +#include <gst/audio/audio.h> #include <flite/flite.h> @@ -49,9 +49,7 @@ struct _GstFliteTestSrc GstAdapter *adapter; - int samplerate; - int n_channels; - GstAudioChannelPosition *layout; + GstAudioInfo info; int samples_per_buffer; @@ -88,7 +86,8 @@ GST_STATIC_PAD_TEMPLATE ("src", GST_PAD_ALWAYS, GST_STATIC_CAPS ("audio/x-raw, " "format = (string) " GST_AUDIO_NE (s16) ", " - "rate = (int) 48000, " "channels = (int) [1,8]") + "layout = (string) interleaved, " + "rate = (int) 48000, " "channels = (int) [1, 8]") ); #define gst_flite_test_src_parent_class parent_class @@ -105,6 +104,7 @@ static GstFlowReturn gst_flite_test_src_create (GstBaseSrc * basesrc, guint64 offset, guint length, GstBuffer ** buffer); static gboolean gst_flite_test_src_set_caps (GstBaseSrc * basesrc, GstCaps * caps); +static void gst_flite_test_src_fixate (GstBaseSrc * bsrc, GstCaps * caps); static void gst_flite_test_src_class_init (GstFliteTestSrcClass * klass) @@ -138,6 +138,7 @@ gst_flite_test_src_class_init (GstFliteTestSrcClass * klass) gstbasesrc_class->stop = GST_DEBUG_FUNCPTR (gst_flite_test_src_stop); gstbasesrc_class->create = GST_DEBUG_FUNCPTR (gst_flite_test_src_create); gstbasesrc_class->set_caps = GST_DEBUG_FUNCPTR (gst_flite_test_src_set_caps); + gstbasesrc_class->fixate = GST_DEBUG_FUNCPTR (gst_flite_test_src_fixate); GST_DEBUG_CATEGORY_INIT (flite_test_src_debug, "flitetestsrc", 0, "Flite Audio Test Source"); @@ -146,7 +147,6 @@ gst_flite_test_src_class_init (GstFliteTestSrcClass * klass) static void gst_flite_test_src_init (GstFliteTestSrc * src) { - src->samplerate = 48000; src->samples_per_buffer = DEFAULT_SAMPLES_PER_BUFFER; /* we operate in time */ @@ -155,39 +155,126 @@ gst_flite_test_src_init (GstFliteTestSrc * src) gst_base_src_set_blocksize (GST_BASE_SRC (src), -1); } -static gboolean -gst_flite_test_src_set_caps (GstBaseSrc * basesrc, GstCaps * caps) +static gint +n_bits_set (guint64 x) +{ + gint i; + gint c = 0; + guint64 y = 1; + + for (i = 0; i < 64; i++) { + if (x & y) + c++; + y <<= 1; + } + + return c; +} + +static void +gst_flite_test_src_fixate (GstBaseSrc * bsrc, GstCaps * caps) { - GstFliteTestSrc *src = GST_FLITE_TEST_SRC (basesrc); GstStructure *structure; - gboolean ret; + gint channels; structure = gst_caps_get_structure (caps, 0); - ret = gst_structure_get_int (structure, "channels", &src->n_channels); - - g_free (src->layout); + gst_structure_fixate_field_nearest_int (structure, "channels", 2); + gst_structure_get_int (structure, "channels", &channels); - if (src->n_channels < 3) { - src->layout = g_malloc (sizeof (GstAudioChannelPosition) * 2); - if (src->n_channels == 1) { - src->layout[0] = GST_AUDIO_CHANNEL_POSITION_FRONT_MONO; - } else { - src->layout[0] = GST_AUDIO_CHANNEL_POSITION_FRONT_LEFT; - src->layout[1] = GST_AUDIO_CHANNEL_POSITION_FRONT_RIGHT; - } + if (channels == 1) { + gst_structure_remove_field (structure, "channel-mask"); } else { - src->layout = gst_audio_get_channel_positions (structure); - if (src->layout == NULL) { - /* thanks, libgstaudio, for returning us NULL instead of - * doing this yourself. */ - int i; - src->layout = - g_malloc (sizeof (GstAudioChannelPosition) * src->n_channels); - for (i = 0; i < src->n_channels; i++) { - src->layout[i] = GST_AUDIO_CHANNEL_POSITION_NONE; + guint64 channel_mask = 0; + gint x = 64; + + if (!gst_structure_get (structure, "channel-mask", GST_TYPE_BITMASK, + &channel_mask, NULL)) { + switch (channels) { + case 8: + channel_mask = + GST_AUDIO_CHANNEL_POSITION_MASK (FRONT_LEFT) | + GST_AUDIO_CHANNEL_POSITION_MASK (FRONT_RIGHT) | + GST_AUDIO_CHANNEL_POSITION_MASK (REAR_LEFT) | + GST_AUDIO_CHANNEL_POSITION_MASK (REAR_RIGHT) | + GST_AUDIO_CHANNEL_POSITION_MASK (FRONT_CENTER) | + GST_AUDIO_CHANNEL_POSITION_MASK (LFE1) | + GST_AUDIO_CHANNEL_POSITION_MASK (SIDE_LEFT) | + GST_AUDIO_CHANNEL_POSITION_MASK (SIDE_RIGHT); + break; + case 7: + channel_mask = + GST_AUDIO_CHANNEL_POSITION_MASK (FRONT_LEFT) | + GST_AUDIO_CHANNEL_POSITION_MASK (FRONT_RIGHT) | + GST_AUDIO_CHANNEL_POSITION_MASK (REAR_LEFT) | + GST_AUDIO_CHANNEL_POSITION_MASK (REAR_RIGHT) | + GST_AUDIO_CHANNEL_POSITION_MASK (FRONT_CENTER) | + GST_AUDIO_CHANNEL_POSITION_MASK (LFE1) | + GST_AUDIO_CHANNEL_POSITION_MASK (REAR_CENTER); + break; + case 6: + channel_mask = + GST_AUDIO_CHANNEL_POSITION_MASK (FRONT_LEFT) | + GST_AUDIO_CHANNEL_POSITION_MASK (FRONT_RIGHT) | + GST_AUDIO_CHANNEL_POSITION_MASK (REAR_LEFT) | + GST_AUDIO_CHANNEL_POSITION_MASK (REAR_RIGHT) | + GST_AUDIO_CHANNEL_POSITION_MASK (FRONT_CENTER) | + GST_AUDIO_CHANNEL_POSITION_MASK (LFE1); + break; + case 5: + channel_mask = + GST_AUDIO_CHANNEL_POSITION_MASK (FRONT_LEFT) | + GST_AUDIO_CHANNEL_POSITION_MASK (FRONT_RIGHT) | + GST_AUDIO_CHANNEL_POSITION_MASK (REAR_LEFT) | + GST_AUDIO_CHANNEL_POSITION_MASK (REAR_RIGHT) | + GST_AUDIO_CHANNEL_POSITION_MASK (FRONT_CENTER); + break; + case 4: + channel_mask = + GST_AUDIO_CHANNEL_POSITION_MASK (FRONT_LEFT) | + GST_AUDIO_CHANNEL_POSITION_MASK (FRONT_RIGHT) | + GST_AUDIO_CHANNEL_POSITION_MASK (REAR_LEFT) | + GST_AUDIO_CHANNEL_POSITION_MASK (REAR_RIGHT); + break; + case 3: + channel_mask = + GST_AUDIO_CHANNEL_POSITION_MASK (FRONT_LEFT) | + GST_AUDIO_CHANNEL_POSITION_MASK (FRONT_RIGHT) | + GST_AUDIO_CHANNEL_POSITION_MASK (LFE1); + break; + case 2: + channel_mask = + GST_AUDIO_CHANNEL_POSITION_MASK (FRONT_LEFT) | + GST_AUDIO_CHANNEL_POSITION_MASK (FRONT_RIGHT); + break; + default: + channel_mask = 0; + break; } } + + while (n_bits_set (channel_mask) > channels) { + channel_mask &= ~(G_GUINT64_CONSTANT (1) << x); + x--; + } + + gst_structure_set (structure, "channel-mask", GST_TYPE_BITMASK, + channel_mask, NULL); + } + + GST_BASE_SRC_CLASS (parent_class)->fixate (bsrc, caps); +} + +static gboolean +gst_flite_test_src_set_caps (GstBaseSrc * basesrc, GstCaps * caps) +{ + GstFliteTestSrc *src = GST_FLITE_TEST_SRC (basesrc); + gboolean ret; + + gst_audio_info_init (&src->info); + if (!gst_audio_info_from_caps (&src->info, caps)) { + GST_ERROR_OBJECT (src, "Invalid caps"); + return FALSE; } return ret; @@ -298,7 +385,6 @@ gst_flite_test_src_start (GstBaseSrc * basesrc) src->adapter = gst_adapter_new (); src->voice = register_cmu_us_kal (); - src->n_channels = 2; return TRUE; } @@ -320,19 +406,25 @@ get_channel_name (GstFliteTestSrc * src, int channel) "zero", "one", "two", "three", "four", "five", "six", "seven", "eight", "nine" }; - const char *names[GST_AUDIO_CHANNEL_POSITION_NUM] = { - "mono", "front left", "front right", "rear center", - "rear left", "rear right", "low frequency effects", - "front center", "front left center", "front right center", - "side left", "side right", - "none" + const char *names[64] = { + "front left", "front right", "front center", "lfe 1", "rear left", + "rear right", "front left of center", "front right of center", + "rear center", "lfe 2", "side left", "side right", "top front left", + "top front right", "top front center", "top center", "top rear left", + "top rear right", "top side left", "top side right", "top rear center", + "bottom front center", "bottom front left", "bottom front right", + "wide left", "wide right", "surround left", "surround right" }; const char *name; - if (src->layout[channel] == GST_AUDIO_CHANNEL_POSITION_INVALID) { + if (src->info.position[channel] == GST_AUDIO_CHANNEL_POSITION_INVALID) { name = "invalid"; + } else if (src->info.position[channel] == GST_AUDIO_CHANNEL_POSITION_NONE) { + name = "none"; + } else if (src->info.position[channel] == GST_AUDIO_CHANNEL_POSITION_MONO) { + name = "mono"; } else { - name = names[src->layout[channel]]; + name = names[src->info.position[channel]]; } return g_strdup_printf ("%s, %s", numbers[channel], name); @@ -347,7 +439,7 @@ gst_flite_test_src_create (GstBaseSrc * basesrc, guint64 offset, src = GST_FLITE_TEST_SRC (basesrc); - n_bytes = src->n_channels * sizeof (gint16) * src->samples_per_buffer; + n_bytes = src->info.channels * sizeof (gint16) * src->samples_per_buffer; while (gst_adapter_available (src->adapter) < n_bytes) { GstBuffer *buf; @@ -361,23 +453,23 @@ gst_flite_test_src_create (GstBaseSrc * basesrc, guint64 offset, wave = flite_text_to_wave (text, src->voice); g_free (text); - cst_wave_resample (wave, 48000); + cst_wave_resample (wave, src->info.rate); GST_DEBUG ("type %s, sample_rate %d, num_samples %d, num_channels %d", wave->type, wave->sample_rate, wave->num_samples, wave->num_channels); - size = src->n_channels * sizeof (gint16) * wave->num_samples; + size = src->info.channels * sizeof (gint16) * wave->num_samples; buf = gst_buffer_new_and_alloc (size); data = gst_buffer_map (buf, NULL, NULL, GST_MAP_WRITE); memset (data, 0, size); for (i = 0; i < wave->num_samples; i++) { - data[i * src->n_channels + src->channel] = wave->samples[i]; + data[i * src->info.channels + src->channel] = wave->samples[i]; } gst_buffer_unmap (buf, data, size); src->channel++; - if (src->channel == src->n_channels) { + if (src->channel == src->info.channels) { src->channel = 0; } |