/* * GStreamer * Copyright (C) 1999-2001 Erik Walthinsen * Copyright (C) 2004 David A. Schleef * * 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., 59 Temple Place - Suite 330, * Boston, MA 02111-1307, USA. */ #ifdef HAVE_CONFIG_H #include "config.h" #endif #include #include #include #include #include #include #include #include #include "gst/gst-i18n-plugin.h" #include "gstsunmixer.h" static void gst_sunaudiomixer_track_class_init (GstSunAudioMixerTrackClass * klass); static void gst_sunaudiomixer_track_init (GstSunAudioMixerTrack * track); static gboolean gst_sunaudiomixer_supported (GstImplementsInterface * iface, GType iface_type); static const GList *gst_sunaudiomixer_list_tracks (GstMixer * sunaudiomixer); static void gst_sunaudiomixer_set_volume (GstMixer * sunaudiomixer, GstMixerTrack * track, gint * volumes); static void gst_sunaudiomixer_get_volume (GstMixer * sunaudiomixer, GstMixerTrack * track, gint * volumes); static void gst_sunaudiomixer_set_mute (GstMixer * sunaudiomixer, GstMixerTrack * track, gboolean mute); static void gst_sunaudiomixer_set_record (GstMixer * sunaudiomixer, GstMixerTrack * track, gboolean record); #define MIXER_DEVICES 3 #define SCALE_FACTOR 2.55 /* 255/100 */ static gchar **labels = NULL; static GstMixerTrackClass *parent_class = NULL; GType gst_sunaudiomixer_track_get_type (void) { static GType gst_sunaudiomixer_track_type = 0; if (!gst_sunaudiomixer_track_type) { static const GTypeInfo sunaudiomixer_track_info = { sizeof (GstSunAudioMixerTrackClass), NULL, NULL, (GClassInitFunc) gst_sunaudiomixer_track_class_init, NULL, NULL, sizeof (GstSunAudioMixerTrack), 0, (GInstanceInitFunc) gst_sunaudiomixer_track_init, NULL }; gst_sunaudiomixer_track_type = g_type_register_static (GST_TYPE_MIXER_TRACK, "GstSunAudioMixerTrack", &sunaudiomixer_track_info, 0); } return gst_sunaudiomixer_track_type; } static void gst_sunaudiomixer_track_class_init (GstSunAudioMixerTrackClass * klass) { parent_class = g_type_class_ref (GST_TYPE_MIXER_TRACK); } static void gst_sunaudiomixer_track_init (GstSunAudioMixerTrack * track) { track->lvol = track->rvol = 0; track->track_num = 0; } void gst_sunaudio_interface_init (GstImplementsInterfaceClass * klass) { /* default virtual functions */ klass->supported = gst_sunaudiomixer_supported; } static gboolean gst_sunaudiomixer_supported (GstImplementsInterface * iface, GType iface_type) { g_assert (iface_type == GST_TYPE_MIXER); return (GST_SUNAUDIOELEMENT (iface)->mixer_fd != -1); } void gst_sunaudiomixer_interface_init (GstMixerClass * klass) { GST_MIXER_TYPE (klass) = GST_MIXER_HARDWARE; klass->list_tracks = gst_sunaudiomixer_list_tracks; klass->set_volume = gst_sunaudiomixer_set_volume; klass->get_volume = gst_sunaudiomixer_get_volume; klass->set_mute = gst_sunaudiomixer_set_mute; klass->set_record = gst_sunaudiomixer_set_record; } static void fill_labels (void) { int i; struct { gchar *given, *wanted; } cases[] = { { "Vol ", N_("Volume")} , { "Gain ", N_("Gain")} , { "Mon ", N_("Monitor")} , { NULL, NULL} }; labels = g_malloc (sizeof (gchar *) * MIXER_DEVICES); for (i = 0; i < MIXER_DEVICES; i++) { labels[i] = g_strdup (cases[i].wanted); } } GstMixerTrack * gst_sunaudiomixer_track_new (GstSunAudioElement * sunaudio, gint track_num, gint max_chans, gint flags) { GstSunAudioMixerTrack *sunaudiotrack; GstMixerTrack *track; gint volume; if (!labels) fill_labels (); sunaudiotrack = g_object_new (GST_TYPE_SUNAUDIOMIXER_TRACK, NULL); track = GST_MIXER_TRACK (sunaudiotrack); track->label = g_strdup (labels[track_num]); track->num_channels = max_chans; track->flags = flags; track->min_volume = 0; track->max_volume = 100; sunaudiotrack->track_num = track_num; sunaudiotrack->lvol = (0 & 0xff); return track; } void gst_sunaudiomixer_build_list (GstSunAudioElement * sunaudio) { GstMixerTrack *track; sunaudio->mixer_fd = open (sunaudio->mixer_dev, O_RDWR); if (sunaudio->mixer_fd == -1) { return; } sunaudio->device_name = g_strdup ("Unknown"); track = gst_sunaudiomixer_track_new (sunaudio, 0, 1, GST_MIXER_TRACK_OUTPUT); sunaudio->tracklist = g_list_append (sunaudio->tracklist, track); track = gst_sunaudiomixer_track_new (sunaudio, 1, 1, 0); sunaudio->tracklist = g_list_append (sunaudio->tracklist, track); track = gst_sunaudiomixer_track_new (sunaudio, 2, 1, 0); sunaudio->tracklist = g_list_append (sunaudio->tracklist, track); } static const GList * gst_sunaudiomixer_list_tracks (GstMixer * mixer) { return (const GList *) GST_SUNAUDIOELEMENT (mixer)->tracklist; } static void gst_sunaudiomixer_set_volume (GstMixer * mixer, GstMixerTrack * track, gint * volumes) { gint volume; gchar buf[100]; struct audio_info audioinfo; GstSunAudioElement *sunaudio = GST_SUNAUDIOELEMENT (mixer); GstSunAudioMixerTrack *sunaudiotrack = GST_SUNAUDIOMIXER_TRACK (track); g_return_if_fail (sunaudio->mixer_fd != -1); volume = volumes[0] * SCALE_FACTOR + 0.5; /* Set the volume */ AUDIO_INITINFO (&audioinfo); switch (sunaudiotrack->track_num) { case 0: audioinfo.play.gain = volume; break; case 1: audioinfo.record.gain = volume; break; case 2: audioinfo.monitor_gain = volume; break; } if (ioctl (sunaudio->mixer_fd, AUDIO_SETINFO, &audioinfo) < 0) { g_warning ("Error setting volume"); return; } } static void gst_sunaudiomixer_get_volume (GstMixer * mixer, GstMixerTrack * track, gint * volumes) { gint volume; struct audio_info audioinfo; GstSunAudioElement *sunaudio = GST_SUNAUDIOELEMENT (mixer); GstSunAudioMixerTrack *sunaudiotrack = GST_SUNAUDIOMIXER_TRACK (track); g_return_if_fail (sunaudio->mixer_fd != -1); if (ioctl (sunaudio->mixer_fd, AUDIO_GETINFO, &audioinfo) < 0) { g_warning ("Error setting volume device"); return; } switch (sunaudiotrack->track_num) { case 0: sunaudiotrack->lvol = volumes[0] = (audioinfo.play.gain / SCALE_FACTOR) + 0.5; break; case 1: sunaudiotrack->lvol = volumes[0] = (audioinfo.record.gain / SCALE_FACTOR) + 0.5; break; case 2: sunaudiotrack->lvol = volumes[0] = (audioinfo.monitor_gain / SCALE_FACTOR) + 0.5; break; } } static void gst_sunaudiomixer_set_mute (GstMixer * mixer, GstMixerTrack * track, gboolean mute) { struct audio_info audioinfo; GstSunAudioElement *sunaudio = GST_SUNAUDIOELEMENT (mixer); GstSunAudioMixerTrack *sunaudiotrack = GST_SUNAUDIOMIXER_TRACK (track); g_return_if_fail (sunaudio->mixer_fd != -1); if (sunaudiotrack->track_num != 0) return; AUDIO_INITINFO (&audioinfo); if (mute) { audioinfo.output_muted = 1; } else { audioinfo.output_muted = 0; } if (ioctl (sunaudio->mixer_fd, AUDIO_SETINFO, &audioinfo) < 0) { g_warning ("Error setting volume device"); return; } } static void gst_sunaudiomixer_set_record (GstMixer * mixer, GstMixerTrack * track, gboolean record) { /* Implementation Pending */ }