/* * Copyright (C) 2005, 2006 Liu Di * * Copyright (C) 2007 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 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 "sound.h" #ifdef ALSA Sound::Sound (QObject * parent, const char *name): QObject (parent, name) { assert (snd_mixer_open (&handle, 0) >= 0); snd_mixer_attach (handle, "default"); snd_mixer_selem_register (handle, NULL, NULL); snd_mixer_load (handle); ///alsa mixer init elem = NULL; for (snd_mixer_elem_t * var = snd_mixer_first_elem (handle); var; var = snd_mixer_elem_next (var)) if (strcasecmp ("PCM", snd_mixer_selem_get_name (var)) == 0) { elem = var; break; } else if (strcasecmp ("Master", snd_mixer_selem_get_name (var)) == 0) { elem = var; } assert (elem); ///dealing with alsa bug long int a, b; snd_mixer_selem_get_playback_volume (elem, SND_MIXER_SCHN_FRONT_LEFT, &a); snd_mixer_selem_get_playback_volume (elem, SND_MIXER_SCHN_FRONT_RIGHT, &b); ///set volume range long min, max; snd_mixer_selem_get_playback_volume_range (elem, &min, &max); snd_mixer_selem_set_playback_volume_range (elem, 0, 100); } Sound::~Sound () { if (handle) snd_mixer_close (handle); } int Sound::volume () { long ll, lr; snd_mixer_handle_events (handle); snd_mixer_selem_get_playback_volume (elem, SND_MIXER_SCHN_FRONT_LEFT, &ll); snd_mixer_selem_get_playback_volume (elem, SND_MIXER_SCHN_FRONT_RIGHT, &lr); return (ll + lr) >> 1; } void Sound::volume (int leftright) { snd_mixer_selem_set_playback_volume (elem, SND_MIXER_SCHN_FRONT_LEFT, leftright); snd_mixer_selem_set_playback_volume (elem, SND_MIXER_SCHN_FRONT_RIGHT, leftright); } #else Sound::Sound (QObject * parent, const char *name): QObject (parent, name) { if ((handle = open ("/dev/mixer", O_RDWR, 0)) == -1) { ::perror ("/dev/mixer"); } } Sound::~Sound () { ::close (handle); } int Sound::volume () { int result; if (::ioctl (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 (handle, MIXER_WRITE (4), &leftright) == -1) { perror ("write_error"); return; } } #endif