mirror of
https://gitlab.freedesktop.org/gstreamer/gstreamer.git
synced 2024-11-18 07:47:17 +00:00
sys: remove sunaudio plugin
Even though hooked up to the build system, it's clear that no one has ever built or used this with GStreamer 1.x. It wants to link against libgstinterfaces, which no longer exists. And uses 0.10-style raw audio caps. And the last meaningful change was done in 2009. Let's just remove it.
This commit is contained in:
parent
2271fee77e
commit
dd23afb6d4
24 changed files with 3 additions and 2858 deletions
2
README
2
README
|
@ -138,7 +138,7 @@ PLATFORMS
|
|||
|
||||
- Linux is of course fully supported
|
||||
- FreeBSD is reported to work; other BSDs should work too
|
||||
- Solaris is reported to work; a specific sunaudiosink plugin has been written
|
||||
- Solaris is reported to work
|
||||
- MacOSX works, binary 1.x packages can be built using the cerbero build tool
|
||||
- Windows works; binary 1.x packages can be built using the cerbero build tool
|
||||
- MSys/MinGW builds
|
||||
|
|
|
@ -454,12 +454,6 @@ AG_GST_CHECK_FEATURE(OSS4, [Open Sound System 4], oss4, [
|
|||
[OSS4_MISSING_HEADER="yes";HAVE_OSS4="no"])
|
||||
])
|
||||
|
||||
dnl *** Sun Audio ***
|
||||
translit(dnm, m, l) AM_CONDITIONAL(USE_SUNAUDIO, true)
|
||||
AG_GST_CHECK_FEATURE(SUNAUDIO, [Sun Audio], sunaudio, [
|
||||
AC_CHECK_HEADER(sys/audioio.h, HAVE_SUNAUDIO="yes", HAVE_SUNAUDIO="no")
|
||||
])
|
||||
|
||||
dnl *** OSX Audio ***
|
||||
translit(dnm, m, l) AM_CONDITIONAL(USE_OSX_AUDIO, true)
|
||||
HAVE_IOS="no"
|
||||
|
@ -888,7 +882,6 @@ AM_CONDITIONAL(USE_PULSE, false)
|
|||
AM_CONDITIONAL(USE_SHOUT2, false)
|
||||
AM_CONDITIONAL(USE_SOUP, false)
|
||||
AM_CONDITIONAL(USE_SPEEX, false)
|
||||
AM_CONDITIONAL(USE_SUNAUDIO, false)
|
||||
AM_CONDITIONAL(USE_TAGLIB, false)
|
||||
AM_CONDITIONAL(USE_VPX, false)
|
||||
AM_CONDITIONAL(USE_WAVEFORM, false)
|
||||
|
@ -1035,7 +1028,6 @@ sys/oss/Makefile
|
|||
sys/oss4/Makefile
|
||||
sys/osxaudio/Makefile
|
||||
sys/osxvideo/Makefile
|
||||
sys/sunaudio/Makefile
|
||||
sys/v4l2/Makefile
|
||||
sys/waveform/Makefile
|
||||
sys/ximage/Makefile
|
||||
|
|
|
@ -100,16 +100,10 @@ check_functions = [
|
|||
['HAVE_ISINF', 'isinf', '#include<math.h>'],
|
||||
# check token HAVE_LIBV4L2
|
||||
['HAVE_MMAP', 'mmap', '#include<sys/mman.h>'],
|
||||
# check token HAVE_OSS
|
||||
# check token HAVE_OSS4
|
||||
# check token HAVE_OSS_INCLUDE_IN_MACHINE
|
||||
# check token HAVE_OSS_INCLUDE_IN_ROOT
|
||||
# check token HAVE_OSS_INCLUDE_IN_SYS
|
||||
# check token HAVE_OSX_AUDIO
|
||||
# check token HAVE_OSX_VIDEO
|
||||
# check token HAVE_RDTSC
|
||||
['HAVE_SINH', 'sinh', '#include<math.h>'],
|
||||
# check token HAVE_SUNAUDIO
|
||||
# check token HAVE_WAVEFORM
|
||||
]
|
||||
|
||||
|
|
|
@ -18,8 +18,6 @@ sys/oss4/oss4-source.c
|
|||
sys/oss/gstosssink.c
|
||||
sys/oss/gstosssrc.c
|
||||
sys/osxaudio/gstosxaudioringbuffer.c
|
||||
sys/sunaudio/gstsunaudiomixeroptions.c
|
||||
sys/sunaudio/gstsunaudiomixertrack.c
|
||||
sys/v4l2/gstv4l2bufferpool.c
|
||||
sys/v4l2/gstv4l2object.c
|
||||
sys/v4l2/gstv4l2radio.c
|
||||
|
|
|
@ -1,9 +1,3 @@
|
|||
# if USE_DXR3
|
||||
# DXR3_DIR=dxr3
|
||||
# else
|
||||
# DXR3_DIR=
|
||||
# endif
|
||||
|
||||
if USE_OSS
|
||||
OSS_DIR=oss
|
||||
else
|
||||
|
@ -16,7 +10,6 @@ else
|
|||
OSS4_DIR=
|
||||
endif
|
||||
|
||||
|
||||
if USE_DIRECTSOUND
|
||||
DIRECTSOUND_DIR=directsound
|
||||
else
|
||||
|
@ -29,12 +22,6 @@ else
|
|||
WAVEFORM_DIR=
|
||||
endif
|
||||
|
||||
if USE_SUNAUDIO
|
||||
SUNAUDIO_DIR=sunaudio
|
||||
else
|
||||
SUNAUDIO_DIR=
|
||||
endif
|
||||
|
||||
if USE_OSX_AUDIO
|
||||
OSX_AUDIO_DIR=osxaudio
|
||||
else
|
||||
|
@ -47,44 +34,20 @@ else
|
|||
OSX_VIDEO_DIR=
|
||||
endif
|
||||
|
||||
# if USE_QCAM
|
||||
# QCAM_DIR=qcam
|
||||
# else
|
||||
# QCAM_DIR=
|
||||
# endif
|
||||
|
||||
if USE_GST_V4L2
|
||||
V4L2_DIR=v4l2
|
||||
else
|
||||
V4L2_DIR=
|
||||
endif
|
||||
|
||||
# if USE_VCD
|
||||
# VCD_DIR=vcd
|
||||
# else
|
||||
# VCD_DIR=
|
||||
# endif
|
||||
|
||||
# if USE_CDROM
|
||||
# CDROM_DIR=cdrom
|
||||
# else
|
||||
# CDROM_DIR=
|
||||
# endif
|
||||
|
||||
# if USE_OPENGL
|
||||
# GL_DIR=glsink
|
||||
# else
|
||||
# GL_DIR=
|
||||
# endif
|
||||
|
||||
if USE_X
|
||||
XIMAGE_DIR=ximage
|
||||
else
|
||||
XIMAGE_DIR=
|
||||
endif
|
||||
|
||||
SUBDIRS=$(DIRECTSOUND_DIR) $(WAVEFORM_DIR) $(OSS_DIR) $(OSS4_DIR) $(OSX_AUDIO_DIR) $(OSX_VIDEO_DIR) $(SUNAUDIO_DIR) $(V4L2_DIR) $(XIMAGE_DIR)
|
||||
SUBDIRS=$(DIRECTSOUND_DIR) $(WAVEFORM_DIR) $(OSS_DIR) $(OSS4_DIR) $(OSX_AUDIO_DIR) $(OSX_VIDEO_DIR) $(V4L2_DIR) $(XIMAGE_DIR)
|
||||
|
||||
DIST_SUBDIRS=directsound oss oss4 osxaudio osxvideo sunaudio v4l2 waveform ximage
|
||||
DIST_SUBDIRS=directsound oss oss4 osxaudio osxvideo v4l2 waveform ximage
|
||||
|
||||
include $(top_srcdir)/common/parallel-subdirs.mak
|
||||
|
|
|
@ -7,5 +7,4 @@ subdir('ximage')
|
|||
# FIXME: Implement these
|
||||
#subdir('osxaudio')
|
||||
#subdir('osxvideo')
|
||||
#subdir('sunaudio')
|
||||
#subdir('waveform')
|
||||
|
|
|
@ -1,25 +0,0 @@
|
|||
plugin_LTLIBRARIES = libgstsunaudio.la
|
||||
|
||||
libgstsunaudio_la_SOURCES = gstsunaudio.c \
|
||||
gstsunaudiosink.c \
|
||||
gstsunaudiomixerctrl.c \
|
||||
gstsunaudiomixer.c \
|
||||
gstsunaudiomixertrack.c \
|
||||
gstsunaudiomixeroptions.c \
|
||||
gstsunaudiosrc.c
|
||||
|
||||
libgstsunaudio_la_CFLAGS = $(GST_PLUGINS_BASE_CFLAGS) $(GST_CFLAGS)
|
||||
libgstsunaudio_la_LIBADD = \
|
||||
-lgstinterfaces-@GST_API_VERSION@ \
|
||||
-lgstaudio-@GST_API_VERSION@ \
|
||||
$(GST_PLUGINS_BASE_LIBS) \
|
||||
$(GST_LIBS)
|
||||
libgstsunaudio_la_LDFLAGS = $(GST_PLUGIN_LDFLAGS)
|
||||
|
||||
noinst_HEADERS = gstsunaudiosink.h \
|
||||
gstsunaudiomixer.h \
|
||||
gstsunaudiomixerctrl.h \
|
||||
gstsunaudiomixertrack.h \
|
||||
gstsunaudiomixeroptions.h \
|
||||
gstsunaudiosrc.h
|
||||
|
|
@ -1,62 +0,0 @@
|
|||
/*
|
||||
* GStreamer - SunAudio plugin
|
||||
* Copyright (C) 2005,2006 Sun Microsystems, Inc.,
|
||||
* Brian Cameron <brian.cameron@sun.com>
|
||||
*
|
||||
* 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.
|
||||
*/
|
||||
|
||||
#ifdef HAVE_CONFIG_H
|
||||
#include "config.h"
|
||||
#endif
|
||||
|
||||
#include "gst/gst-i18n-plugin.h"
|
||||
|
||||
#include "gstsunaudiomixer.h"
|
||||
#include "gstsunaudiosink.h"
|
||||
#include "gstsunaudiosrc.h"
|
||||
|
||||
extern gchar *__gst_oss_plugin_dir;
|
||||
|
||||
GST_DEBUG_CATEGORY (sunaudio_debug);
|
||||
|
||||
static gboolean
|
||||
plugin_init (GstPlugin * plugin)
|
||||
{
|
||||
if (!gst_element_register (plugin, "sunaudiomixer", GST_RANK_NONE,
|
||||
GST_TYPE_SUNAUDIO_MIXER) ||
|
||||
!gst_element_register (plugin, "sunaudiosink", GST_RANK_SECONDARY,
|
||||
GST_TYPE_SUNAUDIO_SINK) ||
|
||||
!gst_element_register (plugin, "sunaudiosrc", GST_RANK_SECONDARY,
|
||||
GST_TYPE_SUNAUDIO_SRC)) {
|
||||
return FALSE;
|
||||
}
|
||||
|
||||
GST_DEBUG_CATEGORY_INIT (sunaudio_debug, "sunaudio", 0, "sunaudio elements");
|
||||
|
||||
#ifdef ENABLE_NLS
|
||||
bindtextdomain (GETTEXT_PACKAGE, LOCALEDIR);
|
||||
bind_textdomain_codeset (GETTEXT_PACKAGE, "UTF-8");
|
||||
#endif /* ENABLE_NLS */
|
||||
|
||||
return TRUE;
|
||||
}
|
||||
|
||||
GST_PLUGIN_DEFINE (GST_VERSION_MAJOR,
|
||||
GST_VERSION_MINOR,
|
||||
sunaudio,
|
||||
"Sun Audio support for GStreamer",
|
||||
plugin_init, VERSION, GST_LICENSE, GST_PACKAGE_NAME, GST_PACKAGE_ORIGIN)
|
|
@ -1,104 +0,0 @@
|
|||
/*
|
||||
* GStreamer - SunAudio mixer
|
||||
* Copyright (C) 2005,2006 Sun Microsystems, Inc.,
|
||||
* Brian Cameron <brian.cameron@sun.com>
|
||||
*
|
||||
* 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.
|
||||
*/
|
||||
|
||||
/**
|
||||
* SECTION:element-sunaudiomixer
|
||||
*
|
||||
* sunaudiomixer is an mixer that controls the sound input and output
|
||||
* levels with the Sun Audio interface available in Solaris.
|
||||
*/
|
||||
|
||||
#ifdef HAVE_CONFIG_H
|
||||
#include "config.h"
|
||||
#endif
|
||||
|
||||
#include "gstsunaudiomixer.h"
|
||||
|
||||
GST_BOILERPLATE_WITH_INTERFACE (GstSunAudioMixer, gst_sunaudiomixer,
|
||||
GstElement, GST_TYPE_ELEMENT, GstMixer, GST_TYPE_MIXER, gst_sunaudiomixer);
|
||||
|
||||
GST_IMPLEMENT_SUNAUDIO_MIXER_CTRL_METHODS (GstSunAudioMixer, gst_sunaudiomixer);
|
||||
|
||||
static GstStateChangeReturn gst_sunaudiomixer_change_state (GstElement *
|
||||
element, GstStateChange transition);
|
||||
|
||||
static void
|
||||
gst_sunaudiomixer_base_init (gpointer klass)
|
||||
{
|
||||
gst_element_class_set_static_metadata (GST_ELEMENT_CLASS (klass),
|
||||
"Sun Audio Mixer", "Generic/Audio",
|
||||
"Control sound input and output levels with Sun Audio",
|
||||
"Brian Cameron <brian.cameron@sun.com>");
|
||||
}
|
||||
|
||||
static void
|
||||
gst_sunaudiomixer_class_init (GstSunAudioMixerClass * klass)
|
||||
{
|
||||
GstElementClass *element_class;
|
||||
|
||||
element_class = (GstElementClass *) klass;
|
||||
|
||||
element_class->change_state = gst_sunaudiomixer_change_state;
|
||||
}
|
||||
|
||||
static void
|
||||
gst_sunaudiomixer_init (GstSunAudioMixer * this,
|
||||
GstSunAudioMixerClass * g_class)
|
||||
{
|
||||
this->mixer = NULL;
|
||||
}
|
||||
|
||||
static GstStateChangeReturn
|
||||
gst_sunaudiomixer_change_state (GstElement * element, GstStateChange transition)
|
||||
{
|
||||
GstSunAudioMixer *this = GST_SUNAUDIO_MIXER (element);
|
||||
|
||||
switch (transition) {
|
||||
case GST_STATE_CHANGE_NULL_TO_READY:
|
||||
if (!this->mixer) {
|
||||
const char *audiodev;
|
||||
|
||||
audiodev = g_getenv ("AUDIODEV");
|
||||
if (audiodev == NULL) {
|
||||
this->mixer = gst_sunaudiomixer_ctrl_new ("/dev/audioctl");
|
||||
} else {
|
||||
gchar *device = g_strdup_printf ("%sctl", audiodev);
|
||||
|
||||
this->mixer = gst_sunaudiomixer_ctrl_new (device);
|
||||
g_free (device);
|
||||
}
|
||||
}
|
||||
break;
|
||||
case GST_STATE_CHANGE_READY_TO_NULL:
|
||||
if (this->mixer) {
|
||||
gst_sunaudiomixer_ctrl_free (this->mixer);
|
||||
this->mixer = NULL;
|
||||
}
|
||||
break;
|
||||
default:
|
||||
break;
|
||||
}
|
||||
|
||||
if (GST_ELEMENT_CLASS (parent_class)->change_state)
|
||||
return GST_ELEMENT_CLASS (parent_class)->change_state (element, transition);
|
||||
|
||||
return GST_STATE_CHANGE_SUCCESS;
|
||||
}
|
|
@ -1,51 +0,0 @@
|
|||
/*
|
||||
* GStreamer - SunAudio mixer
|
||||
* Copyright (C) 2005,2006 Sun Microsystems, Inc.,
|
||||
* Brian Cameron <brian.cameron@sun.com>
|
||||
*
|
||||
* 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 __GST_SUNAUDIO_MIXER_H__
|
||||
#define __GST_SUNAUDIO_MIXER_H__
|
||||
|
||||
#include "gstsunaudiomixerctrl.h"
|
||||
|
||||
G_BEGIN_DECLS
|
||||
|
||||
#define GST_SUNAUDIO_MIXER(obj) (G_TYPE_CHECK_INSTANCE_CAST((obj),GST_TYPE_SUNAUDIO_MIXER,GstSunAudioMixer))
|
||||
#define GST_SUNAUDIO_MIXER_CLASS(klass) (G_TYPE_CHECK_CLASS_CAST((klass),GST_TYPE_SUNAUDIO_MIXER,GstSunAudioMixerClass))
|
||||
#define GST_IS_SUNAUDIO_MIXER(obj) (G_TYPE_CHECK_INSTANCE_TYPE((obj),GST_TYPE_SUNAUDIO_MIXER))
|
||||
#define GST_IS_SUNAUDIO_MIXER_CLASS(klass) (G_TYPE_CHECK_CLASS_TYPE((klass),GST_TYPE_SUNAUDIO_MIXER))
|
||||
#define GST_TYPE_SUNAUDIO_MIXER (gst_sunaudiomixer_get_type())
|
||||
|
||||
typedef struct _GstSunAudioMixer GstSunAudioMixer;
|
||||
typedef struct _GstSunAudioMixerClass GstSunAudioMixerClass;
|
||||
|
||||
struct _GstSunAudioMixer {
|
||||
GstElement parent;
|
||||
|
||||
GstSunAudioMixerCtrl *mixer;
|
||||
};
|
||||
|
||||
struct _GstSunAudioMixerClass {
|
||||
GstElementClass parent;
|
||||
};
|
||||
|
||||
GType gst_sunaudiomixer_get_type (void);
|
||||
|
||||
G_END_DECLS
|
||||
|
||||
#endif /* __GST_SUNAUDIO_MIXER_H__ */
|
|
@ -1,585 +0,0 @@
|
|||
/*
|
||||
* GStreamer - SunAudio mixer interface element
|
||||
* Copyright (C) 2005,2006,2008,2009 Sun Microsystems, Inc.,
|
||||
* Brian Cameron <brian.cameron@sun.com>
|
||||
* Copyright (C) 2008 Sun Microsystems, Inc.,
|
||||
* Jan Schmidt <jan.schmidt@sun.com>
|
||||
* Copyright (C) 2009 Sun Microsystems, Inc.,
|
||||
* Garrett D'Amore <garrett.damore@sun.com>
|
||||
*
|
||||
* 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.
|
||||
*/
|
||||
|
||||
#ifdef HAVE_CONFIG_H
|
||||
#include "config.h"
|
||||
#endif
|
||||
|
||||
#include <stdio.h>
|
||||
#include <stdlib.h>
|
||||
#include <fcntl.h>
|
||||
#include <unistd.h>
|
||||
#include <string.h>
|
||||
#include <errno.h>
|
||||
#include <sys/ioctl.h>
|
||||
#include <sys/audio.h>
|
||||
#include <sys/mixer.h>
|
||||
|
||||
#include <gst/gst-i18n-plugin.h>
|
||||
|
||||
#include "gstsunaudiomixerctrl.h"
|
||||
#include "gstsunaudiomixertrack.h"
|
||||
#include "gstsunaudiomixeroptions.h"
|
||||
|
||||
GST_DEBUG_CATEGORY_EXTERN (sunaudio_debug);
|
||||
#define GST_CAT_DEFAULT sunaudio_debug
|
||||
|
||||
static gboolean
|
||||
gst_sunaudiomixer_ctrl_open (GstSunAudioMixerCtrl * mixer)
|
||||
{
|
||||
int fd;
|
||||
|
||||
/* First try to open non-blocking */
|
||||
fd = open (mixer->device, O_RDWR | O_NONBLOCK);
|
||||
|
||||
if (fd >= 0) {
|
||||
close (fd);
|
||||
fd = open (mixer->device, O_WRONLY);
|
||||
}
|
||||
|
||||
if (fd == -1) {
|
||||
GST_DEBUG_OBJECT (mixer,
|
||||
"Failed to open mixer device %s, mixing disabled: %s", mixer->device,
|
||||
strerror (errno));
|
||||
|
||||
return FALSE;
|
||||
}
|
||||
mixer->mixer_fd = fd;
|
||||
|
||||
/* Try to set the multiple open flag if we can, but ignore errors */
|
||||
ioctl (mixer->mixer_fd, AUDIO_MIXER_MULTIPLE_OPEN);
|
||||
|
||||
GST_DEBUG_OBJECT (mixer, "Opened mixer device %s", mixer->device);
|
||||
|
||||
return TRUE;
|
||||
}
|
||||
|
||||
void
|
||||
gst_sunaudiomixer_ctrl_build_list (GstSunAudioMixerCtrl * mixer)
|
||||
{
|
||||
GstMixerTrack *track;
|
||||
GstMixerOptions *options;
|
||||
|
||||
struct audio_info audioinfo;
|
||||
|
||||
/*
|
||||
* Do not continue appending the same 3 static tracks onto the list
|
||||
*/
|
||||
if (mixer->tracklist == NULL) {
|
||||
g_return_if_fail (mixer->mixer_fd != -1);
|
||||
|
||||
/* query available ports */
|
||||
if (ioctl (mixer->mixer_fd, AUDIO_GETINFO, &audioinfo) < 0) {
|
||||
g_warning ("Error getting audio device volume");
|
||||
return;
|
||||
}
|
||||
|
||||
/* Output & should be MASTER when it's the only one. */
|
||||
track = gst_sunaudiomixer_track_new (GST_SUNAUDIO_TRACK_OUTPUT);
|
||||
mixer->tracklist = g_list_append (mixer->tracklist, track);
|
||||
|
||||
/* Input */
|
||||
track = gst_sunaudiomixer_track_new (GST_SUNAUDIO_TRACK_RECORD);
|
||||
mixer->tracklist = g_list_append (mixer->tracklist, track);
|
||||
|
||||
/* Monitor */
|
||||
track = gst_sunaudiomixer_track_new (GST_SUNAUDIO_TRACK_MONITOR);
|
||||
mixer->tracklist = g_list_append (mixer->tracklist, track);
|
||||
|
||||
if (audioinfo.play.avail_ports & AUDIO_SPEAKER) {
|
||||
track = gst_sunaudiomixer_track_new (GST_SUNAUDIO_TRACK_SPEAKER);
|
||||
mixer->tracklist = g_list_append (mixer->tracklist, track);
|
||||
}
|
||||
if (audioinfo.play.avail_ports & AUDIO_HEADPHONE) {
|
||||
track = gst_sunaudiomixer_track_new (GST_SUNAUDIO_TRACK_HP);
|
||||
mixer->tracklist = g_list_append (mixer->tracklist, track);
|
||||
}
|
||||
if (audioinfo.play.avail_ports & AUDIO_LINE_OUT) {
|
||||
track = gst_sunaudiomixer_track_new (GST_SUNAUDIO_TRACK_LINEOUT);
|
||||
mixer->tracklist = g_list_append (mixer->tracklist, track);
|
||||
}
|
||||
if (audioinfo.play.avail_ports & AUDIO_SPDIF_OUT) {
|
||||
track = gst_sunaudiomixer_track_new (GST_SUNAUDIO_TRACK_SPDIFOUT);
|
||||
mixer->tracklist = g_list_append (mixer->tracklist, track);
|
||||
}
|
||||
if (audioinfo.play.avail_ports & AUDIO_AUX1_OUT) {
|
||||
track = gst_sunaudiomixer_track_new (GST_SUNAUDIO_TRACK_AUX1OUT);
|
||||
mixer->tracklist = g_list_append (mixer->tracklist, track);
|
||||
}
|
||||
if (audioinfo.play.avail_ports & AUDIO_AUX2_OUT) {
|
||||
track = gst_sunaudiomixer_track_new (GST_SUNAUDIO_TRACK_AUX2OUT);
|
||||
mixer->tracklist = g_list_append (mixer->tracklist, track);
|
||||
}
|
||||
|
||||
if (audioinfo.record.avail_ports != AUDIO_NONE) {
|
||||
options =
|
||||
gst_sunaudiomixer_options_new (mixer, GST_SUNAUDIO_TRACK_RECSRC);
|
||||
mixer->tracklist = g_list_append (mixer->tracklist, options);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
GstSunAudioMixerCtrl *
|
||||
gst_sunaudiomixer_ctrl_new (const char *device)
|
||||
{
|
||||
GstSunAudioMixerCtrl *ret = NULL;
|
||||
|
||||
g_return_val_if_fail (device != NULL, NULL);
|
||||
|
||||
ret = g_new0 (GstSunAudioMixerCtrl, 1);
|
||||
|
||||
ret->device = g_strdup (device);
|
||||
ret->mixer_fd = -1;
|
||||
ret->tracklist = NULL;
|
||||
|
||||
if (!gst_sunaudiomixer_ctrl_open (ret))
|
||||
goto error;
|
||||
|
||||
return ret;
|
||||
|
||||
error:
|
||||
if (ret)
|
||||
gst_sunaudiomixer_ctrl_free (ret);
|
||||
|
||||
return NULL;
|
||||
}
|
||||
|
||||
void
|
||||
gst_sunaudiomixer_ctrl_free (GstSunAudioMixerCtrl * mixer)
|
||||
{
|
||||
g_return_if_fail (mixer != NULL);
|
||||
|
||||
if (mixer->device) {
|
||||
g_free (mixer->device);
|
||||
mixer->device = NULL;
|
||||
}
|
||||
|
||||
if (mixer->tracklist) {
|
||||
g_list_foreach (mixer->tracklist, (GFunc) g_object_unref, NULL);
|
||||
g_list_free (mixer->tracklist);
|
||||
mixer->tracklist = NULL;
|
||||
}
|
||||
|
||||
if (mixer->mixer_fd != -1) {
|
||||
close (mixer->mixer_fd);
|
||||
mixer->mixer_fd = -1;
|
||||
}
|
||||
|
||||
g_free (mixer);
|
||||
}
|
||||
|
||||
GstMixerFlags
|
||||
gst_sunaudiomixer_ctrl_get_mixer_flags (GstSunAudioMixerCtrl * mixer)
|
||||
{
|
||||
return GST_MIXER_FLAG_HAS_WHITELIST | GST_MIXER_FLAG_GROUPING;
|
||||
}
|
||||
|
||||
const GList *
|
||||
gst_sunaudiomixer_ctrl_list_tracks (GstSunAudioMixerCtrl * mixer)
|
||||
{
|
||||
gst_sunaudiomixer_ctrl_build_list (mixer);
|
||||
|
||||
return (const GList *) mixer->tracklist;
|
||||
}
|
||||
|
||||
void
|
||||
gst_sunaudiomixer_ctrl_get_volume (GstSunAudioMixerCtrl * mixer,
|
||||
GstMixerTrack * track, gint * volumes)
|
||||
{
|
||||
gint gain, balance;
|
||||
float ratio;
|
||||
struct audio_info audioinfo;
|
||||
GstSunAudioMixerTrack *sunaudiotrack;
|
||||
|
||||
g_return_if_fail (GST_IS_SUNAUDIO_MIXER_TRACK (track));
|
||||
sunaudiotrack = GST_SUNAUDIO_MIXER_TRACK (track);
|
||||
|
||||
g_return_if_fail (mixer->mixer_fd != -1);
|
||||
|
||||
if (ioctl (mixer->mixer_fd, AUDIO_GETINFO, &audioinfo) < 0) {
|
||||
g_warning ("Error getting audio device volume");
|
||||
return;
|
||||
}
|
||||
|
||||
balance = AUDIO_MID_BALANCE;
|
||||
gain = 0;
|
||||
|
||||
switch (sunaudiotrack->track_num) {
|
||||
case GST_SUNAUDIO_TRACK_OUTPUT:
|
||||
gain = (int) audioinfo.play.gain;
|
||||
balance = audioinfo.play.balance;
|
||||
break;
|
||||
case GST_SUNAUDIO_TRACK_RECORD:
|
||||
gain = (int) audioinfo.record.gain;
|
||||
balance = audioinfo.record.balance;
|
||||
break;
|
||||
case GST_SUNAUDIO_TRACK_MONITOR:
|
||||
gain = (int) audioinfo.monitor_gain;
|
||||
balance = audioinfo.record.balance;
|
||||
break;
|
||||
case GST_SUNAUDIO_TRACK_SPEAKER:
|
||||
if (audioinfo.play.port & AUDIO_SPEAKER)
|
||||
gain = AUDIO_MAX_GAIN;
|
||||
break;
|
||||
case GST_SUNAUDIO_TRACK_HP:
|
||||
if (audioinfo.play.port & AUDIO_HEADPHONE)
|
||||
gain = AUDIO_MAX_GAIN;
|
||||
break;
|
||||
case GST_SUNAUDIO_TRACK_LINEOUT:
|
||||
if (audioinfo.play.port & AUDIO_LINE_OUT)
|
||||
gain = AUDIO_MAX_GAIN;
|
||||
break;
|
||||
case GST_SUNAUDIO_TRACK_SPDIFOUT:
|
||||
if (audioinfo.play.port & AUDIO_SPDIF_OUT)
|
||||
gain = AUDIO_MAX_GAIN;
|
||||
break;
|
||||
case GST_SUNAUDIO_TRACK_AUX1OUT:
|
||||
if (audioinfo.play.port & AUDIO_AUX1_OUT)
|
||||
gain = AUDIO_MAX_GAIN;
|
||||
break;
|
||||
case GST_SUNAUDIO_TRACK_AUX2OUT:
|
||||
if (audioinfo.play.port & AUDIO_AUX2_OUT)
|
||||
gain = AUDIO_MAX_GAIN;
|
||||
break;
|
||||
default:
|
||||
break;
|
||||
}
|
||||
|
||||
switch (track->num_channels) {
|
||||
case 2:
|
||||
if (balance == AUDIO_MID_BALANCE) {
|
||||
volumes[0] = gain;
|
||||
volumes[1] = gain;
|
||||
} else if (balance < AUDIO_MID_BALANCE) {
|
||||
volumes[0] = gain;
|
||||
ratio = 1 - (float) (AUDIO_MID_BALANCE - balance) /
|
||||
(float) AUDIO_MID_BALANCE;
|
||||
volumes[1] = (int) ((float) gain * ratio + 0.5);
|
||||
} else {
|
||||
volumes[1] = gain;
|
||||
ratio = 1 - (float) (balance - AUDIO_MID_BALANCE) /
|
||||
(float) AUDIO_MID_BALANCE;
|
||||
volumes[0] = (int) ((float) gain * ratio + 0.5);
|
||||
}
|
||||
break;
|
||||
case 1:
|
||||
volumes[0] = gain;
|
||||
break;
|
||||
}
|
||||
|
||||
/* Likewise reset MUTE */
|
||||
if ((sunaudiotrack->track_num == GST_SUNAUDIO_TRACK_OUTPUT
|
||||
&& audioinfo.output_muted == 1)
|
||||
|| (sunaudiotrack->track_num != GST_SUNAUDIO_TRACK_OUTPUT && gain == 0)) {
|
||||
/*
|
||||
* If MUTE is set, then gain is always 0, so don't bother
|
||||
* resetting our internal value.
|
||||
*/
|
||||
track->flags |= GST_MIXER_TRACK_MUTE;
|
||||
} else {
|
||||
sunaudiotrack->gain = gain;
|
||||
sunaudiotrack->balance = balance;
|
||||
track->flags &= ~GST_MIXER_TRACK_MUTE;
|
||||
}
|
||||
}
|
||||
|
||||
void
|
||||
gst_sunaudiomixer_ctrl_set_volume (GstSunAudioMixerCtrl * mixer,
|
||||
GstMixerTrack * track, gint * volumes)
|
||||
{
|
||||
gint gain;
|
||||
gint balance;
|
||||
gint l_real_gain;
|
||||
gint r_real_gain;
|
||||
float ratio;
|
||||
struct audio_info audioinfo;
|
||||
GstSunAudioMixerTrack *sunaudiotrack = GST_SUNAUDIO_MIXER_TRACK (track);
|
||||
|
||||
l_real_gain = volumes[0];
|
||||
r_real_gain = volumes[1];
|
||||
|
||||
if (l_real_gain == r_real_gain) {
|
||||
gain = l_real_gain;
|
||||
balance = AUDIO_MID_BALANCE;
|
||||
} else if (l_real_gain < r_real_gain) {
|
||||
gain = r_real_gain;
|
||||
ratio = (float) l_real_gain / (float) r_real_gain;
|
||||
balance =
|
||||
AUDIO_RIGHT_BALANCE - (int) (ratio * (float) AUDIO_MID_BALANCE + 0.5);
|
||||
} else {
|
||||
gain = l_real_gain;
|
||||
ratio = (float) r_real_gain / (float) l_real_gain;
|
||||
balance =
|
||||
AUDIO_LEFT_BALANCE + (int) (ratio * (float) AUDIO_MID_BALANCE + 0.5);
|
||||
}
|
||||
|
||||
sunaudiotrack->gain = gain;
|
||||
sunaudiotrack->balance = balance;
|
||||
|
||||
if (GST_MIXER_TRACK_HAS_FLAG (track, GST_MIXER_TRACK_MUTE)) {
|
||||
if (sunaudiotrack->track_num == GST_SUNAUDIO_TRACK_OUTPUT) {
|
||||
return;
|
||||
} else if (gain == 0) {
|
||||
return;
|
||||
} else {
|
||||
/*
|
||||
* If the volume is set to a non-zero value for LINE_IN
|
||||
* or MONITOR, then unset MUTE.
|
||||
*/
|
||||
track->flags &= ~GST_MIXER_TRACK_MUTE;
|
||||
}
|
||||
}
|
||||
|
||||
/* Set the volume */
|
||||
AUDIO_INITINFO (&audioinfo);
|
||||
|
||||
switch (sunaudiotrack->track_num) {
|
||||
case GST_SUNAUDIO_TRACK_OUTPUT:
|
||||
audioinfo.play.gain = gain;
|
||||
audioinfo.play.balance = balance;
|
||||
break;
|
||||
case GST_SUNAUDIO_TRACK_RECORD:
|
||||
audioinfo.record.gain = gain;
|
||||
audioinfo.record.balance = balance;
|
||||
break;
|
||||
case GST_SUNAUDIO_TRACK_MONITOR:
|
||||
audioinfo.monitor_gain = gain;
|
||||
audioinfo.record.balance = balance;
|
||||
break;
|
||||
default:
|
||||
break;
|
||||
}
|
||||
|
||||
g_return_if_fail (mixer->mixer_fd != -1);
|
||||
|
||||
if (ioctl (mixer->mixer_fd, AUDIO_SETINFO, &audioinfo) < 0) {
|
||||
g_warning ("Error setting audio device volume");
|
||||
return;
|
||||
}
|
||||
}
|
||||
|
||||
void
|
||||
gst_sunaudiomixer_ctrl_set_mute (GstSunAudioMixerCtrl * mixer,
|
||||
GstMixerTrack * track, gboolean mute)
|
||||
{
|
||||
struct audio_info audioinfo;
|
||||
struct audio_info oldinfo;
|
||||
GstSunAudioMixerTrack *sunaudiotrack = GST_SUNAUDIO_MIXER_TRACK (track);
|
||||
gint volume, balance;
|
||||
|
||||
AUDIO_INITINFO (&audioinfo);
|
||||
|
||||
if (ioctl (mixer->mixer_fd, AUDIO_GETINFO, &oldinfo) < 0) {
|
||||
g_warning ("Error getting audio device volume");
|
||||
return;
|
||||
}
|
||||
|
||||
if (mute) {
|
||||
volume = 0;
|
||||
track->flags |= GST_MIXER_TRACK_MUTE;
|
||||
} else {
|
||||
volume = sunaudiotrack->gain;
|
||||
track->flags &= ~GST_MIXER_TRACK_MUTE;
|
||||
}
|
||||
|
||||
balance = sunaudiotrack->balance;
|
||||
|
||||
switch (sunaudiotrack->track_num) {
|
||||
case GST_SUNAUDIO_TRACK_OUTPUT:
|
||||
if (mute)
|
||||
audioinfo.output_muted = 1;
|
||||
else
|
||||
audioinfo.output_muted = 0;
|
||||
|
||||
audioinfo.play.gain = volume;
|
||||
audioinfo.play.balance = balance;
|
||||
break;
|
||||
case GST_SUNAUDIO_TRACK_RECORD:
|
||||
audioinfo.record.gain = volume;
|
||||
audioinfo.record.balance = balance;
|
||||
break;
|
||||
case GST_SUNAUDIO_TRACK_MONITOR:
|
||||
audioinfo.monitor_gain = volume;
|
||||
audioinfo.record.balance = balance;
|
||||
break;
|
||||
case GST_SUNAUDIO_TRACK_SPEAKER:
|
||||
if (mute) {
|
||||
audioinfo.play.port = oldinfo.play.port & ~AUDIO_SPEAKER;
|
||||
} else {
|
||||
audioinfo.play.port = oldinfo.play.port | AUDIO_SPEAKER;
|
||||
}
|
||||
break;
|
||||
case GST_SUNAUDIO_TRACK_HP:
|
||||
if (mute) {
|
||||
audioinfo.play.port = oldinfo.play.port & ~AUDIO_HEADPHONE;
|
||||
} else {
|
||||
audioinfo.play.port = oldinfo.play.port | AUDIO_HEADPHONE;
|
||||
}
|
||||
break;
|
||||
case GST_SUNAUDIO_TRACK_LINEOUT:
|
||||
if (mute) {
|
||||
audioinfo.play.port = oldinfo.play.port & ~AUDIO_LINE_OUT;
|
||||
} else {
|
||||
audioinfo.play.port = oldinfo.play.port | AUDIO_LINE_OUT;
|
||||
}
|
||||
break;
|
||||
case GST_SUNAUDIO_TRACK_SPDIFOUT:
|
||||
if (mute) {
|
||||
audioinfo.play.port = oldinfo.play.port & ~AUDIO_SPDIF_OUT;
|
||||
} else {
|
||||
audioinfo.play.port = oldinfo.play.port | AUDIO_SPDIF_OUT;
|
||||
}
|
||||
break;
|
||||
case GST_SUNAUDIO_TRACK_AUX1OUT:
|
||||
if (mute) {
|
||||
audioinfo.play.port = oldinfo.play.port & ~AUDIO_AUX1_OUT;
|
||||
} else {
|
||||
audioinfo.play.port = oldinfo.play.port | AUDIO_AUX1_OUT;
|
||||
}
|
||||
break;
|
||||
case GST_SUNAUDIO_TRACK_AUX2OUT:
|
||||
if (mute) {
|
||||
audioinfo.play.port = oldinfo.play.port & ~AUDIO_AUX2_OUT;
|
||||
} else {
|
||||
audioinfo.play.port = oldinfo.play.port | AUDIO_AUX2_OUT;
|
||||
}
|
||||
break;
|
||||
default:
|
||||
break;
|
||||
}
|
||||
|
||||
if (audioinfo.play.port != ((unsigned) ~0)) {
|
||||
/* mask off ports we can't modify. Hack for broken drivers where mod_ports == 0 */
|
||||
if (oldinfo.play.mod_ports != 0) {
|
||||
audioinfo.play.port &= oldinfo.play.mod_ports;
|
||||
/* and add in any that are forced to be on */
|
||||
audioinfo.play.port |= (oldinfo.play.port & ~oldinfo.play.mod_ports);
|
||||
}
|
||||
}
|
||||
g_return_if_fail (mixer->mixer_fd != -1);
|
||||
|
||||
if (audioinfo.play.port != (guint) (-1) &&
|
||||
audioinfo.play.port != oldinfo.play.port)
|
||||
GST_LOG_OBJECT (mixer, "Changing play port mask to 0x%08x",
|
||||
audioinfo.play.port);
|
||||
|
||||
if (ioctl (mixer->mixer_fd, AUDIO_SETINFO, &audioinfo) < 0) {
|
||||
g_warning ("Error setting audio settings");
|
||||
return;
|
||||
}
|
||||
}
|
||||
|
||||
void
|
||||
gst_sunaudiomixer_ctrl_set_record (GstSunAudioMixerCtrl * mixer,
|
||||
GstMixerTrack * track, gboolean record)
|
||||
{
|
||||
}
|
||||
|
||||
void
|
||||
gst_sunaudiomixer_ctrl_set_option (GstSunAudioMixerCtrl * mixer,
|
||||
GstMixerOptions * options, gchar * value)
|
||||
{
|
||||
struct audio_info audioinfo;
|
||||
GstMixerTrack *track;
|
||||
GstSunAudioMixerOptions *opts;
|
||||
GQuark q;
|
||||
int i;
|
||||
|
||||
g_return_if_fail (mixer != NULL);
|
||||
g_return_if_fail (mixer->mixer_fd != -1);
|
||||
g_return_if_fail (value != NULL);
|
||||
g_return_if_fail (GST_IS_SUNAUDIO_MIXER_OPTIONS (options));
|
||||
|
||||
track = GST_MIXER_TRACK (options);
|
||||
opts = GST_SUNAUDIO_MIXER_OPTIONS (options);
|
||||
|
||||
if (opts->track_num != GST_SUNAUDIO_TRACK_RECSRC) {
|
||||
g_warning ("set_option not supported on track %s", track->label);
|
||||
return;
|
||||
}
|
||||
|
||||
q = g_quark_try_string (value);
|
||||
if (q == 0) {
|
||||
g_warning ("unknown option '%s'", value);
|
||||
return;
|
||||
}
|
||||
|
||||
for (i = 0; i < 8; i++) {
|
||||
if (opts->names[i] == q) {
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
if (((1 << (i)) & opts->avail) == 0) {
|
||||
g_warning ("Record port %s not available", g_quark_to_string (q));
|
||||
return;
|
||||
}
|
||||
|
||||
AUDIO_INITINFO (&audioinfo);
|
||||
audioinfo.record.port = (1 << (i));
|
||||
|
||||
if (ioctl (mixer->mixer_fd, AUDIO_SETINFO, &audioinfo) < 0) {
|
||||
g_warning ("Error setting audio record port");
|
||||
}
|
||||
}
|
||||
|
||||
const gchar *
|
||||
gst_sunaudiomixer_ctrl_get_option (GstSunAudioMixerCtrl * mixer,
|
||||
GstMixerOptions * options)
|
||||
{
|
||||
GstMixerTrack *track;
|
||||
GstSunAudioMixerOptions *opts;
|
||||
struct audio_info audioinfo;
|
||||
int i;
|
||||
|
||||
g_return_val_if_fail (mixer != NULL, NULL);
|
||||
g_return_val_if_fail (mixer->fd != -1, NULL);
|
||||
g_return_val_if_fail (GST_IS_SUNAUDIO_MIXER_OPTIONS (options), NULL);
|
||||
|
||||
track = GST_MIXER_TRACK (options);
|
||||
opts = GST_SUNAUDIO_MIXER_OPTIONS (options);
|
||||
|
||||
g_return_val_if_fail (opts->track_num == GST_SUNAUDIO_TRACK_RECSRC, NULL);
|
||||
|
||||
if (ioctl (mixer->mixer_fd, AUDIO_GETINFO, &audioinfo) < 0) {
|
||||
g_warning ("Error getting audio device settings");
|
||||
return (NULL);
|
||||
}
|
||||
|
||||
for (i = 0; i < 8; i++) {
|
||||
if ((1 << i) == audioinfo.record.port) {
|
||||
const gchar *s = g_quark_to_string (opts->names[i]);
|
||||
GST_DEBUG_OBJECT (mixer, "Getting value for option %d: %s",
|
||||
opts->track_num, s);
|
||||
return (s);
|
||||
}
|
||||
}
|
||||
|
||||
GST_DEBUG_OBJECT (mixer, "Unable to get value for option %d",
|
||||
opts->track_num);
|
||||
|
||||
g_warning ("Record port value %d seems illegal", audioinfo.record.port);
|
||||
return (NULL);
|
||||
}
|
|
@ -1,189 +0,0 @@
|
|||
/*
|
||||
* GStreamer - SunAudio mixer interface element.
|
||||
* Copyright (C) 2005,2006,2009 Sun Microsystems, Inc.,
|
||||
* Brian Cameron <brian.cameron@sun.com>
|
||||
* Copyright (C) 2009 Sun Microsystems, Inc.,
|
||||
* Garrett D'Amore <garrett.damore@sun.com>
|
||||
*
|
||||
* 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 __GST_SUNAUDIO_MIXER_CTRL_H
|
||||
#define __GST_SUNAUDIO_MIXER_CTRL_H
|
||||
|
||||
#include <sys/audioio.h>
|
||||
|
||||
#include <gst/gst.h>
|
||||
#include <gst/interfaces/mixer.h>
|
||||
|
||||
G_BEGIN_DECLS
|
||||
|
||||
#define GST_SUNAUDIO_MIXER_CTRL(obj) ((GstSunAudioMixerCtrl*)(obj))
|
||||
|
||||
typedef struct _GstSunAudioMixerCtrl GstSunAudioMixerCtrl;
|
||||
|
||||
struct _GstSunAudioMixerCtrl {
|
||||
GList * tracklist; /* list of available tracks */
|
||||
|
||||
gint fd;
|
||||
gint mixer_fd;
|
||||
|
||||
gchar * device;
|
||||
};
|
||||
|
||||
GstSunAudioMixerCtrl* gst_sunaudiomixer_ctrl_new (const gchar *device);
|
||||
void gst_sunaudiomixer_ctrl_free (GstSunAudioMixerCtrl *mixer);
|
||||
|
||||
const GList* gst_sunaudiomixer_ctrl_list_tracks (GstSunAudioMixerCtrl * mixer);
|
||||
void gst_sunaudiomixer_ctrl_set_volume (GstSunAudioMixerCtrl * mixer,
|
||||
GstMixerTrack * track,
|
||||
gint * volumes);
|
||||
void gst_sunaudiomixer_ctrl_get_volume (GstSunAudioMixerCtrl * mixer,
|
||||
GstMixerTrack * track,
|
||||
gint * volumes);
|
||||
void gst_sunaudiomixer_ctrl_set_record (GstSunAudioMixerCtrl * mixer,
|
||||
GstMixerTrack * track,
|
||||
gboolean record);
|
||||
void gst_sunaudiomixer_ctrl_set_mute (GstSunAudioMixerCtrl * mixer,
|
||||
GstMixerTrack * track,
|
||||
gboolean mute);
|
||||
void gst_sunaudiomixer_ctrl_set_option (GstSunAudioMixerCtrl * mixer,
|
||||
GstMixerOptions * options,
|
||||
gchar * value);
|
||||
const gchar * gst_sunaudiomixer_ctrl_get_option (GstSunAudioMixerCtrl * mixer,
|
||||
GstMixerOptions * options);
|
||||
GstMixerFlags gst_sunaudiomixer_ctrl_get_mixer_flags (GstSunAudioMixerCtrl *mixer);
|
||||
|
||||
#define GST_IMPLEMENT_SUNAUDIO_MIXER_CTRL_METHODS(Type, interface_as_function) \
|
||||
static gboolean \
|
||||
interface_as_function ## _supported (Type *this, GType iface_type) \
|
||||
{ \
|
||||
g_assert (iface_type == GST_TYPE_MIXER); \
|
||||
\
|
||||
return (this->mixer != NULL); \
|
||||
} \
|
||||
\
|
||||
static const GList* \
|
||||
interface_as_function ## _list_tracks (GstMixer * mixer) \
|
||||
{ \
|
||||
Type *this = (Type*) mixer; \
|
||||
\
|
||||
g_return_val_if_fail (this != NULL, NULL); \
|
||||
g_return_val_if_fail (this->mixer != NULL, NULL); \
|
||||
\
|
||||
return gst_sunaudiomixer_ctrl_list_tracks (this->mixer); \
|
||||
} \
|
||||
\
|
||||
static void \
|
||||
interface_as_function ## _set_volume (GstMixer * mixer, GstMixerTrack * track, \
|
||||
gint * volumes) \
|
||||
{ \
|
||||
Type *this = (Type*) mixer; \
|
||||
\
|
||||
g_return_if_fail (this != NULL); \
|
||||
g_return_if_fail (this->mixer != NULL); \
|
||||
\
|
||||
gst_sunaudiomixer_ctrl_set_volume (this->mixer, track, volumes); \
|
||||
} \
|
||||
\
|
||||
static void \
|
||||
interface_as_function ## _get_volume (GstMixer * mixer, GstMixerTrack * track, \
|
||||
gint * volumes) \
|
||||
{ \
|
||||
Type *this = (Type*) mixer; \
|
||||
\
|
||||
g_return_if_fail (this != NULL); \
|
||||
g_return_if_fail (this->mixer != NULL); \
|
||||
\
|
||||
gst_sunaudiomixer_ctrl_get_volume (this->mixer, track, volumes); \
|
||||
} \
|
||||
\
|
||||
static void \
|
||||
interface_as_function ## _set_record (GstMixer * mixer, GstMixerTrack * track, \
|
||||
gboolean record) \
|
||||
{ \
|
||||
Type *this = (Type*) mixer; \
|
||||
\
|
||||
g_return_if_fail (this != NULL); \
|
||||
g_return_if_fail (this->mixer != NULL); \
|
||||
\
|
||||
gst_sunaudiomixer_ctrl_set_record (this->mixer, track, record); \
|
||||
} \
|
||||
\
|
||||
static void \
|
||||
interface_as_function ## _set_mute (GstMixer * mixer, GstMixerTrack * track, \
|
||||
gboolean mute) \
|
||||
{ \
|
||||
Type *this = (Type*) mixer; \
|
||||
\
|
||||
g_return_if_fail (this != NULL); \
|
||||
g_return_if_fail (this->mixer != NULL); \
|
||||
\
|
||||
gst_sunaudiomixer_ctrl_set_mute (this->mixer, track, mute); \
|
||||
} \
|
||||
\
|
||||
static const gchar * \
|
||||
interface_as_function ## _get_option (GstMixer * mixer, GstMixerOptions * opts) \
|
||||
{ \
|
||||
Type *this = (Type*) mixer; \
|
||||
\
|
||||
g_return_val_if_fail (this != NULL, NULL); \
|
||||
g_return_val_if_fail (this->mixer != NULL, NULL); \
|
||||
\
|
||||
return gst_sunaudiomixer_ctrl_get_option (this->mixer, opts); \
|
||||
} \
|
||||
\
|
||||
static void \
|
||||
interface_as_function ## _set_option (GstMixer * mixer, GstMixerOptions * opts, \
|
||||
gchar * value) \
|
||||
{ \
|
||||
Type *this = (Type*) mixer; \
|
||||
\
|
||||
g_return_if_fail (this != NULL); \
|
||||
g_return_if_fail (this->mixer != NULL); \
|
||||
\
|
||||
gst_sunaudiomixer_ctrl_set_option (this->mixer, opts, value); \
|
||||
} \
|
||||
\
|
||||
static GstMixerFlags \
|
||||
interface_as_function ## _get_mixer_flags (GstMixer * mixer) \
|
||||
{ \
|
||||
Type *this = (Type*) mixer; \
|
||||
\
|
||||
g_return_val_if_fail (this != NULL, GST_MIXER_FLAG_NONE); \
|
||||
g_return_val_if_fail (this->mixer != NULL, GST_MIXER_FLAG_NONE); \
|
||||
\
|
||||
return gst_sunaudiomixer_ctrl_get_mixer_flags (this->mixer); \
|
||||
} \
|
||||
\
|
||||
static void \
|
||||
interface_as_function ## _interface_init (GstMixerInterface * iface) \
|
||||
{ \
|
||||
GST_MIXER_TYPE (iface) = GST_MIXER_HARDWARE; \
|
||||
\
|
||||
/* set up the interface hooks */ \
|
||||
iface->list_tracks = interface_as_function ## _list_tracks; \
|
||||
iface->set_volume = interface_as_function ## _set_volume; \
|
||||
iface->get_volume = interface_as_function ## _get_volume; \
|
||||
iface->set_mute = interface_as_function ## _set_mute; \
|
||||
iface->set_record = interface_as_function ## _set_record; \
|
||||
iface->get_option = interface_as_function ## _get_option; \
|
||||
iface->set_option = interface_as_function ## _set_option; \
|
||||
iface->get_mixer_flags = interface_as_function ## _get_mixer_flags; \
|
||||
}
|
||||
|
||||
G_END_DECLS
|
||||
|
||||
#endif
|
|
@ -1,157 +0,0 @@
|
|||
/*
|
||||
* GStreamer SunAudio mixer track implementation
|
||||
* Copyright (C) 2009 Sun Microsystems, Inc.,
|
||||
* Brian Cameron <brian.cameron@sun.com>
|
||||
* Garrett D'Amore <garrett.damore@sun.com>
|
||||
*
|
||||
* gstsunaudiomixeroptions.c: Sun Audio mixer options object
|
||||
*
|
||||
* 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.
|
||||
*/
|
||||
|
||||
#ifdef HAVE_CONFIG_H
|
||||
#include "config.h"
|
||||
#endif
|
||||
#include <stdio.h>
|
||||
#include <stdlib.h>
|
||||
#include <fcntl.h>
|
||||
#include <unistd.h>
|
||||
#include <string.h>
|
||||
#include <errno.h>
|
||||
#include <sys/ioctl.h>
|
||||
#include <sys/audio.h>
|
||||
#include <sys/mixer.h>
|
||||
|
||||
#include <gst/gst-i18n-plugin.h>
|
||||
|
||||
#include "gstsunaudiomixeroptions.h"
|
||||
#include "gstsunaudiomixertrack.h"
|
||||
|
||||
GST_DEBUG_CATEGORY_EXTERN (sunaudio_debug);
|
||||
#define GST_CAT_DEFAULT sunaudio_debug
|
||||
|
||||
static void gst_sunaudiomixer_options_init (GstSunAudioMixerOptions * sun_opts);
|
||||
static void gst_sunaudiomixer_options_class_init (gpointer g_class,
|
||||
gpointer class_data);
|
||||
|
||||
static GstMixerOptionsClass *parent_class = NULL;
|
||||
|
||||
GType
|
||||
gst_sunaudiomixer_options_get_type (void)
|
||||
{
|
||||
static GType opts_type = 0;
|
||||
|
||||
if (!opts_type) {
|
||||
static const GTypeInfo opts_info = {
|
||||
sizeof (GstSunAudioMixerOptionsClass),
|
||||
NULL,
|
||||
NULL,
|
||||
gst_sunaudiomixer_options_class_init,
|
||||
NULL,
|
||||
NULL,
|
||||
sizeof (GstSunAudioMixerOptions),
|
||||
0,
|
||||
(GInstanceInitFunc) gst_sunaudiomixer_options_init,
|
||||
};
|
||||
|
||||
opts_type =
|
||||
g_type_register_static (GST_TYPE_MIXER_OPTIONS,
|
||||
"GstSunAudioMixerOptions", &opts_info, 0);
|
||||
}
|
||||
|
||||
return opts_type;
|
||||
}
|
||||
|
||||
static void
|
||||
gst_sunaudiomixer_options_class_init (gpointer g_class, gpointer class_data)
|
||||
{
|
||||
parent_class = g_type_class_peek_parent (g_class);
|
||||
}
|
||||
|
||||
static void
|
||||
gst_sunaudiomixer_options_init (GstSunAudioMixerOptions * sun_opts)
|
||||
{
|
||||
}
|
||||
|
||||
GstMixerOptions *
|
||||
gst_sunaudiomixer_options_new (GstSunAudioMixerCtrl * mixer, gint track_num)
|
||||
{
|
||||
GstMixerOptions *opts;
|
||||
GstSunAudioMixerOptions *sun_opts;
|
||||
GstMixerTrack *track;
|
||||
const gchar *label;
|
||||
gint i;
|
||||
struct audio_info audioinfo;
|
||||
|
||||
if ((mixer == NULL) || (mixer->mixer_fd == -1)) {
|
||||
g_warning ("mixer not initialized");
|
||||
return NULL;
|
||||
}
|
||||
|
||||
if (track_num != GST_SUNAUDIO_TRACK_RECSRC) {
|
||||
g_warning ("invalid options track");
|
||||
return (NULL);
|
||||
}
|
||||
|
||||
label = N_("Record Source");
|
||||
|
||||
opts = g_object_new (GST_TYPE_SUNAUDIO_MIXER_OPTIONS,
|
||||
"untranslated-label", label, NULL);
|
||||
sun_opts = GST_SUNAUDIO_MIXER_OPTIONS (opts);
|
||||
track = GST_MIXER_TRACK (opts);
|
||||
|
||||
GST_DEBUG_OBJECT (opts, "New mixer options, track %d: %s",
|
||||
track_num, GST_STR_NULL (label));
|
||||
|
||||
/* save off names for the record sources */
|
||||
sun_opts->names[0] = g_quark_from_string (_("Microphone"));
|
||||
sun_opts->names[1] = g_quark_from_string (_("Line In"));
|
||||
sun_opts->names[2] = g_quark_from_string (_("Internal CD"));
|
||||
sun_opts->names[3] = g_quark_from_string (_("SPDIF In"));
|
||||
sun_opts->names[4] = g_quark_from_string (_("AUX 1 In"));
|
||||
sun_opts->names[5] = g_quark_from_string (_("AUX 2 In"));
|
||||
sun_opts->names[6] = g_quark_from_string (_("Codec Loopback"));
|
||||
sun_opts->names[7] = g_quark_from_string (_("SunVTS Loopback"));
|
||||
|
||||
/* set basic information */
|
||||
track->label = g_strdup (_(label));
|
||||
track->num_channels = 0;
|
||||
track->min_volume = 0;
|
||||
track->max_volume = 0;
|
||||
track->flags =
|
||||
GST_MIXER_TRACK_INPUT | GST_MIXER_TRACK_WHITELIST |
|
||||
GST_MIXER_TRACK_NO_RECORD;
|
||||
|
||||
if (ioctl (mixer->mixer_fd, AUDIO_GETINFO, &audioinfo) < 0) {
|
||||
g_warning ("Error getting audio device settings");
|
||||
g_object_unref (G_OBJECT (sun_opts));
|
||||
return NULL;
|
||||
}
|
||||
|
||||
sun_opts->avail = audioinfo.record.avail_ports;
|
||||
sun_opts->track_num = track_num;
|
||||
|
||||
for (i = 0; i < 8; i++) {
|
||||
if ((1 << i) & audioinfo.record.avail_ports) {
|
||||
const char *s = g_quark_to_string (sun_opts->names[i]);
|
||||
opts->values = g_list_append (opts->values, g_strdup (s));
|
||||
GST_DEBUG_OBJECT (opts, "option for track %d: %s",
|
||||
track_num, GST_STR_NULL (s));
|
||||
}
|
||||
}
|
||||
|
||||
return opts;
|
||||
}
|
|
@ -1,65 +0,0 @@
|
|||
/*
|
||||
* GStreamer SunAudio mixer track implementation
|
||||
* Copyright (C) 2009 Sun Microsystems, Inc.,
|
||||
* Brian Cameron <brian.cameron@sun.com>
|
||||
* Garrett D'Amore <garrett.damore@sun.com>
|
||||
*
|
||||
* gstsunaudiomixeroptions.h: Sun Audio mixer options object
|
||||
*
|
||||
* 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,
|
||||
*/
|
||||
|
||||
#ifndef __GST_SUNAUDIO_MIXER_OPTIONS_H__
|
||||
#define __GST_SUNAUDIO_MIXER_OPTIONS_H__
|
||||
|
||||
|
||||
#include "gstsunaudiomixer.h"
|
||||
#include <gst/interfaces/mixeroptions.h>
|
||||
|
||||
|
||||
G_BEGIN_DECLS
|
||||
|
||||
|
||||
#define GST_SUNAUDIO_MIXER_OPTIONS(obj) (G_TYPE_CHECK_INSTANCE_CAST((obj),GST_TYPE_SUNAUDIO_MIXER_OPTIONS, GstSunAudioMixerOptions))
|
||||
#define GST_SUNAUDIO_MIXER_OPTIONS_CLASS(klass) (G_TYPE_CHECK_CLASS_CAST((klass),GST_TYPE_SUNAUDIO_MIXER_OPTIONS, GstSunAudioMixerOptionsClass))
|
||||
#define GST_IS_SUNAUDIO_MIXER_OPTIONS(obj) (G_TYPE_CHECK_INSTANCE_TYPE((obj),GST_TYPE_SUNAUDIO_MIXER_OPTIONS))
|
||||
#define GST_IS_SUNAUDIO_MIXER_OPTIONS_CLASS(klass) (G_TYPE_CHECK_CLASS_TYPE((klass),GST_TYPE_SUNAUDIO_MIXER_OPTIONS))
|
||||
#define GST_TYPE_SUNAUDIO_MIXER_OPTIONS (gst_sunaudiomixer_options_get_type())
|
||||
|
||||
|
||||
typedef struct _GstSunAudioMixerOptions GstSunAudioMixerOptions;
|
||||
typedef struct _GstSunAudioMixerOptionsClass GstSunAudioMixerOptionsClass;
|
||||
|
||||
|
||||
struct _GstSunAudioMixerOptions {
|
||||
GstMixerOptions parent;
|
||||
gint track_num;
|
||||
GQuark names[8]; /* only 8 possible */
|
||||
gint avail; /* mask of avail */
|
||||
};
|
||||
|
||||
struct _GstSunAudioMixerOptionsClass {
|
||||
GstMixerOptionsClass parent;
|
||||
};
|
||||
|
||||
|
||||
GType gst_sunaudiomixer_options_get_type (void);
|
||||
GstMixerOptions *gst_sunaudiomixer_options_new (GstSunAudioMixerCtrl *mixer, gint track_num);
|
||||
|
||||
|
||||
G_END_DECLS
|
||||
|
||||
|
||||
#endif /* __GST_SUNAUDIO_MIXER_OPTIONS_H__ */
|
|
@ -1,158 +0,0 @@
|
|||
/*
|
||||
* GStreamer
|
||||
* Copyright (C) 2005,2008, 2009 Sun Microsystems, Inc.,
|
||||
* Brian Cameron <brian.cameron@sun.com>
|
||||
* Copyright (C) 2009 Sun Microsystems, Inc.,
|
||||
* Garrett D'Amore <garrett.damore@sun.com>
|
||||
*
|
||||
* gstsunaudiomixer.c: mixer interface implementation for OSS
|
||||
*
|
||||
* 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.
|
||||
*/
|
||||
|
||||
#ifdef HAVE_CONFIG_H
|
||||
#include "config.h"
|
||||
#endif
|
||||
|
||||
#include <stdio.h>
|
||||
#include <stdlib.h>
|
||||
#include <fcntl.h>
|
||||
#include <unistd.h>
|
||||
#include <string.h>
|
||||
#include <errno.h>
|
||||
#include <sys/ioctl.h>
|
||||
#include <sys/audioio.h>
|
||||
|
||||
#include <gst/gst-i18n-plugin.h>
|
||||
|
||||
#include "gstsunaudiomixertrack.h"
|
||||
|
||||
GST_DEBUG_CATEGORY_EXTERN (sunaudio_debug);
|
||||
#define GST_CAT_DEFAULT sunaudio_debug
|
||||
|
||||
#define MASK_BIT_IS_SET(mask, bit) \
|
||||
(mask & (1 << bit))
|
||||
|
||||
G_DEFINE_TYPE (GstSunAudioMixerTrack, gst_sunaudiomixer_track,
|
||||
GST_TYPE_MIXER_TRACK);
|
||||
|
||||
static void
|
||||
gst_sunaudiomixer_track_class_init (GstSunAudioMixerTrackClass * klass)
|
||||
{
|
||||
/* nop */
|
||||
}
|
||||
|
||||
static void
|
||||
gst_sunaudiomixer_track_init (GstSunAudioMixerTrack * track)
|
||||
{
|
||||
track->gain = 0;
|
||||
track->balance = AUDIO_MID_BALANCE;
|
||||
track->track_num = 0;
|
||||
}
|
||||
|
||||
GstMixerTrack *
|
||||
gst_sunaudiomixer_track_new (GstSunAudioTrackType track_num)
|
||||
{
|
||||
const gchar *labels[] = { N_("Volume"),
|
||||
N_("Gain"),
|
||||
N_("Monitor"),
|
||||
N_("Built-in Speaker"),
|
||||
N_("Headphone"),
|
||||
N_("Line Out"),
|
||||
N_("SPDIF Out"),
|
||||
N_("AUX 1 Out"),
|
||||
N_("AUX 2 Out"),
|
||||
};
|
||||
|
||||
|
||||
GstSunAudioMixerTrack *sunaudiotrack;
|
||||
GstMixerTrack *track;
|
||||
const gchar *untranslated_label;
|
||||
|
||||
if ((guint) track_num < G_N_ELEMENTS (labels))
|
||||
untranslated_label = labels[track_num];
|
||||
else
|
||||
untranslated_label = NULL;
|
||||
|
||||
sunaudiotrack = g_object_new (GST_TYPE_SUNAUDIO_MIXER_TRACK,
|
||||
"untranslated-label", untranslated_label, NULL);
|
||||
|
||||
GST_DEBUG_OBJECT (sunaudiotrack, "Creating new mixer track of type %d: %s",
|
||||
track_num, GST_STR_NULL (untranslated_label));
|
||||
|
||||
switch (track_num) {
|
||||
case GST_SUNAUDIO_TRACK_OUTPUT:
|
||||
/* these are sliders */
|
||||
track = GST_MIXER_TRACK (sunaudiotrack);
|
||||
track->label = g_strdup (_(untranslated_label));
|
||||
track->num_channels = 2;
|
||||
track->flags = GST_MIXER_TRACK_OUTPUT | GST_MIXER_TRACK_WHITELIST |
|
||||
GST_MIXER_TRACK_MASTER;
|
||||
track->min_volume = 0;
|
||||
track->max_volume = 255;
|
||||
sunaudiotrack->track_num = track_num;
|
||||
sunaudiotrack->gain = (0 & 0xff);
|
||||
sunaudiotrack->balance = AUDIO_MID_BALANCE;
|
||||
break;
|
||||
case GST_SUNAUDIO_TRACK_RECORD:
|
||||
/* these are sliders */
|
||||
track = GST_MIXER_TRACK (sunaudiotrack);
|
||||
track->label = g_strdup (_(untranslated_label));
|
||||
track->num_channels = 2;
|
||||
track->flags = GST_MIXER_TRACK_INPUT | GST_MIXER_TRACK_NO_RECORD |
|
||||
GST_MIXER_TRACK_WHITELIST;
|
||||
track->min_volume = 0;
|
||||
track->max_volume = 255;
|
||||
sunaudiotrack->track_num = track_num;
|
||||
sunaudiotrack->gain = (0 & 0xff);
|
||||
sunaudiotrack->balance = AUDIO_MID_BALANCE;
|
||||
break;
|
||||
case GST_SUNAUDIO_TRACK_MONITOR:
|
||||
/* these are sliders */
|
||||
track = GST_MIXER_TRACK (sunaudiotrack);
|
||||
track->label = g_strdup (_(untranslated_label));
|
||||
track->num_channels = 2;
|
||||
track->flags = GST_MIXER_TRACK_INPUT | GST_MIXER_TRACK_NO_RECORD;
|
||||
track->min_volume = 0;
|
||||
track->max_volume = 255;
|
||||
sunaudiotrack->track_num = track_num;
|
||||
sunaudiotrack->gain = (0 & 0xff);
|
||||
sunaudiotrack->balance = AUDIO_MID_BALANCE;
|
||||
break;
|
||||
case GST_SUNAUDIO_TRACK_SPEAKER:
|
||||
case GST_SUNAUDIO_TRACK_HP:
|
||||
case GST_SUNAUDIO_TRACK_LINEOUT:
|
||||
case GST_SUNAUDIO_TRACK_SPDIFOUT:
|
||||
case GST_SUNAUDIO_TRACK_AUX1OUT:
|
||||
case GST_SUNAUDIO_TRACK_AUX2OUT:
|
||||
/* these are switches */
|
||||
track = GST_MIXER_TRACK (sunaudiotrack);
|
||||
track->label = g_strdup (_(untranslated_label));
|
||||
track->num_channels = 0;
|
||||
track->flags = GST_MIXER_TRACK_OUTPUT | GST_MIXER_TRACK_WHITELIST;
|
||||
track->min_volume = 0;
|
||||
track->max_volume = 255;
|
||||
sunaudiotrack->track_num = track_num;
|
||||
sunaudiotrack->gain = (0 & 0xff);
|
||||
sunaudiotrack->balance = AUDIO_MID_BALANCE;
|
||||
break;
|
||||
default:
|
||||
g_warning ("Unknown sun audio track num %d", track_num);
|
||||
track = NULL;
|
||||
}
|
||||
|
||||
return track;
|
||||
}
|
|
@ -1,78 +0,0 @@
|
|||
/*
|
||||
* GStreamer SunAudio mixer track implementation
|
||||
* Copyright (C) 2005,2006,2009 Sun Microsystems, Inc.,
|
||||
* Brian Cameron <brian.cameron@sun.com>
|
||||
* Copyright (C) 2009 Sun Microsystems, Inc.,
|
||||
* Garrett D'Amore <garrett.damore@sun.com>
|
||||
*
|
||||
* gstsunaudiomixertrack.h: SunAudio mixer tracks
|
||||
*
|
||||
* 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 __GST_SUNAUDIO_MIXER_TRACK_H__
|
||||
#define __GST_SUNAUDIO_MIXER_TRACK_H__
|
||||
|
||||
#include <gst/gst.h>
|
||||
#include <gst/interfaces/mixer.h>
|
||||
|
||||
G_BEGIN_DECLS
|
||||
|
||||
typedef enum
|
||||
{
|
||||
GST_SUNAUDIO_TRACK_OUTPUT = 0,
|
||||
GST_SUNAUDIO_TRACK_RECORD,
|
||||
GST_SUNAUDIO_TRACK_MONITOR,
|
||||
GST_SUNAUDIO_TRACK_SPEAKER,
|
||||
GST_SUNAUDIO_TRACK_HP,
|
||||
GST_SUNAUDIO_TRACK_LINEOUT,
|
||||
GST_SUNAUDIO_TRACK_SPDIFOUT,
|
||||
GST_SUNAUDIO_TRACK_AUX1OUT,
|
||||
GST_SUNAUDIO_TRACK_AUX2OUT,
|
||||
GST_SUNAUDIO_TRACK_RECSRC
|
||||
} GstSunAudioTrackType;
|
||||
|
||||
#define GST_TYPE_SUNAUDIO_MIXER_TRACK \
|
||||
(gst_sunaudiomixer_track_get_type ())
|
||||
#define GST_SUNAUDIO_MIXER_TRACK(obj) \
|
||||
(G_TYPE_CHECK_INSTANCE_CAST ((obj), GST_TYPE_SUNAUDIO_MIXER_TRACK, \
|
||||
GstSunAudioMixerTrack))
|
||||
#define GST_SUNAUDIO_MIXER_TRACK_CLASS(klass) \
|
||||
(G_TYPE_CHECK_CLASS_CAST ((klass), GST_TYPE_SUNAUDIO_MIXER_TRACK, \
|
||||
GstSunAudioMixerTrackClass))
|
||||
#define GST_IS_SUNAUDIO_MIXER_TRACK(obj) \
|
||||
(G_TYPE_CHECK_INSTANCE_TYPE ((obj), GST_TYPE_SUNAUDIO_MIXER_TRACK))
|
||||
#define GST_IS_SUNAUDIO_MIXER_TRACK_CLASS(klass) \
|
||||
(G_TYPE_CHECK_CLASS_TYPE ((klass), GST_TYPE_SUNAUDIO_MIXER_TRACK))
|
||||
|
||||
typedef struct _GstSunAudioMixerTrack {
|
||||
GstMixerTrack parent;
|
||||
|
||||
gint gain;
|
||||
gint balance;
|
||||
GstSunAudioTrackType track_num;
|
||||
} GstSunAudioMixerTrack;
|
||||
|
||||
typedef struct _GstSunAudioMixerTrackClass {
|
||||
GstMixerTrackClass parent;
|
||||
} GstSunAudioMixerTrackClass;
|
||||
|
||||
GType gst_sunaudiomixer_track_get_type (void);
|
||||
GstMixerTrack* gst_sunaudiomixer_track_new (GstSunAudioTrackType track_num);
|
||||
|
||||
G_END_DECLS
|
||||
|
||||
#endif /* __GST_SUNAUDIO_MIXER_TRACK_H__ */
|
|
@ -1,650 +0,0 @@
|
|||
/*
|
||||
* GStreamer - SunAudio sink
|
||||
* Copyright (C) 2004 David A. Schleef <ds@schleef.org>
|
||||
* Copyright (C) 2005,2006 Sun Microsystems, Inc.,
|
||||
* Brian Cameron <brian.cameron@sun.com>
|
||||
* Copyright (C) 2006 Jan Schmidt <thaytan@mad.scientist.com>
|
||||
*
|
||||
* 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.
|
||||
*/
|
||||
|
||||
/**
|
||||
* SECTION:element-sunaudiosink
|
||||
*
|
||||
* sunaudiosink is an audio sink designed to work with the Sun Audio
|
||||
* interface available in Solaris.
|
||||
*
|
||||
* <refsect2>
|
||||
* <title>Example launch line</title>
|
||||
* |[
|
||||
* gst-launch-1.0 audiotestsrc volume=0.5 ! sunaudiosink
|
||||
* ]|
|
||||
* </refsect2>
|
||||
*/
|
||||
|
||||
#ifdef HAVE_CONFIG_H
|
||||
#include "config.h"
|
||||
#endif
|
||||
|
||||
#include <fcntl.h>
|
||||
#include <string.h>
|
||||
#include <stropts.h>
|
||||
#include <unistd.h>
|
||||
#include <sys/mman.h>
|
||||
|
||||
#include "gstsunaudiosink.h"
|
||||
|
||||
GST_DEBUG_CATEGORY_EXTERN (sunaudio_debug);
|
||||
#define GST_CAT_DEFAULT sunaudio_debug
|
||||
|
||||
static void gst_sunaudiosink_base_init (gpointer g_class);
|
||||
static void gst_sunaudiosink_class_init (GstSunAudioSinkClass * klass);
|
||||
static void gst_sunaudiosink_init (GstSunAudioSink * filter);
|
||||
static void gst_sunaudiosink_dispose (GObject * object);
|
||||
static void gst_sunaudiosink_finalize (GObject * object);
|
||||
|
||||
static void gst_sunaudiosink_set_property (GObject * object, guint prop_id,
|
||||
const GValue * value, GParamSpec * pspec);
|
||||
static void gst_sunaudiosink_get_property (GObject * object, guint prop_id,
|
||||
GValue * value, GParamSpec * pspec);
|
||||
|
||||
static GstCaps *gst_sunaudiosink_getcaps (GstBaseSink * bsink);
|
||||
|
||||
static gboolean gst_sunaudiosink_open (GstAudioSink * asink);
|
||||
static gboolean gst_sunaudiosink_close (GstAudioSink * asink);
|
||||
static gboolean gst_sunaudiosink_prepare (GstAudioSink * asink,
|
||||
GstRingBufferSpec * spec);
|
||||
static gboolean gst_sunaudiosink_unprepare (GstAudioSink * asink);
|
||||
static guint gst_sunaudiosink_write (GstAudioSink * asink, gpointer data,
|
||||
guint length);
|
||||
static guint gst_sunaudiosink_delay (GstAudioSink * asink);
|
||||
static void gst_sunaudiosink_reset (GstAudioSink * asink);
|
||||
|
||||
#define DEFAULT_DEVICE "/dev/audio"
|
||||
enum
|
||||
{
|
||||
PROP_0,
|
||||
PROP_DEVICE,
|
||||
};
|
||||
|
||||
static GstStaticPadTemplate gst_sunaudiosink_factory =
|
||||
GST_STATIC_PAD_TEMPLATE ("sink",
|
||||
GST_PAD_SINK,
|
||||
GST_PAD_ALWAYS,
|
||||
GST_STATIC_CAPS ("audio/x-raw-int, "
|
||||
"endianness = (int) BYTE_ORDER, "
|
||||
"signed = (boolean) TRUE, " "width = (int) 16, " "depth = (int) 16, "
|
||||
/* [5510,48000] seems to be a Solaris limit */
|
||||
"rate = (int) [ 5510, 48000 ], " "channels = (int) [ 1, 2 ]")
|
||||
);
|
||||
|
||||
static GstElementClass *parent_class = NULL;
|
||||
|
||||
GType
|
||||
gst_sunaudiosink_get_type (void)
|
||||
{
|
||||
static GType plugin_type = 0;
|
||||
|
||||
if (!plugin_type) {
|
||||
static const GTypeInfo plugin_info = {
|
||||
sizeof (GstSunAudioSinkClass),
|
||||
gst_sunaudiosink_base_init,
|
||||
NULL,
|
||||
(GClassInitFunc) gst_sunaudiosink_class_init,
|
||||
NULL,
|
||||
NULL,
|
||||
sizeof (GstSunAudioSink),
|
||||
0,
|
||||
(GInstanceInitFunc) gst_sunaudiosink_init,
|
||||
};
|
||||
|
||||
plugin_type = g_type_register_static (GST_TYPE_AUDIO_SINK,
|
||||
"GstSunAudioSink", &plugin_info, 0);
|
||||
}
|
||||
return plugin_type;
|
||||
}
|
||||
|
||||
static void
|
||||
gst_sunaudiosink_dispose (GObject * object)
|
||||
{
|
||||
G_OBJECT_CLASS (parent_class)->dispose (object);
|
||||
}
|
||||
|
||||
static void
|
||||
gst_sunaudiosink_finalize (GObject * object)
|
||||
{
|
||||
GstSunAudioSink *sunaudiosink = GST_SUNAUDIO_SINK (object);
|
||||
|
||||
g_mutex_free (sunaudiosink->write_mutex);
|
||||
g_cond_free (sunaudiosink->sleep_cond);
|
||||
|
||||
g_free (sunaudiosink->device);
|
||||
|
||||
if (sunaudiosink->fd != -1) {
|
||||
close (sunaudiosink->fd);
|
||||
sunaudiosink->fd = -1;
|
||||
}
|
||||
|
||||
G_OBJECT_CLASS (parent_class)->finalize (object);
|
||||
}
|
||||
|
||||
static void
|
||||
gst_sunaudiosink_base_init (gpointer g_class)
|
||||
{
|
||||
GstElementClass *element_class = GST_ELEMENT_CLASS (g_class);
|
||||
|
||||
gst_element_class_add_static_pad_template (element_class,
|
||||
&gst_sunaudiosink_factory);
|
||||
gst_element_class_set_static_metadata (element_class, "Sun Audio Sink",
|
||||
"Sink/Audio", "Audio sink for Sun Audio devices",
|
||||
"David A. Schleef <ds@schleef.org>, "
|
||||
"Brian Cameron <brian.cameron@sun.com>");
|
||||
}
|
||||
|
||||
static void
|
||||
gst_sunaudiosink_class_init (GstSunAudioSinkClass * klass)
|
||||
{
|
||||
GObjectClass *gobject_class;
|
||||
GstElementClass *gstelement_class;
|
||||
GstBaseSinkClass *gstbasesink_class;
|
||||
GstBaseAudioSinkClass *gstbaseaudiosink_class;
|
||||
GstAudioSinkClass *gstaudiosink_class;
|
||||
|
||||
gobject_class = (GObjectClass *) klass;
|
||||
gstelement_class = (GstElementClass *) klass;
|
||||
gstbasesink_class = (GstBaseSinkClass *) klass;
|
||||
gstbaseaudiosink_class = (GstBaseAudioSinkClass *) klass;
|
||||
gstaudiosink_class = (GstAudioSinkClass *) klass;
|
||||
|
||||
parent_class = g_type_class_peek_parent (klass);
|
||||
|
||||
gobject_class->dispose = gst_sunaudiosink_dispose;
|
||||
gobject_class->finalize = gst_sunaudiosink_finalize;
|
||||
|
||||
gobject_class->set_property = gst_sunaudiosink_set_property;
|
||||
gobject_class->get_property = gst_sunaudiosink_get_property;
|
||||
|
||||
gstbasesink_class->get_caps = GST_DEBUG_FUNCPTR (gst_sunaudiosink_getcaps);
|
||||
|
||||
gstaudiosink_class->open = GST_DEBUG_FUNCPTR (gst_sunaudiosink_open);
|
||||
gstaudiosink_class->close = GST_DEBUG_FUNCPTR (gst_sunaudiosink_close);
|
||||
gstaudiosink_class->prepare = GST_DEBUG_FUNCPTR (gst_sunaudiosink_prepare);
|
||||
gstaudiosink_class->unprepare =
|
||||
GST_DEBUG_FUNCPTR (gst_sunaudiosink_unprepare);
|
||||
gstaudiosink_class->write = GST_DEBUG_FUNCPTR (gst_sunaudiosink_write);
|
||||
gstaudiosink_class->delay = GST_DEBUG_FUNCPTR (gst_sunaudiosink_delay);
|
||||
gstaudiosink_class->reset = GST_DEBUG_FUNCPTR (gst_sunaudiosink_reset);
|
||||
|
||||
g_object_class_install_property (gobject_class, PROP_DEVICE,
|
||||
g_param_spec_string ("device", "Device", "Audio Device (/dev/audio)",
|
||||
DEFAULT_DEVICE, G_PARAM_READWRITE | G_PARAM_STATIC_STRINGS));
|
||||
}
|
||||
|
||||
static void
|
||||
gst_sunaudiosink_init (GstSunAudioSink * sunaudiosink)
|
||||
{
|
||||
const char *audiodev;
|
||||
|
||||
GST_DEBUG_OBJECT (sunaudiosink, "initializing sunaudiosink");
|
||||
|
||||
sunaudiosink->fd = -1;
|
||||
|
||||
audiodev = g_getenv ("AUDIODEV");
|
||||
if (audiodev == NULL)
|
||||
audiodev = DEFAULT_DEVICE;
|
||||
sunaudiosink->device = g_strdup (audiodev);
|
||||
|
||||
/* mutex and gcond used to control the write method */
|
||||
sunaudiosink->write_mutex = g_mutex_new ();
|
||||
sunaudiosink->sleep_cond = g_cond_new ();
|
||||
}
|
||||
|
||||
static void
|
||||
gst_sunaudiosink_set_property (GObject * object, guint prop_id,
|
||||
const GValue * value, GParamSpec * pspec)
|
||||
{
|
||||
GstSunAudioSink *sunaudiosink;
|
||||
|
||||
sunaudiosink = GST_SUNAUDIO_SINK (object);
|
||||
|
||||
switch (prop_id) {
|
||||
case PROP_DEVICE:
|
||||
GST_OBJECT_LOCK (sunaudiosink);
|
||||
g_free (sunaudiosink->device);
|
||||
sunaudiosink->device = g_strdup (g_value_get_string (value));
|
||||
GST_OBJECT_UNLOCK (sunaudiosink);
|
||||
break;
|
||||
default:
|
||||
G_OBJECT_WARN_INVALID_PROPERTY_ID (object, prop_id, pspec);
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
static void
|
||||
gst_sunaudiosink_get_property (GObject * object, guint prop_id,
|
||||
GValue * value, GParamSpec * pspec)
|
||||
{
|
||||
GstSunAudioSink *sunaudiosink;
|
||||
|
||||
sunaudiosink = GST_SUNAUDIO_SINK (object);
|
||||
|
||||
switch (prop_id) {
|
||||
case PROP_DEVICE:
|
||||
GST_OBJECT_LOCK (sunaudiosink);
|
||||
g_value_set_string (value, sunaudiosink->device);
|
||||
GST_OBJECT_UNLOCK (sunaudiosink);
|
||||
break;
|
||||
default:
|
||||
G_OBJECT_WARN_INVALID_PROPERTY_ID (object, prop_id, pspec);
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
static GstCaps *
|
||||
gst_sunaudiosink_getcaps (GstBaseSink * bsink)
|
||||
{
|
||||
GstPadTemplate *pad_template;
|
||||
GstCaps *caps = NULL;
|
||||
GstSunAudioSink *sunaudiosink = GST_SUNAUDIO_SINK (bsink);
|
||||
|
||||
GST_DEBUG_OBJECT (sunaudiosink, "getcaps called");
|
||||
|
||||
pad_template = gst_static_pad_template_get (&gst_sunaudiosink_factory);
|
||||
caps = gst_caps_copy (gst_pad_template_get_caps (pad_template));
|
||||
|
||||
gst_object_unref (pad_template);
|
||||
|
||||
return caps;
|
||||
}
|
||||
|
||||
static gboolean
|
||||
gst_sunaudiosink_open (GstAudioSink * asink)
|
||||
{
|
||||
GstSunAudioSink *sunaudiosink = GST_SUNAUDIO_SINK (asink);
|
||||
int fd, ret;
|
||||
|
||||
/* First try to open non-blocking */
|
||||
GST_OBJECT_LOCK (sunaudiosink);
|
||||
fd = open (sunaudiosink->device, O_WRONLY | O_NONBLOCK);
|
||||
|
||||
if (fd >= 0) {
|
||||
close (fd);
|
||||
fd = open (sunaudiosink->device, O_WRONLY);
|
||||
}
|
||||
|
||||
if (fd == -1) {
|
||||
GST_OBJECT_UNLOCK (sunaudiosink);
|
||||
goto open_failed;
|
||||
}
|
||||
|
||||
sunaudiosink->fd = fd;
|
||||
GST_OBJECT_UNLOCK (sunaudiosink);
|
||||
|
||||
ret = ioctl (fd, AUDIO_GETDEV, &sunaudiosink->dev);
|
||||
if (ret == -1)
|
||||
goto ioctl_error;
|
||||
|
||||
GST_DEBUG_OBJECT (sunaudiosink, "name %s", sunaudiosink->dev.name);
|
||||
GST_DEBUG_OBJECT (sunaudiosink, "version %s", sunaudiosink->dev.version);
|
||||
GST_DEBUG_OBJECT (sunaudiosink, "config %s", sunaudiosink->dev.config);
|
||||
|
||||
ret = ioctl (fd, AUDIO_GETINFO, &sunaudiosink->info);
|
||||
if (ret == -1)
|
||||
goto ioctl_error;
|
||||
|
||||
GST_DEBUG_OBJECT (sunaudiosink, "monitor_gain %d",
|
||||
sunaudiosink->info.monitor_gain);
|
||||
GST_DEBUG_OBJECT (sunaudiosink, "output_muted %d",
|
||||
sunaudiosink->info.output_muted);
|
||||
GST_DEBUG_OBJECT (sunaudiosink, "hw_features %08x",
|
||||
sunaudiosink->info.hw_features);
|
||||
GST_DEBUG_OBJECT (sunaudiosink, "sw_features %08x",
|
||||
sunaudiosink->info.sw_features);
|
||||
GST_DEBUG_OBJECT (sunaudiosink, "sw_features_enabled %08x",
|
||||
sunaudiosink->info.sw_features_enabled);
|
||||
|
||||
return TRUE;
|
||||
|
||||
open_failed:
|
||||
GST_ELEMENT_ERROR (sunaudiosink, RESOURCE, OPEN_WRITE, (NULL),
|
||||
("can't open connection to Sun Audio device %s", sunaudiosink->device));
|
||||
return FALSE;
|
||||
ioctl_error:
|
||||
close (sunaudiosink->fd);
|
||||
GST_ELEMENT_ERROR (sunaudiosink, RESOURCE, SETTINGS, (NULL), ("%s",
|
||||
strerror (errno)));
|
||||
return FALSE;
|
||||
}
|
||||
|
||||
static gboolean
|
||||
gst_sunaudiosink_close (GstAudioSink * asink)
|
||||
{
|
||||
GstSunAudioSink *sunaudiosink = GST_SUNAUDIO_SINK (asink);
|
||||
|
||||
if (sunaudiosink->fd != -1) {
|
||||
close (sunaudiosink->fd);
|
||||
sunaudiosink->fd = -1;
|
||||
}
|
||||
return TRUE;
|
||||
}
|
||||
|
||||
static gboolean
|
||||
gst_sunaudiosink_prepare (GstAudioSink * asink, GstRingBufferSpec * spec)
|
||||
{
|
||||
GstSunAudioSink *sunaudiosink = GST_SUNAUDIO_SINK (asink);
|
||||
audio_info_t ainfo;
|
||||
int ret;
|
||||
int ports;
|
||||
|
||||
ret = ioctl (sunaudiosink->fd, AUDIO_GETINFO, &ainfo);
|
||||
if (ret == -1) {
|
||||
GST_ELEMENT_ERROR (sunaudiosink, RESOURCE, SETTINGS, (NULL), ("%s",
|
||||
strerror (errno)));
|
||||
return FALSE;
|
||||
}
|
||||
|
||||
if (spec->width != 16)
|
||||
return FALSE;
|
||||
|
||||
ports = ainfo.play.port;
|
||||
|
||||
AUDIO_INITINFO (&ainfo);
|
||||
|
||||
ainfo.play.sample_rate = spec->rate;
|
||||
ainfo.play.channels = spec->channels;
|
||||
ainfo.play.precision = spec->width;
|
||||
ainfo.play.encoding = AUDIO_ENCODING_LINEAR;
|
||||
ainfo.play.port = ports;
|
||||
|
||||
/* buffer_time for playback is not implemented in Solaris at the moment,
|
||||
but at some point in the future, it might be */
|
||||
ainfo.play.buffer_size =
|
||||
gst_util_uint64_scale (spec->rate * spec->bytes_per_sample,
|
||||
spec->buffer_time, GST_SECOND / GST_USECOND);
|
||||
|
||||
spec->silence_sample[0] = 0;
|
||||
spec->silence_sample[1] = 0;
|
||||
spec->silence_sample[2] = 0;
|
||||
spec->silence_sample[3] = 0;
|
||||
|
||||
ret = ioctl (sunaudiosink->fd, AUDIO_SETINFO, &ainfo);
|
||||
if (ret == -1) {
|
||||
GST_ELEMENT_ERROR (sunaudiosink, RESOURCE, SETTINGS, (NULL), ("%s",
|
||||
strerror (errno)));
|
||||
return FALSE;
|
||||
}
|
||||
|
||||
/* Now read back the info to find out the actual buffer size and set
|
||||
segtotal */
|
||||
AUDIO_INITINFO (&ainfo);
|
||||
|
||||
ret = ioctl (sunaudiosink->fd, AUDIO_GETINFO, &ainfo);
|
||||
if (ret == -1) {
|
||||
GST_ELEMENT_ERROR (sunaudiosink, RESOURCE, SETTINGS, (NULL), ("%s",
|
||||
strerror (errno)));
|
||||
return FALSE;
|
||||
}
|
||||
#if 0
|
||||
/* We don't actually use the buffer_size from the sound device, because
|
||||
* it seems it's just bogus sometimes */
|
||||
sunaudiosink->segtotal = spec->segtotal =
|
||||
ainfo.play.buffer_size / spec->segsize;
|
||||
#else
|
||||
sunaudiosink->segtotal = spec->segtotal;
|
||||
#endif
|
||||
sunaudiosink->segtotal_samples =
|
||||
spec->segtotal * spec->segsize / spec->bytes_per_sample;
|
||||
|
||||
sunaudiosink->segs_written = (gint) ainfo.play.eof;
|
||||
sunaudiosink->samples_written = ainfo.play.samples;
|
||||
sunaudiosink->bytes_per_sample = spec->bytes_per_sample;
|
||||
|
||||
GST_DEBUG_OBJECT (sunaudiosink, "Got device buffer_size of %u",
|
||||
ainfo.play.buffer_size);
|
||||
|
||||
return TRUE;
|
||||
}
|
||||
|
||||
static gboolean
|
||||
gst_sunaudiosink_unprepare (GstAudioSink * asink)
|
||||
{
|
||||
return TRUE;
|
||||
}
|
||||
|
||||
#define LOOP_WHILE_EINTR(v,func) do { (v) = (func); } \
|
||||
while ((v) == -1 && errno == EINTR);
|
||||
|
||||
/* Called with the write_mutex held */
|
||||
static void
|
||||
gst_sunaudio_sink_do_delay (GstSunAudioSink * sink)
|
||||
{
|
||||
GstBaseAudioSink *ba_sink = GST_BASE_AUDIO_SINK (sink);
|
||||
GstClockTime total_sleep;
|
||||
GstClockTime max_sleep;
|
||||
gint sleep_usecs;
|
||||
GTimeVal sleep_end;
|
||||
gint err;
|
||||
audio_info_t ainfo;
|
||||
guint diff;
|
||||
|
||||
/* This code below ensures that we don't race any further than buffer_time
|
||||
* ahead of the audio output, by sleeping if the next write call would cause
|
||||
* us to advance too far in the ring-buffer */
|
||||
LOOP_WHILE_EINTR (err, ioctl (sink->fd, AUDIO_GETINFO, &ainfo));
|
||||
if (err < 0)
|
||||
goto write_error;
|
||||
|
||||
/* Compute our offset from the output (copes with overflow) */
|
||||
diff = (guint) (sink->segs_written) - ainfo.play.eof;
|
||||
if (diff > sink->segtotal) {
|
||||
/* This implies that reset did a flush just as the sound device aquired
|
||||
* some buffers internally, and it causes us to be out of sync with the
|
||||
* eof measure. This corrects it */
|
||||
sink->segs_written = ainfo.play.eof;
|
||||
diff = 0;
|
||||
}
|
||||
|
||||
if (diff + 1 < sink->segtotal)
|
||||
return; /* no need to sleep at all */
|
||||
|
||||
/* Never sleep longer than the initial number of undrained segments in the
|
||||
device plus one */
|
||||
total_sleep = 0;
|
||||
max_sleep = (diff + 1) * (ba_sink->latency_time * GST_USECOND);
|
||||
/* sleep for a segment period between .eof polls */
|
||||
sleep_usecs = ba_sink->latency_time;
|
||||
|
||||
/* Current time is our reference point */
|
||||
g_get_current_time (&sleep_end);
|
||||
|
||||
/* If the next segment would take us too far along the ring buffer,
|
||||
* sleep for a bit to free up a slot. If there were a way to find out
|
||||
* when the eof field actually increments, we could use, but the only
|
||||
* notification mechanism seems to be SIGPOLL, which we can't use from
|
||||
* a support library */
|
||||
while (diff + 1 >= sink->segtotal && total_sleep < max_sleep) {
|
||||
GST_LOG_OBJECT (sink, "need to block to drain segment(s). "
|
||||
"Sleeping for %d us", sleep_usecs);
|
||||
|
||||
g_time_val_add (&sleep_end, sleep_usecs);
|
||||
|
||||
if (g_cond_timed_wait (sink->sleep_cond, sink->write_mutex, &sleep_end)) {
|
||||
GST_LOG_OBJECT (sink, "Waking up early due to reset");
|
||||
return; /* Got told to wake up */
|
||||
}
|
||||
total_sleep += (sleep_usecs * GST_USECOND);
|
||||
|
||||
LOOP_WHILE_EINTR (err, ioctl (sink->fd, AUDIO_GETINFO, &ainfo));
|
||||
if (err < 0)
|
||||
goto write_error;
|
||||
|
||||
/* Compute our (new) offset from the output (copes with overflow) */
|
||||
diff = (guint) g_atomic_int_get (&sink->segs_written) - ainfo.play.eof;
|
||||
}
|
||||
|
||||
return;
|
||||
|
||||
write_error:
|
||||
GST_ELEMENT_ERROR (sink, RESOURCE, OPEN_WRITE, (NULL),
|
||||
("Playback error on device '%s': %s", sink->device, strerror (errno)));
|
||||
return;
|
||||
}
|
||||
|
||||
static guint
|
||||
gst_sunaudiosink_write (GstAudioSink * asink, gpointer data, guint length)
|
||||
{
|
||||
GstSunAudioSink *sink = GST_SUNAUDIO_SINK (asink);
|
||||
|
||||
gint bytes_written, err;
|
||||
|
||||
g_mutex_lock (sink->write_mutex);
|
||||
if (sink->flushing) {
|
||||
/* Exit immediately if reset tells us to */
|
||||
g_mutex_unlock (sink->write_mutex);
|
||||
return length;
|
||||
}
|
||||
|
||||
LOOP_WHILE_EINTR (bytes_written, write (sink->fd, data, length));
|
||||
if (bytes_written < 0) {
|
||||
err = bytes_written;
|
||||
goto write_error;
|
||||
}
|
||||
|
||||
/* Increment our sample counter, for delay calcs */
|
||||
g_atomic_int_add (&sink->samples_written, length / sink->bytes_per_sample);
|
||||
|
||||
/* Don't consider the segment written if we didn't output the whole lot yet */
|
||||
if (bytes_written < length) {
|
||||
g_mutex_unlock (sink->write_mutex);
|
||||
return (guint) bytes_written;
|
||||
}
|
||||
|
||||
/* Write a zero length output to trigger increment of the eof field */
|
||||
LOOP_WHILE_EINTR (err, write (sink->fd, NULL, 0));
|
||||
if (err < 0)
|
||||
goto write_error;
|
||||
|
||||
/* Count this extra segment we've written */
|
||||
sink->segs_written += 1;
|
||||
|
||||
/* Now delay so we don't overrun the ring buffer */
|
||||
gst_sunaudio_sink_do_delay (sink);
|
||||
|
||||
g_mutex_unlock (sink->write_mutex);
|
||||
return length;
|
||||
|
||||
write_error:
|
||||
g_mutex_unlock (sink->write_mutex);
|
||||
|
||||
GST_ELEMENT_ERROR (sink, RESOURCE, OPEN_WRITE, (NULL),
|
||||
("Playback error on device '%s': %s", sink->device, strerror (errno)));
|
||||
return length; /* Say we wrote the segment to let the ringbuffer exit */
|
||||
}
|
||||
|
||||
/*
|
||||
* Provide the current number of unplayed samples that have been written
|
||||
* to the device */
|
||||
static guint
|
||||
gst_sunaudiosink_delay (GstAudioSink * asink)
|
||||
{
|
||||
GstSunAudioSink *sink = GST_SUNAUDIO_SINK (asink);
|
||||
audio_info_t ainfo;
|
||||
gint ret;
|
||||
guint offset;
|
||||
|
||||
ret = ioctl (sink->fd, AUDIO_GETINFO, &ainfo);
|
||||
if (G_UNLIKELY (ret == -1))
|
||||
return 0;
|
||||
|
||||
offset = (g_atomic_int_get (&sink->samples_written) - ainfo.play.samples);
|
||||
|
||||
/* If the offset is larger than the total ringbuffer size, then we asked
|
||||
between the write call and when samples_written is updated */
|
||||
if (G_UNLIKELY (offset > sink->segtotal_samples))
|
||||
return 0;
|
||||
|
||||
return offset;
|
||||
}
|
||||
|
||||
static void
|
||||
gst_sunaudiosink_reset (GstAudioSink * asink)
|
||||
{
|
||||
/* Get current values */
|
||||
GstSunAudioSink *sunaudiosink = GST_SUNAUDIO_SINK (asink);
|
||||
audio_info_t ainfo;
|
||||
int ret;
|
||||
|
||||
ret = ioctl (sunaudiosink->fd, AUDIO_GETINFO, &ainfo);
|
||||
if (ret == -1) {
|
||||
/*
|
||||
* Should never happen, but if we couldn't getinfo, then no point
|
||||
* trying to setinfo
|
||||
*/
|
||||
GST_ELEMENT_ERROR (sunaudiosink, RESOURCE, SETTINGS, (NULL), ("%s",
|
||||
strerror (errno)));
|
||||
return;
|
||||
}
|
||||
|
||||
/*
|
||||
* Pause the audio - so audio stops playing immediately rather than
|
||||
* waiting for the ringbuffer to empty.
|
||||
*/
|
||||
ainfo.play.pause = !NULL;
|
||||
ret = ioctl (sunaudiosink->fd, AUDIO_SETINFO, &ainfo);
|
||||
if (ret == -1) {
|
||||
GST_ELEMENT_ERROR (sunaudiosink, RESOURCE, SETTINGS, (NULL), ("%s",
|
||||
strerror (errno)));
|
||||
}
|
||||
|
||||
/* Flush the audio */
|
||||
ret = ioctl (sunaudiosink->fd, I_FLUSH, FLUSHW);
|
||||
if (ret == -1) {
|
||||
GST_ELEMENT_ERROR (sunaudiosink, RESOURCE, SETTINGS, (NULL), ("%s",
|
||||
strerror (errno)));
|
||||
}
|
||||
|
||||
/* Now, we take the write_mutex and signal to ensure the write thread
|
||||
* is not busy, and we signal the condition to wake up any sleeper,
|
||||
* then we flush again in case the write wrote something after we flushed,
|
||||
* and finally release the lock and unpause */
|
||||
g_mutex_lock (sunaudiosink->write_mutex);
|
||||
sunaudiosink->flushing = TRUE;
|
||||
|
||||
g_cond_signal (sunaudiosink->sleep_cond);
|
||||
|
||||
ret = ioctl (sunaudiosink->fd, I_FLUSH, FLUSHW);
|
||||
if (ret == -1) {
|
||||
GST_ELEMENT_ERROR (sunaudiosink, RESOURCE, SETTINGS, (NULL), ("%s",
|
||||
strerror (errno)));
|
||||
}
|
||||
|
||||
/* unpause the audio */
|
||||
ainfo.play.pause = NULL;
|
||||
ret = ioctl (sunaudiosink->fd, AUDIO_SETINFO, &ainfo);
|
||||
if (ret == -1) {
|
||||
GST_ELEMENT_ERROR (sunaudiosink, RESOURCE, SETTINGS, (NULL), ("%s",
|
||||
strerror (errno)));
|
||||
}
|
||||
|
||||
/* After flushing the audio device, we need to remeasure the sample count
|
||||
* and segments written count so we're in sync with the device */
|
||||
|
||||
sunaudiosink->segs_written = ainfo.play.eof;
|
||||
g_atomic_int_set (&sunaudiosink->samples_written, ainfo.play.samples);
|
||||
|
||||
sunaudiosink->flushing = FALSE;
|
||||
g_mutex_unlock (sunaudiosink->write_mutex);
|
||||
}
|
|
@ -1,78 +0,0 @@
|
|||
/*
|
||||
* GStreamer - SunAudio sink
|
||||
* Copyright (C) 2004 David A. Schleef <ds@schleef.org>
|
||||
* Copyright (C) 2005,2006 Sun Microsystems, Inc.,
|
||||
* Brian Cameron <brian.cameron@sun.com>
|
||||
* Copyright (C) 2006 Jan Schmidt <thaytan@mad.scientist.com>
|
||||
*
|
||||
* gstsunaudiosink.h:
|
||||
*
|
||||
* 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 __GST_SUNAUDIO_SINK_H__
|
||||
#define __GST_SUNAUDIO_SINK_H__
|
||||
|
||||
#include <sys/audioio.h>
|
||||
#include <gst/gst.h>
|
||||
#include <gst/audio/gstaudiosink.h>
|
||||
|
||||
G_BEGIN_DECLS
|
||||
|
||||
#define GST_TYPE_SUNAUDIO_SINK (gst_sunaudiosink_get_type())
|
||||
#define GST_SUNAUDIO_SINK(obj) (G_TYPE_CHECK_INSTANCE_CAST((obj),GST_TYPE_SUNAUDIO_SINK,GstSunAudioSink))
|
||||
#define GST_SUNAUDIO_SINK_CLASS(klass) (G_TYPE_CHECK_CLASS_CAST((klass),GST_TYPE_SUNAUDIO_SINK,GstSunAudioSinkClass))
|
||||
#define GST_IS_SUNAUDIO_SINK(obj) (G_TYPE_CHECK_INSTANCE_TYPE((obj),GST_TYPE_SUNAUDIO_SINK))
|
||||
#define GST_IS_SUNAUDIO_SINK_CLASS(klass) (G_TYPE_CHECK_CLASS_TYPE((klass),GST_TYPE_SUNAUDIO_SINK))
|
||||
|
||||
typedef struct _GstSunAudioSink GstSunAudioSink;
|
||||
typedef struct _GstSunAudioSinkClass GstSunAudioSinkClass;
|
||||
|
||||
struct _GstSunAudioSink {
|
||||
GstAudioSink sink;
|
||||
|
||||
gchar *device;
|
||||
gint fd;
|
||||
|
||||
audio_device_t dev;
|
||||
audio_info_t info;
|
||||
|
||||
/* Number of segments the ringbuffer is configured for */
|
||||
guint segtotal;
|
||||
guint segtotal_samples;
|
||||
|
||||
/* Number of segments written to the device */
|
||||
gint segs_written;
|
||||
/* Number of samples written to the device */
|
||||
gint samples_written;
|
||||
guint bytes_per_sample;
|
||||
|
||||
/* mutex and gcond used to control the write method */
|
||||
GMutex *write_mutex;
|
||||
GCond *sleep_cond;
|
||||
gboolean flushing;
|
||||
};
|
||||
|
||||
struct _GstSunAudioSinkClass {
|
||||
GstAudioSinkClass parent_class;
|
||||
};
|
||||
|
||||
GType gst_sunaudiosink_get_type(void);
|
||||
|
||||
G_END_DECLS
|
||||
|
||||
#endif /* __GST_SUNAUDIO_SINK_H__ */
|
||||
|
|
@ -1,421 +0,0 @@
|
|||
/*
|
||||
* GStreamer - SunAudio source
|
||||
* Copyright (C) 2005,2006 Sun Microsystems, Inc.,
|
||||
* Brian Cameron <brian.cameron@sun.com>
|
||||
*
|
||||
* gstsunaudiosrc.c:
|
||||
*
|
||||
* 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.
|
||||
*/
|
||||
|
||||
/**
|
||||
* SECTION:element-sunaudiosrc
|
||||
*
|
||||
* sunaudiosrc is an audio source designed to work with the Sun Audio
|
||||
* interface available in Solaris.
|
||||
*
|
||||
* <refsect2>
|
||||
* <title>Example launch line</title>
|
||||
* |[
|
||||
* gst-launch-1.0 sunaudiosrc ! wavenc ! filesink location=audio.wav
|
||||
* ]|
|
||||
* </refsect2>
|
||||
*/
|
||||
|
||||
#ifdef HAVE_CONFIG_H
|
||||
#include "config.h"
|
||||
#endif
|
||||
|
||||
#include <fcntl.h>
|
||||
#include <string.h>
|
||||
#include <unistd.h>
|
||||
#include <stropts.h>
|
||||
#include <sys/mixer.h>
|
||||
|
||||
#include "gstsunaudiosrc.h"
|
||||
|
||||
GST_DEBUG_CATEGORY_EXTERN (sunaudio_debug);
|
||||
#define GST_CAT_DEFAULT sunaudio_debug
|
||||
|
||||
static void gst_sunaudiosrc_base_init (gpointer g_class);
|
||||
static void gst_sunaudiosrc_class_init (GstSunAudioSrcClass * klass);
|
||||
static void gst_sunaudiosrc_init (GstSunAudioSrc * sunaudiosrc,
|
||||
GstSunAudioSrcClass * g_class);
|
||||
static void gst_sunaudiosrc_dispose (GObject * object);
|
||||
|
||||
static void gst_sunaudiosrc_set_property (GObject * object, guint prop_id,
|
||||
const GValue * value, GParamSpec * pspec);
|
||||
static void gst_sunaudiosrc_get_property (GObject * object, guint prop_id,
|
||||
GValue * value, GParamSpec * pspec);
|
||||
|
||||
static GstCaps *gst_sunaudiosrc_getcaps (GstBaseSrc * bsrc);
|
||||
|
||||
static gboolean gst_sunaudiosrc_open (GstAudioSrc * asrc);
|
||||
static gboolean gst_sunaudiosrc_close (GstAudioSrc * asrc);
|
||||
static gboolean gst_sunaudiosrc_prepare (GstAudioSrc * asrc,
|
||||
GstRingBufferSpec * spec);
|
||||
static gboolean gst_sunaudiosrc_unprepare (GstAudioSrc * asrc);
|
||||
static guint gst_sunaudiosrc_read (GstAudioSrc * asrc, gpointer data,
|
||||
guint length);
|
||||
static guint gst_sunaudiosrc_delay (GstAudioSrc * asrc);
|
||||
static void gst_sunaudiosrc_reset (GstAudioSrc * asrc);
|
||||
|
||||
#define DEFAULT_DEVICE "/dev/audio"
|
||||
|
||||
enum
|
||||
{
|
||||
PROP_0,
|
||||
PROP_DEVICE
|
||||
};
|
||||
|
||||
GST_BOILERPLATE_WITH_INTERFACE (GstSunAudioSrc, gst_sunaudiosrc,
|
||||
GstAudioSrc, GST_TYPE_AUDIO_SRC, GstMixer, GST_TYPE_MIXER, gst_sunaudiosrc);
|
||||
|
||||
GST_IMPLEMENT_SUNAUDIO_MIXER_CTRL_METHODS (GstSunAudioSrc, gst_sunaudiosrc);
|
||||
|
||||
static GstStaticPadTemplate gst_sunaudiosrc_factory =
|
||||
GST_STATIC_PAD_TEMPLATE ("src",
|
||||
GST_PAD_SRC,
|
||||
GST_PAD_ALWAYS,
|
||||
GST_STATIC_CAPS ("audio/x-raw-int, "
|
||||
"endianness = (int) BYTE_ORDER, "
|
||||
"signed = (boolean) TRUE, " "width = (int) 16, " "depth = (int) 16, "
|
||||
/* [5510,48000] seems to be a Solaris limit */
|
||||
"rate = (int) [ 5510, 48000 ], " "channels = (int) [ 1, 2 ]")
|
||||
);
|
||||
|
||||
static void
|
||||
gst_sunaudiosrc_dispose (GObject * object)
|
||||
{
|
||||
G_OBJECT_CLASS (parent_class)->dispose (object);
|
||||
}
|
||||
|
||||
static void
|
||||
gst_sunaudiosrc_base_init (gpointer g_class)
|
||||
{
|
||||
GstElementClass *element_class = GST_ELEMENT_CLASS (g_class);
|
||||
|
||||
gst_element_class_add_static_pad_template (element_class,
|
||||
&gst_sunaudiosrc_factory);
|
||||
gst_element_class_set_static_metadata (element_class, "Sun Audio Source",
|
||||
"Source/Audio", "Audio source for Sun Audio devices",
|
||||
"Brian Cameron <brian.cameron@sun.com>");
|
||||
}
|
||||
|
||||
static void
|
||||
gst_sunaudiosrc_class_init (GstSunAudioSrcClass * klass)
|
||||
{
|
||||
GObjectClass *gobject_class;
|
||||
GstElementClass *gstelement_class;
|
||||
GstBaseSrcClass *gstbasesrc_class;
|
||||
GstBaseAudioSrcClass *gstbaseaudiosrc_class;
|
||||
GstAudioSrcClass *gstaudiosrc_class;
|
||||
|
||||
gobject_class = (GObjectClass *) klass;
|
||||
gstelement_class = (GstElementClass *) klass;
|
||||
gstbasesrc_class = (GstBaseSrcClass *) klass;
|
||||
gstbaseaudiosrc_class = (GstBaseAudioSrcClass *) klass;
|
||||
gstaudiosrc_class = (GstAudioSrcClass *) klass;
|
||||
|
||||
gobject_class->dispose = gst_sunaudiosrc_dispose;
|
||||
gobject_class->get_property = gst_sunaudiosrc_get_property;
|
||||
gobject_class->set_property = gst_sunaudiosrc_set_property;
|
||||
|
||||
gstbasesrc_class->get_caps = GST_DEBUG_FUNCPTR (gst_sunaudiosrc_getcaps);
|
||||
|
||||
gstaudiosrc_class->open = GST_DEBUG_FUNCPTR (gst_sunaudiosrc_open);
|
||||
gstaudiosrc_class->prepare = GST_DEBUG_FUNCPTR (gst_sunaudiosrc_prepare);
|
||||
gstaudiosrc_class->unprepare = GST_DEBUG_FUNCPTR (gst_sunaudiosrc_unprepare);
|
||||
gstaudiosrc_class->close = GST_DEBUG_FUNCPTR (gst_sunaudiosrc_close);
|
||||
gstaudiosrc_class->read = GST_DEBUG_FUNCPTR (gst_sunaudiosrc_read);
|
||||
gstaudiosrc_class->delay = GST_DEBUG_FUNCPTR (gst_sunaudiosrc_delay);
|
||||
gstaudiosrc_class->reset = GST_DEBUG_FUNCPTR (gst_sunaudiosrc_reset);
|
||||
|
||||
g_object_class_install_property (gobject_class, PROP_DEVICE,
|
||||
g_param_spec_string ("device", "Device",
|
||||
"SunAudio device (usually /dev/audio)", DEFAULT_DEVICE,
|
||||
G_PARAM_READWRITE | G_PARAM_STATIC_STRINGS));
|
||||
}
|
||||
|
||||
static void
|
||||
gst_sunaudiosrc_init (GstSunAudioSrc * sunaudiosrc,
|
||||
GstSunAudioSrcClass * g_class)
|
||||
{
|
||||
const char *audiodev;
|
||||
|
||||
GST_DEBUG_OBJECT (sunaudiosrc, "initializing sunaudiosrc");
|
||||
|
||||
sunaudiosrc->fd = -1;
|
||||
|
||||
audiodev = g_getenv ("AUDIODEV");
|
||||
if (audiodev == NULL)
|
||||
audiodev = DEFAULT_DEVICE;
|
||||
sunaudiosrc->device = g_strdup (audiodev);
|
||||
}
|
||||
|
||||
static void
|
||||
gst_sunaudiosrc_set_property (GObject * object, guint prop_id,
|
||||
const GValue * value, GParamSpec * pspec)
|
||||
{
|
||||
GstSunAudioSrc *sunaudiosrc;
|
||||
|
||||
sunaudiosrc = GST_SUNAUDIO_SRC (object);
|
||||
|
||||
switch (prop_id) {
|
||||
case PROP_DEVICE:
|
||||
g_free (sunaudiosrc->device);
|
||||
sunaudiosrc->device = g_value_dup_string (value);
|
||||
break;
|
||||
default:
|
||||
G_OBJECT_WARN_INVALID_PROPERTY_ID (object, prop_id, pspec);
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
static void
|
||||
gst_sunaudiosrc_get_property (GObject * object, guint prop_id,
|
||||
GValue * value, GParamSpec * pspec)
|
||||
{
|
||||
GstSunAudioSrc *sunaudiosrc;
|
||||
|
||||
sunaudiosrc = GST_SUNAUDIO_SRC (object);
|
||||
|
||||
switch (prop_id) {
|
||||
case PROP_DEVICE:
|
||||
g_value_set_string (value, sunaudiosrc->device);
|
||||
break;
|
||||
default:
|
||||
G_OBJECT_WARN_INVALID_PROPERTY_ID (object, prop_id, pspec);
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
static GstCaps *
|
||||
gst_sunaudiosrc_getcaps (GstBaseSrc * bsrc)
|
||||
{
|
||||
GstPadTemplate *pad_template;
|
||||
GstCaps *caps = NULL;
|
||||
GstSunAudioSrc *sunaudiosrc = GST_SUNAUDIO_SRC (bsrc);
|
||||
|
||||
GST_DEBUG_OBJECT (sunaudiosrc, "getcaps called");
|
||||
|
||||
pad_template = gst_static_pad_template_get (&gst_sunaudiosrc_factory);
|
||||
caps = gst_caps_copy (gst_pad_template_get_caps (pad_template));
|
||||
|
||||
gst_object_unref (pad_template);
|
||||
|
||||
return caps;
|
||||
}
|
||||
|
||||
static gboolean
|
||||
gst_sunaudiosrc_open (GstAudioSrc * asrc)
|
||||
{
|
||||
GstSunAudioSrc *sunaudiosrc = GST_SUNAUDIO_SRC (asrc);
|
||||
int fd, ret;
|
||||
|
||||
fd = open (sunaudiosrc->device, O_RDONLY);
|
||||
|
||||
if (fd == -1) {
|
||||
GST_ELEMENT_ERROR (sunaudiosrc, RESOURCE, OPEN_READ, (NULL),
|
||||
("can't open connection to Sun Audio device %s", sunaudiosrc->device));
|
||||
|
||||
return FALSE;
|
||||
}
|
||||
|
||||
sunaudiosrc->fd = fd;
|
||||
|
||||
ret = ioctl (fd, AUDIO_GETDEV, &sunaudiosrc->dev);
|
||||
if (ret == -1) {
|
||||
GST_ELEMENT_ERROR (sunaudiosrc, RESOURCE, SETTINGS, (NULL), ("%s",
|
||||
strerror (errno)));
|
||||
return FALSE;
|
||||
}
|
||||
|
||||
GST_DEBUG_OBJECT (sunaudiosrc, "name %s", sunaudiosrc->dev.name);
|
||||
GST_DEBUG_OBJECT (sunaudiosrc, "version %s", sunaudiosrc->dev.version);
|
||||
GST_DEBUG_OBJECT (sunaudiosrc, "config %s", sunaudiosrc->dev.config);
|
||||
|
||||
ret = ioctl (fd, AUDIO_GETINFO, &sunaudiosrc->info);
|
||||
if (ret == -1) {
|
||||
GST_ELEMENT_ERROR (sunaudiosrc, RESOURCE, SETTINGS, (NULL), ("%s",
|
||||
strerror (errno)));
|
||||
return FALSE;
|
||||
}
|
||||
|
||||
GST_DEBUG_OBJECT (sunaudiosrc, "monitor_gain %d",
|
||||
sunaudiosrc->info.monitor_gain);
|
||||
GST_DEBUG_OBJECT (sunaudiosrc, "output_muted %d",
|
||||
sunaudiosrc->info.output_muted);
|
||||
GST_DEBUG_OBJECT (sunaudiosrc, "hw_features %08x",
|
||||
sunaudiosrc->info.hw_features);
|
||||
GST_DEBUG_OBJECT (sunaudiosrc, "sw_features %08x",
|
||||
sunaudiosrc->info.sw_features);
|
||||
GST_DEBUG_OBJECT (sunaudiosrc, "sw_features_enabled %08x",
|
||||
sunaudiosrc->info.sw_features_enabled);
|
||||
|
||||
if (!sunaudiosrc->mixer) {
|
||||
const char *audiodev;
|
||||
|
||||
audiodev = g_getenv ("AUDIODEV");
|
||||
if (audiodev == NULL) {
|
||||
sunaudiosrc->mixer = gst_sunaudiomixer_ctrl_new ("/dev/audioctl");
|
||||
} else {
|
||||
gchar *device = g_strdup_printf ("%sctl", audiodev);
|
||||
|
||||
sunaudiosrc->mixer = gst_sunaudiomixer_ctrl_new (device);
|
||||
g_free (device);
|
||||
}
|
||||
}
|
||||
|
||||
return TRUE;
|
||||
}
|
||||
|
||||
static gboolean
|
||||
gst_sunaudiosrc_close (GstAudioSrc * asrc)
|
||||
{
|
||||
GstSunAudioSrc *sunaudiosrc = GST_SUNAUDIO_SRC (asrc);
|
||||
|
||||
close (sunaudiosrc->fd);
|
||||
sunaudiosrc->fd = -1;
|
||||
|
||||
if (sunaudiosrc->mixer) {
|
||||
gst_sunaudiomixer_ctrl_free (sunaudiosrc->mixer);
|
||||
sunaudiosrc->mixer = NULL;
|
||||
}
|
||||
|
||||
return TRUE;
|
||||
}
|
||||
|
||||
static gboolean
|
||||
gst_sunaudiosrc_prepare (GstAudioSrc * asrc, GstRingBufferSpec * spec)
|
||||
{
|
||||
GstSunAudioSrc *sunaudiosrc = GST_SUNAUDIO_SRC (asrc);
|
||||
audio_info_t ainfo;
|
||||
int ret;
|
||||
GstSunAudioMixerCtrl *mixer;
|
||||
struct audio_info audioinfo;
|
||||
|
||||
ret = ioctl (sunaudiosrc->fd, AUDIO_GETINFO, &ainfo);
|
||||
if (ret == -1) {
|
||||
GST_ELEMENT_ERROR (sunaudiosrc, RESOURCE, SETTINGS, (NULL), ("%s",
|
||||
strerror (errno)));
|
||||
return FALSE;
|
||||
}
|
||||
|
||||
if (spec->width != 16)
|
||||
return FALSE;
|
||||
|
||||
AUDIO_INITINFO (&ainfo);
|
||||
|
||||
ainfo.record.sample_rate = spec->rate;
|
||||
ainfo.record.precision = spec->width;
|
||||
ainfo.record.channels = spec->channels;
|
||||
ainfo.record.encoding = AUDIO_ENCODING_LINEAR;
|
||||
ainfo.record.buffer_size = spec->buffer_time;
|
||||
|
||||
mixer = sunaudiosrc->mixer;
|
||||
|
||||
if (ioctl (mixer->mixer_fd, AUDIO_GETINFO, &audioinfo) < 0) {
|
||||
g_warning ("Error getting audio device volume");
|
||||
}
|
||||
ainfo.record.port = audioinfo.record.port;
|
||||
ainfo.record.gain = audioinfo.record.gain;
|
||||
ainfo.record.balance = audioinfo.record.balance;
|
||||
|
||||
spec->segsize = 128;
|
||||
spec->segtotal = spec->buffer_time / 128;
|
||||
|
||||
spec->silence_sample[0] = 0;
|
||||
spec->silence_sample[1] = 0;
|
||||
spec->silence_sample[2] = 0;
|
||||
spec->silence_sample[3] = 0;
|
||||
|
||||
ret = ioctl (sunaudiosrc->fd, AUDIO_SETINFO, &ainfo);
|
||||
if (ret == -1) {
|
||||
GST_ELEMENT_ERROR (sunaudiosrc, RESOURCE, SETTINGS, (NULL), ("%s",
|
||||
strerror (errno)));
|
||||
return FALSE;
|
||||
}
|
||||
|
||||
|
||||
ioctl (sunaudiosrc->fd, I_FLUSH, FLUSHR);
|
||||
|
||||
return TRUE;
|
||||
}
|
||||
|
||||
static gboolean
|
||||
gst_sunaudiosrc_unprepare (GstAudioSrc * asrc)
|
||||
{
|
||||
return TRUE;
|
||||
}
|
||||
|
||||
static guint
|
||||
gst_sunaudiosrc_read (GstAudioSrc * asrc, gpointer data, guint length)
|
||||
{
|
||||
return read (GST_SUNAUDIO_SRC (asrc)->fd, data, length);
|
||||
}
|
||||
|
||||
static guint
|
||||
gst_sunaudiosrc_delay (GstAudioSrc * asrc)
|
||||
{
|
||||
return 0;
|
||||
}
|
||||
|
||||
static void
|
||||
gst_sunaudiosrc_reset (GstAudioSrc * asrc)
|
||||
{
|
||||
/* Get current values */
|
||||
GstSunAudioSrc *sunaudiosrc = GST_SUNAUDIO_SRC (asrc);
|
||||
audio_info_t ainfo;
|
||||
int ret;
|
||||
|
||||
ret = ioctl (sunaudiosrc->fd, AUDIO_GETINFO, &ainfo);
|
||||
if (ret == -1) {
|
||||
/*
|
||||
* Should never happen, but if we couldn't getinfo, then no point
|
||||
* trying to setinfo
|
||||
*/
|
||||
GST_ELEMENT_ERROR (sunaudiosrc, RESOURCE, SETTINGS, (NULL), ("%s",
|
||||
strerror (errno)));
|
||||
return;
|
||||
}
|
||||
|
||||
/*
|
||||
* Pause the audio - so audio stops playing immediately rather than
|
||||
* waiting for the ringbuffer to empty.
|
||||
*/
|
||||
ainfo.record.pause = !NULL;
|
||||
ret = ioctl (sunaudiosrc->fd, AUDIO_SETINFO, &ainfo);
|
||||
if (ret == -1) {
|
||||
GST_ELEMENT_ERROR (sunaudiosrc, RESOURCE, SETTINGS, (NULL), ("%s",
|
||||
strerror (errno)));
|
||||
}
|
||||
|
||||
/* Flush the audio */
|
||||
ret = ioctl (sunaudiosrc->fd, I_FLUSH, FLUSHR);
|
||||
if (ret == -1) {
|
||||
GST_ELEMENT_ERROR (sunaudiosrc, RESOURCE, SETTINGS, (NULL), ("%s",
|
||||
strerror (errno)));
|
||||
}
|
||||
|
||||
/* unpause the audio */
|
||||
ainfo.record.pause = NULL;
|
||||
ret = ioctl (sunaudiosrc->fd, AUDIO_SETINFO, &ainfo);
|
||||
if (ret == -1) {
|
||||
GST_ELEMENT_ERROR (sunaudiosrc, RESOURCE, SETTINGS, (NULL), ("%s",
|
||||
strerror (errno)));
|
||||
}
|
||||
}
|
|
@ -1,67 +0,0 @@
|
|||
/* GStreamer - SunAudio source
|
||||
* Copyright (C) 2005,2006 Sun Microsystems, Inc.,
|
||||
* Brian Cameron <brian.cameron@sun.com>
|
||||
*
|
||||
* gstsunaudiosrc.h:
|
||||
*
|
||||
* 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 __GST_SUNAUDIO_SRC_H__
|
||||
#define __GST_SUNAUDIO_SRC_H__
|
||||
|
||||
#include <sys/audioio.h>
|
||||
#include <gst/gst.h>
|
||||
#include <gst/audio/gstaudiosrc.h>
|
||||
|
||||
#include "gstsunaudiomixerctrl.h"
|
||||
|
||||
G_BEGIN_DECLS
|
||||
|
||||
#define GST_TYPE_SUNAUDIO_SRC (gst_sunaudiosrc_get_type())
|
||||
#define GST_SUNAUDIO_SRC(obj) (G_TYPE_CHECK_INSTANCE_CAST((obj),GST_TYPE_SUNAUDIO_SRC,GstSunAudioSrc))
|
||||
#define GST_SUNAUDIO_SRC_CLASS(klass) (G_TYPE_CHECK_CLASS_CAST((klass),GST_TYPE_SUNAUDIO_SRC,GstSunAudioSrcClass))
|
||||
#define GST_IS_SUNAUDIO_SRC(obj) (G_TYPE_CHECK_INSTANCE_TYPE((obj),GST_TYPE_SUNAUDIO_SRC))
|
||||
#define GST_IS_SUNAUDIO_SRC_CLASS(klass) (G_TYPE_CHECK_CLASS_TYPE((klass),GST_TYPE_SUNAUDIO_SRC))
|
||||
|
||||
typedef struct _GstSunAudioSrc GstSunAudioSrc;
|
||||
typedef struct _GstSunAudioSrcClass GstSunAudioSrcClass;
|
||||
|
||||
struct _GstSunAudioSrc {
|
||||
GstAudioSrc src;
|
||||
|
||||
gchar *device;
|
||||
gint fd;
|
||||
gint control_fd;
|
||||
|
||||
audio_device_t dev;
|
||||
audio_info_t info;
|
||||
|
||||
gint bytes_per_sample;
|
||||
|
||||
GstSunAudioMixerCtrl *mixer;
|
||||
};
|
||||
|
||||
struct _GstSunAudioSrcClass {
|
||||
GstAudioSrcClass parent_class;
|
||||
};
|
||||
|
||||
GType gst_sunaudiosrc_get_type(void);
|
||||
|
||||
G_END_DECLS
|
||||
|
||||
#endif /* __GST_SUNAUDIO_SRC_H__ */
|
||||
|
|
@ -255,12 +255,6 @@ else
|
|||
check_spectrum =
|
||||
endif
|
||||
|
||||
if USE_SUNAUDIO
|
||||
check_sunaudio = elements/sunaudio
|
||||
else
|
||||
check_sunaudio =
|
||||
endif
|
||||
|
||||
if USE_PLUGIN_SHAPEWIPE
|
||||
check_shapewipe = elements/shapewipe
|
||||
else
|
||||
|
@ -382,7 +376,6 @@ check_PROGRAMS = \
|
|||
$(check_shapewipe) \
|
||||
$(check_soup) \
|
||||
$(check_spectrum) \
|
||||
$(check_sunaudio) \
|
||||
$(check_taglib) \
|
||||
$(check_udp) \
|
||||
$(check_videobox) \
|
||||
|
@ -552,13 +545,6 @@ elements_rtpmux_LDADD = $(GST_PLUGINS_BASE_LIBS) -lgstrtp-$(GST_API_VERSION) $(G
|
|||
elements_souphttpsrc_CFLAGS = $(SOUP_CFLAGS) $(AM_CFLAGS)
|
||||
elements_souphttpsrc_LDADD = $(SOUP_LIBS) $(LDADD)
|
||||
|
||||
elements_sunaudio_CFLAGS = \
|
||||
$(GST_PLUGINS_BASE_CFLAGS) $(CFLAGS) \
|
||||
$(AM_CFLAGS)
|
||||
elements_sunaudio_LDADD = \
|
||||
$(GST_PLUGINS_BASE_LIBS) \
|
||||
$(LDADD)
|
||||
|
||||
elements_udpsrc_CFLAGS = $(AM_CFLAGS) $(GIO_CFLAGS)
|
||||
elements_udpsrc_LDADD = $(LDADD) $(GIO_LIBS)
|
||||
|
||||
|
|
1
tests/check/elements/.gitignore
vendored
1
tests/check/elements/.gitignore
vendored
|
@ -67,7 +67,6 @@ shapewipe
|
|||
souphttpsrc
|
||||
spectrum
|
||||
splitmux
|
||||
sunaudio
|
||||
udpsink
|
||||
udpsrc
|
||||
videocrop
|
||||
|
|
|
@ -1,95 +0,0 @@
|
|||
/* GStreamer unit tests for the sun audio elements
|
||||
*
|
||||
* Copyright (C) 2007 Tim-Philipp Müller <tim centricular net>
|
||||
*
|
||||
* 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 <gst/check/gstcheck.h>
|
||||
#include <gst/interfaces/propertyprobe.h>
|
||||
#include <gst/interfaces/mixer.h>
|
||||
#include <gst/gst.h>
|
||||
|
||||
GST_START_TEST (test_sun_audio_mixer_track)
|
||||
{
|
||||
GstStateChangeReturn state_ret;
|
||||
GstElement *mixer;
|
||||
GList *tracks, *l;
|
||||
|
||||
mixer = gst_element_factory_make ("sunaudiomixer", "sunaudiomixer");
|
||||
fail_unless (mixer != NULL, "Failed to create 'sunaudiomixer' element!");
|
||||
|
||||
state_ret = gst_element_set_state (mixer, GST_STATE_READY);
|
||||
if (state_ret != GST_STATE_CHANGE_SUCCESS) {
|
||||
gst_object_unref (mixer);
|
||||
return;
|
||||
}
|
||||
|
||||
GST_LOG ("opened sunaudiomixer");
|
||||
fail_unless (GST_IS_MIXER (mixer), "is not a GstMixer?!");
|
||||
|
||||
tracks = (GList *) gst_mixer_list_tracks (GST_MIXER (mixer));
|
||||
for (l = tracks; l != NULL; l = l->next) {
|
||||
GObjectClass *klass;
|
||||
GstMixerTrack *track;
|
||||
gchar *ulabel = NULL, *label = NULL;
|
||||
|
||||
track = GST_MIXER_TRACK (l->data);
|
||||
|
||||
g_object_get (track, "label", &label, NULL);
|
||||
fail_unless (label == NULL || g_utf8_validate (label, -1, NULL));
|
||||
|
||||
/* FIXME: remove this check once we depend on -base >= 0.10.12.1 */
|
||||
klass = G_OBJECT_GET_CLASS (track);
|
||||
if (g_object_class_find_property (klass, "untranslated-label")) {
|
||||
g_object_get (track, "untranslated-label", &ulabel, NULL);
|
||||
}
|
||||
|
||||
if (ulabel != NULL) {
|
||||
gchar *p;
|
||||
|
||||
for (p = ulabel; p != NULL && *p != '\0'; ++p) {
|
||||
fail_unless (g_ascii_isprint (*p),
|
||||
"untranslated label '%s' not printable ASCII", ulabel);
|
||||
}
|
||||
}
|
||||
GST_DEBUG ("%s: %s", GST_STR_NULL (ulabel), GST_STR_NULL (label));
|
||||
g_free (label);
|
||||
g_free (ulabel);
|
||||
}
|
||||
|
||||
fail_unless_equals_int (gst_element_set_state (mixer, GST_STATE_NULL),
|
||||
GST_STATE_CHANGE_SUCCESS);
|
||||
|
||||
gst_object_unref (mixer);
|
||||
}
|
||||
|
||||
GST_END_TEST;
|
||||
|
||||
|
||||
static Suite *
|
||||
sunaudio_suite (void)
|
||||
{
|
||||
Suite *s = suite_create ("sunaudio");
|
||||
TCase *tc_chain = tcase_create ("general");
|
||||
|
||||
suite_add_tcase (s, tc_chain);
|
||||
tcase_add_test (tc_chain, test_sun_audio_mixer_track);
|
||||
|
||||
return s;
|
||||
}
|
||||
|
||||
GST_CHECK_MAIN (sunaudio)
|
|
@ -80,7 +80,6 @@ good_tests = [
|
|||
[ 'elements/rtpsession' ],
|
||||
[ 'elements/souphttpsrc', not libsoup_dep.found(), [libsoup_dep] ],
|
||||
[ 'elements/spectrum' ],
|
||||
# [ 'elements/sunaudio' ],
|
||||
[ 'elements/shapewipe' ],
|
||||
[ 'elements/id3v2mux', not taglib_dep.found() ],
|
||||
[ 'elements/apev2mux', not taglib_dep.found() ],
|
||||
|
|
Loading…
Reference in a new issue