diff options
| author | trialuser02 <trialuser02@90c681e8-e032-0410-971d-27865f9a5e38> | 2016-05-19 11:55:55 +0000 |
|---|---|---|
| committer | trialuser02 <trialuser02@90c681e8-e032-0410-971d-27865f9a5e38> | 2016-05-19 11:55:55 +0000 |
| commit | afefc873f2c140a95b06b5c6c95a7203747deaa1 (patch) | |
| tree | ab7a0a4250e4cab741d6d86d5e8fa7a3b711ff08 | |
| parent | 101eb6c9cd4b0074f9ee041ca924a7870effbd58 (diff) | |
| download | qmmp-afefc873f2c140a95b06b5c6c95a7203747deaa1.tar.gz qmmp-afefc873f2c140a95b06b5c6c95a7203747deaa1.tar.bz2 qmmp-afefc873f2c140a95b06b5c6c95a7203747deaa1.zip | |
prepare for WASAPI implementation
git-svn-id: http://svn.code.sf.net/p/qmmp-dev/code/trunk/qmmp@6363 90c681e8-e032-0410-971d-27865f9a5e38
| -rw-r--r-- | src/plugins/Output/Output.pro | 1 | ||||
| -rw-r--r-- | src/plugins/Output/wasapi/CMakeLists.txt | 53 | ||||
| -rw-r--r-- | src/plugins/Output/wasapi/outputwasapi.cpp | 404 | ||||
| -rw-r--r-- | src/plugins/Output/wasapi/outputwasapi.h | 101 | ||||
| -rw-r--r-- | src/plugins/Output/wasapi/outputwasapifactory.cpp | 65 | ||||
| -rw-r--r-- | src/plugins/Output/wasapi/outputwasapifactory.h | 44 | ||||
| -rw-r--r-- | src/plugins/Output/wasapi/wasapi.pro | 31 |
7 files changed, 699 insertions, 0 deletions
diff --git a/src/plugins/Output/Output.pro b/src/plugins/Output/Output.pro index 8ce94616a..0ef07e2fd 100644 --- a/src/plugins/Output/Output.pro +++ b/src/plugins/Output/Output.pro @@ -3,6 +3,7 @@ include(../../../qmmp.pri) TEMPLATE = subdirs win32:SUBDIRS += waveout win32:SUBDIRS += directsound +win32:SUBDIRS += wasapi SUBDIRS += null diff --git a/src/plugins/Output/wasapi/CMakeLists.txt b/src/plugins/Output/wasapi/CMakeLists.txt new file mode 100644 index 000000000..1eb54884d --- /dev/null +++ b/src/plugins/Output/wasapi/CMakeLists.txt @@ -0,0 +1,53 @@ +project(libwasapi) + +cmake_minimum_required(VERSION 2.4.7) + +INCLUDE(CheckIncludeFile) + +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}/../../../ +) + +# libqmmp +include_directories(${CMAKE_CURRENT_SOURCE_DIR}/../../../) +link_directories(${CMAKE_CURRENT_BINARY_DIR}/../../../qmmp) + +# Win32 wasapi +CHECK_INCLUDE_FILE(dsound.h DSOUND_H_FOUND) + +SET(libwasapi_SRCS + outputwasapi.cpp + outputwasapifactory.cpp +) + +SET(libwasapi_HDRS + outputwasapi.h +) + +SET(libwasapi_RCCS translations/translations.qrc) + +QT4_ADD_RESOURCES(libwasapi_RCC_SRCS ${libwasapi_RCCS}) + + +IF(DSOUND_H_FOUND) +ADD_LIBRARY(wasapi MODULE ${libwasapi_SRCS} ${libwasapi_RCC_SRCS} ${libwasapi_HDRS}) +add_dependencies(wasapi qmmp) +target_link_libraries(wasapi ${QT_LIBRARIES} libqmmp -ldxguid -lstrmiids -ldmoguids -lmsdmo -lole32 -loleaut32 -luuid -lgdi32 -ldsound) +install(TARGETS wasapi DESTINATION ${LIB_DIR}/qmmp/Output) +ENDIF(DSOUND_H_FOUND) + diff --git a/src/plugins/Output/wasapi/outputwasapi.cpp b/src/plugins/Output/wasapi/outputwasapi.cpp new file mode 100644 index 000000000..802f6d045 --- /dev/null +++ b/src/plugins/Output/wasapi/outputwasapi.cpp @@ -0,0 +1,404 @@ +/***************************************************************************
+ * Copyright (C) 2014-2016 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., *
+ * 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA. *
+ ***************************************************************************/
+
+#include <QObject>
+#include <QSettings>
+#include <string.h>
+#include <iostream>
+#include <unistd.h>
+#include <qmmp/buffer.h>
+#include <math.h>
+#include "outputwasapi.h"
+
+const CLSID CLSID_MMDeviceEnumerator = __uuidof(MMDeviceEnumerator);
+const IID IID_IMMDeviceEnumerator = __uuidof(IMMDeviceEnumerator);
+const IID IID_IAudioClient = __uuidof(IAudioClient);
+const IID IID_IAudioRenderClient = __uuidof(IAudioRenderClient);
+
+#define DS_BUFSIZE (96*1024)
+
+OutputWASAPI *OutputWASAPI::instance = 0;
+//VolumeDirectSound *OutputDirectSound::volumeControl = 0;
+OutputWASAPI::DSoundChannels OutputWASAPI::m_dsound_pos[10] = {
+ {Qmmp::CHAN_FRONT_LEFT, SPEAKER_FRONT_LEFT},
+ {Qmmp::CHAN_FRONT_RIGHT, SPEAKER_FRONT_RIGHT},
+ {Qmmp::CHAN_FRONT_CENTER, SPEAKER_FRONT_CENTER},
+ {Qmmp::CHAN_LFE, SPEAKER_LOW_FREQUENCY},
+ {Qmmp::CHAN_REAR_LEFT, SPEAKER_BACK_LEFT},
+ {Qmmp::CHAN_REAR_RIGHT, SPEAKER_BACK_RIGHT},
+ {Qmmp::CHAN_REAR_CENTER, SPEAKER_BACK_CENTER},
+ {Qmmp::CHAN_SIDE_LEFT, SPEAKER_SIDE_LEFT},
+ {Qmmp::CHAN_SIDE_RIGHT, SPEAKER_BACK_RIGHT},
+ {Qmmp::CHAN_NULL, 0}
+};
+
+OutputWASAPI::OutputWASAPI() : Output()
+{
+ //m_ds = 0;
+ //m_primaryBuffer = 0;
+ //m_dsBuffer = 0;
+ m_dsBufferAt = 0;
+ m_pEnumerator = 0;
+ m_pDevice = 0;
+ m_pAudioClient = 0;
+ m_pRenderClient = 0;
+ instance = this;
+}
+
+OutputWASAPI::~OutputWASAPI()
+{
+ instance = 0;
+ uninitialize();
+}
+
+bool OutputWASAPI::initialize(quint32 freq, ChannelMap map, Qmmp::AudioFormat format)
+{
+ HRESULT result = CoCreateInstance(CLSID_MMDeviceEnumerator, NULL, CLSCTX_ALL, IID_IMMDeviceEnumerator, (void**)&m_pEnumerator);
+
+ //DSBUFFERDESC bufferDesc;
+
+ //HRESULT result = DirectSoundCreate8(0, &m_ds, 0);
+ if(result != S_OK)
+ {
+ qWarning("OutputWASAPI: CoCreateInstance failed, error code = 0x%lx", result);
+ m_pEnumerator = 0;
+ return false;
+ }
+
+ if((result = m_pEnumerator->GetDefaultAudioEndpoint(eRender, eConsole, &m_pDevice)) != S_OK)
+ {
+ qWarning("OutputWASAPI: IMMDeviceEnumerator::GetDefaultAudioEndpoint failed, error code = 0x%lx", result);
+ m_pDevice = 0;
+ return false;
+ }
+
+ if((result = m_pDevice->Activate(IID_IAudioClient, CLSCTX_ALL, NULL, (void**)&m_pAudioClient)) != S_OK)
+ {
+ qWarning("OutputWASAPI: IMMDevice::Activate failed, error code = 0x%lx", result);
+ m_pAudioClient = 0;
+ return false;
+ }
+
+ /*if((result = m_ds->SetCooperativeLevel(GetDesktopWindow(), DSSCL_PRIORITY)) != DS_OK)
+ {
+ qWarning("OutputDirectSound: SetCooperativeLevel failed, error code = 0x%lx", result);
+ return false;
+ }
+
+ ZeroMemory(&bufferDesc, sizeof(DSBUFFERDESC));
+ bufferDesc.dwSize = sizeof(DSBUFFERDESC);
+ bufferDesc.dwFlags = DSBCAPS_PRIMARYBUFFER | DSBCAPS_CTRLVOLUME | DSBCAPS_LOCHARDWARE;
+ bufferDesc.dwBufferBytes = 0;
+ bufferDesc.lpwfxFormat = NULL;
+
+ if((result = m_ds->CreateSoundBuffer(&bufferDesc, &m_primaryBuffer, NULL)) != DS_OK)
+ {
+ m_primaryBuffer = 0;
+ qWarning("OutputDirectSound: CreateSoundBuffer failed, error code = 0x%lx", result);
+ return false;
+ }
+
+ WAVEFORMATEXTENSIBLE wfex;
+ wfex.Format.wFormatTag = WAVE_FORMAT_EXTENSIBLE;
+ wfex.Format.nChannels = map.count();
+ wfex.Format.nSamplesPerSec = freq;
+ wfex.Format.cbSize = sizeof(WAVEFORMATEXTENSIBLE);
+
+ if(format == Qmmp::PCM_S16LE)
+ {
+ wfex.Format.wBitsPerSample = 16;
+ wfex.Samples.wValidBitsPerSample = 16;
+ }
+ else if(format == Qmmp::PCM_S24LE)
+ {
+ wfex.Format.wBitsPerSample = 32;
+ wfex.Samples.wValidBitsPerSample = 24;
+ }
+ else if(format == Qmmp::PCM_S32LE)
+ {
+ wfex.Format.wBitsPerSample = 32;
+ wfex.Samples.wValidBitsPerSample = 32;
+ }
+ else
+ {
+ format = Qmmp::PCM_S16LE;
+ wfex.Format.wBitsPerSample = 16;
+ wfex.Samples.wValidBitsPerSample = 16;
+ }
+
+ wfex.Format.nBlockAlign = (wfex.Format.wBitsPerSample / 8) * wfex.Format.nChannels;
+ wfex.Format.nAvgBytesPerSec = wfex.Format.nSamplesPerSec * wfex.Format.nBlockAlign;
+
+ //generate channel order
+ ChannelMap out_map;
+ int i = 0;
+ DWORD mask = 0;
+ while(m_dsound_pos[i].pos != Qmmp::CHAN_NULL)
+ {
+ if(map.contains(m_dsound_pos[i].pos))
+ {
+ mask |= m_dsound_pos[i].chan_mask;
+ out_map << m_dsound_pos[i].pos;
+ }
+ i++;
+ }
+
+ wfex.dwChannelMask = mask;
+ wfex.SubFormat = KSDATAFORMAT_SUBTYPE_PCM;
+
+ if((result = m_primaryBuffer->SetFormat((WAVEFORMATEX*)&wfex)) != DS_OK)
+ {
+ qWarning("OutputDirectSound: SetFormat failed, error code = 0x%lx", result);
+ return false;
+ }
+
+ if((result = m_primaryBuffer->Play(0, 0, DSBPLAY_LOOPING)) != DS_OK)
+ {
+ qWarning("OutputDirectSound: Play failed, error code = 0x%lx", result);
+ return false;
+ }
+
+ ZeroMemory(&bufferDesc, sizeof(DSBUFFERDESC));
+ bufferDesc.dwSize = sizeof(DSBUFFERDESC);
+ bufferDesc.dwFlags = DSBCAPS_CTRLFREQUENCY | DSBCAPS_CTRLPAN | DSBCAPS_CTRLVOLUME |
+ DSBCAPS_GLOBALFOCUS | DSBCAPS_GETCURRENTPOSITION2 | DSBCAPS_CTRLPOSITIONNOTIFY;
+ bufferDesc.lpwfxFormat = (WAVEFORMATEX*)&wfex;
+ bufferDesc.dwBufferBytes = DS_BUFSIZE; // buffer size
+
+ IDirectSoundBuffer *pDSB;
+ if((result = m_ds->CreateSoundBuffer(&bufferDesc, &pDSB, NULL)) != DS_OK)
+ {
+ qWarning("OutputDirectSound: CreateSoundBuffer failed, error code = 0x%lx", result);
+ return false;
+ }
+
+ if((result = pDSB->QueryInterface(IID_IDirectSoundBuffer8, (void**)&m_dsBuffer)) != DS_OK)
+ {
+ m_dsBuffer = 0;
+ qWarning("OutputDirectSound: QueryInterface failed, error code = 0x%lx", result);
+ pDSB->Release();
+ return false;
+ }
+
+ m_dsBuffer->SetCurrentPosition(0);
+ m_dsBuffer->Play(0,0,DSBPLAY_LOOPING);
+ m_dsBufferAt = 0;
+ configure(freq, out_map, format);
+ //if(volumeControl)
+ // volumeControl->restore();*/
+ return true;
+}
+
+
+qint64 OutputWASAPI::latency()
+{
+ return 0;
+}
+
+qint64 OutputWASAPI::writeAudio(unsigned char *data, qint64 len)
+{
+ /*unsigned char *ptr = 0, *ptr2 = 0;
+ DWORD size = 0, size2 = 0;
+
+ DWORD available = bytesToWrite(); //available bytes
+ if(available < 128)
+ {
+ usleep(5000);
+ return 0;
+ }
+ DWORD lockSize = qMin((DWORD)len, available); //required size
+
+ HRESULT result = m_dsBuffer->Lock(m_dsBufferAt, lockSize,
+ (void**)&ptr, (DWORD*)&size,
+ (void**)&ptr2, (DWORD*)&size2, 0);
+ if(result == DSERR_BUFFERLOST)
+ {
+ m_dsBuffer->Restore();
+ result = m_dsBuffer->Lock(m_dsBufferAt, lockSize,
+ (void**)&ptr, (DWORD*)&size,
+ (void**)&ptr2, (DWORD*)&size2, 0);
+ }
+ if(result != DS_OK)
+ {
+ qWarning("OutputDirectSound: unable to lock buffer, error = 0x%lx", result);
+ return -1;
+ }
+
+ DWORD totalSize = size + size2; //total locked size
+
+ if(format() == Qmmp::PCM_S24LE)
+ {
+ for(DWORD i = 0; i < totalSize / 4; ++i)
+ {
+ ((quint32*) data)[i] <<= 8;
+ }
+ }
+
+ memmove(ptr, data, size);
+ if(size2 > 0)
+ memmove(ptr2, data + size, size2);
+
+ m_dsBuffer->Unlock((void*)ptr, size, (void*)ptr2, size2);
+
+ m_dsBufferAt += totalSize;
+ m_dsBufferAt %= DS_BUFSIZE;
+
+ return totalSize;*/
+}
+
+void OutputWASAPI::drain()
+{
+ /*DWORD dsCurrentPlayCursor = 0;
+ m_dsBuffer->GetCurrentPosition((DWORD*)&dsCurrentPlayCursor, 0);
+
+ while(dsCurrentPlayCursor >= m_dsBufferAt)
+ {
+ m_dsBuffer->GetCurrentPosition((DWORD*)&dsCurrentPlayCursor, 0);
+ }
+ while (dsCurrentPlayCursor <= m_dsBufferAt)
+ {
+ m_dsBuffer->GetCurrentPosition((DWORD*)&dsCurrentPlayCursor, 0);
+ }*/
+}
+
+void OutputWASAPI::suspend()
+{
+ //m_dsBuffer->Stop();
+}
+
+void OutputWASAPI::resume()
+{
+ /*HRESULT result = m_dsBuffer->Play(0,0,DSBPLAY_LOOPING);
+ if(result == DSERR_BUFFERLOST)
+ {
+ result = m_dsBuffer->Play(0,0,DSBPLAY_LOOPING);
+ m_dsBuffer->Restore();
+ }*/
+}
+
+void OutputWASAPI::reset()
+{
+ //m_dsBuffer->SetCurrentPosition(m_dsBufferAt-128);
+}
+
+/*IDirectSoundBuffer8 *OutputWASAPI::secondaryBuffer()
+{
+ return m_dsBuffer;
+}*/
+
+void OutputWASAPI::uninitialize()
+{
+ m_dsBufferAt = 0;
+ /*if(m_dsBuffer)
+ {
+ m_dsBuffer->Stop();
+ m_dsBuffer->Release();
+ m_dsBuffer = 0;
+ }
+ if(m_primaryBuffer)
+ {
+ m_primaryBuffer->Stop();
+ m_primaryBuffer->Release();
+ m_primaryBuffer = 0;
+ }
+ if(m_ds)
+ {
+ m_ds->Release();
+ m_ds = 0;
+ }*/
+}
+
+DWORD OutputWASAPI::bytesToWrite()
+{
+ /*DWORD dsCurrentPlayCursor = 0;
+ m_dsBuffer->GetCurrentPosition((DWORD*)&dsCurrentPlayCursor, 0);
+ long available = dsCurrentPlayCursor - m_dsBufferAt; //available bytes
+
+ if(available < 0)
+ {
+ available += DS_BUFSIZE;
+ }
+ return available;*/
+}
+
+/***** MIXER *****/
+/*VolumeDirectSound::VolumeDirectSound()
+{
+ OutputWASAPI::volumeControl = this;
+ QSettings settings(Qmmp::configFile(), QSettings::IniFormat);
+ m_volume.left = settings.value("DirectSound/left_volume", 100).toInt();
+ m_volume.right = settings.value("DirectSound/right_volume", 100).toInt();
+}
+
+VolumeDirectSound::~VolumeDirectSound()
+{
+ m_volume = volume();
+ QSettings settings(Qmmp::configFile(), QSettings::IniFormat);
+ settings.setValue("DirectSound/left_volume", m_volume.left);
+ settings.setValue("DirectSound/right_volume", m_volume.right);
+ OutputWASAPI::volumeControl = 0;
+}
+
+void VolumeDirectSound::setVolume(const VolumeSettings &vol)
+{
+ if(OutputWASAPI::instance && OutputWASAPI::instance->secondaryBuffer())
+ {
+ int maxVol = qMax(vol.left, vol.right);
+ double voldB = -100.0, pandB = 0;
+ if(maxVol)
+ {
+ voldB = 20.0*log(maxVol/100.0)/log(10);
+ int balance = (vol.right - vol.left)*100.0/maxVol;
+ pandB = balance ? 20.0*log((100.0 - fabs(balance))/100.0)/log(10) : 0;
+ if(balance > 0)
+ pandB = -pandB;
+ }
+ OutputWASAPI::instance->secondaryBuffer()->SetVolume(voldB*100);
+ OutputWASAPI::instance->secondaryBuffer()->SetPan(pandB*100);
+ }
+ m_volume = vol;
+}
+
+VolumeSettings VolumeDirectSound::volume() const
+{
+ VolumeSettings vol;
+ if(OutputWASAPI::instance && OutputWASAPI::instance->secondaryBuffer())
+ {
+ long v = 0;
+ double voldB = 0, pandB = 0;
+ OutputWASAPI::instance->secondaryBuffer()->GetVolume(&v);
+ voldB = v / 100.0;
+ OutputWASAPI::instance->secondaryBuffer()->GetPan(&v);
+ pandB = v / 100.0;
+ int volume = 100*pow(10, voldB/20.0);
+ int balance = 100 - 100*pow(10, abs(pandB)/20.0);
+ if(pandB > 0)
+ balance = -balance;
+ vol.left = volume-qMax(balance,0)*volume/100.0;
+ vol.right = volume+qMin(balance,0)*volume/100.0;
+ return vol;
+ }
+ return m_volume;
+}
+
+void VolumeDirectSound::restore()
+{
+ setVolume(m_volume);
+}*/
diff --git a/src/plugins/Output/wasapi/outputwasapi.h b/src/plugins/Output/wasapi/outputwasapi.h new file mode 100644 index 000000000..bfec494d7 --- /dev/null +++ b/src/plugins/Output/wasapi/outputwasapi.h @@ -0,0 +1,101 @@ +/***************************************************************************
+ * Copyright (C) 2016 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., *
+ * 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA. *
+ ***************************************************************************/
+
+#ifndef OUTPUTWASAPI_H
+#define OUTPUTWASAPI_H
+
+#include <stdio.h>
+#include <windows.h>
+#include <mmdeviceapi.h>
+#include <Audioclient.h>
+#include <qmmp/volume.h>
+#include <qmmp/output.h>
+
+//class VolumeDirectSound;
+
+/**
+ @author Ilya Kotov <forkotov02@hotmail.ru>
+*/
+class OutputWASAPI : public Output
+{
+public:
+ OutputWASAPI();
+ ~OutputWASAPI();
+
+ bool initialize(quint32, ChannelMap map, Qmmp::AudioFormat format);
+
+ //output api
+ qint64 latency();
+ qint64 writeAudio(unsigned char *data, qint64 size);
+ void drain();
+ void suspend();
+ void resume();
+ void reset();
+
+ //volume control
+ static OutputWASAPI *instance;
+ //static VolumeDirectSound *volumeControl;
+ //IDirectSoundBuffer8 *secondaryBuffer();
+
+
+private:
+ // helper functions
+ void status();
+ void uninitialize();
+ DWORD bytesToWrite();
+
+ IMMDeviceEnumerator *m_pEnumerator;
+ IMMDevice *m_pDevice;
+ IAudioClient *m_pAudioClient;
+ IAudioRenderClient *m_pRenderClient;
+
+ //IDirectSound8 *m_ds;
+ //IDirectSoundBuffer *m_primaryBuffer;
+ //IDirectSoundBuffer8 *m_dsBuffer;
+ DWORD m_dsBufferAt;
+
+ typedef struct
+ {
+ Qmmp::ChannelPosition pos;
+ DWORD chan_mask;
+ } DSoundChannels;
+
+ static DSoundChannels m_dsound_pos[10];
+};
+
+/**
+ @author Ilya Kotov <forkotov02@hotmail.ru>
+*/
+/*class VolumeDirectSound : public Volume
+{
+public:
+ VolumeDirectSound();
+ ~VolumeDirectSound();
+
+ void setVolume(const VolumeSettings &vol);
+ VolumeSettings volume() const;
+ void restore();
+
+private:
+ VolumeSettings m_volume;
+};*/
+
+
+#endif // OUTPUTWASAPI_H
diff --git a/src/plugins/Output/wasapi/outputwasapifactory.cpp b/src/plugins/Output/wasapi/outputwasapifactory.cpp new file mode 100644 index 000000000..3ff8cda6e --- /dev/null +++ b/src/plugins/Output/wasapi/outputwasapifactory.cpp @@ -0,0 +1,65 @@ +/***************************************************************************
+ * Copyright (C) 2016 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., *
+ * 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA. *
+ ***************************************************************************/
+
+#include <QtGui>
+#include "outputwasapi.h"
+#include "outputwasapifactory.h"
+
+const OutputProperties OutputWASAPIFactory::properties() const
+{
+ OutputProperties properties;
+ properties.name = tr("WASAPI Plugin");
+ properties.hasAbout = true;
+ properties.hasSettings = false;
+ properties.shortName = "wasapi";
+ return properties;
+}
+
+Output* OutputWASAPIFactory::create()
+{
+ return new OutputWASAPI();
+}
+
+Volume *OutputWASAPIFactory::createVolume()
+{
+ return 0;
+}
+
+void OutputWASAPIFactory::showSettings(QWidget* parent)
+{
+ Q_UNUSED(parent);
+}
+
+void OutputWASAPIFactory::showAbout(QWidget *parent)
+{
+ QMessageBox::about (parent, tr("About WASAPI Output Plugin"),
+ tr("Qmmp WASAPI Output Plugin")+"\n"+
+ tr("Written by: Ilya Kotov <forkotov02@hotmail.ru>"));
+}
+
+QTranslator *OutputWASAPIFactory::createTranslator(QObject *parent)
+{
+ QTranslator *translator = new QTranslator(parent);
+ QString locale = Qmmp::systemLanguageID();
+ translator->load(QString(":/wasapi_plugin_") + locale);
+ return translator;
+}
+
+Q_EXPORT_PLUGIN2(wasapi,OutputWASAPIFactory)
diff --git a/src/plugins/Output/wasapi/outputwasapifactory.h b/src/plugins/Output/wasapi/outputwasapifactory.h new file mode 100644 index 000000000..9b9d78fa7 --- /dev/null +++ b/src/plugins/Output/wasapi/outputwasapifactory.h @@ -0,0 +1,44 @@ +/***************************************************************************
+ * Copyright (C) 2016 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., *
+ * 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA. *
+ ***************************************************************************/
+#ifndef OUTPUTWASAPIFACTORY_H
+#define OUTPUTWASAPIFACTORY_H
+
+#include <QObject>
+#include <QString>
+#include <QIODevice>
+#include <QWidget>
+#include <qmmp/output.h>
+#include <qmmp/outputfactory.h>
+
+class OutputWASAPIFactory : public QObject, OutputFactory
+{
+Q_OBJECT
+Q_INTERFACES(OutputFactory)
+
+public:
+ const OutputProperties properties() const;
+ Output* create();
+ Volume *createVolume();
+ void showSettings(QWidget* parent);
+ void showAbout(QWidget *parent);
+ QTranslator *createTranslator(QObject *parent);
+};
+
+#endif
diff --git a/src/plugins/Output/wasapi/wasapi.pro b/src/plugins/Output/wasapi/wasapi.pro new file mode 100644 index 000000000..08a8b0b23 --- /dev/null +++ b/src/plugins/Output/wasapi/wasapi.pro @@ -0,0 +1,31 @@ +include(../../plugins.pri) + +HEADERS += outputwasapifactory.h \ + outputwasapi.h + +SOURCES += outputwasapifactory.cpp \ + outputwasapi.cpp + +HEADERS += ../../../../src/qmmp/output.h + + +TARGET=$$PLUGINS_PREFIX/Output/wasapi + +INCLUDEPATH += ../../../ +QMAKE_LIBDIR += ../../../../bin + +CONFIG += warn_on \ +thread \ +plugin + +TEMPLATE = lib +LIBS += -lqmmp0 -ldxguid -lstrmiids -ldmoguids -lmsdmo -lole32 -loleaut32 -luuid -lgdi32 -ldsound -lksuser + +#RESOURCES = translations/translations.qrc + +isEmpty (LIB_DIR){ +LIB_DIR = /lib +} + +target.path = $$LIB_DIR/qmmp/Output +INSTALLS += target |
