aboutsummaryrefslogtreecommitdiff
path: root/src/plugins/Output/oss
diff options
context:
space:
mode:
Diffstat (limited to 'src/plugins/Output/oss')
-rw-r--r--src/plugins/Output/oss/CMakeLists.txt67
-rw-r--r--src/plugins/Output/oss/oss.pro36
-rw-r--r--src/plugins/Output/oss/outputoss.cpp505
-rw-r--r--src/plugins/Output/oss/outputoss.h76
-rw-r--r--src/plugins/Output/oss/outputossfactory.cpp70
-rw-r--r--src/plugins/Output/oss/outputossfactory.h48
-rw-r--r--src/plugins/Output/oss/settingsdialog.cpp60
-rw-r--r--src/plugins/Output/oss/settingsdialog.h47
-rw-r--r--src/plugins/Output/oss/settingsdialog.ui309
-rw-r--r--src/plugins/Output/oss/translations/oss_plugin_cs.ts90
10 files changed, 1308 insertions, 0 deletions
diff --git a/src/plugins/Output/oss/CMakeLists.txt b/src/plugins/Output/oss/CMakeLists.txt
new file mode 100644
index 000000000..8ab6f8d88
--- /dev/null
+++ b/src/plugins/Output/oss/CMakeLists.txt
@@ -0,0 +1,67 @@
+project(liboss)
+
+cmake_minimum_required(VERSION 2.4.0)
+
+
+INCLUDE(UsePkgConfig)
+INCLUDE(FindQt4)
+
+find_package(Qt4 REQUIRED) # find and setup Qt4 for this project
+include(${QT_USE_FILE})
+
+# qt plugin
+ADD_DEFINITIONS( -Wall )
+ADD_DEFINITIONS(${QT_DEFINITIONS})
+ADD_DEFINITIONS(-DQT_PLUGIN)
+ADD_DEFINITIONS(-DQT_NO_DEBUG)
+ADD_DEFINITIONS(-DQT_SHARED)
+ADD_DEFINITIONS(-DQT_THREAD)
+
+include_directories(${CMAKE_CURRENT_BINARY_DIR})
+
+SET(QT_INCLUDES
+ ${QT_INCLUDES}
+ ${CMAKE_CURRENT_BINARY_DIR}/../../../
+)
+
+# libqmmp
+include_directories(${CMAKE_CURRENT_BINARY_DIR}/../../../)
+link_directories(${CMAKE_CURRENT_BINARY_DIR}/../../../)
+
+
+
+include_directories(${JACK_INCLUDE_DIR} ${JACK_INCLUDE_DIR})
+link_directories(${SAMPLERATE_LINK_DIR} ${SAMPLERATE_LINK_DIR})
+
+ADD_DEFINITIONS(${JACK_CFLAGS})
+ADD_DEFINITIONS(${SAMPLERATE_CFLAGS})
+
+
+SET(liboss_SRCS
+ outputossfactory.cpp
+ outputoss.cpp
+ settingsdialog.cpp
+)
+
+SET(liboss_MOC_HDRS
+ outputossfactory.h
+ outputoss.h
+ settingsdialog.h
+)
+
+#SET(libjack_RCCS translations/translations.qrc)
+
+QT4_ADD_RESOURCES(libjack_RCC_SRCS ${libjack_RCCS})
+
+QT4_WRAP_CPP(liboss_MOC_SRCS ${liboss_MOC_HDRS})
+
+SET(liboss_UIS
+ settingsdialog.ui
+)
+
+QT4_WRAP_UI(liboss_UIS_H ${liboss_UIS})
+
+ADD_LIBRARY(oss SHARED ${liboss_SRCS} ${liboss_MOC_SRCS} ${liboss_UIS_H})
+target_link_libraries(oss ${QT_LIBRARIES} -lqmmp )
+install(TARGETS oss DESTINATION ${LIB_DIR}/qmmp/Output PERMISSIONS OWNER_WRITE OWNER_READ OWNER_EXECUTE GROUP_EXECUTE GROUP_READ WORLD_EXECUTE WORLD_READ)
+
diff --git a/src/plugins/Output/oss/oss.pro b/src/plugins/Output/oss/oss.pro
new file mode 100644
index 000000000..e401f14b0
--- /dev/null
+++ b/src/plugins/Output/oss/oss.pro
@@ -0,0 +1,36 @@
+include(../../plugins.pri)
+FORMS += settingsdialog.ui
+
+HEADERS += outputossfactory.h \
+ outputoss.h \
+ settingsdialog.h
+
+
+SOURCES += outputossfactory.cpp \
+ outputoss.cpp \
+ settingsdialog.cpp
+
+TARGET=$$PLUGINS_PREFIX/Output/oss
+QMAKE_CLEAN =$$PLUGINS_PREFIX/Output/liboss.so
+
+
+INCLUDEPATH += ../../../qmmp
+QMAKE_LIBDIR += ../../../../lib
+CONFIG += release \
+warn_on \
+thread \
+plugin
+
+TEMPLATE = lib
+LIBS += -lqmmp
+
+#TRANSLATIONS = translations/oss_plugin_ru.ts \
+# translations/oss_plugin_uk_UA.ts \
+# translations/oss_plugin_zh_CN.ts
+#RESOURCES = translations/translations.qrc
+isEmpty (LIB_DIR){
+LIB_DIR = /lib
+}
+
+target.path = $$LIB_DIR/qmmp/Output
+INSTALLS += target
diff --git a/src/plugins/Output/oss/outputoss.cpp b/src/plugins/Output/oss/outputoss.cpp
new file mode 100644
index 000000000..9c52ac777
--- /dev/null
+++ b/src/plugins/Output/oss/outputoss.cpp
@@ -0,0 +1,505 @@
+/***************************************************************************
+ * Copyright (C) 2007 by Uriy Zhuravlev stalkerg@gmail.com *
+ * *
+ * Copyright (c) 2000-2001 Brad Hughes bhughes@trolltech.com *
+ * *
+ * 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 <QApplication>
+
+#include "outputoss.h"
+#include "constants.h"
+#include "buffer.h"
+#include "visual.h"
+
+#include <stdio.h>
+#include <string.h>
+#include <QtGlobal>
+#include <QSettings>
+#include <QDir>
+
+#include <iostream>
+
+//extern Q_EXPORT QApplication* qApp;
+
+
+void OutputOSS::stop()
+{
+ m_userStop = TRUE;
+}
+
+void OutputOSS::status()
+{
+ long ct = (m_totalWritten - latency()) / m_bps;
+
+ if (ct < 0)
+ ct = 0;
+
+ if (ct > m_currentSeconds)
+ {
+ m_currentSeconds = ct;
+ dispatch(m_currentSeconds, m_totalWritten, m_rate,
+ m_frequency, m_precision, m_channels);
+ }
+}
+
+long OutputOSS::written()
+{
+ return m_totalWritten;
+}
+
+void OutputOSS::seek(long pos)
+{
+ recycler()->mutex()->lock();
+ recycler()->clear();
+ recycler()->mutex()->unlock();
+
+ m_totalWritten = (pos * m_bps);
+ m_currentSeconds = -1;
+}
+
+
+#include <unistd.h>
+#include <fcntl.h>
+#include <sys/ioctl.h>
+#include <sys/time.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(QObject * parent)
+ : Output(parent), m_inited(FALSE), m_pause(FALSE), m_play(FALSE),
+ m_userStop(FALSE),
+ m_totalWritten(0), m_currentSeconds(-1),
+ m_bps(1), m_frequency(-1), m_channels(-1), m_precision(-1),
+ do_select(TRUE),
+ m_audio_fd(-1), m_mixer_fd(-1)
+{
+QSettings settings(QDir::homePath()+"/.qmmp/qmmprc", QSettings::IniFormat);
+m_master = true;
+m_audio_device = settings.value("OSS/device","/dev/dsp").toString();
+m_mixer_device = settings.value("OSS/mixer_device","/dev/mixer").toString();
+openMixer();
+}
+
+OutputOSS::~OutputOSS()
+{
+ if (m_audio_fd > 0)
+ {
+ close(m_audio_fd);
+ m_audio_fd = -1;
+ }
+ if (m_mixer_fd > 0)
+ {
+ close(m_mixer_fd);
+ m_mixer_fd = -1;
+ }
+}
+
+void OutputOSS::configure(long freq, int chan, int prec, int rate)
+{
+ // we need to configure
+ if (freq != m_frequency || chan != m_channels || prec != m_precision) {
+ // we have already configured, but are changing settings...
+ // reset the device
+ resetDSP();
+
+ m_frequency = freq;
+ m_channels = chan;
+ m_precision = prec;
+
+ m_bps = freq * chan * (prec / 8);
+
+ int p;
+ switch(prec) {
+ default:
+ case 16:
+#if defined(AFMT_S16_NE)
+ p = AFMT_S16_NE;
+#else
+ p = AFMT_S16_LE;
+#endif
+ break;
+
+ case 8:
+ p = AFMT_S8;
+ break;
+
+ }
+
+ ioctl(m_audio_fd, SNDCTL_DSP_SETFMT, &p);
+ ioctl(m_audio_fd, SNDCTL_DSP_SAMPLESIZE, &prec);
+ int stereo = (chan > 1) ? 1 : 0;
+ ioctl(m_audio_fd, SNDCTL_DSP_STEREO, &stereo);
+ ioctl(m_audio_fd, SNDCTL_DSP_SPEED, &freq);
+ }
+
+ m_rate = rate;
+}
+
+
+void OutputOSS::reset()
+{
+ if (m_audio_fd > 0)
+ {
+ close(m_audio_fd);
+ m_audio_fd = -1;
+ }
+
+ m_audio_fd = open(m_audio_device.toAscii(), O_WRONLY, 0);
+
+ if (m_audio_fd < 0)
+ {
+ error(QString("OSSOutput: failed to open output device '%1'").
+ arg(m_audio_device));
+ return;
+ }
+
+ int flags;
+ if ((flags = fcntl(m_audio_fd, F_GETFL, 0)) > 0)
+ {
+ flags &= O_NDELAY;
+ fcntl(m_audio_fd, F_SETFL, flags);
+ }
+
+ fd_set afd;
+ FD_ZERO(&afd);
+ FD_SET(m_audio_fd, &afd);
+ struct timeval tv;
+ tv.tv_sec = 0l;
+ tv.tv_usec = 50000l;
+ do_select = (select(m_audio_fd + 1, 0, &afd, 0, &tv) > 0);
+
+ if (m_audio_fd > 0)
+ {
+ close(m_mixer_fd);
+ m_mixer_fd = -1;
+ }
+ openMixer();
+}
+
+void OutputOSS::openMixer()
+{
+ if (m_mixer_fd != -1)
+ return;
+
+ if ((m_mixer_fd = open(m_mixer_device.toAscii(), O_RDWR)) == -1)
+ {
+ return;
+ }
+ if (m_audio_fd < 0)
+ {
+ error(QString("OSSOutput: failed to open mixer device '%1'").
+ arg(m_mixer_device));
+ return;
+ }
+}
+
+void OutputOSS::pause()
+{
+ m_pause = (m_pause) ? FALSE : TRUE;
+}
+
+void OutputOSS::post()
+{
+ if (m_audio_fd < 1)
+ return;
+
+ int unused;
+ ioctl(m_audio_fd, SNDCTL_DSP_POST, &unused);
+}
+
+void OutputOSS::sync()
+{
+ if (m_audio_fd < 1)
+ return;
+
+ int unused;
+ ioctl(m_audio_fd, SNDCTL_DSP_SYNC, &unused);
+}
+
+
+void OutputOSS::resetDSP()
+{
+ if (m_audio_fd < 1)
+ return;
+
+ int unused;
+ ioctl(m_audio_fd, SNDCTL_DSP_RESET, &unused);
+}
+
+
+bool OutputOSS::initialize()
+{
+ m_inited = m_pause = m_play = m_userStop = FALSE;
+
+
+ reset();
+ if (m_audio_fd < 0)
+ return FALSE;
+ if (m_mixer_fd < 0)
+ return FALSE;
+
+
+ m_currentSeconds = -1;
+ m_totalWritten = 0;
+ stat = OutputState::Stopped;
+
+ m_inited = TRUE;
+ return TRUE;
+}
+
+void OutputOSS::uninitialize()
+{
+ if (!m_inited)
+ return;
+ m_inited = FALSE;
+ m_pause = FALSE;
+ m_play = FALSE;
+ m_userStop = FALSE;
+ m_totalWritten = 0;
+ m_currentSeconds = -1;
+ m_bps = -1;
+ m_frequency = -1;
+ m_channels = -1;
+ m_precision = -1;
+ resetDSP();
+ if (m_audio_fd > 0)
+ {
+ close(m_audio_fd);
+ m_audio_fd = -1;
+ }
+ if (m_audio_fd > 0)
+ {
+ close(m_mixer_fd);
+ m_mixer_fd = -1;
+ }
+
+ qDebug("OutputOSS: uninitialize");
+ dispatch(OutputState::Stopped);
+}
+
+long OutputOSS::latency()
+{
+ ulong used = 0;
+
+ if (! m_pause)
+ {
+ if (ioctl(m_audio_fd, SNDCTL_DSP_GETODELAY, &used) == -1)
+ used = 0;
+ }
+
+ return used;
+}
+
+void OutputOSS::run()
+{
+ mutex()->lock();
+
+ if (! m_inited)
+ {
+ mutex()->unlock();
+
+ return;
+ }
+
+ m_play = TRUE;
+
+ mutex()->unlock();
+
+ fd_set afd;
+ struct timeval tv;
+ Buffer *b = 0;
+ bool done = FALSE;
+ unsigned long n = 0, m = 0, l = 0;
+
+ dispatch(OutputState::Playing);
+
+ FD_ZERO(&afd);
+
+ while (! done) {
+ mutex()->lock();
+
+ recycler()->mutex()->lock();
+
+ done = m_userStop;
+
+ while (! done && (recycler()->empty() || m_pause)) {
+ post();
+
+ mutex()->unlock();
+
+ {
+ stat = m_pause ? OutputState::Paused : OutputState::Buffering;
+ OutputState e((OutputState::Type) stat);
+ dispatch(e);
+ }
+
+ recycler()->cond()->wakeOne();
+ recycler()->cond()->wait(recycler()->mutex());
+
+ mutex()->lock();
+ done = m_userStop;
+ status();
+ }
+
+ if (! b) {
+ b = recycler()->next();
+ if (b->rate)
+ m_rate = b->rate;
+ }
+
+ recycler()->cond()->wakeOne();
+ recycler()->mutex()->unlock();
+
+ FD_ZERO(&afd);
+ FD_SET(m_audio_fd, &afd);
+ // nice long poll timeout
+ tv.tv_sec = 5l;
+ tv.tv_usec = 0l;
+
+ if (b &&
+ (! do_select || (select(m_audio_fd + 1, 0, &afd, 0, &tv) > 0 &&
+ FD_ISSET(m_audio_fd, &afd)))) {
+ l = qMin(int(2048), int(b->nbytes - n));
+ if (l > 0) {
+ m = write(m_audio_fd, b->data + n, l);
+ n += m;
+
+ status();
+ dispatchVisual(b, m_totalWritten, m_channels, m_precision);
+ } else {
+ // force buffer change
+ n = b->nbytes;
+ m = 0;
+ }
+ }
+
+ m_totalWritten += m;
+
+ if (n == b->nbytes) {
+ recycler()->mutex()->lock();
+ recycler()->done();
+ recycler()->mutex()->unlock();
+
+ b = 0;
+ n = 0;
+ }
+
+ mutex()->unlock();
+ }
+
+ mutex()->lock();
+
+ if (! m_userStop)
+ sync();
+ resetDSP();
+
+ m_play = FALSE;
+
+ dispatch(OutputState::Stopped);
+ mutex()->unlock();
+}
+
+
+void OutputOSS::setVolume(int l, int r)
+{
+ int v, devs;
+ long cmd;
+
+ ioctl(m_mixer_fd, SOUND_MIXER_READ_DEVMASK, &devs);
+ if ((devs & SOUND_MASK_PCM) && (m_master == false))
+ cmd = SOUND_MIXER_WRITE_PCM;
+ else if ((devs & SOUND_MASK_VOLUME) && (m_master == true))
+ cmd = SOUND_MIXER_WRITE_VOLUME;
+ else
+ {
+ //close(mifd);
+ return;
+ }
+ v = (r << 8) | l;
+ ioctl(m_mixer_fd, cmd, &v);
+}
+
+void OutputOSS::volume(int *ll,int *rr)
+{
+ *ll = 0;
+ *rr = 0;
+ int cmd;
+ int v, devs;
+
+ ioctl(m_mixer_fd, SOUND_MIXER_READ_DEVMASK, &devs);
+ if ((devs & SOUND_MASK_PCM) && (m_master == 0))
+ cmd = SOUND_MIXER_READ_PCM;
+ else if ((devs & SOUND_MASK_VOLUME) && (m_master == 1))
+ cmd = SOUND_MIXER_READ_VOLUME;
+ else
+ return;
+
+ ioctl(m_mixer_fd, cmd, &v);
+ *ll = (v & 0xFF00) >> 8;
+ *rr = (v & 0x00FF);
+
+ *ll = (*ll > 100) ? 100 : *ll;
+ *rr = (*rr > 100) ? 100 : *rr;
+ *ll = (*ll < 0) ? 0 : *ll;
+ *rr = (*rr < 0) ? 0 : *rr;
+}
+
+
+void OutputOSS::checkVolume()
+{
+ long ll = 0, lr = 0, cmd;
+ int v, devs;
+
+ /*
+ * We dont show any errors if this fails, as this is called
+ * rather often
+ */
+// if (!open_mixer_device()) {
+ ioctl(m_mixer_fd, SOUND_MIXER_READ_DEVMASK, &devs);
+ if ((devs & SOUND_MASK_PCM) && (m_master == 0))
+ cmd = SOUND_MIXER_READ_PCM;
+ else if ((devs & SOUND_MASK_VOLUME) && (m_master == 1))
+ cmd = SOUND_MIXER_READ_VOLUME;
+ else
+ return;
+
+ ioctl(m_mixer_fd, cmd, &v);
+ ll = (v & 0xFF00) >> 8;
+ lr = (v & 0x00FF);
+
+ ll = (ll > 100) ? 100 : ll;
+ lr = (lr > 100) ? 100 : lr;
+ ll = (ll < 0) ? 0 : ll;
+ lr = (lr < 0) ? 0 : lr;
+ if (bl!=ll || br!=lr)
+ {
+ bl = ll;
+ br = lr;
+ dispatchVolume(ll,lr);
+ }
+// }
+}
+
+
diff --git a/src/plugins/Output/oss/outputoss.h b/src/plugins/Output/oss/outputoss.h
new file mode 100644
index 000000000..a2f260057
--- /dev/null
+++ b/src/plugins/Output/oss/outputoss.h
@@ -0,0 +1,76 @@
+/***************************************************************************
+ * Copyright (C) 2007 by Uriy Zhuravlev stalkerg@gmail.com *
+ * *
+ * Copyright (c) 2000-2001 Brad Hughes bhughes@trolltech.com *
+ * *
+ * 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. *
+ ***************************************************************************/
+
+
+#ifndef OUTPUTOSS_H
+#define OUTPUTOSS_H
+
+class OutputOSS;
+
+#include <output.h>
+#include <QObject>
+
+class OutputOSS : public Output
+{
+Q_OBJECT
+public:
+ OutputOSS(QObject * parent = 0);
+ virtual ~OutputOSS();
+
+ bool isInitialized() const { return m_inited; }
+ bool initialize();
+ void uninitialize();
+ void configure(long, int, int, int);
+ void stop();
+ void pause();
+ long written();
+ long latency();
+ void seek(long);
+ void setVolume(int l, int r);
+ void volume(int* l,int* r);
+ void checkVolume();
+
+private:
+ // thread run function
+ void run();
+
+ // helper functions
+ void reset();
+ void resetDSP();
+ void status();
+ void post();
+ void sync();
+ void openMixer();
+
+ QString m_audio_device, m_mixer_device;
+
+ bool m_inited, m_pause, m_play, m_userStop, m_master;
+ long m_totalWritten, m_currentSeconds, m_bps;
+ int stat;
+ int m_rate, m_frequency, m_channels, m_precision;
+
+ bool do_select;
+ int m_audio_fd, m_mixer_fd;
+ long bl, br;
+};
+
+
+#endif
diff --git a/src/plugins/Output/oss/outputossfactory.cpp b/src/plugins/Output/oss/outputossfactory.cpp
new file mode 100644
index 000000000..3fa8c07a2
--- /dev/null
+++ b/src/plugins/Output/oss/outputossfactory.cpp
@@ -0,0 +1,70 @@
+/***************************************************************************
+ * Copyright (C) 2007 by Zhuravlev Uriy *
+ * stalkerg@gmail.com *
+ * *
+ * 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 <QtGui>
+
+#include "settingsdialog.h"
+#include "outputoss.h"
+#include "outputossfactory.h"
+
+
+const QString& OutputOSSFactory::name() const
+{
+ static QString name(tr("OSS Plugin"));
+ return name;
+}
+
+Output* OutputOSSFactory::create(QObject* parent,bool)
+{
+ return new OutputOSS(parent);
+}
+
+const OutputProperties OutputOSSFactory::properties() const
+{
+ OutputProperties properties;
+ properties.name = name();
+ properties.hasAbout = TRUE;
+ properties.hasSettings = TRUE;
+ return properties;
+}
+
+void OutputOSSFactory::showSettings(QWidget* parent)
+{
+ SettingsDialog *s = new SettingsDialog(parent);
+ s -> show();
+}
+
+void OutputOSSFactory::showAbout(QWidget *parent)
+{
+QMessageBox::about (parent, tr("About OSS Output Plugin"),
+ tr("Qmmp OSS Output Plugin")+"\n"+
+ tr("Writen by: Yuriy Zhuravlev <slalkerg@gmail.com>")+"\n"+
+ tr("Based on code by:Brad Hughes <bhughes@trolltech.com>"));
+}
+
+QTranslator *OutputOSSFactory::createTranslator(QObject *parent)
+{
+ QTranslator *translator = new QTranslator(parent);
+ QString locale = QLocale::system().name();
+ translator->load(QString(":/oss_plugin_") + locale);
+ return translator;
+}
+
+Q_EXPORT_PLUGIN(OutputOSSFactory)
diff --git a/src/plugins/Output/oss/outputossfactory.h b/src/plugins/Output/oss/outputossfactory.h
new file mode 100644
index 000000000..03166bb94
--- /dev/null
+++ b/src/plugins/Output/oss/outputossfactory.h
@@ -0,0 +1,48 @@
+/***************************************************************************
+ * Copyright (C) 2006 by Ilya Kotov *
+ * forkotov02@hotmail.ru *
+ * *
+ * 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. *
+ ***************************************************************************/
+#ifndef OUTPUTOSSFACTORY_H
+#define OUTPUTOSSFACTORY_H
+
+
+#include <QObject>
+#include <QString>
+#include <QIODevice>
+#include <QWidget>
+
+#include <output.h>
+#include <outputfactory.h>
+
+
+class OutputOSSFactory : public QObject,
+ OutputFactory
+{
+Q_OBJECT
+Q_INTERFACES(OutputFactory);
+
+public:
+ const QString& name() const;
+ Output* create(QObject* parent,bool);
+ void showSettings(QWidget* parent);
+ void showAbout(QWidget *parent);
+ QTranslator *createTranslator(QObject *parent);
+ const OutputProperties properties() const;
+};
+
+#endif
diff --git a/src/plugins/Output/oss/settingsdialog.cpp b/src/plugins/Output/oss/settingsdialog.cpp
new file mode 100644
index 000000000..8d75b06eb
--- /dev/null
+++ b/src/plugins/Output/oss/settingsdialog.cpp
@@ -0,0 +1,60 @@
+/***************************************************************************
+ * Copyright (C) 2007 by Zhuravlev Uriy *
+ * stalkerg@gmail.com *
+ * *
+ * 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 <QSettings>
+#include <QDir>
+
+#include "settingsdialog.h"
+
+SettingsDialog::SettingsDialog ( QWidget *parent )
+ : QDialog ( parent )
+{
+ ui.setupUi ( this );
+ setAttribute ( Qt::WA_DeleteOnClose );
+ connect(ui.okButton, SIGNAL(clicked()), SLOT(writeSettings()));
+ QSettings settings(QDir::homePath()+"/.qmmp/qmmprc", QSettings::IniFormat);
+ settings.beginGroup("OSS");
+ ui.lineEdit->insert(settings.value("device","/dev/dsp").toString());
+ ui.lineEdit_2->insert(settings.value("mixer_device","/dev/mixer").toString());
+ ui.bufferSpinBox->setValue(settings.value("buffer_time",500).toInt());
+ ui.periodSpinBox->setValue(settings.value("period_time",100).toInt());
+
+ settings.endGroup();
+}
+
+
+SettingsDialog::~SettingsDialog()
+{}
+
+
+
+void SettingsDialog::writeSettings()
+{
+ qDebug("SettingsDialog (OSS):: writeSettings()");
+ QSettings settings(QDir::homePath()+"/.qmmp/qmmprc", QSettings::IniFormat);
+ settings.beginGroup("OSS");
+ settings.setValue("device", ui.lineEdit->text());
+ settings.setValue("buffer_time",ui.bufferSpinBox->value());
+ settings.setValue("period_time",ui.periodSpinBox->value());
+ settings.setValue("mixer_device", ui.lineEdit_2->text());
+ settings.endGroup();
+ accept();
+}
+
+
diff --git a/src/plugins/Output/oss/settingsdialog.h b/src/plugins/Output/oss/settingsdialog.h
new file mode 100644
index 000000000..fd75c5698
--- /dev/null
+++ b/src/plugins/Output/oss/settingsdialog.h
@@ -0,0 +1,47 @@
+/***************************************************************************
+ * Copyright (C) 2007 by Zhuravlev Uriy *
+ * stalkerg@gmail.com *
+ * *
+ * 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. *
+ ***************************************************************************/
+#ifndef SETTINGSDIALOG_H
+#define SETTINGSDIALOG_H
+
+#include <QDialog>
+
+
+#include "ui_settingsdialog.h"
+
+/**
+ @author Yuriy Zhuravlev <stalkerg@gmail.com>
+*/
+class SettingsDialog : public QDialog
+{
+Q_OBJECT
+public:
+ SettingsDialog(QWidget *parent = 0);
+
+ ~SettingsDialog();
+
+private slots:
+ void writeSettings();
+
+private:
+ Ui::SettingsDialog ui;
+
+};
+
+#endif
diff --git a/src/plugins/Output/oss/settingsdialog.ui b/src/plugins/Output/oss/settingsdialog.ui
new file mode 100644
index 000000000..ce1c40894
--- /dev/null
+++ b/src/plugins/Output/oss/settingsdialog.ui
@@ -0,0 +1,309 @@
+<ui version="4.0" >
+ <class>SettingsDialog</class>
+ <widget class="QDialog" name="SettingsDialog" >
+ <property name="geometry" >
+ <rect>
+ <x>0</x>
+ <y>0</y>
+ <width>422</width>
+ <height>334</height>
+ </rect>
+ </property>
+ <property name="windowTitle" >
+ <string>OSS Plugin Settings</string>
+ </property>
+ <layout class="QGridLayout" >
+ <property name="leftMargin" >
+ <number>9</number>
+ </property>
+ <property name="topMargin" >
+ <number>9</number>
+ </property>
+ <property name="rightMargin" >
+ <number>9</number>
+ </property>
+ <property name="bottomMargin" >
+ <number>9</number>
+ </property>
+ <property name="horizontalSpacing" >
+ <number>6</number>
+ </property>
+ <property name="verticalSpacing" >
+ <number>6</number>
+ </property>
+ <item row="0" column="0" colspan="3" >
+ <widget class="QTabWidget" name="tabWidget" >
+ <property name="currentIndex" >
+ <number>0</number>
+ </property>
+ <widget class="QWidget" name="tab" >
+ <attribute name="title" >
+ <string>Device Settings</string>
+ </attribute>
+ <layout class="QVBoxLayout" >
+ <property name="spacing" >
+ <number>6</number>
+ </property>
+ <property name="leftMargin" >
+ <number>9</number>
+ </property>
+ <property name="topMargin" >
+ <number>9</number>
+ </property>
+ <property name="rightMargin" >
+ <number>9</number>
+ </property>
+ <property name="bottomMargin" >
+ <number>9</number>
+ </property>
+ <item>
+ <widget class="QGroupBox" name="groupBox" >
+ <property name="title" >
+ <string>Audio device</string>
+ </property>
+ <layout class="QVBoxLayout" >
+ <item>
+ <widget class="QLineEdit" name="lineEdit" >
+ <property name="text" >
+ <string/>
+ </property>
+ </widget>
+ </item>
+ </layout>
+ </widget>
+ </item>
+ <item>
+ <widget class="QGroupBox" name="groupBox_2" >
+ <property name="title" >
+ <string>Mixer device</string>
+ </property>
+ <layout class="QGridLayout" >
+ <property name="leftMargin" >
+ <number>9</number>
+ </property>
+ <property name="topMargin" >
+ <number>9</number>
+ </property>
+ <property name="rightMargin" >
+ <number>9</number>
+ </property>
+ <property name="bottomMargin" >
+ <number>9</number>
+ </property>
+ <property name="horizontalSpacing" >
+ <number>6</number>
+ </property>
+ <property name="verticalSpacing" >
+ <number>6</number>
+ </property>
+ <item row="0" column="0" >
+ <widget class="QLineEdit" name="lineEdit_2" >
+ <property name="text" >
+ <string/>
+ </property>
+ </widget>
+ </item>
+ </layout>
+ </widget>
+ </item>
+ </layout>
+ </widget>
+ <widget class="QWidget" name="tab_2" >
+ <attribute name="title" >
+ <string>Advanced Settings</string>
+ </attribute>
+ <layout class="QVBoxLayout" >
+ <property name="spacing" >
+ <number>6</number>
+ </property>
+ <property name="leftMargin" >
+ <number>9</number>
+ </property>
+ <property name="topMargin" >
+ <number>9</number>
+ </property>
+ <property name="rightMargin" >
+ <number>9</number>
+ </property>
+ <property name="bottomMargin" >
+ <number>9</number>
+ </property>
+ <item>
+ <widget class="QGroupBox" name="groupBox_3" >
+ <property name="title" >
+ <string>Soundcard</string>
+ </property>
+ <layout class="QGridLayout" >
+ <property name="leftMargin" >
+ <number>9</number>
+ </property>
+ <property name="topMargin" >
+ <number>9</number>
+ </property>
+ <property name="rightMargin" >
+ <number>9</number>
+ </property>
+ <property name="bottomMargin" >
+ <number>9</number>
+ </property>
+ <property name="horizontalSpacing" >
+ <number>6</number>
+ </property>
+ <property name="verticalSpacing" >
+ <number>6</number>
+ </property>
+ <item row="3" column="1" >
+ <spacer>
+ <property name="orientation" >
+ <enum>Qt::Vertical</enum>
+ </property>
+ <property name="sizeHint" >
+ <size>
+ <width>20</width>
+ <height>111</height>
+ </size>
+ </property>
+ </spacer>
+ </item>
+ <item row="0" column="2" >
+ <spacer>
+ <property name="orientation" >
+ <enum>Qt::Horizontal</enum>
+ </property>
+ <property name="sizeHint" >
+ <size>
+ <width>188</width>
+ <height>20</height>
+ </size>
+ </property>
+ </spacer>
+ </item>
+ <item row="1" column="1" >
+ <widget class="QSpinBox" name="periodSpinBox" >
+ <property name="minimum" >
+ <number>20</number>
+ </property>
+ <property name="maximum" >
+ <number>5000</number>
+ </property>
+ <property name="value" >
+ <number>100</number>
+ </property>
+ </widget>
+ </item>
+ <item row="0" column="1" >
+ <widget class="QSpinBox" name="bufferSpinBox" >
+ <property name="minimum" >
+ <number>200</number>
+ </property>
+ <property name="maximum" >
+ <number>10000</number>
+ </property>
+ <property name="value" >
+ <number>500</number>
+ </property>
+ </widget>
+ </item>
+ <item row="0" column="0" >
+ <widget class="QLabel" name="label" >
+ <property name="text" >
+ <string>Buffer time (ms):</string>
+ </property>
+ <property name="alignment" >
+ <set>Qt::AlignRight|Qt::AlignTrailing|Qt::AlignVCenter</set>
+ </property>
+ </widget>
+ </item>
+ <item row="1" column="0" >
+ <widget class="QLabel" name="label_2" >
+ <property name="text" >
+ <string>Period time (ms):</string>
+ </property>
+ <property name="alignment" >
+ <set>Qt::AlignRight|Qt::AlignTrailing|Qt::AlignVCenter</set>
+ </property>
+ </widget>
+ </item>
+ <item row="1" column="2" >
+ <spacer>
+ <property name="orientation" >
+ <enum>Qt::Horizontal</enum>
+ </property>
+ <property name="sizeHint" >
+ <size>
+ <width>188</width>
+ <height>20</height>
+ </size>
+ </property>
+ </spacer>
+ </item>
+ <item row="2" column="1" >
+ <widget class="QCheckBox" name="checkBox" >
+ <property name="text" >
+ <string/>
+ </property>
+ </widget>
+ </item>
+ <item row="2" column="0" >
+ <widget class="QLabel" name="label_3" >
+ <property name="text" >
+ <string>PCM over Master</string>
+ </property>
+ </widget>
+ </item>
+ </layout>
+ </widget>
+ </item>
+ </layout>
+ </widget>
+ </widget>
+ </item>
+ <item row="1" column="0" >
+ <spacer>
+ <property name="orientation" >
+ <enum>Qt::Horizontal</enum>
+ </property>
+ <property name="sizeHint" >
+ <size>
+ <width>191</width>
+ <height>20</height>
+ </size>
+ </property>
+ </spacer>
+ </item>
+ <item row="1" column="2" >
+ <widget class="QPushButton" name="cancelButton" >
+ <property name="text" >
+ <string>Cancel</string>
+ </property>
+ </widget>
+ </item>
+ <item row="1" column="1" >
+ <widget class="QPushButton" name="okButton" >
+ <property name="text" >
+ <string>OK</string>
+ </property>
+ </widget>
+ </item>
+ </layout>
+ </widget>
+ <resources/>
+ <connections>
+ <connection>
+ <sender>cancelButton</sender>
+ <signal>clicked()</signal>
+ <receiver>SettingsDialog</receiver>
+ <slot>reject()</slot>
+ <hints>
+ <hint type="sourcelabel" >
+ <x>338</x>
+ <y>283</y>
+ </hint>
+ <hint type="destinationlabel" >
+ <x>164</x>
+ <y>294</y>
+ </hint>
+ </hints>
+ </connection>
+ </connections>
+</ui>
diff --git a/src/plugins/Output/oss/translations/oss_plugin_cs.ts b/src/plugins/Output/oss/translations/oss_plugin_cs.ts
new file mode 100644
index 000000000..424d320e7
--- /dev/null
+++ b/src/plugins/Output/oss/translations/oss_plugin_cs.ts
@@ -0,0 +1,90 @@
+<?xml version="1.0" encoding="utf-8"?>
+<!DOCTYPE TS><TS version="1.1" language="pl">
+<defaultcodec></defaultcodec>
+<context>
+ <name>OutputOSSFactory</name>
+ <message>
+ <location filename="../outputossfactory.cpp" line="30"/>
+ <source>OSS Plugin</source>
+ <translation>Plugin OSS</translation>
+ </message>
+ <message>
+ <location filename="../outputossfactory.cpp" line="47"/>
+ <source>About OSS Output Plugin</source>
+ <translation>O pluginu OSS</translation>
+ </message>
+ <message>
+ <location filename="../outputossfactory.cpp" line="48"/>
+ <source>Qmmp OSS Output Plugin</source>
+ <translation>Výstupní plugin Qmmp OSS</translation>
+ </message>
+ <message>
+ <location filename="../outputossfactory.cpp" line="49"/>
+ <source>Writen by: Yuriy Zhuravlev &lt;slalkerg@gmail.com&gt;</source>
+ <translation>Autor: Jurij Žuravljov &lt;slalkerg@gmail.com&gt;</translation>
+ </message>
+ <message>
+ <location filename="../outputossfactory.cpp" line="50"/>
+ <source>Based on code by:Brad Hughes &lt;bhughes@trolltech.com&gt;</source>
+ <translation>Založeno na kódu Brada Hughese &lt;bhughes@trolltech.com&gt;</translation>
+ </message>
+</context>
+<context>
+ <name>SettingsDialog</name>
+ <message>
+ <location filename="../ui_settingsdialog.h" line="202"/>
+ <source>OSS Plugin Settings</source>
+ <translation>Nastavení pluginu OSS</translation>
+ </message>
+ <message>
+ <location filename="../ui_settingsdialog.h" line="207"/>
+ <source>Device Settings</source>
+ <translation>Nastavení zařízení</translation>
+ </message>
+ <message>
+ <location filename="../ui_settingsdialog.h" line="203"/>
+ <source>Audio device</source>
+ <translation>Zvukové zařízení</translation>
+ </message>
+ <message>
+ <location filename="../ui_settingsdialog.h" line="205"/>
+ <source>Mixer device</source>
+ <translation>Ovládání hlasitosti</translation>
+ </message>
+ <message>
+ <location filename="../ui_settingsdialog.h" line="213"/>
+ <source>Advanced Settings</source>
+ <translation>Pokročilá nastavení</translation>
+ </message>
+ <message>
+ <location filename="../ui_settingsdialog.h" line="208"/>
+ <source>Soundcard</source>
+ <translation>Zvuková karta</translation>
+ </message>
+ <message>
+ <location filename="../ui_settingsdialog.h" line="209"/>
+ <source>Buffer time (ms):</source>
+ <translation>Velikost bufferu (ms):</translation>
+ </message>
+ <message>
+ <location filename="../ui_settingsdialog.h" line="210"/>
+ <source>Period time (ms):</source>
+ <translation type="unfinished"></translation>
+ </message>
+ <message>
+ <location filename="../ui_settingsdialog.h" line="212"/>
+ <source>PCM over Master</source>
+ <translation type="unfinished"></translation>
+ </message>
+ <message>
+ <location filename="../ui_settingsdialog.h" line="214"/>
+ <source>Cancel</source>
+ <translation>Zrušit</translation>
+ </message>
+ <message>
+ <location filename="../ui_settingsdialog.h" line="215"/>
+ <source>OK</source>
+ <translation>OK</translation>
+ </message>
+</context>
+</TS>