/* * This file part of gsopcast - A gtk front-end of p2p tv sopcast. * http://lianwei3.googlepages.com/home2 * Copyright (C) 2006 Wei Lian * * This program is free software; you can redistribute it and/or modify * it under the terms of the GNU General Public License as published by * the Free Software Foundation; either version 2 of the License, or * (at your option) any later version. * * This program 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 General Public License * along with this program; if not, write to the Free Software * Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. */ #include "header.h" #include "sound.h" extern GtkObject *adj_sound; extern Sound *sound; #ifdef HAVE_ALSA /////////////////////hareware related stuff // throw SoundError on failed to init. Sound::Sound () { assert (snd_mixer_open (&mixer, 0) >= 0); snd_mixer_attach (mixer, "default"); snd_mixer_selem_register (mixer, NULL, NULL); snd_mixer_load (mixer); ///alsa mixer init pcm_element = NULL; for (snd_mixer_elem_t * elem = snd_mixer_first_elem (mixer); elem; elem = snd_mixer_elem_next (elem)) if (strcasecmp ("PCM", snd_mixer_selem_get_name (elem)) == 0) { pcm_element = elem; break; } else if (strcasecmp ("Master", snd_mixer_selem_get_name (elem)) == 0) { pcm_element = elem; } assert (pcm_element); if (!pcm_element) throw new SoundError(); ///dealing with alsa bug long int a, b; snd_mixer_selem_get_playback_volume (pcm_element, SND_MIXER_SCHN_FRONT_LEFT, &a); snd_mixer_selem_get_playback_volume (pcm_element, SND_MIXER_SCHN_FRONT_RIGHT, &b); ///set volume range long alsa_min_vol, alsa_max_vol; snd_mixer_selem_get_playback_volume_range (pcm_element, &alsa_min_vol, &alsa_max_vol); snd_mixer_selem_set_playback_volume_range (pcm_element, 0, 100); } //----------------------------------------------------- int Sound::volume () { long ll, lr; snd_mixer_handle_events (mixer); snd_mixer_selem_get_playback_volume (pcm_element, SND_MIXER_SCHN_FRONT_LEFT, &ll); snd_mixer_selem_get_playback_volume (pcm_element, SND_MIXER_SCHN_FRONT_RIGHT, &lr); return (ll + lr) >> 1; } //----------------------------------------------------- void Sound::volume (int leftright) { snd_mixer_selem_set_playback_volume (pcm_element, SND_MIXER_SCHN_FRONT_LEFT, leftright); snd_mixer_selem_set_playback_volume (pcm_element, SND_MIXER_SCHN_FRONT_RIGHT, leftright); } //----------------------------------------------------- Sound::~Sound () { snd_mixer_close (mixer); } #else // throw SoundError on failed to init. Sound::Sound () { if ((sound_handle = open ("/dev/mixer", O_RDWR, 0)) == -1) { ::perror ("/dev/mixer"); throw new SoundError(); } } Sound::~Sound () { ::close (sound_handle); } int Sound::volume () { int result; if (::ioctl (sound_handle, MIXER_READ (4), &result) == -1) { ::perror ("read_error"); return -1; } result = ((result >> 8) + (result & 0xFF)) >> 1; result = (result > 0) ? result : 0; result = (result < 100) ? result : 100; return result; } void Sound::volume (int leftright) { leftright = (leftright < 0) ? 0 : leftright; leftright = (leftright > 100) ? 100 : leftright; leftright = (leftright << 8) | (leftright & 0xFF); if (::ioctl (sound_handle, MIXER_WRITE (4), &leftright) == -1) { perror ("write_error"); return; } } #endif //----------------------------------------------------- gboolean sound_timer (void *) { int value = sound->volume (); if (gtk_adjustment_get_value (GTK_ADJUSTMENT (adj_sound)) != value) { gtk_adjustment_set_value (GTK_ADJUSTMENT (adj_sound), value); } return TRUE; }