aboutsummaryrefslogtreecommitdiff
path: root/src/plugins/Output/oss/outputoss.cpp
diff options
context:
space:
mode:
Diffstat (limited to 'src/plugins/Output/oss/outputoss.cpp')
-rw-r--r--src/plugins/Output/oss/outputoss.cpp224
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
}