Browse files

Merge pull request #4313 from FernetMenta/wasapi

WASAPI: increase audio buffer for USB devices, fixes audible distortion
  • Loading branch information...
2 parents a122c65 + ba63a2b commit 2f72ec5b364741e4a891f94382bef10217be1f57 @jmarshallnz jmarshallnz committed Mar 4, 2014
View
9 xbmc/cores/AudioEngine/Engines/ActiveAE/ActiveAE.cpp
@@ -32,6 +32,7 @@ using namespace ActiveAE;
#define MAX_CACHE_LEVEL 0.5 // total cache time of stream in seconds
#define MAX_WATER_LEVEL 0.25 // buffered time after stream stages in seconds
+#define MAX_BUFFER_TIME 0.1 // max time of a buffer in seconds
void CEngineStats::Reset(unsigned int sampleRate)
{
@@ -942,11 +943,11 @@ void CActiveAE::Configure(AEAudioFormat *desiredFmt)
m_sink.m_controlPort.SendOutMessage(CSinkControlProtocol::VOLUME, &m_volume, sizeof(float));
// limit buffer size in case of sink returns large buffer
- unsigned int buffertime = (m_sinkFormat.m_frames*1000) / m_sinkFormat.m_sampleRate;
- if (buffertime > 80)
+ unsigned int buffertime = m_sinkFormat.m_frames / m_sinkFormat.m_sampleRate;
+ if (buffertime > MAX_BUFFER_TIME)
{
- CLog::Log(LOGWARNING, "ActiveAE::%s - sink returned large buffer of %d ms, reducing to 80 ms", __FUNCTION__, buffertime);
- m_sinkFormat.m_frames = 80 * m_sinkFormat.m_sampleRate / 1000;
+ CLog::Log(LOGWARNING, "ActiveAE::%s - sink returned large buffer of %d ms, reducing to %d ms", __FUNCTION__, buffertime, MAX_BUFFER_TIME*1000);
+ m_sinkFormat.m_frames = MAX_BUFFER_TIME * m_sinkFormat.m_sampleRate;
}
}
View
26 xbmc/cores/AudioEngine/Sinks/AESinkWASAPI.cpp
@@ -143,6 +143,7 @@ AEDeviceInfoList DeviceInfoList;
#define ERRTOSTR(err) case err: return #err
DEFINE_PROPERTYKEY(PKEY_Device_FriendlyName, 0xa45c254e, 0xdf1c, 0x4efd, 0x80, 0x20, 0x67, 0xd1, 0x46, 0xa8, 0x50, 0xe0, 14);
+DEFINE_PROPERTYKEY(PKEY_Device_EnumeratorName, 0xa45c254e, 0xdf1c, 0x4efd, 0x80, 0x20, 0x67, 0xd1, 0x46, 0xa8, 0x50, 0xe0, 24);
DWORD ChLayoutToChMask(const enum AEChannel * layout, unsigned int * numberOfChannels = NULL)
{
@@ -1117,6 +1118,11 @@ bool CAESinkWASAPI::InitializeExclusive(AEAudioFormat &format)
REFERENCE_TIME audioSinkBufferDurationMsec, hnsLatency;
audioSinkBufferDurationMsec = (REFERENCE_TIME)500000;
+ if (IsUSBDevice())
+ {
+ CLog::Log(LOGDEBUG, __FUNCTION__": detected USB device, increating buffer size");
+ audioSinkBufferDurationMsec = (REFERENCE_TIME)1000000;
+ }
audioSinkBufferDurationMsec = (REFERENCE_TIME)((audioSinkBufferDurationMsec / format.m_frameSize) * format.m_frameSize); //even number of frames
if (AE_IS_RAW(format.m_dataFormat))
@@ -1276,3 +1282,23 @@ void CAESinkWASAPI::Drain()
}
m_running = false;
}
+
+bool CAESinkWASAPI::IsUSBDevice()
+{
+ IPropertyStore *pProperty = NULL;
+ PROPVARIANT varName;
+ PropVariantInit(&varName);
+ bool ret = false;
+
+ HRESULT hr = m_pDevice->OpenPropertyStore(STGM_READ, &pProperty);
+ if (!SUCCEEDED(hr))
+ return ret;
+ hr = pProperty->GetValue(PKEY_Device_EnumeratorName, &varName);
+
+ std::string str = localWideToUtf(varName.pwszVal);
+ StringUtils::ToUpper(str);
+ ret = (str == "USB");
+ PropVariantClear(&varName);
+ SAFE_RELEASE(pProperty);
+ return ret;
+}
View
1 xbmc/cores/AudioEngine/Sinks/AESinkWASAPI.h
@@ -49,6 +49,7 @@ class CAESinkWASAPI : public IAESink
static DWORD SpeakerMaskFromAEChannels(const CAEChannelInfo &channels);
static void BuildWaveFormatExtensible(AEAudioFormat &format, WAVEFORMATEXTENSIBLE &wfxex);
static void BuildWaveFormatExtensibleIEC61397(AEAudioFormat &format, WAVEFORMATEXTENSIBLE_IEC61937 &wfxex);
+ bool IsUSBDevice();
static const char *WASAPIErrToStr(HRESULT err);

0 comments on commit 2f72ec5

Please sign in to comment.