mirror of
https://github.com/juce-framework/JUCE.git
synced 2026-01-10 23:44:24 +00:00
Updated old code where the 'volatile' keyword was still being used
This commit is contained in:
parent
5faef29f3e
commit
e2dcc32f88
17 changed files with 580 additions and 649 deletions
|
|
@ -192,7 +192,7 @@ JUCE_IUNKNOWNCLASS (IMMDeviceEnumerator, "A95664D2-9614-4F35-A746-DE8DB63617E6")
|
|||
|
||||
JUCE_COMCLASS (MMDeviceEnumerator, "BCDE0395-E52F-467C-8E3D-C4579291692E");
|
||||
|
||||
typedef LONGLONG REFERENCE_TIME;
|
||||
using REFERENCE_TIME = LONGLONG;
|
||||
|
||||
enum AVRT_PRIORITY
|
||||
{
|
||||
|
|
@ -308,7 +308,7 @@ JUCE_IUNKNOWNCLASS (IAudioSessionControl, "F4B1A599-7266-4319-A8CA-E70ACB11E8CD"
|
|||
namespace WasapiClasses
|
||||
{
|
||||
|
||||
String getDeviceID (IMMDevice* const device)
|
||||
String getDeviceID (IMMDevice* device)
|
||||
{
|
||||
String s;
|
||||
WCHAR* deviceId = nullptr;
|
||||
|
|
@ -332,17 +332,17 @@ EDataFlow getDataFlow (const ComSmartPtr<IMMDevice>& device)
|
|||
return flow;
|
||||
}
|
||||
|
||||
int refTimeToSamples (const REFERENCE_TIME& t, const double sampleRate) noexcept
|
||||
int refTimeToSamples (const REFERENCE_TIME& t, double sampleRate) noexcept
|
||||
{
|
||||
return roundToInt (sampleRate * ((double) t) * 0.0000001);
|
||||
}
|
||||
|
||||
REFERENCE_TIME samplesToRefTime (const int numSamples, const double sampleRate) noexcept
|
||||
REFERENCE_TIME samplesToRefTime (int numSamples, double sampleRate) noexcept
|
||||
{
|
||||
return (REFERENCE_TIME) ((numSamples * 10000.0 * 1000.0 / sampleRate) + 0.5);
|
||||
}
|
||||
|
||||
void copyWavFormat (WAVEFORMATEXTENSIBLE& dest, const WAVEFORMATEX* const src) noexcept
|
||||
void copyWavFormat (WAVEFORMATEXTENSIBLE& dest, const WAVEFORMATEX* src) noexcept
|
||||
{
|
||||
memcpy (&dest, src, src->wFormatTag == WAVE_FORMAT_EXTENSIBLE ? sizeof (WAVEFORMATEXTENSIBLE)
|
||||
: sizeof (WAVEFORMATEX));
|
||||
|
|
@ -352,21 +352,8 @@ void copyWavFormat (WAVEFORMATEXTENSIBLE& dest, const WAVEFORMATEX* const src) n
|
|||
class WASAPIDeviceBase
|
||||
{
|
||||
public:
|
||||
WASAPIDeviceBase (const ComSmartPtr<IMMDevice>& d, const bool exclusiveMode)
|
||||
: device (d),
|
||||
sampleRate (0),
|
||||
defaultSampleRate (0),
|
||||
numChannels (0),
|
||||
actualNumChannels (0),
|
||||
minBufferSize (0),
|
||||
defaultBufferSize (0),
|
||||
latencySamples (0),
|
||||
useExclusiveMode (exclusiveMode),
|
||||
actualBufferSize (0),
|
||||
bytesPerSample (0),
|
||||
bytesPerFrame (0),
|
||||
sampleRateHasChanged (false),
|
||||
shouldClose (false)
|
||||
WASAPIDeviceBase (const ComSmartPtr<IMMDevice>& d, bool exclusiveMode)
|
||||
: device (d), useExclusiveMode (exclusiveMode)
|
||||
{
|
||||
clientEvent = CreateEvent (nullptr, false, false, nullptr);
|
||||
|
||||
|
|
@ -443,20 +430,19 @@ public:
|
|||
{
|
||||
sampleRateHasChanged = false;
|
||||
shouldClose = false;
|
||||
|
||||
channelMaps.clear();
|
||||
|
||||
for (int i = 0; i <= channels.getHighestBit(); ++i)
|
||||
if (channels[i])
|
||||
channelMaps.add (i);
|
||||
|
||||
REFERENCE_TIME latency;
|
||||
|
||||
if (check (client->GetStreamLatency (&latency)))
|
||||
latencySamples = refTimeToSamples (latency, sampleRate);
|
||||
|
||||
(void) check (client->GetBufferSize (&actualBufferSize));
|
||||
|
||||
createSessionEventCallback();
|
||||
|
||||
return check (client->SetEventHandle (clientEvent));
|
||||
}
|
||||
|
||||
|
|
@ -486,26 +472,25 @@ public:
|
|||
//==============================================================================
|
||||
ComSmartPtr<IMMDevice> device;
|
||||
ComSmartPtr<IAudioClient> client;
|
||||
double sampleRate, defaultSampleRate;
|
||||
int numChannels, actualNumChannels;
|
||||
int minBufferSize, defaultBufferSize, latencySamples;
|
||||
DWORD mixFormatChannelMask;
|
||||
double sampleRate = 0, defaultSampleRate = 0;
|
||||
int numChannels = 0, actualNumChannels = 0;
|
||||
int minBufferSize = 0, defaultBufferSize = 0, latencySamples = 0;
|
||||
DWORD mixFormatChannelMask = 0;
|
||||
const bool useExclusiveMode;
|
||||
Array<double> rates;
|
||||
HANDLE clientEvent;
|
||||
HANDLE clientEvent = {};
|
||||
BigInteger channels;
|
||||
Array<int> channelMaps;
|
||||
UINT32 actualBufferSize;
|
||||
int bytesPerSample, bytesPerFrame;
|
||||
bool sampleRateHasChanged, shouldClose;
|
||||
UINT32 actualBufferSize = 0;
|
||||
int bytesPerSample = 0, bytesPerFrame = 0;
|
||||
bool sampleRateHasChanged = false, shouldClose = false;
|
||||
|
||||
virtual void updateFormat (bool isFloat) = 0;
|
||||
|
||||
private:
|
||||
//==============================================================================
|
||||
class SessionEventCallback : public ComBaseClassHelper<IAudioSessionEvents>
|
||||
struct SessionEventCallback : public ComBaseClassHelper<IAudioSessionEvents>
|
||||
{
|
||||
public:
|
||||
SessionEventCallback (WASAPIDeviceBase& d) : owner (d) {}
|
||||
|
||||
JUCE_COMRESULT OnDisplayNameChanged (LPCWSTR, LPCGUID) { return S_OK; }
|
||||
|
|
@ -513,6 +498,7 @@ private:
|
|||
JUCE_COMRESULT OnSimpleVolumeChanged (float, BOOL, LPCGUID) { return S_OK; }
|
||||
JUCE_COMRESULT OnChannelVolumeChanged (DWORD, float*, DWORD, LPCGUID) { return S_OK; }
|
||||
JUCE_COMRESULT OnGroupingParamChanged (LPCGUID, LPCGUID) { return S_OK; }
|
||||
|
||||
JUCE_COMRESULT OnStateChanged(AudioSessionState state)
|
||||
{
|
||||
if (state == AudioSessionStateInactive || state == AudioSessionStateExpired)
|
||||
|
|
@ -530,9 +516,7 @@ private:
|
|||
return S_OK;
|
||||
}
|
||||
|
||||
private:
|
||||
WASAPIDeviceBase& owner;
|
||||
|
||||
JUCE_DECLARE_NON_COPYABLE_WITH_LEAK_DETECTOR (SessionEventCallback)
|
||||
};
|
||||
|
||||
|
|
@ -644,7 +628,7 @@ private:
|
|||
return false;
|
||||
}
|
||||
|
||||
bool tryInitialisingWithBufferSize (const int bufferSizeSamples)
|
||||
bool tryInitialisingWithBufferSize (int bufferSizeSamples)
|
||||
{
|
||||
WAVEFORMATEXTENSIBLE format;
|
||||
|
||||
|
|
@ -701,9 +685,8 @@ private:
|
|||
class WASAPIInputDevice : public WASAPIDeviceBase
|
||||
{
|
||||
public:
|
||||
WASAPIInputDevice (const ComSmartPtr<IMMDevice>& d, const bool exclusiveMode)
|
||||
: WASAPIDeviceBase (d, exclusiveMode),
|
||||
reservoir (1, 1)
|
||||
WASAPIInputDevice (const ComSmartPtr<IMMDevice>& d, bool exclusiveMode)
|
||||
: WASAPIDeviceBase (d, exclusiveMode)
|
||||
{
|
||||
}
|
||||
|
||||
|
|
@ -712,7 +695,7 @@ public:
|
|||
close();
|
||||
}
|
||||
|
||||
bool open (const double newSampleRate, const BigInteger& newChannels, int bufferSizeSamples)
|
||||
bool open (double newSampleRate, const BigInteger& newChannels, int bufferSizeSamples)
|
||||
{
|
||||
return openClient (newSampleRate, newChannels, bufferSizeSamples)
|
||||
&& (numChannels == 0 || check (client->GetService (__uuidof (IAudioCaptureClient),
|
||||
|
|
@ -724,13 +707,14 @@ public:
|
|||
closeClient();
|
||||
captureClient = nullptr;
|
||||
reservoir.reset();
|
||||
reservoirReadPos = reservoirWritePos = 0;
|
||||
reservoirReadPos = 0;
|
||||
reservoirWritePos = 0;
|
||||
}
|
||||
|
||||
template<class SourceType>
|
||||
void updateFormatWithType (SourceType*) noexcept
|
||||
{
|
||||
typedef AudioData::Pointer<AudioData::Float32, AudioData::NativeEndian, AudioData::NonInterleaved, AudioData::NonConst> NativeType;
|
||||
using NativeType = AudioData::Pointer<AudioData::Float32, AudioData::NativeEndian, AudioData::NonInterleaved, AudioData::NonConst>;
|
||||
converter.reset (new AudioData::ConverterInstance<AudioData::Pointer<SourceType, AudioData::LittleEndian, AudioData::Interleaved, AudioData::Const>, NativeType> (actualNumChannels, 1));
|
||||
}
|
||||
|
||||
|
|
@ -742,12 +726,13 @@ public:
|
|||
else updateFormatWithType ((AudioData::Int16*) nullptr);
|
||||
}
|
||||
|
||||
bool start (const int userBufferSize)
|
||||
bool start (int userBufferSize)
|
||||
{
|
||||
reservoirSize = actualBufferSize + userBufferSize;
|
||||
reservoirMask = nextPowerOfTwo (reservoirSize) - 1;
|
||||
reservoir.setSize ((reservoirMask + 1) * bytesPerFrame, true);
|
||||
reservoirReadPos = reservoirWritePos = 0;
|
||||
reservoirReadPos = 0;
|
||||
reservoirWritePos = 0;
|
||||
xruns = 0;
|
||||
|
||||
if (! check (client->Start()))
|
||||
|
|
@ -768,7 +753,7 @@ public:
|
|||
captureClient->ReleaseBuffer (numSamplesAvailable);
|
||||
}
|
||||
|
||||
int getNumSamplesInReservoir() const noexcept { return reservoirWritePos - reservoirReadPos; }
|
||||
int getNumSamplesInReservoir() const noexcept { return reservoirWritePos.load() - reservoirReadPos.load(); }
|
||||
|
||||
void handleDeviceBuffer()
|
||||
{
|
||||
|
|
@ -788,9 +773,9 @@ public:
|
|||
|
||||
while (samplesLeft > 0)
|
||||
{
|
||||
const int localWrite = reservoirWritePos & reservoirMask;
|
||||
const int samplesToDo = jmin (samplesLeft, reservoirMask + 1 - localWrite);
|
||||
const int samplesToDoBytes = samplesToDo * bytesPerFrame;
|
||||
auto localWrite = reservoirWritePos.load() & reservoirMask;
|
||||
auto samplesToDo = jmin (samplesLeft, reservoirMask + 1 - localWrite);
|
||||
auto samplesToDoBytes = samplesToDo * bytesPerFrame;
|
||||
|
||||
void* reservoirPtr = addBytesToPointer (reservoir.getData(), localWrite * bytesPerFrame);
|
||||
|
||||
|
|
@ -805,7 +790,7 @@ public:
|
|||
}
|
||||
|
||||
if (getNumSamplesInReservoir() > reservoirSize)
|
||||
reservoirReadPos = reservoirWritePos - reservoirSize;
|
||||
reservoirReadPos = reservoirWritePos.load() - reservoirSize;
|
||||
|
||||
captureClient->ReleaseBuffer (numSamplesAvailable);
|
||||
}
|
||||
|
|
@ -829,13 +814,13 @@ public:
|
|||
|
||||
while (bufferSize > 0)
|
||||
{
|
||||
const int localRead = reservoirReadPos & reservoirMask;
|
||||
auto localRead = reservoirReadPos.load() & reservoirMask;
|
||||
auto samplesToDo = jmin (bufferSize, getNumSamplesInReservoir(), reservoirMask + 1 - localRead);
|
||||
|
||||
const int samplesToDo = jmin (bufferSize, getNumSamplesInReservoir(), reservoirMask + 1 - localRead);
|
||||
if (samplesToDo <= 0)
|
||||
break;
|
||||
|
||||
const int reservoirOffset = localRead * bytesPerFrame;
|
||||
auto reservoirOffset = localRead * bytesPerFrame;
|
||||
|
||||
for (int i = 0; i < numDestBuffers; ++i)
|
||||
converter->convertSamples (destBuffers[i] + offset, 0, addBytesToPointer (reservoir.getData(), reservoirOffset), channelMaps.getUnchecked(i), samplesToDo);
|
||||
|
|
@ -849,7 +834,7 @@ public:
|
|||
ComSmartPtr<IAudioCaptureClient> captureClient;
|
||||
MemoryBlock reservoir;
|
||||
int reservoirSize, reservoirMask, xruns;
|
||||
volatile int reservoirReadPos, reservoirWritePos;
|
||||
std::atomic<int> reservoirReadPos, reservoirWritePos;
|
||||
|
||||
std::unique_ptr<AudioData::Converter> converter;
|
||||
|
||||
|
|
@ -861,7 +846,7 @@ private:
|
|||
class WASAPIOutputDevice : public WASAPIDeviceBase
|
||||
{
|
||||
public:
|
||||
WASAPIOutputDevice (const ComSmartPtr<IMMDevice>& d, const bool exclusiveMode)
|
||||
WASAPIOutputDevice (const ComSmartPtr<IMMDevice>& d, bool exclusiveMode)
|
||||
: WASAPIDeviceBase (d, exclusiveMode)
|
||||
{
|
||||
}
|
||||
|
|
@ -871,7 +856,7 @@ public:
|
|||
close();
|
||||
}
|
||||
|
||||
bool open (const double newSampleRate, const BigInteger& newChannels, int bufferSizeSamples)
|
||||
bool open (double newSampleRate, const BigInteger& newChannels, int bufferSizeSamples)
|
||||
{
|
||||
return openClient (newSampleRate, newChannels, bufferSizeSamples)
|
||||
&& (numChannels == 0 || check (client->GetService (__uuidof (IAudioRenderClient),
|
||||
|
|
@ -887,7 +872,7 @@ public:
|
|||
template<class DestType>
|
||||
void updateFormatWithType (DestType*)
|
||||
{
|
||||
typedef AudioData::Pointer<AudioData::Float32, AudioData::NativeEndian, AudioData::NonInterleaved, AudioData::Const> NativeType;
|
||||
using NativeType = AudioData::Pointer<AudioData::Float32, AudioData::NativeEndian, AudioData::NonInterleaved, AudioData::Const>;
|
||||
converter.reset (new AudioData::ConverterInstance<NativeType, AudioData::Pointer<DestType, AudioData::LittleEndian, AudioData::Interleaved, AudioData::NonConst>> (1, actualNumChannels));
|
||||
}
|
||||
|
||||
|
|
@ -901,7 +886,7 @@ public:
|
|||
|
||||
bool start()
|
||||
{
|
||||
int samplesToDo = getNumSamplesAvailableToCopy();
|
||||
auto samplesToDo = getNumSamplesAvailableToCopy();
|
||||
uint8* outputData;
|
||||
|
||||
if (check (renderClient->GetBuffer (samplesToDo, &outputData)))
|
||||
|
|
@ -918,6 +903,7 @@ public:
|
|||
if (! useExclusiveMode)
|
||||
{
|
||||
UINT32 padding = 0;
|
||||
|
||||
if (check (client->GetCurrentPadding (&padding)))
|
||||
return actualBufferSize - (int) padding;
|
||||
}
|
||||
|
|
@ -925,7 +911,7 @@ public:
|
|||
return actualBufferSize;
|
||||
}
|
||||
|
||||
void copyBuffers (const float** const srcBuffers, const int numSrcBuffers, int bufferSize,
|
||||
void copyBuffers (const float** srcBuffers, int numSrcBuffers, int bufferSize,
|
||||
WASAPIInputDevice* inputDevice, Thread& thread)
|
||||
{
|
||||
if (numChannels <= 0)
|
||||
|
|
@ -985,18 +971,12 @@ public:
|
|||
const String& typeName,
|
||||
const String& outputDeviceID,
|
||||
const String& inputDeviceID,
|
||||
const bool exclusiveMode)
|
||||
bool exclusiveMode)
|
||||
: AudioIODevice (deviceName, typeName),
|
||||
Thread ("JUCE WASAPI"),
|
||||
outputDeviceId (outputDeviceID),
|
||||
inputDeviceId (inputDeviceID),
|
||||
useExclusiveMode (exclusiveMode),
|
||||
isOpen_ (false),
|
||||
isStarted (false),
|
||||
currentBufferSizeSamples (0),
|
||||
currentSampleRate (0),
|
||||
callback (nullptr),
|
||||
deviceBecameInactive (false)
|
||||
useExclusiveMode (exclusiveMode)
|
||||
{
|
||||
}
|
||||
|
||||
|
|
@ -1085,7 +1065,7 @@ public:
|
|||
BigInteger getActiveOutputChannels() const override { return outputDevice != nullptr ? outputDevice->channels : BigInteger(); }
|
||||
BigInteger getActiveInputChannels() const override { return inputDevice != nullptr ? inputDevice->channels : BigInteger(); }
|
||||
String getLastError() override { return lastError; }
|
||||
int getXRunCount () const noexcept override { return inputDevice != nullptr ? inputDevice->xruns : -1; }
|
||||
int getXRunCount() const noexcept override { return inputDevice != nullptr ? inputDevice->xruns : -1; }
|
||||
|
||||
String open (const BigInteger& inputChannels, const BigInteger& outputChannels,
|
||||
double sampleRate, int bufferSizeSamples) override
|
||||
|
|
@ -1209,7 +1189,7 @@ public:
|
|||
{
|
||||
if (isStarted)
|
||||
{
|
||||
AudioIODeviceCallback* const callbackLocal = callback;
|
||||
auto* callbackLocal = callback;
|
||||
|
||||
{
|
||||
const ScopedLock sl (startStopLock);
|
||||
|
|
@ -1230,9 +1210,8 @@ public:
|
|||
if (avSetMmThreadCharacteristics != 0 && avSetMmThreadPriority != 0)
|
||||
{
|
||||
DWORD dummy = 0;
|
||||
HANDLE h = avSetMmThreadCharacteristics (L"Pro Audio", &dummy);
|
||||
|
||||
if (h != 0)
|
||||
if (auto h = avSetMmThreadCharacteristics (L"Pro Audio", &dummy))
|
||||
avSetMmThreadPriority (h, AVRT_PRIORITY_NORMAL);
|
||||
}
|
||||
}
|
||||
|
|
@ -1241,15 +1220,15 @@ public:
|
|||
{
|
||||
setMMThreadPriority();
|
||||
|
||||
const int bufferSize = currentBufferSizeSamples;
|
||||
const int numInputBuffers = getActiveInputChannels().countNumberOfSetBits();
|
||||
const int numOutputBuffers = getActiveOutputChannels().countNumberOfSetBits();
|
||||
auto bufferSize = currentBufferSizeSamples;
|
||||
auto numInputBuffers = getActiveInputChannels().countNumberOfSetBits();
|
||||
auto numOutputBuffers = getActiveOutputChannels().countNumberOfSetBits();
|
||||
bool sampleRateHasChanged = false;
|
||||
|
||||
AudioBuffer<float> ins (jmax (1, numInputBuffers), bufferSize + 32);
|
||||
AudioBuffer<float> outs (jmax (1, numOutputBuffers), bufferSize + 32);
|
||||
float** const inputBuffers = ins.getArrayOfWritePointers();
|
||||
float** const outputBuffers = outs.getArrayOfWritePointers();
|
||||
auto inputBuffers = ins.getArrayOfWritePointers();
|
||||
auto outputBuffers = outs.getArrayOfWritePointers();
|
||||
ins.clear();
|
||||
outs.clear();
|
||||
|
||||
|
|
@ -1329,21 +1308,21 @@ private:
|
|||
std::unique_ptr<WASAPIInputDevice> inputDevice;
|
||||
std::unique_ptr<WASAPIOutputDevice> outputDevice;
|
||||
const bool useExclusiveMode;
|
||||
double defaultSampleRate;
|
||||
int minBufferSize, defaultBufferSize;
|
||||
int latencyIn, latencyOut;
|
||||
double defaultSampleRate = 0;
|
||||
int minBufferSize = 0, defaultBufferSize = 0;
|
||||
int latencyIn = 0, latencyOut = 0;
|
||||
Array<double> sampleRates;
|
||||
Array<int> bufferSizes;
|
||||
|
||||
// Active state...
|
||||
bool isOpen_, isStarted;
|
||||
int currentBufferSizeSamples;
|
||||
double currentSampleRate;
|
||||
bool isOpen_ = false, isStarted = false;
|
||||
int currentBufferSizeSamples = 0;
|
||||
double currentSampleRate = 0;
|
||||
|
||||
AudioIODeviceCallback* callback;
|
||||
AudioIODeviceCallback* callback = {};
|
||||
CriticalSection startStopLock;
|
||||
|
||||
bool sampleRateChangedByOutput, deviceBecameInactive;
|
||||
bool sampleRateChangedByOutput = false, deviceBecameInactive = false;
|
||||
|
||||
BigInteger lastKnownInputChannels, lastKnownOutputChannels;
|
||||
|
||||
|
|
@ -1351,28 +1330,33 @@ private:
|
|||
bool createDevices()
|
||||
{
|
||||
ComSmartPtr<IMMDeviceEnumerator> enumerator;
|
||||
|
||||
if (! check (enumerator.CoCreateInstance (__uuidof (MMDeviceEnumerator))))
|
||||
return false;
|
||||
|
||||
ComSmartPtr<IMMDeviceCollection> deviceCollection;
|
||||
|
||||
if (! check (enumerator->EnumAudioEndpoints (eAll, DEVICE_STATE_ACTIVE, deviceCollection.resetAndGetPointerAddress())))
|
||||
return false;
|
||||
|
||||
UINT32 numDevices = 0;
|
||||
|
||||
if (! check (deviceCollection->GetCount (&numDevices)))
|
||||
return false;
|
||||
|
||||
for (UINT32 i = 0; i < numDevices; ++i)
|
||||
{
|
||||
ComSmartPtr<IMMDevice> device;
|
||||
|
||||
if (! check (deviceCollection->Item (i, device.resetAndGetPointerAddress())))
|
||||
continue;
|
||||
|
||||
const String deviceId (getDeviceID (device));
|
||||
auto deviceId = getDeviceID (device);
|
||||
|
||||
if (deviceId.isEmpty())
|
||||
continue;
|
||||
|
||||
const EDataFlow flow = getDataFlow (device);
|
||||
auto flow = getDataFlow (device);
|
||||
|
||||
if (deviceId == inputDeviceId && flow == eCapture)
|
||||
inputDevice.reset (new WASAPIInputDevice (device, useExclusiveMode));
|
||||
|
|
@ -1381,7 +1365,7 @@ private:
|
|||
}
|
||||
|
||||
return (outputDeviceId.isEmpty() || (outputDevice != nullptr && outputDevice->isOk()))
|
||||
&& (inputDeviceId.isEmpty() || (inputDevice != nullptr && inputDevice->isOk()));
|
||||
&& (inputDeviceId.isEmpty() || (inputDevice != nullptr && inputDevice->isOk()));
|
||||
}
|
||||
|
||||
//==============================================================================
|
||||
|
|
@ -1428,8 +1412,7 @@ public:
|
|||
WASAPIAudioIODeviceType (bool exclusive)
|
||||
: AudioIODeviceType (exclusive ? "Windows Audio (Exclusive Mode)" : "Windows Audio"),
|
||||
DeviceChangeDetector (L"Windows Audio"),
|
||||
exclusiveMode (exclusive),
|
||||
hasScanned (false)
|
||||
exclusiveMode (exclusive)
|
||||
{
|
||||
}
|
||||
|
||||
|
|
@ -1471,7 +1454,7 @@ public:
|
|||
{
|
||||
jassert (hasScanned); // need to call scanForDevices() before doing this
|
||||
|
||||
if (WASAPIAudioIODevice* const d = dynamic_cast<WASAPIAudioIODevice*> (device))
|
||||
if (auto d = dynamic_cast<WASAPIAudioIODevice*> (device))
|
||||
return asInput ? inputDeviceIds.indexOf (d->inputDeviceId)
|
||||
: outputDeviceIds.indexOf (d->outputDeviceId);
|
||||
|
||||
|
|
@ -1487,8 +1470,8 @@ public:
|
|||
|
||||
std::unique_ptr<WASAPIAudioIODevice> device;
|
||||
|
||||
const int outputIndex = outputDeviceNames.indexOf (outputDeviceName);
|
||||
const int inputIndex = inputDeviceNames.indexOf (inputDeviceName);
|
||||
auto outputIndex = outputDeviceNames.indexOf (outputDeviceName);
|
||||
auto inputIndex = inputDeviceNames.indexOf (inputDeviceName);
|
||||
|
||||
if (outputIndex >= 0 || inputIndex >= 0)
|
||||
{
|
||||
|
|
@ -1511,7 +1494,8 @@ public:
|
|||
StringArray inputDeviceNames, inputDeviceIds;
|
||||
|
||||
private:
|
||||
bool exclusiveMode, hasScanned;
|
||||
const bool exclusiveMode;
|
||||
bool hasScanned = false;
|
||||
ComSmartPtr<IMMDeviceEnumerator> enumerator;
|
||||
|
||||
//==============================================================================
|
||||
|
|
@ -1538,7 +1522,7 @@ private:
|
|||
ComSmartPtr<ChangeNotificationClient> notifyClient;
|
||||
|
||||
//==============================================================================
|
||||
static String getDefaultEndpoint (IMMDeviceEnumerator* const enumerator, const bool forCapture)
|
||||
static String getDefaultEndpoint (IMMDeviceEnumerator* enumerator, bool forCapture)
|
||||
{
|
||||
String s;
|
||||
IMMDevice* dev = nullptr;
|
||||
|
|
@ -1575,8 +1559,8 @@ private:
|
|||
enumerator->RegisterEndpointNotificationCallback (notifyClient);
|
||||
}
|
||||
|
||||
const String defaultRenderer (getDefaultEndpoint (enumerator, false));
|
||||
const String defaultCapture (getDefaultEndpoint (enumerator, true));
|
||||
auto defaultRenderer = getDefaultEndpoint (enumerator, false);
|
||||
auto defaultCapture = getDefaultEndpoint (enumerator, true);
|
||||
|
||||
ComSmartPtr<IMMDeviceCollection> deviceCollection;
|
||||
UINT32 numDevices = 0;
|
||||
|
|
@ -1588,18 +1572,21 @@ private:
|
|||
for (UINT32 i = 0; i < numDevices; ++i)
|
||||
{
|
||||
ComSmartPtr<IMMDevice> device;
|
||||
|
||||
if (! check (deviceCollection->Item (i, device.resetAndGetPointerAddress())))
|
||||
continue;
|
||||
|
||||
DWORD state = 0;
|
||||
|
||||
if (! (check (device->GetState (&state)) && state == DEVICE_STATE_ACTIVE))
|
||||
continue;
|
||||
|
||||
const String deviceId (getDeviceID (device));
|
||||
auto deviceId = getDeviceID (device);
|
||||
String name;
|
||||
|
||||
{
|
||||
ComSmartPtr<IPropertyStore> properties;
|
||||
|
||||
if (! check (device->OpenPropertyStore (STGM_READ, properties.resetAndGetPointerAddress())))
|
||||
continue;
|
||||
|
||||
|
|
@ -1615,7 +1602,7 @@ private:
|
|||
PropVariantClear (&value);
|
||||
}
|
||||
|
||||
const EDataFlow flow = getDataFlow (device);
|
||||
auto flow = getDataFlow (device);
|
||||
|
||||
if (flow == eRender)
|
||||
{
|
||||
|
|
@ -1666,9 +1653,11 @@ struct MMDeviceMasterVolume
|
|||
MMDeviceMasterVolume()
|
||||
{
|
||||
ComSmartPtr<IMMDeviceEnumerator> enumerator;
|
||||
|
||||
if (check (enumerator.CoCreateInstance (__uuidof (MMDeviceEnumerator))))
|
||||
{
|
||||
ComSmartPtr<IMMDevice> device;
|
||||
|
||||
if (check (enumerator->GetDefaultAudioEndpoint (eRender, eConsole, device.resetAndGetPointerAddress())))
|
||||
check (device->Activate (__uuidof (IAudioEndpointVolume), CLSCTX_INPROC_SERVER, nullptr,
|
||||
(void**) endpointVolume.resetAndGetPointerAddress()));
|
||||
|
|
@ -1678,6 +1667,7 @@ struct MMDeviceMasterVolume
|
|||
float getGain() const
|
||||
{
|
||||
float vol = 0.0f;
|
||||
|
||||
if (endpointVolume != nullptr)
|
||||
check (endpointVolume->GetMasterVolumeLevelScalar (&vol));
|
||||
|
||||
|
|
|
|||
Loading…
Add table
Add a link
Reference in a new issue