From 8e0b73ced591e10f286b21df88bb09d3ad663f83 Mon Sep 17 00:00:00 2001 From: trialuser02 Date: Fri, 20 May 2016 09:04:35 +0000 Subject: wasapi output: minimal implementation git-svn-id: http://svn.code.sf.net/p/qmmp-dev/code/trunk/qmmp@6364 90c681e8-e032-0410-971d-27865f9a5e38 --- src/plugins/Output/wasapi/outputwasapi.cpp | 90 ++++++++++++++++++++++++++++++ src/plugins/Output/wasapi/outputwasapi.h | 1 + 2 files changed, 91 insertions(+) (limited to 'src/plugins/Output') diff --git a/src/plugins/Output/wasapi/outputwasapi.cpp b/src/plugins/Output/wasapi/outputwasapi.cpp index 802f6d045..e53823ced 100644 --- a/src/plugins/Output/wasapi/outputwasapi.cpp +++ b/src/plugins/Output/wasapi/outputwasapi.cpp @@ -96,6 +96,81 @@ bool OutputWASAPI::initialize(quint32 freq, ChannelMap map, Qmmp::AudioFormat fo 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_pAudioClient->Initialize(AUDCLNT_SHAREMODE_SHARED,0, 200, 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) + { + 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); @@ -214,6 +289,21 @@ qint64 OutputWASAPI::latency() qint64 OutputWASAPI::writeAudio(unsigned char *data, qint64 len) { + UINT32 frames = 0; + BYTE *pData = 0; + DWORD flags = 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; + + /*unsigned char *ptr = 0, *ptr2 = 0; DWORD size = 0, size2 = 0; diff --git a/src/plugins/Output/wasapi/outputwasapi.h b/src/plugins/Output/wasapi/outputwasapi.h index bfec494d7..5d6df6172 100644 --- a/src/plugins/Output/wasapi/outputwasapi.h +++ b/src/plugins/Output/wasapi/outputwasapi.h @@ -70,6 +70,7 @@ private: //IDirectSoundBuffer *m_primaryBuffer; //IDirectSoundBuffer8 *m_dsBuffer; DWORD m_dsBufferAt; + UINT32 m_bufferSize; typedef struct { -- cgit v1.2.3-13-gbd6f