diff options
Diffstat (limited to 'src/plugins/Output/oss/outputoss.cpp')
| -rw-r--r-- | src/plugins/Output/oss/outputoss.cpp | 224 |
1 files changed, 61 insertions, 163 deletions
diff --git a/src/plugins/Output/oss/outputoss.cpp b/src/plugins/Output/oss/outputoss.cpp index eea53584d..6722f18ad 100644 --- a/src/plugins/Output/oss/outputoss.cpp +++ b/src/plugins/Output/oss/outputoss.cpp @@ -20,6 +20,8 @@ ***************************************************************************/ #include <QApplication> +#include <QSettings> +#include <QDir> extern "C" { @@ -30,123 +32,94 @@ extern "C" #endif } -#include "outputoss.h" -#include <qmmp/buffer.h> -#include <qmmp/visual.h> - #include <stdio.h> #include <string.h> -#include <QtGlobal> -#include <QSettings> -#include <QDir> - +#include <errno.h> #include <iostream> - #include <unistd.h> #include <fcntl.h> #include <sys/ioctl.h> #include <sys/time.h> +#include <qmmp/buffer.h> +#include <qmmp/visual.h> +#include "outputoss.h" -#if defined(__FreeBSD__) -# include <sys/soundcard.h> -#elif defined(__linux__) -# include <linux/soundcard.h> -#elif defined(__bsdi__) -# include <sys/soundcard.h> -#endif - -OutputOSS *OutputOSS::m_instance = 0; -VolumeControlOSS *VolumeControlOSS::m_instance = 0; - -OutputOSS* OutputOSS::instance() -{ - return m_instance; -} - -OutputOSS::OutputOSS(QObject * parent) - : Output(parent), m_inited(false), - m_frequency(-1), m_channels(-1), - do_select(true), - m_audio_fd(-1) +OutputOSS::OutputOSS(QObject * parent) : Output(parent), do_select(true), m_audio_fd(-1) { QSettings settings(Qmmp::configFile(), QSettings::IniFormat); m_audio_device = settings.value("OSS/device","/dev/dsp").toString(); - m_instance = this; -} - -int OutputOSS::audio_fd() -{ - return m_audio_fd; } OutputOSS::~OutputOSS() { - uninitialize(); - m_instance = 0; + if (m_audio_fd >= 0) + { + ioctl(m_audio_fd, SNDCTL_DSP_RESET, 0); + close(m_audio_fd); + m_audio_fd = -1; + } } void OutputOSS::configure(quint32 freq, int chan, Qmmp::AudioFormat format) { - -#if SOUND_VERSION >= 0x040000 - if (VolumeControlOSS::instance()) - { - long cmd; - int v; - cmd = SNDCTL_DSP_SETPLAYVOL; - v = (VolumeControlOSS::instance()->right() << 8) | VolumeControlOSS::instance()->left(); - if(m_audio_fd > 1) - ioctl(m_audio_fd, cmd, &v); - } -#endif - m_frequency = freq; - m_channels = chan; - - //m_bps = freq * chan * (prec / 8); - int p; switch (format) { - default: case Qmmp::PCM_S16LE: -#if defined(AFMT_S16_NE) - p = AFMT_S16_NE; -#else p = AFMT_S16_LE; -#endif break; - case Qmmp::PCM_S8: p = AFMT_S8; break; - + default: + qWarning("OutputOSS: unsupported audio format"); + return; } - - if (ioctl(m_audio_fd, SNDCTL_DSP_SETFMT, &p) == -1) - qWarning("OutputOSS: can't set audio format"); - int stereo = (chan > 1) ? 1 : 0; - ioctl(m_audio_fd, SNDCTL_DSP_STEREO, &stereo); - if (ioctl(m_audio_fd, SNDCTL_DSP_SPEED, &freq) == -1) - qWarning("OutputOSS: can't set audio format"); + int param = p; + if (ioctl(m_audio_fd, SNDCTL_DSP_SETFMT, &p) < 0) + { + qWarning("OutputOSS: ioctl SNDCTL_DSP_SETFMT failed: %s",strerror(errno)); + return; + } + if(param != p) + { + qWarning("OutputOSS: unsupported audio format"); + return; + } + param = chan; + if(ioctl(m_audio_fd, SNDCTL_DSP_CHANNELS, &chan) < 0) + { + qWarning("OutputOSS: ioctl SNDCTL_DSP_CHANNELS failed: %s", strerror(errno)); + return; + } + if(param != chan) + { + qWarning("OutputOSS: unsupported %d-channel mode", param); + return; + } + uint param2 = freq; + if (ioctl(m_audio_fd, SNDCTL_DSP_SPEED, &freq) < 0) + { + qWarning("OutputOSS: ioctl SNDCTL_DSP_SPEED failed: %s", strerror(errno)); + return; + } + if(param2 != freq) + { + qWarning("OutputOSS: unsupported sample rate"); + return; + } + ioctl(m_audio_fd, SNDCTL_DSP_RESET, 0); Output::configure(freq, chan, format); } void OutputOSS::post() { - if (m_audio_fd < 1) - return; - - int unused; - ioctl(m_audio_fd, SNDCTL_DSP_POST, &unused); + ioctl(m_audio_fd, SNDCTL_DSP_POST, 0); } void OutputOSS::sync() { - if (m_audio_fd < 1) - return; - - int unused; - ioctl(m_audio_fd, SNDCTL_DSP_SYNC, &unused); + ioctl(m_audio_fd, SNDCTL_DSP_SYNC, 0); } bool OutputOSS::initialize() @@ -172,26 +145,9 @@ bool OutputOSS::initialize() tv.tv_sec = 0l; tv.tv_usec = 50000l; do_select = (select(m_audio_fd + 1, 0, &afd, 0, &tv) > 0); - m_inited = true; return true; } -void OutputOSS::uninitialize() -{ - if (!m_inited) - return; - m_inited = false; - m_frequency = -1; - m_channels = -1; - if (m_audio_fd > 0) - { - ioctl(m_audio_fd, SNDCTL_DSP_RESET, 0); - close(m_audio_fd); - m_audio_fd = -1; - } - qDebug("OutputOSS: uninitialize"); -} - qint64 OutputOSS::latency() { //ulong used = 0; @@ -211,7 +167,7 @@ qint64 OutputOSS::writeAudio(unsigned char *data, qint64 maxSize) // nice long poll timeout tv.tv_sec = 5l; tv.tv_usec = 0l; - if ((! do_select || (select(m_audio_fd + 1, 0, &afd, 0, &tv) > 0 && + if ((!do_select || (select(m_audio_fd + 1, 0, &afd, 0, &tv) > 0 && FD_ISSET(m_audio_fd, &afd)))) { l = qMin(int(2048), int(maxSize)); @@ -235,71 +191,31 @@ void OutputOSS::reset() } /***** MIXER *****/ -VolumeControlOSS *VolumeControlOSS::instance() -{ - return m_instance; -} - VolumeControlOSS::VolumeControlOSS(QObject *parent) : VolumeControl(parent) { m_master = true; m_mixer_fd = -1; QSettings settings(Qmmp::configFile(), QSettings::IniFormat); -#if SOUND_VERSION < 0x040000 m_mixer_device = settings.value("OSS/mixer_device","/dev/mixer").toString(); openMixer(); -#else - m_mixer_device = settings.value("OSS/device","/dev/dsp").toString(); - int mixer_fd = -1; - bool to_close = false; - if (OutputOSS::instance() && OutputOSS::instance()->audio_fd() > 0) - mixer_fd = OutputOSS::instance()->audio_fd(); - else - { - mixer_fd = open(m_audio_device.toAscii(), O_WRONLY, 0); - to_close = true; - } - if(mixer_fd > 0) - { - int v; - long cmd = SNDCTL_DSP_GETPLAYVOL; - if (ioctl(mixer_fd, cmd, &v) == -1) - v = 0; - m_left2 = (v & 0xFF00) >> 8; - m_right2 = (v & 0x00FF); - } - if(to_close) - { - close(mixer_fd); - mixer_fd = -1; - } -#endif - m_instance = this; + } VolumeControlOSS::~VolumeControlOSS() { -#if SOUND_VERSION < 0x040000 - if (m_mixer_fd > 0) + if (m_mixer_fd >= 0) { close(m_mixer_fd); m_mixer_fd = -1; } -#endif - if (m_mixer_fd > 0 && !OutputOSS::instance()) - { - close(m_mixer_fd); - m_mixer_fd = -1; - } - m_instance = 0; } void VolumeControlOSS::setVolume(int l, int r) { + if (m_mixer_fd < 0) + return; int v; long cmd; - -#if SOUND_VERSION < 0x040000 int devs = 0; ioctl(m_mixer_fd, SOUND_MIXER_READ_DEVMASK, &devs); if ((devs & SOUND_MASK_PCM) && !m_master) @@ -313,22 +229,15 @@ void VolumeControlOSS::setVolume(int l, int r) } v = (r << 8) | l; ioctl(m_mixer_fd, cmd, &v); -#else - cmd = SNDCTL_DSP_SETPLAYVOL; - v = (r << 8) | l; - if (OutputOSS::instance() && OutputOSS::instance()->audio_fd() > 0) - ioctl(OutputOSS::instance()->audio_fd(), cmd, &v); - m_left2 = l; - m_right2 = r; -#endif } void VolumeControlOSS::volume(int *ll,int *rr) { *ll = 0; *rr = 0; -#if SOUND_VERSION < 0x040000 - int cmd; + if(m_mixer_fd < 0) + return; + int cmd; int v, devs = 0; ioctl(m_mixer_fd, SOUND_MIXER_READ_DEVMASK, &devs); if ((devs & SOUND_MASK_PCM) && !m_master) @@ -347,21 +256,11 @@ void VolumeControlOSS::volume(int *ll,int *rr) *rr = (*rr > 100) ? 100 : *rr; *ll = (*ll < 0) ? 0 : *ll; *rr = (*rr < 0) ? 0 : *rr; -#else - /*cmd = SNDCTL_DSP_GETPLAYVOL; - if (ioctl(m_audio_fd, cmd, &v) == -1) - v = 0; - *rr = (v & 0xFF00) >> 8; - *ll = (v & 0x00FF);*/ - *rr = m_left2; - *ll = m_right2; -#endif } void VolumeControlOSS::openMixer() { -#if SOUND_VERSION < 0x040000 - if (m_mixer_fd != -1) + if (m_mixer_fd >= 0) return; m_mixer_fd = open(m_mixer_device.toAscii(), O_RDWR); if (m_mixer_fd < 0) @@ -369,5 +268,4 @@ void VolumeControlOSS::openMixer() qWarning("VolumeControlOSS: unable to open mixer device '%s'", qPrintable(m_mixer_device)); return; } -#endif } |
