aboutsummaryrefslogtreecommitdiff
path: root/src
diff options
context:
space:
mode:
authortrialuser02 <trialuser02@90c681e8-e032-0410-971d-27865f9a5e38>2016-05-20 13:05:19 +0000
committertrialuser02 <trialuser02@90c681e8-e032-0410-971d-27865f9a5e38>2016-05-20 13:05:19 +0000
commit472fac2ade80ddaa4b68bbc718042a09c0f710ad (patch)
tree28518d331a7f633e3afa31847df8c5fa303b57a9 /src
parent8e0b73ced591e10f286b21df88bb09d3ad663f83 (diff)
downloadqmmp-472fac2ade80ddaa4b68bbc718042a09c0f710ad.tar.gz
qmmp-472fac2ade80ddaa4b68bbc718042a09c0f710ad.tar.bz2
qmmp-472fac2ade80ddaa4b68bbc718042a09c0f710ad.zip
wasapi output: fixed remaining bugs, added volume control
git-svn-id: http://svn.code.sf.net/p/qmmp-dev/code/trunk/qmmp@6365 90c681e8-e032-0410-971d-27865f9a5e38
Diffstat (limited to 'src')
-rw-r--r--src/plugins/Output/wasapi/outputwasapi.cpp341
-rw-r--r--src/plugins/Output/wasapi/outputwasapi.h27
-rw-r--r--src/plugins/Output/wasapi/outputwasapifactory.cpp2
-rw-r--r--src/plugins/Output/wasapi/wasapi.pro2
4 files changed, 97 insertions, 275 deletions
diff --git a/src/plugins/Output/wasapi/outputwasapi.cpp b/src/plugins/Output/wasapi/outputwasapi.cpp
index e53823ced..2585240bd 100644
--- a/src/plugins/Output/wasapi/outputwasapi.cpp
+++ b/src/plugins/Output/wasapi/outputwasapi.cpp
@@ -1,5 +1,5 @@
/***************************************************************************
- * Copyright (C) 2014-2016 by Ilya Kotov *
+ * Copyright (C) 2016 by Ilya Kotov *
* forkotov02@hotmail.ru *
* *
* This program is free software; you can redistribute it and/or modify *
@@ -31,12 +31,14 @@ const CLSID CLSID_MMDeviceEnumerator = __uuidof(MMDeviceEnumerator);
const IID IID_IMMDeviceEnumerator = __uuidof(IMMDeviceEnumerator);
const IID IID_IAudioClient = __uuidof(IAudioClient);
const IID IID_IAudioRenderClient = __uuidof(IAudioRenderClient);
+const IID IID_IChannelAudioVolume = __uuidof(IChannelAudioVolume);
+const IID IID_ISimpleAudioVolume = __uuidof(ISimpleAudioVolume);
-#define DS_BUFSIZE (96*1024)
+#define WASAPI_BUFSIZE 20000000LL //2s
OutputWASAPI *OutputWASAPI::instance = 0;
-//VolumeDirectSound *OutputDirectSound::volumeControl = 0;
-OutputWASAPI::DSoundChannels OutputWASAPI::m_dsound_pos[10] = {
+VolumeWASAPI *OutputWASAPI::volumeControl = 0;
+OutputWASAPI::DWASAPIChannels OutputWASAPI::m_wasapi_pos[10] = {
{Qmmp::CHAN_FRONT_LEFT, SPEAKER_FRONT_LEFT},
{Qmmp::CHAN_FRONT_RIGHT, SPEAKER_FRONT_RIGHT},
{Qmmp::CHAN_FRONT_CENTER, SPEAKER_FRONT_CENTER},
@@ -51,14 +53,11 @@ OutputWASAPI::DSoundChannels OutputWASAPI::m_dsound_pos[10] = {
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;
+ m_pSimpleAudioVolume = 0;
instance = this;
}
@@ -71,10 +70,6 @@ OutputWASAPI::~OutputWASAPI()
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);
@@ -131,12 +126,12 @@ bool OutputWASAPI::initialize(quint32 freq, ChannelMap map, Qmmp::AudioFormat fo
ChannelMap out_map;
int i = 0;
DWORD mask = 0;
- while(m_dsound_pos[i].pos != Qmmp::CHAN_NULL)
+ while(m_wasapi_pos[i].pos != Qmmp::CHAN_NULL)
{
- if(map.contains(m_dsound_pos[i].pos))
+ if(map.contains(m_wasapi_pos[i].pos))
{
- mask |= m_dsound_pos[i].chan_mask;
- out_map << m_dsound_pos[i].pos;
+ mask |= m_wasapi_pos[i].chan_mask;
+ out_map << m_wasapi_pos[i].pos;
}
i++;
}
@@ -144,144 +139,44 @@ bool OutputWASAPI::initialize(quint32 freq, ChannelMap map, Qmmp::AudioFormat fo
wfex.dwChannelMask = mask;
wfex.SubFormat = KSDATAFORMAT_SUBTYPE_PCM;
- if((result = m_pAudioClient->Initialize(AUDCLNT_SHAREMODE_SHARED,0, 200, 0, (WAVEFORMATEX *)&wfex, NULL)) != S_OK)
+ if((result = m_pAudioClient->Initialize(AUDCLNT_SHAREMODE_SHARED,0, 20000000LL, 0, (WAVEFORMATEX *)&wfex, NULL)) != S_OK)
{
qWarning("OutputWASAPI: IAudioClient::Initialize failed, error code = 0x%lx", result);
return false;
}
- if((result = m_pAudioClient->GetBufferSize(&m_bufferSize)) != S_OK)
+ if((result = m_pAudioClient->GetBufferSize(&m_bufferFrames)) != S_OK)
{
qWarning("OutputWASAPI: IAudioClient::GetBufferSize failed, error code = 0x%lx", result);
return false;
}
- if((result = m_pAudioClient->GetService(IID_IAudioRenderClient, (void**)&m_pRenderClient)) != S_OK)
- {
- qWarning("OutputWASAPI: IAudioClient::GetService failed, error code = 0x%lx", result);
- return false;
- }
-
- if((result = m_pAudioClient->Start()) != S_OK)
- {
- qWarning("OutputWASAPI: IAudioClient::Start failed, error code = 0x%lx", result);
- return false;
- }
-
- configure(freq, out_map, format);
-
-
- /*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)
+ if((result = m_pAudioClient->GetService(IID_IAudioRenderClient, (void**)&m_pRenderClient)) != S_OK)
{
- qWarning("OutputDirectSound: SetFormat failed, error code = 0x%lx", result);
+ qWarning("OutputWASAPI: IAudioClient::GetService failed, error code = 0x%lx", result);
return false;
}
- if((result = m_primaryBuffer->Play(0, 0, DSBPLAY_LOOPING)) != DS_OK)
+ if((result = m_pAudioClient->GetService(IID_ISimpleAudioVolume, (void**)&m_pSimpleAudioVolume)) != S_OK)
{
- qWarning("OutputDirectSound: Play failed, error code = 0x%lx", result);
+ qWarning("OutputWASAPI: IAudioClient::GetService 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)
+ if((result = m_pAudioClient->Start()) != S_OK)
{
- m_dsBuffer = 0;
- qWarning("OutputDirectSound: QueryInterface failed, error code = 0x%lx", result);
- pDSB->Release();
+ qWarning("OutputWASAPI: IAudioClient::Start failed, error code = 0x%lx", result);
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();*/
+ m_frameSize = sampleSize() * channels();
+ if(volumeControl)
+ volumeControl->restore();
return true;
}
-
qint64 OutputWASAPI::latency()
{
return 0;
@@ -292,203 +187,133 @@ qint64 OutputWASAPI::writeAudio(unsigned char *data, qint64 len)
UINT32 frames = 0;
BYTE *pData = 0;
DWORD flags = 0;
+ DWORD result = 0;
m_pAudioClient->GetCurrentPadding(&frames);
- UINT32 framesAvailable = m_bufferSize - frames;
-
- UINT32 to_write = qMin(framesAvailable, (UINT32)len / 4);
-
- m_pRenderClient->GetBuffer(to_write, &pData);
- memcpy(pData, data, to_write * 4);
- m_pRenderClient->ReleaseBuffer(to_write, flags);
- return to_write * 4;
+ UINT32 framesAvailable = m_bufferFrames - frames;
+ UINT32 framesToWrite = qMin(framesAvailable, (UINT32)len / m_frameSize);
- /*unsigned char *ptr = 0, *ptr2 = 0;
- DWORD size = 0, size2 = 0;
-
- DWORD available = bytesToWrite(); //available bytes
- if(available < 128)
+ //wait until buffer is not full
+ if(framesToWrite == 0)
{
- usleep(5000);
- return 0;
+ usleep(m_bufferFrames * 1000000L / sampleRate() / 2);
+ m_pAudioClient->GetCurrentPadding(&frames);
+ framesAvailable = m_bufferFrames - frames;
+ framesToWrite = qMin(framesAvailable, (UINT32)len / m_frameSize);
}
- 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)
+ if((result = m_pRenderClient->GetBuffer(framesToWrite, &pData)) != S_OK)
{
- qWarning("OutputDirectSound: unable to lock buffer, error = 0x%lx", result);
+ qWarning("OutputWASAPI: IAudioClient::GetBuffer failed, error code = 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;*/
+ memcpy(pData, data, framesToWrite * m_frameSize);
+ m_pRenderClient->ReleaseBuffer(framesToWrite, flags);
+ return framesToWrite * m_frameSize;
}
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);
- }*/
+ UINT32 frames = 0;
+ m_pAudioClient->GetCurrentPadding(&frames);
+ usleep((m_bufferFrames - frames) * 1000000L / sampleRate());
}
void OutputWASAPI::suspend()
{
- //m_dsBuffer->Stop();
+ m_pAudioClient->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();
- }*/
+ m_pAudioClient->Start();
}
void OutputWASAPI::reset()
{
- //m_dsBuffer->SetCurrentPosition(m_dsBufferAt-128);
+ m_pAudioClient->Stop();
+ m_pAudioClient->Reset();
+ m_pAudioClient->Start();
}
-/*IDirectSoundBuffer8 *OutputWASAPI::secondaryBuffer()
+ISimpleAudioVolume *OutputWASAPI::simpleAudioVolume()
{
- return m_dsBuffer;
-}*/
+ return m_pSimpleAudioVolume;
+}
void OutputWASAPI::uninitialize()
{
- m_dsBufferAt = 0;
- /*if(m_dsBuffer)
+ if(m_pAudioClient)
{
- m_dsBuffer->Stop();
- m_dsBuffer->Release();
- m_dsBuffer = 0;
+ m_pAudioClient->Stop();
+ m_pAudioClient->Release();
+ m_pAudioClient = 0;
}
- if(m_primaryBuffer)
+ if(m_pEnumerator)
{
- m_primaryBuffer->Stop();
- m_primaryBuffer->Release();
- m_primaryBuffer = 0;
+ m_pEnumerator->Release();
+ m_pEnumerator = 0;
}
- if(m_ds)
+ if(m_pDevice)
{
- 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)
+ m_pDevice->Release();
+ m_pDevice = 0;
+ }
+ if(m_pRenderClient)
+ {
+ m_pRenderClient->Release();
+ m_pRenderClient = 0;
+ }
+ if(m_pSimpleAudioVolume)
{
- available += DS_BUFSIZE;
+ m_pSimpleAudioVolume->Release();
+ m_pSimpleAudioVolume = 0;
}
- return available;*/
}
/***** MIXER *****/
-/*VolumeDirectSound::VolumeDirectSound()
+VolumeWASAPI::VolumeWASAPI()
{
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();
+ m_volume.left = settings.value("WASAPI/left_volume", 100).toInt();
+ m_volume.right = settings.value("WASAPI/right_volume", 100).toInt();
}
-VolumeDirectSound::~VolumeDirectSound()
+VolumeWASAPI::~VolumeWASAPI()
{
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);
+ settings.setValue("WASAPI/left_volume", m_volume.left);
+ settings.setValue("WASAPI/right_volume", m_volume.right);
OutputWASAPI::volumeControl = 0;
}
-void VolumeDirectSound::setVolume(const VolumeSettings &vol)
+void VolumeWASAPI::setVolume(const VolumeSettings &vol)
{
- if(OutputWASAPI::instance && OutputWASAPI::instance->secondaryBuffer())
+ if(OutputWASAPI::instance && OutputWASAPI::instance->simpleAudioVolume())
{
- 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);
+ OutputWASAPI::instance->simpleAudioVolume()->SetMasterVolume(float(qMax(vol.left, vol.right)) / 100.0f, 0);
}
m_volume = vol;
}
-VolumeSettings VolumeDirectSound::volume() const
+VolumeSettings VolumeWASAPI::volume() const
{
VolumeSettings vol;
- if(OutputWASAPI::instance && OutputWASAPI::instance->secondaryBuffer())
+ if(OutputWASAPI::instance && OutputWASAPI::instance->simpleAudioVolume())
{
- 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;
+ float level = 0;
+ OutputWASAPI::instance->simpleAudioVolume()->GetMasterVolume(&level);
+ vol.left = ceilf(level * 100.0f);
+ vol.right = vol.left;
return vol;
}
return m_volume;
}
-void VolumeDirectSound::restore()
+void VolumeWASAPI::restore()
{
setVolume(m_volume);
-}*/
+}
diff --git a/src/plugins/Output/wasapi/outputwasapi.h b/src/plugins/Output/wasapi/outputwasapi.h
index 5d6df6172..421c01010 100644
--- a/src/plugins/Output/wasapi/outputwasapi.h
+++ b/src/plugins/Output/wasapi/outputwasapi.h
@@ -28,7 +28,7 @@
#include <qmmp/volume.h>
#include <qmmp/output.h>
-//class VolumeDirectSound;
+class VolumeWASAPI;
/**
@author Ilya Kotov <forkotov02@hotmail.ru>
@@ -50,45 +50,42 @@ public:
void reset();
//volume control
+ ISimpleAudioVolume *simpleAudioVolume();
static OutputWASAPI *instance;
- //static VolumeDirectSound *volumeControl;
- //IDirectSoundBuffer8 *secondaryBuffer();
+ static VolumeWASAPI *volumeControl;
private:
// helper functions
void status();
void uninitialize();
- DWORD bytesToWrite();
IMMDeviceEnumerator *m_pEnumerator;
IMMDevice *m_pDevice;
IAudioClient *m_pAudioClient;
IAudioRenderClient *m_pRenderClient;
+ ISimpleAudioVolume *m_pSimpleAudioVolume;
- //IDirectSound8 *m_ds;
- //IDirectSoundBuffer *m_primaryBuffer;
- //IDirectSoundBuffer8 *m_dsBuffer;
- DWORD m_dsBufferAt;
- UINT32 m_bufferSize;
+ UINT32 m_bufferFrames;
+ int m_frameSize;
typedef struct
{
Qmmp::ChannelPosition pos;
DWORD chan_mask;
- } DSoundChannels;
+ } DWASAPIChannels;
- static DSoundChannels m_dsound_pos[10];
+ static DWASAPIChannels m_wasapi_pos[10];
};
/**
@author Ilya Kotov <forkotov02@hotmail.ru>
*/
-/*class VolumeDirectSound : public Volume
+class VolumeWASAPI : public Volume
{
public:
- VolumeDirectSound();
- ~VolumeDirectSound();
+ VolumeWASAPI();
+ ~VolumeWASAPI();
void setVolume(const VolumeSettings &vol);
VolumeSettings volume() const;
@@ -96,7 +93,7 @@ public:
private:
VolumeSettings m_volume;
-};*/
+};
#endif // OUTPUTWASAPI_H
diff --git a/src/plugins/Output/wasapi/outputwasapifactory.cpp b/src/plugins/Output/wasapi/outputwasapifactory.cpp
index 3ff8cda6e..5a362e543 100644
--- a/src/plugins/Output/wasapi/outputwasapifactory.cpp
+++ b/src/plugins/Output/wasapi/outputwasapifactory.cpp
@@ -39,7 +39,7 @@ Output* OutputWASAPIFactory::create()
Volume *OutputWASAPIFactory::createVolume()
{
- return 0;
+ return new VolumeWASAPI;
}
void OutputWASAPIFactory::showSettings(QWidget* parent)
diff --git a/src/plugins/Output/wasapi/wasapi.pro b/src/plugins/Output/wasapi/wasapi.pro
index 08a8b0b23..9b1a7dbdd 100644
--- a/src/plugins/Output/wasapi/wasapi.pro
+++ b/src/plugins/Output/wasapi/wasapi.pro
@@ -19,7 +19,7 @@ thread \
plugin
TEMPLATE = lib
-LIBS += -lqmmp0 -ldxguid -lstrmiids -ldmoguids -lmsdmo -lole32 -loleaut32 -luuid -lgdi32 -ldsound -lksuser
+LIBS += -lqmmp0 -lstrmiids -ldmoguids -lmsdmo -lole32 -loleaut32 -luuid -lgdi32 -lksuser
#RESOURCES = translations/translations.qrc