diff --git a/sys/opensles/Makefile.am b/sys/opensles/Makefile.am index c0ef4ec982..62368337b3 100644 --- a/sys/opensles/Makefile.am +++ b/sys/opensles/Makefile.am @@ -1,7 +1,8 @@ plugin_LTLIBRARIES = libgstopensles.la -libgstopensles_la_SOURCES = openslesringbuffer.c \ +libgstopensles_la_SOURCES = openslescommon.c \ + openslesringbuffer.c \ openslessink.c \ openslessrc.c \ opensles.c @@ -16,7 +17,8 @@ libgstopensles_la_LIBADD = \ libgstopensles_la_LDFLAGS = $(GST_PLUGIN_LDFLAGS) -lOpenSLES libgstopensles_la_LIBTOOLFLAGS = $(GST_PLUGIN_LIBTOOLFLAGS) -noinst_HEADERS = openslesringbuffer.h \ +noinst_HEADERS = openslescommon.h \ + openslesringbuffer.h \ openslessink.h \ openslessrc.h diff --git a/sys/opensles/openslescommon.c b/sys/opensles/openslescommon.c new file mode 100644 index 0000000000..e35640f735 --- /dev/null +++ b/sys/opensles/openslescommon.c @@ -0,0 +1,76 @@ +/* GStreamer + * Copyright (C) 2015 Centricular Ltd., + * Arun Raghavan + * + * This library is free software; you can redistribute it and/or + * modify it under the terms of the GNU Library General Public + * License as published by the Free Software Foundation; either + * version 2 of the License, or (at your option) any later version. + * + * This library is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU + * Library General Public License for more details. + * + * You should have received a copy of the GNU Library General Public + * License along with this library; if not, write to the + * Free Software Foundation, Inc., 51 Franklin St, Fifth Floor, + * Boston, MA 02110-1301, USA. + */ + +#include "openslescommon.h" + +GType +gst_opensles_recording_preset_get_type (void) +{ + static const GEnumValue values[] = { + {GST_OPENSLES_RECORDING_PRESET_NONE, + "GST_OPENSLES_RECORDING_PRESET_NONE", "none"}, + {GST_OPENSLES_RECORDING_PRESET_GENERIC, + "GST_OPENSLES_RECORDING_PRESET_GENERIC", "generic"}, + {GST_OPENSLES_RECORDING_PRESET_CAMCORDER, + "GST_OPENSLES_RECORDING_PRESET_CAMCORDER", "camcorder"}, + {GST_OPENSLES_RECORDING_PRESET_VOICE_RECOGNITION, + "GST_OPENSLES_RECORDING_PRESET_VOICE_RECOGNITION", "voice-recognition"}, + {GST_OPENSLES_RECORDING_PRESET_VOICE_COMMUNICATION, + "GST_OPENSLES_RECORDING_PRESET_VOICE_COMMUNICATION", + "voice-communication"}, + {0, NULL, NULL} + }; + static volatile GType id = 0; + + if (g_once_init_enter ((gsize *) & id)) { + GType _id; + + _id = g_enum_register_static ("GstOpenSLESRecordingPreset", values); + + g_once_init_leave ((gsize *) & id, _id); + } + + return id; +} + +SLint32 +gst_to_opensles_recording_preset (GstOpenSLESRecordingPreset preset) +{ + switch (preset) { + case GST_OPENSLES_RECORDING_PRESET_NONE: + return SL_ANDROID_RECORDING_PRESET_NONE; + + case GST_OPENSLES_RECORDING_PRESET_GENERIC: + return SL_ANDROID_RECORDING_PRESET_GENERIC; + + case GST_OPENSLES_RECORDING_PRESET_CAMCORDER: + return SL_ANDROID_RECORDING_PRESET_CAMCORDER; + + case GST_OPENSLES_RECORDING_PRESET_VOICE_RECOGNITION: + return SL_ANDROID_RECORDING_PRESET_VOICE_RECOGNITION; + + case GST_OPENSLES_RECORDING_PRESET_VOICE_COMMUNICATION: + return SL_ANDROID_RECORDING_PRESET_VOICE_COMMUNICATION; + + default: + GST_ERROR ("Unsupported preset: %d", (int) preset); + return SL_ANDROID_RECORDING_PRESET_NONE; + } +} diff --git a/sys/opensles/openslescommon.h b/sys/opensles/openslescommon.h new file mode 100644 index 0000000000..44ae065d23 --- /dev/null +++ b/sys/opensles/openslescommon.h @@ -0,0 +1,48 @@ +/* GStreamer + * Copyright (C) 2015 Centricular Ltd. + * Author: Arun Raghavan + * + * This library is free software; you can redistribute it and/or + * modify it under the terms of the GNU Library General Public + * License as published by the Free Software Foundation; either + * version 2 of the License, or (at your option) any later version. + * + * This library is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU + * Library General Public License for more details. + * + * You should have received a copy of the GNU Library General Public + * License along with this library; if not, write to the + * Free Software Foundation, Inc., 51 Franklin St, Fifth Floor, + * Boston, MA 02110-1301, USA. + */ + +#ifndef __OPENSLESCOMMON_H__ +#define __OPENSLESCOMMON_H__ + +#include + +#include +#include + +G_BEGIN_DECLS + +typedef enum { + GST_OPENSLES_RECORDING_PRESET_NONE, + GST_OPENSLES_RECORDING_PRESET_GENERIC, + GST_OPENSLES_RECORDING_PRESET_CAMCORDER, + GST_OPENSLES_RECORDING_PRESET_VOICE_RECOGNITION, + GST_OPENSLES_RECORDING_PRESET_VOICE_COMMUNICATION, +} GstOpenSLESRecordingPreset; + +#define GST_TYPE_OPENSLES_RECORDING_PRESET \ + (gst_opensles_recording_preset_get_type()) + +GType gst_opensles_recording_preset_get_type (void); + +SLint32 gst_to_opensles_recording_preset (GstOpenSLESRecordingPreset preset); + +G_END_DECLS + +#endif /* __OPENSLESCOMMON_H__ */ diff --git a/sys/opensles/openslesringbuffer.c b/sys/opensles/openslesringbuffer.c index 5f993ec802..28263e5793 100644 --- a/sys/opensles/openslesringbuffer.c +++ b/sys/opensles/openslesringbuffer.c @@ -114,6 +114,7 @@ _opensles_recorder_acquire (GstAudioRingBuffer * rb, GstOpenSLESRingBuffer *thiz = GST_OPENSLES_RING_BUFFER_CAST (rb); SLresult result; SLDataFormat_PCM format; + SLAndroidConfigurationItf config; /* Configure audio source */ SLDataLocator_IODevice loc_dev = { @@ -129,21 +130,44 @@ _opensles_recorder_acquire (GstAudioRingBuffer * rb, SLDataSink audioSink = { &loc_bq, &format }; /* Required optional interfaces */ - const SLInterfaceID id[1] = { SL_IID_ANDROIDSIMPLEBUFFERQUEUE }; - const SLboolean req[1] = { SL_BOOLEAN_TRUE }; + const SLInterfaceID ids[2] = { SL_IID_ANDROIDSIMPLEBUFFERQUEUE, + SL_IID_ANDROIDCONFIGURATION + }; + const SLboolean req[2] = { SL_BOOLEAN_TRUE, SL_BOOLEAN_FALSE }; /* Define the audio format in OpenSL ES terminology */ _opensles_format (spec, &format); /* Create the audio recorder object (requires the RECORD_AUDIO permission) */ result = (*thiz->engineEngine)->CreateAudioRecorder (thiz->engineEngine, - &thiz->recorderObject, &audioSrc, &audioSink, 1, id, req); + &thiz->recorderObject, &audioSrc, &audioSink, 2, ids, req); if (result != SL_RESULT_SUCCESS) { GST_ERROR_OBJECT (thiz, "engine.CreateAudioRecorder failed(0x%08x)", (guint32) result); goto failed; } + /* Set the recording preset if we have one */ + if (thiz->preset != GST_OPENSLES_RECORDING_PRESET_NONE) { + SLint32 preset = gst_to_opensles_recording_preset (thiz->preset); + + result = (*thiz->recorderObject)->GetInterface (thiz->recorderObject, + SL_IID_ANDROIDCONFIGURATION, &config); + + if (result == SL_RESULT_SUCCESS) { + result = (*config)->SetConfiguration (config, + SL_ANDROID_KEY_RECORDING_PRESET, &preset, sizeof (preset)); + + if (result != SL_RESULT_SUCCESS) { + GST_WARNING_OBJECT (thiz, "Failed to set playback stream type (0x%08x)", + (guint32) result); + } + } else { + GST_WARNING_OBJECT (thiz, + "Could not get configuration interface 0x%08x", (guint32) result); + } + } + /* Realize the audio recorder object */ result = (*thiz->recorderObject)->Realize (thiz->recorderObject, SL_BOOLEAN_FALSE); diff --git a/sys/opensles/openslesringbuffer.h b/sys/opensles/openslesringbuffer.h index d821e06166..3d2242641d 100644 --- a/sys/opensles/openslesringbuffer.h +++ b/sys/opensles/openslesringbuffer.h @@ -22,6 +22,7 @@ #include #include +#include "openslescommon.h" #include #include @@ -84,6 +85,7 @@ struct _GstOpenSLESRingBuffer /* recorder interfaces */ SLObjectItf recorderObject; SLRecordItf recorderRecord; + GstOpenSLESRecordingPreset preset; /* buffer queue */ SLAndroidSimpleBufferQueueItf bufferQueue; diff --git a/sys/opensles/openslessrc.c b/sys/opensles/openslessrc.c index 18db5eb193..d0dfa32c83 100644 --- a/sys/opensles/openslessrc.c +++ b/sys/opensles/openslessrc.c @@ -60,12 +60,54 @@ static GstStaticPadTemplate src_factory = GST_STATIC_PAD_TEMPLATE ("src", G_DEFINE_TYPE_WITH_CODE (GstOpenSLESSrc, gst_opensles_src, GST_TYPE_AUDIO_BASE_SRC, _do_init); +enum +{ + PROP_0, + PROP_PRESET, +}; + +#define DEFAULT_PRESET GST_OPENSLES_RECORDING_PRESET_NONE + + +static void +gst_opensles_src_set_property (GObject * object, guint prop_id, + const GValue * value, GParamSpec * pspec) +{ + GstOpenSLESSrc *src = GST_OPENSLES_SRC (object); + + switch (prop_id) { + case PROP_PRESET: + src->preset = g_value_get_enum (value); + break; + default: + G_OBJECT_WARN_INVALID_PROPERTY_ID (object, prop_id, pspec); + break; + } +} + +static void +gst_opensles_src_get_property (GObject * object, guint prop_id, + GValue * value, GParamSpec * pspec) +{ + GstOpenSLESSrc *src = GST_OPENSLES_SRC (object); + + switch (prop_id) { + case PROP_PRESET: + g_value_set_enum (value, src->preset); + break; + default: + G_OBJECT_WARN_INVALID_PROPERTY_ID (object, prop_id, pspec); + break; + } +} + static GstAudioRingBuffer * gst_opensles_src_create_ringbuffer (GstAudioBaseSrc * base) { GstAudioRingBuffer *rb; rb = gst_opensles_ringbuffer_new (RB_MODE_SRC); + GST_OPENSLES_RING_BUFFER (rb)->preset = GST_OPENSLES_SRC (base)->preset; return rb; } @@ -73,12 +115,22 @@ gst_opensles_src_create_ringbuffer (GstAudioBaseSrc * base) static void gst_opensles_src_class_init (GstOpenSLESSrcClass * klass) { + GObjectClass *gobject_class; GstElementClass *gstelement_class; GstAudioBaseSrcClass *gstaudiobasesrc_class; + gobject_class = (GObjectClass *) klass; gstelement_class = (GstElementClass *) klass; gstaudiobasesrc_class = (GstAudioBaseSrcClass *) klass; + gobject_class->set_property = gst_opensles_src_set_property; + gobject_class->get_property = gst_opensles_src_get_property; + + g_object_class_install_property (gobject_class, PROP_PRESET, + g_param_spec_enum ("preset", "Preset", "Recording preset to use", + GST_TYPE_OPENSLES_RECORDING_PRESET, DEFAULT_PRESET, + G_PARAM_READWRITE | G_PARAM_STATIC_STRINGS)); + gst_element_class_add_pad_template (gstelement_class, gst_static_pad_template_get (&src_factory)); @@ -98,4 +150,6 @@ gst_opensles_src_init (GstOpenSLESSrc * src) * processing 20ms buffers as minimum buffer size. */ GST_AUDIO_BASE_SRC (src)->buffer_time = 200000; GST_AUDIO_BASE_SRC (src)->latency_time = 20000; + + src->preset = DEFAULT_PRESET; } diff --git a/sys/opensles/openslessrc.h b/sys/opensles/openslessrc.h index 5311ea8cec..805bcaa47e 100644 --- a/sys/opensles/openslessrc.h +++ b/sys/opensles/openslessrc.h @@ -39,6 +39,7 @@ typedef struct _GstOpenSLESSrcClass GstOpenSLESSrcClass; struct _GstOpenSLESSrc { GstAudioBaseSrc src; + GstOpenSLESRecordingPreset preset; }; struct _GstOpenSLESSrcClass