/*************************************************************************** * Copyright (C) 2010-2015 by Ilya Kotov * * forkotov02@ya.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., * * 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA. * ***************************************************************************/ #include #include #include extern "C" { #ifdef HAVE_SYS_SOUNDCARD_H #include #else #include #endif //#include } #include #include #include #include #include #include #include #include #include #include #include "outputoss4.h" OutputOSS4 *OutputOSS4::m_instance = 0; VolumeOSS4 *OutputOSS4::m_vc = 0; Qmmp::ChannelPosition OutputOSS4::m_oss_pos[16] = { Qmmp::CHAN_NULL, //0 = null Qmmp::CHAN_FRONT_LEFT, //1 = left Qmmp::CHAN_FRONT_RIGHT, //2 = right Qmmp::CHAN_FRONT_CENTER, //3 = center Qmmp::CHAN_LFE, //4 = lfe Qmmp::CHAN_SIDE_LEFT, //5 = left surround Qmmp::CHAN_SIDE_RIGHT, //6 = right surround Qmmp::CHAN_REAR_LEFT, //7 = left rear Qmmp::CHAN_REAR_LEFT, //8 = right rear Qmmp::CHAN_NULL, Qmmp::CHAN_NULL, Qmmp::CHAN_NULL, Qmmp::CHAN_NULL, Qmmp::CHAN_NULL, Qmmp::CHAN_NULL, Qmmp::CHAN_NULL }; OutputOSS4::OutputOSS4() : Output() { m_audio_fd = -1; QSettings settings(Qmmp::configFile(), QSettings::IniFormat); m_audio_device = settings.value("OSS4/device", DEFAULT_DEV).toString(); m_instance = this; } OutputOSS4::~OutputOSS4() { if (m_audio_fd >= 0) { ioctl(m_audio_fd, SNDCTL_DSP_RESET, 0); close(m_audio_fd); m_audio_fd = -1; } m_instance = 0; } int OutputOSS4::fd() { return m_audio_fd; } OutputOSS4 *OutputOSS4::instance() { return m_instance; } void OutputOSS4::post() { ioctl(m_audio_fd, SNDCTL_DSP_POST, 0); } void OutputOSS4::sync() { ioctl(m_audio_fd, SNDCTL_DSP_SYNC, 0); } bool OutputOSS4::initialize(quint32 freq, ChannelMap map, Qmmp::AudioFormat format) { m_audio_fd = open(m_audio_device.toLatin1(), O_WRONLY); if (m_audio_fd < 0) { qWarning("OSS4Output: unable to open output device '%s'; error: %s", qPrintable(m_audio_device), strerror(errno)); return false; } ioctl(m_audio_fd, SNDCTL_DSP_RESET, 0); int p; int chan = map.count(); switch (format) { case Qmmp::PCM_S32LE: p = AFMT_S32_LE; break; case Qmmp::PCM_S24LE: p = AFMT_S24_LE; break; case Qmmp::PCM_S16LE: p = AFMT_S16_LE; break; case Qmmp::PCM_S8: p = AFMT_S8; break; default: qWarning("OutputOSS4: unsupported audio format"); return false; } if (ioctl(m_audio_fd, SNDCTL_DSP_SETFMT, &p) == -1) qWarning("OutputOSS4: ioctl SNDCTL_DSP_SETFMT failed: %s",strerror(errno)); if(ioctl(m_audio_fd, SNDCTL_DSP_CHANNELS, &chan) == -1) qWarning("OutputOSS4: ioctl SNDCTL_DSP_CHANNELS failed: %s", strerror(errno)); if (ioctl(m_audio_fd, SNDCTL_DSP_SPEED, &freq) < 0) qWarning("OutputOSS4: ioctl SNDCTL_DSP_SPEED failed: %s", strerror(errno)); int enabled = 1; if(ioctl(m_audio_fd, SNDCTL_DSP_COOKEDMODE, &enabled) == -1) qWarning("OutputOSS4: ioctl SNDCTL_DSP_COOKEDMODE: %s", strerror(errno)); quint64 layout = 0; if (ioctl (m_audio_fd, SNDCTL_DSP_GET_CHNORDER, &layout) == -1) { qWarning("OutputOSS4: couldn't query channel layout, assuming default"); layout = CHNORDER_NORMAL; } ChannelMap oss_map; for(int i = 0; i < chan; i++) { quint32 pos = ((layout >> (i * 4)) & 0x0f); oss_map << m_oss_pos[pos]; } project(libincdecvolumeoption) cmake_minimum_required(VERSION 2.4.7) if(COMMAND cmake_policy) cmake_policy(SET CMP0003 NEW) endif(COMMAND cmake_policy) # 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_SOURCE_DIR}/../../../ ) # libqmmpui include_directories(${CMAKE_CURRENT_SOURCE_DIR}/../../../) link_directories(${CMAKE_CURRENT_BINARY_DIR}/../../../qmmpui) link_directories(${CMAKE_CURRENT_BINARY_DIR}/../../../qmmp) SET(libincdecvolumeoption_SRCS incdecvolumeoption.cpp ) SET(libincdecvolumeoption_MOC_HDRS incdecvolumeoption.h ) SET(libincdecvolumeoption_RCCS translations/translations.qrc) QT4_ADD_RESOURCES(libincdecvolumeoption_RCC_SRCS ${libincdecvolumeoption_RCCS}) QT4_WRAP_CPP(libincdecvolumeoption_MOC_SRCS ${libincdecvolumeoption_MOC_HDRS}) # Don't forget to include output directory, otherwise # the UI file won't be wrapped! include_directories(${CMAKE_CURRENT_BINARY_DIR}) ADD_LIBRARY(incdecvolumeoption MODULE ${libincdecvolumeoption_SRCS} ${libincdecvolumeoption_MOC_SRCS} ${libincdecvolumeoption_RCC_SRCS}) add_dependencies(incdecvolumeoption qmmpui) target_link_libraries(incdecvolumeoption ${QT_LIBRARIES} -lqmmpui -lqmmp) install(TARGETS incdecvolumeoption DESTINATION ${LIB_DIR}/qmmp/CommandLineOptions) >fd(), SNDCTL_DSP_SETPLAYVOL, &m_volume); } }