#include <gst/gst.h>
#include <gst/base/gstbasetransform.h>
+#ifdef HAVE_ORC
+#include <orc/orcfunctions.h>
+#else
+#define orc_memset memset
+#endif
+
#include "audiopanorama.h"
+#include "audiopanoramaorc.h"
#define GST_CAT_DEFAULT gst_audio_panorama_debug
GST_DEBUG_CATEGORY_STATIC (GST_CAT_DEFAULT);
static gboolean gst_audio_panorama_set_caps (GstBaseTransform * base,
GstCaps * incaps, GstCaps * outcaps);
-static void gst_audio_panorama_transform_m2s_int (GstAudioPanorama * filter,
+static void gst_audio_panorama_m2s_int (gfloat pan,
gint16 * idata, gint16 * odata, guint num_samples);
-static void gst_audio_panorama_transform_s2s_int (GstAudioPanorama * filter,
+static void gst_audio_panorama_s2s_int (gfloat pan,
gint16 * idata, gint16 * odata, guint num_samples);
-static void gst_audio_panorama_transform_m2s_float (GstAudioPanorama * filter,
+static void gst_audio_panorama_m2s_float (gfloat pan,
gfloat * idata, gfloat * odata, guint num_samples);
-static void gst_audio_panorama_transform_s2s_float (GstAudioPanorama * filter,
+static void gst_audio_panorama_s2s_float (gfloat pan,
gfloat * idata, gfloat * odata, guint num_samples);
-static void gst_audio_panorama_transform_m2s_int_simple (GstAudioPanorama *
- filter, gint16 * idata, gint16 * odata, guint num_samples);
-static void gst_audio_panorama_transform_s2s_int_simple (GstAudioPanorama *
- filter, gint16 * idata, gint16 * odata, guint num_samples);
-static void gst_audio_panorama_transform_m2s_float_simple (GstAudioPanorama *
- filter, gfloat * idata, gfloat * odata, guint num_samples);
-static void gst_audio_panorama_transform_s2s_float_simple (GstAudioPanorama *
- filter, gfloat * idata, gfloat * odata, guint num_samples);
+static void gst_audio_panorama_m2s_int_simple (gfloat pan,
+ gint16 * idata, gint16 * odata, guint num_samples);
+static void gst_audio_panorama_s2s_int_simple (gfloat pan,
+ gint16 * idata, gint16 * odata, guint num_samples);
+static void gst_audio_panorama_m2s_float_simple (gfloat pan,
+ gfloat * idata, gfloat * odata, guint num_samples);
+static void gst_audio_panorama_s2s_float_simple (gfloat pan,
+ gfloat * idata, gfloat * odata, guint num_samples);
static GstFlowReturn gst_audio_panorama_transform (GstBaseTransform * base,
GstBuffer * inbuf, GstBuffer * outbuf);
/* Table with processing functions: [channels][format][method] */
static GstAudioPanoramaProcessFunc panorama_process_functions[2][2][2] = {
{
- {(GstAudioPanoramaProcessFunc) gst_audio_panorama_transform_m2s_int,
- (GstAudioPanoramaProcessFunc)
- gst_audio_panorama_transform_m2s_int_simple},
- {(GstAudioPanoramaProcessFunc) gst_audio_panorama_transform_m2s_float,
- (GstAudioPanoramaProcessFunc)
- gst_audio_panorama_transform_m2s_float_simple}
+ {
+ (GstAudioPanoramaProcessFunc) gst_audio_panorama_m2s_int,
+ (GstAudioPanoramaProcessFunc) gst_audio_panorama_m2s_int_simple},
+ {
+ (GstAudioPanoramaProcessFunc) gst_audio_panorama_m2s_float,
+ (GstAudioPanoramaProcessFunc) gst_audio_panorama_m2s_float_simple}
},
{
- {(GstAudioPanoramaProcessFunc) gst_audio_panorama_transform_s2s_int,
- (GstAudioPanoramaProcessFunc)
- gst_audio_panorama_transform_s2s_int_simple},
- {(GstAudioPanoramaProcessFunc) gst_audio_panorama_transform_s2s_float,
- (GstAudioPanoramaProcessFunc)
- gst_audio_panorama_transform_s2s_float_simple}
+ {
+ (GstAudioPanoramaProcessFunc) gst_audio_panorama_s2s_int,
+ (GstAudioPanoramaProcessFunc) gst_audio_panorama_s2s_int_simple},
+ {
+ (GstAudioPanoramaProcessFunc) gst_audio_panorama_s2s_float,
+ (GstAudioPanoramaProcessFunc) gst_audio_panorama_s2s_float_simple}
}
};
}
/* psychoacoustic processing functions */
+
+/* mono to stereo panning
+ * pan: -1.0 0.0 1.0
+ * l: 1.0 0.5 0.0
+ * r: 0.0 0.5 1.0
+ *
+ * FIXME: we should use -3db (1/sqtr(2)) for 50:50
+ */
static void
-gst_audio_panorama_transform_m2s_int (GstAudioPanorama * filter, gint16 * idata,
- gint16 * odata, guint num_samples)
+gst_audio_panorama_m2s_int (gfloat pan, gint16 * idata, gint16 * odata, guint n)
{
- guint i;
- gdouble val;
- glong lval, rval;
- gdouble rpan, lpan;
-
- /* pan: -1.0 0.0 1.0
- * lpan: 1.0 0.5 0.0
- * rpan: 0.0 0.5 1.0
- *
- * FIXME: we should use -3db (1/sqtr(2)) for 50:50
- */
- rpan = (gdouble) (filter->panorama + 1.0) / 2.0;
- lpan = 1.0 - rpan;
-
- for (i = 0; i < num_samples; i++) {
- val = (gdouble) * idata++;
-
- lval = (glong) (val * lpan);
- rval = (glong) (val * rpan);
-
- *odata++ = (gint16) CLAMP (lval, G_MININT16, G_MAXINT16);
- *odata++ = (gint16) CLAMP (rval, G_MININT16, G_MAXINT16);
- }
+ gfloat r = (pan + 1.0) / 2.0;
+ audiopanoramam_orc_process_s16_ch1_psy (odata, idata, 1.0 - r, r, n);
}
static void
-gst_audio_panorama_transform_s2s_int (GstAudioPanorama * filter, gint16 * idata,
- gint16 * odata, guint num_samples)
+gst_audio_panorama_m2s_float (gfloat pan, gfloat * idata,
+ gfloat * odata, guint n)
{
- guint i;
- glong lval, rval;
- gdouble lival, rival;
- gdouble lrpan, llpan, rrpan, rlpan;
-
- /* pan: -1.0 0.0 1.0
- * llpan: 1.0 1.0 0.0
- * lrpan: 1.0 0.0 0.0
- * rrpan: 0.0 1.0 1.0
- * rlpan: 0.0 0.0 1.0
- */
- if (filter->panorama > 0) {
- rlpan = (gdouble) filter->panorama;
- llpan = 1.0 - rlpan;
- lrpan = 0.0;
- rrpan = 1.0;
- } else {
- rrpan = (gdouble) (1.0 + filter->panorama);
- lrpan = 1.0 - rrpan;
- rlpan = 0.0;
- llpan = 1.0;
- }
-
- for (i = 0; i < num_samples; i++) {
- lival = (gdouble) * idata++;
- rival = (gdouble) * idata++;
-
- lval = lival * llpan + rival * lrpan;
- rval = lival * rlpan + rival * rrpan;
-
- *odata++ = (gint16) CLAMP (lval, G_MININT16, G_MAXINT16);
- *odata++ = (gint16) CLAMP (rval, G_MININT16, G_MAXINT16);
- }
+ gfloat r = (pan + 1.0) / 2.0;
+ audiopanoramam_orc_process_f32_ch1_psy (odata, idata, 1.0 - r, r, n);
}
+/* stereo balance
+ * pan: -1.0 0.0 1.0
+ * ll: 1.0 1.0 0.0
+ * lr: 1.0 0.0 0.0
+ * rr: 0.0 1.0 1.0
+ * rl: 0.0 0.0 1.0
+ */
static void
-gst_audio_panorama_transform_m2s_float (GstAudioPanorama * filter,
- gfloat * idata, gfloat * odata, guint num_samples)
+gst_audio_panorama_s2s_int (gfloat pan, gint16 * idata, gint16 * odata, guint n)
{
- guint i;
- gfloat val;
- gdouble rpan, lpan;
-
- /* pan: -1.0 0.0 1.0
- * lpan: 1.0 0.5 0.0
- * rpan: 0.0 0.5 1.0
- *
- * FIXME: we should use -3db (1/sqtr(2)) for 50:50
- */
- rpan = (gdouble) (filter->panorama + 1.0) / 2.0;
- lpan = 1.0 - rpan;
-
- for (i = 0; i < num_samples; i++) {
- val = *idata++;
-
- *odata++ = val * lpan;
- *odata++ = val * rpan;
+ if (pan == 0.0) {
+ audiopanoramam_orc_process_s16_ch2_none (odata, idata, n);
+ } else if (pan > 0.0) {
+ gfloat rl = pan;
+ gfloat ll = 1.0 - rl;
+ audiopanoramam_orc_process_s16_ch2_psy_right (odata, idata, ll, rl, n);
+ } else {
+ gfloat rr = 1.0 + pan;
+ gfloat lr = 1.0 - rr;
+ audiopanoramam_orc_process_s16_ch2_psy_left (odata, idata, lr, rr, n);
}
}
static void
-gst_audio_panorama_transform_s2s_float (GstAudioPanorama * filter,
- gfloat * idata, gfloat * odata, guint num_samples)
+gst_audio_panorama_s2s_float (gfloat pan, gfloat * idata,
+ gfloat * odata, guint n)
{
- guint i;
- gfloat lival, rival;
- gdouble lrpan, llpan, rrpan, rlpan;
-
- /* pan: -1.0 0.0 1.0
- * llpan: 1.0 1.0 0.0
- * lrpan: 1.0 0.0 0.0
- * rrpan: 0.0 1.0 1.0
- * rlpan: 0.0 0.0 1.0
- */
- if (filter->panorama > 0) {
- rlpan = (gdouble) filter->panorama;
- llpan = 1.0 - rlpan;
- lrpan = 0.0;
- rrpan = 1.0;
+ if (pan == 0.0) {
+ audiopanoramam_orc_process_f32_ch2_none (odata, idata, n);
+ } else if (pan > 0.0) {
+ gfloat rl = pan;
+ gfloat ll = 1.0 - rl;
+ audiopanoramam_orc_process_f32_ch2_psy_right (odata, idata, ll, rl, n);
} else {
- rrpan = (gdouble) (1.0 + filter->panorama);
- lrpan = 1.0 - rrpan;
- rlpan = 0.0;
- llpan = 1.0;
- }
-
- for (i = 0; i < num_samples; i++) {
- lival = *idata++;
- rival = *idata++;
-
- *odata++ = lival * llpan + rival * lrpan;
- *odata++ = lival * rlpan + rival * rrpan;
+ gfloat rr = 1.0 + pan;
+ gfloat lr = 1.0 - rr;
+ audiopanoramam_orc_process_f32_ch2_psy_left (odata, idata, lr, rr, n);
}
}
/* simple processing functions */
+
static void
-gst_audio_panorama_transform_m2s_int_simple (GstAudioPanorama * filter,
- gint16 * idata, gint16 * odata, guint num_samples)
+gst_audio_panorama_m2s_int_simple (gfloat pan, gint16 * idata,
+ gint16 * odata, guint n)
{
- guint i;
- gdouble pan;
- glong lval, rval;
-
- if (filter->panorama > 0.0) {
- pan = 1.0 - filter->panorama;
- for (i = 0; i < num_samples; i++) {
- rval = *idata++;
- lval = (glong) ((gdouble) rval * pan);
-
- *odata++ = (gint16) CLAMP (lval, G_MININT16, G_MAXINT16);
- *odata++ = (gint16) rval;
- }
+ if (pan == 0.0) {
+ audiopanoramam_orc_process_s16_ch1_none (odata, idata, n);
+ } else if (pan > 0.0) {
+ gfloat lpan = 1.0 - pan;
+ audiopanoramam_orc_process_s16_ch1_sim_left (odata, idata, lpan, n);
} else {
- pan = 1.0 + filter->panorama;
- for (i = 0; i < num_samples; i++) {
- lval = *idata++;
- rval = (glong) ((gdouble) lval * pan);
-
- *odata++ = (gint16) lval;
- *odata++ = (gint16) CLAMP (rval, G_MININT16, G_MAXINT16);
- }
+ gfloat rpan = 1.0 + pan;
+ audiopanoramam_orc_process_s16_ch1_sim_right (odata, idata, rpan, n);
}
}
static void
-gst_audio_panorama_transform_s2s_int_simple (GstAudioPanorama * filter,
- gint16 * idata, gint16 * odata, guint num_samples)
+gst_audio_panorama_s2s_int_simple (gfloat pan, gint16 * idata,
+ gint16 * odata, guint n)
{
- guint i;
- glong lval, rval;
- gdouble lival, rival, pan;
-
- if (filter->panorama > 0.0) {
- pan = 1.0 - filter->panorama;
- for (i = 0; i < num_samples; i++) {
- lival = (gdouble) * idata++;
- rival = (gdouble) * idata++;
-
- lval = (glong) (lival * pan);
- rval = (glong) rival;
-
- *odata++ = (gint16) CLAMP (lval, G_MININT16, G_MAXINT16);
- *odata++ = (gint16) rval;
- }
+ if (pan == 0.0) {
+ audiopanoramam_orc_process_s16_ch2_none (odata, idata, n);
+ } else if (pan > 0.0) {
+ gfloat lpan = 1.0 - pan;
+ audiopanoramam_orc_process_s16_ch2_sim_left (odata, idata, lpan, n);
} else {
- pan = 1.0 + filter->panorama;
- for (i = 0; i < num_samples; i++) {
- lival = (gdouble) * idata++;
- rival = (gdouble) * idata++;
-
- lval = (glong) lival;
- rval = (glong) (rival * pan);
-
- *odata++ = (gint16) lval;
- *odata++ = (gint16) CLAMP (rval, G_MININT16, G_MAXINT16);
- }
+ gfloat rpan = 1.0 + pan;
+ audiopanoramam_orc_process_s16_ch2_sim_right (odata, idata, rpan, n);
}
}
static void
-gst_audio_panorama_transform_m2s_float_simple (GstAudioPanorama * filter,
- gfloat * idata, gfloat * odata, guint num_samples)
+gst_audio_panorama_m2s_float_simple (gfloat pan, gfloat * idata,
+ gfloat * odata, guint n)
{
- guint i;
- gfloat val, pan;
-
- if (filter->panorama > 0.0) {
- pan = 1.0 - filter->panorama;
- for (i = 0; i < num_samples; i++) {
- val = *idata++;
-
- *odata++ = val * pan;
- *odata++ = val;
- }
+ if (pan == 0.0) {
+ audiopanoramam_orc_process_f32_ch1_none (odata, idata, n);
+ } else if (pan > 0.0) {
+ gfloat lpan = 1.0 - pan;
+ audiopanoramam_orc_process_f32_ch1_sim_left (odata, idata, lpan, n);
} else {
- pan = 1.0 + filter->panorama;
- for (i = 0; i < num_samples; i++) {
- val = *idata++;
-
- *odata++ = val;
- *odata++ = val * pan;
- }
+ gfloat rpan = 1.0 + pan;
+ audiopanoramam_orc_process_f32_ch1_sim_right (odata, idata, rpan, n);
}
}
static void
-gst_audio_panorama_transform_s2s_float_simple (GstAudioPanorama * filter,
- gfloat * idata, gfloat * odata, guint num_samples)
+gst_audio_panorama_s2s_float_simple (gfloat pan, gfloat * idata,
+ gfloat * odata, guint n)
{
- guint i;
- gfloat lival, rival, pan;
-
- if (filter->panorama > 0.0) {
- pan = 1.0 - filter->panorama;
- for (i = 0; i < num_samples; i++) {
- lival = *idata++;
- rival = *idata++;
-
- *odata++ = lival * pan;
- *odata++ = rival;
- }
+ if (pan == 0.0) {
+ audiopanoramam_orc_process_f32_ch2_none (odata, idata, n);
+ } else if (pan > 0.0) {
+ gfloat lpan = 1.0 - pan;
+ audiopanoramam_orc_process_f32_ch2_sim_left (odata, idata, lpan, n);
} else {
- pan = 1.0 + filter->panorama;
- for (i = 0; i < num_samples; i++) {
- lival = *idata++;
- rival = *idata++;
-
- *odata++ = lival;
- *odata++ = rival * pan;
- }
+ gfloat rpan = 1.0 + pan;
+ audiopanoramam_orc_process_f32_ch2_sim_right (odata, idata, rpan, n);
}
}
if (G_UNLIKELY (GST_BUFFER_FLAG_IS_SET (inbuf, GST_BUFFER_FLAG_GAP))) {
GST_BUFFER_FLAG_SET (outbuf, GST_BUFFER_FLAG_GAP);
- memset (outmap.data, 0, outmap.size);
+ orc_memset (outmap.data, 0, outmap.size);
} else {
/* output always stereo, input mono or stereo,
* and info describes input format */
guint num_samples = outmap.size / (2 * GST_AUDIO_INFO_BPS (&filter->info));
- filter->process (filter, inmap.data, outmap.data, num_samples);
+ filter->process (filter->panorama, inmap.data, outmap.data, num_samples);
}
gst_buffer_unmap (inbuf, &inmap);