1
0
Fork 0
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:
jules 2018-04-30 15:39:39 +01:00
parent 5faef29f3e
commit e2dcc32f88
17 changed files with 580 additions and 649 deletions

View file

@ -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));