Browse Source

Updated old code where the 'volatile' keyword was still being used

tags/2021-05-28
jules 7 years ago
parent
commit
e2dcc32f88
17 changed files with 581 additions and 650 deletions
  1. +6
    -6
      examples/Audio/AudioRecordingDemo.h
  2. +34
    -33
      modules/juce_audio_basics/sources/juce_BufferingAudioSource.cpp
  3. +3
    -3
      modules/juce_audio_basics/sources/juce_BufferingAudioSource.h
  4. +1
    -1
      modules/juce_audio_basics/sources/juce_ReverbAudioSource.h
  5. +43
    -46
      modules/juce_audio_devices/native/juce_mac_CoreMidi.cpp
  6. +123
    -160
      modules/juce_audio_devices/native/juce_win32_ASIO.cpp
  7. +87
    -97
      modules/juce_audio_devices/native/juce_win32_WASAPI.cpp
  8. +3
    -3
      modules/juce_audio_devices/sources/juce_AudioTransportSource.h
  9. +2
    -2
      modules/juce_audio_formats/format/juce_AudioFormatReaderSource.h
  10. +8
    -12
      modules/juce_audio_formats/format/juce_AudioFormatWriter.cpp
  11. +167
    -167
      modules/juce_core/native/java/AndroidCamera.java
  12. +61
    -65
      modules/juce_core/native/juce_posix_SharedCode.h
  13. +30
    -34
      modules/juce_core/network/juce_Socket.cpp
  14. +6
    -10
      modules/juce_core/network/juce_Socket.h
  15. +3
    -4
      modules/juce_core/threads/juce_ThreadPool.cpp
  16. +2
    -5
      modules/juce_core/threads/juce_ThreadPool.h
  17. +2
    -2
      modules/juce_events/messages/juce_MessageManager.cpp

+ 6
- 6
examples/Audio/AudioRecordingDemo.h View File

@@ -120,7 +120,7 @@ public:
bool isRecording() const
{
return activeWriter != nullptr;
return activeWriter.load() != nullptr;
}
//==============================================================================
@@ -140,9 +140,9 @@ public:
{
const ScopedLock sl (writerLock);
if (activeWriter != nullptr && numInputChannels >= thumbnail.getNumChannels())
if (activeWriter.load() != nullptr && numInputChannels >= thumbnail.getNumChannels())
{
activeWriter->write (inputChannelData, numSamples);
activeWriter.load()->write (inputChannelData, numSamples);
// Create an AudioBuffer to wrap our incoming data, note that this does no allocations or copies, it simply references our input data
AudioBuffer<float> buffer (const_cast<float**> (inputChannelData), thumbnail.getNumChannels(), numSamples);
@@ -158,13 +158,13 @@ public:
private:
AudioThumbnail& thumbnail;
TimeSliceThread backgroundThread { "Audio Recorder Thread" }; // the thread that will write our audio data to disk
TimeSliceThread backgroundThread { "Audio Recorder Thread" }; // the thread that will write our audio data to disk
std::unique_ptr<AudioFormatWriter::ThreadedWriter> threadedWriter; // the FIFO used to buffer the incoming data
double sampleRate = 0.0;
double sampleRate = 0.0;
int64 nextSampleNum = 0;
CriticalSection writerLock;
AudioFormatWriter::ThreadedWriter* volatile activeWriter = nullptr;
std::atomic<AudioFormatWriter::ThreadedWriter*> activeWriter { nullptr };
};
//==============================================================================


+ 34
- 33
modules/juce_audio_basics/sources/juce_BufferingAudioSource.cpp View File

@@ -25,20 +25,14 @@ namespace juce
BufferingAudioSource::BufferingAudioSource (PositionableAudioSource* s,
TimeSliceThread& thread,
const bool deleteSourceWhenDeleted,
const int bufferSizeSamples,
const int numChannels,
bool deleteSourceWhenDeleted,
int bufferSizeSamples,
int numChannels,
bool prefillBufferOnPrepareToPlay)
: source (s, deleteSourceWhenDeleted),
backgroundThread (thread),
numberOfSamplesToBuffer (jmax (1024, bufferSizeSamples)),
numberOfChannels (numChannels),
bufferValidStart (0),
bufferValidEnd (0),
nextPlayPos (0),
sampleRate (0),
wasSourceLooping (false),
isPrepared (false),
prefillBuffer (prefillBufferOnPrepareToPlay)
{
jassert (source != nullptr);
@@ -55,7 +49,7 @@ BufferingAudioSource::~BufferingAudioSource()
//==============================================================================
void BufferingAudioSource::prepareToPlay (int samplesPerBlockExpected, double newSampleRate)
{
const int bufferSizeNeeded = jmax (samplesPerBlockExpected * 2, numberOfSamplesToBuffer);
auto bufferSizeNeeded = jmax (samplesPerBlockExpected * 2, numberOfSamplesToBuffer);
if (newSampleRate != sampleRate
|| bufferSizeNeeded != buffer.getNumSamples()
@@ -104,8 +98,12 @@ void BufferingAudioSource::getNextAudioBlock (const AudioSourceChannelInfo& info
{
const ScopedLock sl (bufferStartPosLock);
const int validStart = (int) (jlimit (bufferValidStart, bufferValidEnd, nextPlayPos) - nextPlayPos);
const int validEnd = (int) (jlimit (bufferValidStart, bufferValidEnd, nextPlayPos + info.numSamples) - nextPlayPos);
auto start = bufferValidStart.load();
auto end = bufferValidEnd.load();
auto pos = nextPlayPos.load();
auto validStart = (int) (jlimit (start, end, pos) - pos);
auto validEnd = (int) (jlimit (start, end, pos + info.numSamples) - pos);
if (validStart == validEnd)
{
@@ -126,8 +124,8 @@ void BufferingAudioSource::getNextAudioBlock (const AudioSourceChannelInfo& info
for (int chan = jmin (numberOfChannels, info.buffer->getNumChannels()); --chan >= 0;)
{
jassert (buffer.getNumSamples() > 0);
const int startBufferIndex = (int) ((validStart + nextPlayPos) % buffer.getNumSamples());
const int endBufferIndex = (int) ((validEnd + nextPlayPos) % buffer.getNumSamples());
auto startBufferIndex = (int) ((validStart + nextPlayPos) % buffer.getNumSamples());
auto endBufferIndex = (int) ((validEnd + nextPlayPos) % buffer.getNumSamples());
if (startBufferIndex < endBufferIndex)
{
@@ -138,7 +136,7 @@ void BufferingAudioSource::getNextAudioBlock (const AudioSourceChannelInfo& info
}
else
{
const int initialSize = buffer.getNumSamples() - startBufferIndex;
auto initialSize = buffer.getNumSamples() - startBufferIndex;
info.buffer->copyFrom (chan, info.startSample + validStart,
buffer,
@@ -157,7 +155,7 @@ void BufferingAudioSource::getNextAudioBlock (const AudioSourceChannelInfo& info
}
}
bool BufferingAudioSource::waitForNextAudioBlockReady (const AudioSourceChannelInfo& info, const uint32 timeout)
bool BufferingAudioSource::waitForNextAudioBlockReady (const AudioSourceChannelInfo& info, uint32 timeout)
{
if (!source || source->getTotalLength() <= 0)
return false;
@@ -168,26 +166,28 @@ bool BufferingAudioSource::waitForNextAudioBlockReady (const AudioSourceChannelI
if (! isLooping() && nextPlayPos > getTotalLength())
return true;
uint32 now = Time::getMillisecondCounter();
const uint32 startTime = now;
auto now = Time::getMillisecondCounter();
auto startTime = now;
uint32 elapsed = (now >= startTime ? now - startTime
: (std::numeric_limits<uint32>::max() - startTime) + now);
auto elapsed = (now >= startTime ? now - startTime
: (std::numeric_limits<uint32>::max() - startTime) + now);
while (elapsed <= timeout)
{
{
const ScopedLock sl (bufferStartPosLock);
const int validStart = static_cast<int> (jlimit (bufferValidStart, bufferValidEnd, nextPlayPos) - nextPlayPos);
const int validEnd = static_cast<int> (jlimit (bufferValidStart, bufferValidEnd, nextPlayPos + info.numSamples) - nextPlayPos);
auto start = bufferValidStart.load();
auto end = bufferValidEnd.load();
auto pos = nextPlayPos.load();
auto validStart = static_cast<int> (jlimit (start, end, pos) - pos);
auto validEnd = static_cast<int> (jlimit (start, end, pos + info.numSamples) - pos);
if (validStart <= 0 && validStart < validEnd && validEnd >= info.numSamples)
return true;
}
if (elapsed < timeout && (! bufferReadyEvent.wait (static_cast<int> (timeout - elapsed))))
return false;
@@ -202,9 +202,11 @@ bool BufferingAudioSource::waitForNextAudioBlockReady (const AudioSourceChannelI
int64 BufferingAudioSource::getNextReadPosition() const
{
jassert (source->getTotalLength() > 0);
auto pos = nextPlayPos.load();
return (source->isLooping() && nextPlayPos > 0)
? nextPlayPos % source->getTotalLength()
: nextPlayPos;
? pos % source->getTotalLength()
: pos;
}
void BufferingAudioSource::setNextReadPosition (int64 newPosition)
@@ -229,7 +231,7 @@ bool BufferingAudioSource::readNextBufferChunk()
bufferValidEnd = 0;
}
newBVS = jmax ((int64) 0, nextPlayPos);
newBVS = jmax ((int64) 0, nextPlayPos.load());
newBVE = newBVS + buffer.getNumSamples() - 4;
sectionToReadStart = 0;
sectionToReadEnd = 0;
@@ -255,7 +257,7 @@ bool BufferingAudioSource::readNextBufferChunk()
sectionToReadEnd = newBVE;
bufferValidStart = newBVS;
bufferValidEnd = jmin (bufferValidEnd, newBVE);
bufferValidEnd = jmin (bufferValidEnd.load(), newBVE);
}
}
@@ -263,8 +265,8 @@ bool BufferingAudioSource::readNextBufferChunk()
return false;
jassert (buffer.getNumSamples() > 0);
const int bufferIndexStart = (int) (sectionToReadStart % buffer.getNumSamples());
const int bufferIndexEnd = (int) (sectionToReadEnd % buffer.getNumSamples());
auto bufferIndexStart = (int) (sectionToReadStart % buffer.getNumSamples());
auto bufferIndexEnd = (int) (sectionToReadEnd % buffer.getNumSamples());
if (bufferIndexStart < bufferIndexEnd)
{
@@ -274,7 +276,7 @@ bool BufferingAudioSource::readNextBufferChunk()
}
else
{
const int initialSize = buffer.getNumSamples() - bufferIndexStart;
auto initialSize = buffer.getNumSamples() - bufferIndexStart;
readBufferSection (sectionToReadStart,
initialSize,
@@ -293,11 +295,10 @@ bool BufferingAudioSource::readNextBufferChunk()
}
bufferReadyEvent.signal();
return true;
}
void BufferingAudioSource::readBufferSection (const int64 start, const int length, const int bufferOffset)
void BufferingAudioSource::readBufferSection (int64 start, int length, int bufferOffset)
{
if (source->getNextReadPosition() != start)
source->setNextReadPosition (start);


+ 3
- 3
modules/juce_audio_basics/sources/juce_BufferingAudioSource.h View File

@@ -105,9 +105,9 @@ private:
AudioBuffer<float> buffer;
CriticalSection bufferStartPosLock;
WaitableEvent bufferReadyEvent;
int64 volatile bufferValidStart, bufferValidEnd, nextPlayPos;
double volatile sampleRate;
bool wasSourceLooping, isPrepared, prefillBuffer;
std::atomic<int64> bufferValidStart { 0 }, bufferValidEnd { 0 }, nextPlayPos { 0 };
double sampleRate = 0;
bool wasSourceLooping = false, isPrepared = false, prefillBuffer;
bool readNextBufferChunk();
void readBufferSection (int64 start, int length, int bufferOffset);


+ 1
- 1
modules/juce_audio_basics/sources/juce_ReverbAudioSource.h View File

@@ -66,7 +66,7 @@ private:
CriticalSection lock;
OptionalScopedPointer<AudioSource> input;
Reverb reverb;
volatile bool bypass;
std::atomic<bool> bypass;
JUCE_DECLARE_NON_COPYABLE_WITH_LEAK_DETECTOR (ReverbAudioSource)
};


+ 43
- 46
modules/juce_audio_devices/native/juce_mac_CoreMidi.cpp View File

@@ -29,7 +29,7 @@ namespace juce
namespace CoreMidiHelpers
{
static bool checkError (const OSStatus err, const int lineNum)
static bool checkError (OSStatus err, int lineNum)
{
if (err == noErr)
return true;
@@ -48,10 +48,10 @@ namespace CoreMidiHelpers
//==============================================================================
struct ScopedCFString
{
ScopedCFString() noexcept : cfString (nullptr) {}
ScopedCFString() noexcept {}
~ScopedCFString() noexcept { if (cfString != nullptr) CFRelease (cfString); }
CFStringRef cfString;
CFStringRef cfString = {};
};
static String getMidiObjectName (MIDIObjectRef entity)
@@ -87,7 +87,7 @@ namespace CoreMidiHelpers
static String getEndpointName (MIDIEndpointRef endpoint, bool isExternal)
{
String result (getMidiObjectName (endpoint));
auto result = getMidiObjectName (endpoint);
MIDIEntityRef entity = 0; // NB: don't attempt to use nullptr for refs - it fails in some types of build.
MIDIEndpointGetEntity (endpoint, &entity);
@@ -104,7 +104,7 @@ namespace CoreMidiHelpers
if (device != 0)
{
const String deviceName (getMidiObjectName (device));
auto deviceName = getMidiObjectName (device);
if (deviceName.isNotEmpty())
{
@@ -141,14 +141,14 @@ namespace CoreMidiHelpers
if (numConnections > 0)
{
const SInt32* pid = reinterpret_cast<const SInt32*> (CFDataGetBytePtr (connections));
auto pid = reinterpret_cast<const SInt32*> (CFDataGetBytePtr (connections));
for (int i = 0; i < numConnections; ++i, ++pid)
{
MIDIUniqueID uid = (MIDIUniqueID) ByteOrder::swapIfLittleEndian ((uint32) *pid);
auto uid = (MIDIUniqueID) ByteOrder::swapIfLittleEndian ((uint32) *pid);
MIDIObjectRef connObject;
MIDIObjectType connObjectType;
OSStatus err = MIDIObjectFindByUniqueID (uid, &connObject, &connObjectType);
auto err = MIDIObjectFindByUniqueID (uid, &connObject, &connObjectType);
if (err == noErr)
{
@@ -192,11 +192,12 @@ namespace CoreMidiHelpers
#if defined (JucePlugin_CFBundleIdentifier)
portUniqueId = JUCE_STRINGIFY (JucePlugin_CFBundleIdentifier);
#else
File appBundle (File::getSpecialLocation (File::currentApplicationFile));
CFURLRef bundleURL = CFURLCreateWithFileSystemPath (kCFAllocatorDefault, appBundle.getFullPathName().toCFString(), kCFURLPOSIXPathStyle, true);
if (bundleURL != nullptr)
auto appBundle = File::getSpecialLocation (File::currentApplicationFile);
if (auto bundleURL = CFURLCreateWithFileSystemPath (kCFAllocatorDefault, appBundle.getFullPathName().toCFString(),
kCFURLPOSIXPathStyle, true))
{
CFBundleRef bundleRef = CFBundleCreate (kCFAllocatorDefault, bundleURL);
auto bundleRef = CFBundleCreate (kCFAllocatorDefault, bundleURL);
CFRelease (bundleURL);
if (bundleRef != nullptr)
@@ -211,31 +212,30 @@ namespace CoreMidiHelpers
if (portUniqueId.isNotEmpty())
{
portUniqueId += (String ("." + portName + String (isInput ? ".input" : ".output")));
portUniqueId += "." + portName + (isInput ? ".input" : ".output");
CHECK_ERROR (MIDIObjectSetStringProperty (device, kMIDIPropertyUniqueID, portUniqueId.toCFString()));
}
}
static StringArray findDevices (const bool forInput)
static StringArray findDevices (bool forInput)
{
// It seems that OSX can be a bit picky about the thread that's first used to
// search for devices. It's safest to use the message thread for calling this.
jassert (MessageManager::getInstance()->isThisTheMessageThread());
StringArray s;
enableSimulatorMidiSession();
const ItemCount num = forInput ? MIDIGetNumberOfSources()
: MIDIGetNumberOfDestinations();
StringArray s;
auto num = forInput ? MIDIGetNumberOfSources()
: MIDIGetNumberOfDestinations();
for (ItemCount i = 0; i < num; ++i)
{
MIDIEndpointRef dest = forInput ? MIDIGetSource (i)
: MIDIGetDestination (i);
String name;
if (dest != 0)
if (auto dest = forInput ? MIDIGetSource (i)
: MIDIGetDestination (i))
name = getConnectedEndpointName (dest);
if (name.isEmpty())
@@ -298,7 +298,7 @@ namespace CoreMidiHelpers
MIDIEndpointDispose (endPoint);
}
void send (const MIDIPacketList* const packets) noexcept
void send (const MIDIPacketList* packets) noexcept
{
if (port != 0)
MIDISend (port, endPoint, packets);
@@ -311,16 +311,13 @@ namespace CoreMidiHelpers
};
//==============================================================================
class MidiPortAndCallback;
struct MidiPortAndCallback;
CriticalSection callbackLock;
Array<MidiPortAndCallback*> activeCallbacks;
class MidiPortAndCallback
struct MidiPortAndCallback
{
public:
MidiPortAndCallback (MidiInputCallback& cb) : callback (cb)
{
}
MidiPortAndCallback (MidiInputCallback& cb) : callback (cb) {}
~MidiPortAndCallback()
{
@@ -335,7 +332,7 @@ namespace CoreMidiHelpers
CHECK_ERROR (MIDIPortDisconnectSource (portAndEndpoint->port, portAndEndpoint->endPoint));
}
void handlePackets (const MIDIPacketList* const pktlist)
void handlePackets (const MIDIPacketList* pktlist)
{
auto time = Time::getMillisecondCounterHiRes() * 0.001;
@@ -357,7 +354,7 @@ namespace CoreMidiHelpers
MidiInput* input = nullptr;
std::unique_ptr<MidiPortAndEndpoint> portAndEndpoint;
volatile bool active = false;
std::atomic<bool> active { false };
private:
MidiInputCallback& callback;
@@ -380,15 +377,15 @@ MidiOutput* MidiOutput::openDevice (int index)
if (isPositiveAndBelow (index, MIDIGetNumberOfDestinations()))
{
MIDIEndpointRef endPoint = MIDIGetDestination ((ItemCount) index);
auto endPoint = MIDIGetDestination ((ItemCount) index);
CoreMidiHelpers::ScopedCFString pname;
if (CHECK_ERROR (MIDIObjectGetStringProperty (endPoint, kMIDIPropertyName, &pname.cfString)))
{
MIDIClientRef client = CoreMidiHelpers::getGlobalMidiClient();
auto client = CoreMidiHelpers::getGlobalMidiClient();
MIDIPortRef port;
String deviceName = CoreMidiHelpers::getConnectedEndpointName (endPoint);
auto deviceName = CoreMidiHelpers::getConnectedEndpointName (endPoint);
if (client != 0 && CHECK_ERROR (MIDIOutputPortCreate (client, pname.cfString, &port)))
{
@@ -413,7 +410,7 @@ MidiOutput* MidiOutput::createNewDevice (const String& deviceName)
{
CoreMidiHelpers::setUniqueIdForMidiPort (endPoint, deviceName, false);
MidiOutput* mo = new MidiOutput (deviceName);
auto mo = new MidiOutput (deviceName);
mo->internal = new CoreMidiHelpers::MidiPortAndEndpoint (0, endPoint);
return mo;
}
@@ -438,8 +435,8 @@ void MidiOutput::sendMessageNow (const MidiMessage& message)
HeapBlock<MIDIPacketList> allocatedPackets;
MIDIPacketList stackPacket;
MIDIPacketList* packetToSend = &stackPacket;
const size_t dataSize = (size_t) message.getRawDataSize();
auto* packetToSend = &stackPacket;
auto dataSize = (size_t) message.getRawDataSize();
if (message.isSysEx())
{
@@ -450,7 +447,7 @@ void MidiOutput::sendMessageNow (const MidiMessage& message)
packetToSend = allocatedPackets;
packetToSend->numPackets = (UInt32) numPackets;
MIDIPacket* p = packetToSend->packet;
auto* p = packetToSend->packet;
for (int i = 0; i < numPackets; ++i)
{
@@ -464,7 +461,7 @@ void MidiOutput::sendMessageNow (const MidiMessage& message)
}
else if (dataSize < 65536) // max packet size
{
const size_t stackCapacity = sizeof (stackPacket.packet->data);
auto stackCapacity = sizeof (stackPacket.packet->data);
if (dataSize > stackCapacity)
{
@@ -473,7 +470,7 @@ void MidiOutput::sendMessageNow (const MidiMessage& message)
}
packetToSend->numPackets = 1;
MIDIPacket& p = *(packetToSend->packet);
auto& p = *(packetToSend->packet);
p.timeStamp = timeStamp;
p.length = (UInt16) dataSize;
memcpy (p.data, message.getRawData(), dataSize);
@@ -500,13 +497,13 @@ MidiInput* MidiInput::openDevice (int index, MidiInputCallback* callback)
if (isPositiveAndBelow (index, MIDIGetNumberOfSources()))
{
if (MIDIEndpointRef endPoint = MIDIGetSource ((ItemCount) index))
if (auto endPoint = MIDIGetSource ((ItemCount) index))
{
ScopedCFString name;
if (CHECK_ERROR (MIDIObjectGetStringProperty (endPoint, kMIDIPropertyName, &name.cfString)))
{
if (MIDIClientRef client = getGlobalMidiClient())
if (auto client = getGlobalMidiClient())
{
MIDIPortRef port;
std::unique_ptr<MidiPortAndCallback> mpc (new MidiPortAndCallback (*callback));
@@ -540,11 +537,9 @@ MidiInput* MidiInput::openDevice (int index, MidiInputCallback* callback)
MidiInput* MidiInput::createNewDevice (const String& deviceName, MidiInputCallback* callback)
{
jassert (callback != nullptr);
using namespace CoreMidiHelpers;
MidiInput* mi = nullptr;
if (MIDIClientRef client = getGlobalMidiClient())
if (auto client = getGlobalMidiClient())
{
std::unique_ptr<MidiPortAndCallback> mpc (new MidiPortAndCallback (*callback));
mpc->active = false;
@@ -555,20 +550,22 @@ MidiInput* MidiInput::createNewDevice (const String& deviceName, MidiInputCallba
if (CHECK_ERROR (MIDIDestinationCreate (client, name.cfString, midiInputProc, mpc.get(), &endPoint)))
{
CoreMidiHelpers::setUniqueIdForMidiPort (endPoint, deviceName, true);
setUniqueIdForMidiPort (endPoint, deviceName, true);
mpc->portAndEndpoint.reset (new MidiPortAndEndpoint (0, endPoint));
mi = new MidiInput (deviceName);
auto mi = new MidiInput (deviceName);
mpc->input = mi;
mi->internal = mpc.get();
const ScopedLock sl (callbackLock);
activeCallbacks.add (mpc.release());
return mi;
}
}
return mi;
return nullptr;
}
MidiInput::MidiInput (const String& nm) : name (nm)


+ 123
- 160
modules/juce_audio_devices/native/juce_win32_ASIO.cpp View File

@@ -77,11 +77,7 @@ struct ASIOSampleFormat
{
ASIOSampleFormat() noexcept {}
ASIOSampleFormat (const long type) noexcept
: bitDepth (24),
littleEndian (true),
formatIsFloat (false),
byteStride (4)
ASIOSampleFormat (long type) noexcept
{
switch (type)
{
@@ -114,7 +110,7 @@ struct ASIOSampleFormat
}
}
void convertToFloat (const void* const src, float* const dst, const int samps) const noexcept
void convertToFloat (const void* src, float* dst, int samps) const noexcept
{
if (formatIsFloat)
{
@@ -132,7 +128,7 @@ struct ASIOSampleFormat
}
}
void convertFromFloat (const float* const src, void* const dst, const int samps) const noexcept
void convertFromFloat (const float* src, void* dst, int samps) const noexcept
{
if (formatIsFloat)
{
@@ -150,18 +146,18 @@ struct ASIOSampleFormat
}
}
void clear (void* dst, const int numSamps) noexcept
void clear (void* dst, int numSamps) noexcept
{
if (dst != nullptr)
zeromem (dst, numSamps * byteStride);
}
int bitDepth, byteStride;
bool formatIsFloat, littleEndian;
int bitDepth = 24, byteStride = 4;
bool formatIsFloat = false, littleEndian = true;
private:
static void convertInt16ToFloat (const char* src, float* dest, const int srcStrideBytes,
int numSamples, const bool littleEndian) noexcept
static void convertInt16ToFloat (const char* src, float* dest, int srcStrideBytes,
int numSamples, bool littleEndian) noexcept
{
const double g = 1.0 / 32768.0;
@@ -183,8 +179,8 @@ private:
}
}
static void convertFloatToInt16 (const float* src, char* dest, const int dstStrideBytes,
int numSamples, const bool littleEndian) noexcept
static void convertFloatToInt16 (const float* src, char* dest, int dstStrideBytes,
int numSamples, bool littleEndian) noexcept
{
const double maxVal = (double) 0x7fff;
@@ -206,8 +202,8 @@ private:
}
}
static void convertInt24ToFloat (const char* src, float* dest, const int srcStrideBytes,
int numSamples, const bool littleEndian) noexcept
static void convertInt24ToFloat (const char* src, float* dest, int srcStrideBytes,
int numSamples, bool littleEndian) noexcept
{
const double g = 1.0 / 0x7fffff;
@@ -229,8 +225,8 @@ private:
}
}
static void convertFloatToInt24 (const float* src, char* dest, const int dstStrideBytes,
int numSamples, const bool littleEndian) noexcept
static void convertFloatToInt24 (const float* src, char* dest, int dstStrideBytes,
int numSamples, bool littleEndian) noexcept
{
const double maxVal = (double) 0x7fffff;
@@ -252,8 +248,8 @@ private:
}
}
static void convertInt32ToFloat (const char* src, float* dest, const int srcStrideBytes,
int numSamples, const bool littleEndian) noexcept
static void convertInt32ToFloat (const char* src, float* dest, int srcStrideBytes,
int numSamples, bool littleEndian) noexcept
{
const double g = 1.0 / 0x7fffffff;
@@ -275,8 +271,8 @@ private:
}
}
static void convertFloatToInt32 (const float* src, char* dest, const int dstStrideBytes,
int numSamples, const bool littleEndian) noexcept
static void convertFloatToInt32 (const float* src, char* dest, int dstStrideBytes,
int numSamples, bool littleEndian) noexcept
{
const double maxVal = (double) 0x7fffffff;
@@ -300,8 +296,9 @@ private:
};
//==============================================================================
constexpr int maxNumASIODevices = 16;
class ASIOAudioIODevice;
static ASIOAudioIODevice* volatile currentASIODev[16] = { 0 };
static ASIOAudioIODevice* currentASIODev[maxNumASIODevices] = {};
extern HWND juce_messageWindowHandle;
@@ -314,33 +311,10 @@ class ASIOAudioIODevice : public AudioIODevice,
{
public:
ASIOAudioIODevice (ASIOAudioIODeviceType* ownerType, const String& devName,
const CLSID clsID, const int slotNumber)
CLSID clsID, int slotNumber)
: AudioIODevice (devName, "ASIO"),
owner (ownerType),
asioObject (nullptr),
classId (clsID),
inputLatency (0),
outputLatency (0),
minBufferSize (0), maxBufferSize (0),
preferredBufferSize (0),
bufferGranularity (0),
numClockSources (0),
currentBlockSizeSamples (0),
currentBitDepth (16),
currentSampleRate (0),
currentCallback (nullptr),
bufferIndex (0),
numActiveInputChans (0),
numActiveOutputChans (0),
deviceIsOpen (false),
isStarted (false),
buffersCreated (false),
calledback (false),
littleEndian (false),
postOutput (true),
needToReset (false),
insideControlPanelModalLoop (false),
shouldUsePreferredSize (false)
classId (clsID)
{
::CoInitialize (nullptr);
@@ -348,15 +322,15 @@ public:
inBuffers.calloc (4);
outBuffers.calloc (4);
jassert (currentASIODev [slotNumber] == nullptr);
currentASIODev [slotNumber] = this;
jassert (currentASIODev[slotNumber] == nullptr);
currentASIODev[slotNumber] = this;
openDevice();
}
~ASIOAudioIODevice()
{
for (int i = 0; i < numElementsInArray (currentASIODev); ++i)
for (int i = 0; i < maxNumASIODevices; ++i)
if (currentASIODev[i] == this)
currentASIODev[i] = nullptr;
@@ -381,7 +355,7 @@ public:
if (newRates.isEmpty())
{
double cr = getSampleRate();
auto cr = getSampleRate();
JUCE_ASIO_LOG ("No sample rates supported - current rate: " + String ((int) cr));
if (cr > 0)
@@ -394,8 +368,9 @@ public:
#if JUCE_ASIO_DEBUGGING
StringArray s;
for (int i = 0; i < sampleRates.size(); ++i)
s.add (String (sampleRates.getUnchecked(i)));
for (auto r : sampleRates)
s.add (String (r));
JUCE_ASIO_LOG ("Rates: " + s.joinIntoString (" "));
#endif
@@ -425,21 +400,20 @@ public:
if (asioObject == nullptr)
{
const String openingError (openDevice());
auto openingError = openDevice();
if (asioObject == nullptr)
return openingError;
}
isStarted = false;
bufferIndex = -1;
long err = asioObject->getChannels (&totalNumInputChans, &totalNumOutputChans);
auto err = asioObject->getChannels (&totalNumInputChans, &totalNumOutputChans);
jassert (err == ASE_OK);
bufferSizeSamples = readBufferSizes (bufferSizeSamples);
double sampleRate = sr;
auto sampleRate = sr;
currentSampleRate = sampleRate;
currentBlockSizeSamples = bufferSizeSamples;
currentChansOut.clear();
@@ -450,9 +424,11 @@ public:
if (sampleRate == 0 || (sampleRates.size() > 0 && ! sampleRates.contains (sampleRate)))
sampleRate = sampleRates[0];
jassert (sampleRate != 0);
if (sampleRate == 0)
{
jassertfalse;
sampleRate = 44100.0;
}
updateClockSources();
currentSampleRate = getSampleRate();
@@ -486,7 +462,7 @@ public:
needToReset = false;
}
const int totalBuffers = resetBuffers (inputChannels, outputChannels);
auto totalBuffers = resetBuffers (inputChannels, outputChannels);
setCallbackFunctions();
@@ -508,7 +484,7 @@ public:
if (err == ASE_OK)
{
buffersCreated = true;
tempBuffer.calloc (totalBuffers * currentBlockSizeSamples + 32);
ioBufferSpace.calloc (totalBuffers * currentBlockSizeSamples + 32);
int n = 0;
Array<int> types;
@@ -518,7 +494,7 @@ public:
{
if (inputChannels[i])
{
inBuffers[n] = tempBuffer + (currentBlockSizeSamples * n);
inBuffers[n] = ioBufferSpace + (currentBlockSizeSamples * n);
ASIOChannelInfo channelInfo = { 0 };
channelInfo.channel = i;
@@ -540,7 +516,7 @@ public:
{
if (outputChannels[i])
{
outBuffers[n] = tempBuffer + (currentBlockSizeSamples * (numActiveInputChans + n));
outBuffers[n] = ioBufferSpace + (currentBlockSizeSamples * (numActiveInputChans + n));
ASIOChannelInfo channelInfo = { 0 };
channelInfo.channel = i;
@@ -564,8 +540,8 @@ public:
for (int i = 0; i < numActiveOutputChans; ++i)
{
outputFormat[i].clear (bufferInfos [numActiveInputChans + i].buffers[0], currentBlockSizeSamples);
outputFormat[i].clear (bufferInfos [numActiveInputChans + i].buffers[1], currentBlockSizeSamples);
outputFormat[i].clear (bufferInfos[numActiveInputChans + i].buffers[0], currentBlockSizeSamples);
outputFormat[i].clear (bufferInfos[numActiveInputChans + i].buffers[1], currentBlockSizeSamples);
}
readLatencies();
@@ -615,7 +591,7 @@ public:
isStarted = false;
deviceIsOpen = false;
const String errorCopy (error);
auto errorCopy = error;
close(); // (this resets the error string)
error = errorCopy;
}
@@ -678,7 +654,7 @@ public:
void stop() override
{
AudioIODeviceCallback* const lastCallback = currentCallback;
auto* lastCallback = currentCallback;
{
const ScopedLock sl (callbackLock);
@@ -698,15 +674,13 @@ public:
bool done = false;
insideControlPanelModalLoop = true;
const uint32 started = Time::getMillisecondCounter();
auto started = Time::getMillisecondCounter();
if (asioObject != nullptr)
{
asioObject->controlPanel();
const int spent = (int) Time::getMillisecondCounter() - (int) started;
auto spent = (int) (Time::getMillisecondCounter() - started);
JUCE_ASIO_LOG ("spent: " + String (spent));
if (spent > 300)
@@ -730,13 +704,10 @@ public:
if (! insideControlPanelModalLoop)
{
stopTimer();
JUCE_ASIO_LOG ("restart request!");
AudioIODeviceCallback* const oldCallback = currentCallback;
auto* oldCallback = currentCallback;
close();
needToReset = true;
open (BigInteger (currentChansIn), BigInteger (currentChansOut),
currentSampleRate, currentBlockSizeSamples);
@@ -757,51 +728,49 @@ public:
private:
//==============================================================================
WeakReference<ASIOAudioIODeviceType> owner;
IASIO* volatile asioObject;
IASIO* asioObject = {};
ASIOCallbacks callbacks;
CLSID classId;
String error;
long totalNumInputChans, totalNumOutputChans;
long totalNumInputChans = 0, totalNumOutputChans = 0;
StringArray inputChannelNames, outputChannelNames;
Array<double> sampleRates;
Array<int> bufferSizes;
long inputLatency, outputLatency;
long minBufferSize, maxBufferSize, preferredBufferSize, bufferGranularity;
ASIOClockSource clocks[32];
int numClockSources;
int volatile currentBlockSizeSamples;
int volatile currentBitDepth;
double volatile currentSampleRate;
long inputLatency = 0, outputLatency = 0;
long minBufferSize = 0, maxBufferSize = 0, preferredBufferSize = 0, bufferGranularity = 0;
ASIOClockSource clocks[32] = {};
int numClockSources = 0;
int currentBlockSizeSamples = 0;
int currentBitDepth = 16;
double currentSampleRate = 0;
BigInteger currentChansOut, currentChansIn;
AudioIODeviceCallback* volatile currentCallback;
AudioIODeviceCallback* currentCallback = {};
CriticalSection callbackLock;
HeapBlock<ASIOBufferInfo> bufferInfos;
HeapBlock<float*> inBuffers, outBuffers;
HeapBlock<float> ioBufferSpace;
HeapBlock<ASIOSampleFormat> inputFormat, outputFormat;
int numActiveInputChans = 0, numActiveOutputChans = 0;
WaitableEvent event1;
HeapBlock<float> tempBuffer;
int volatile bufferIndex, numActiveInputChans, numActiveOutputChans;
bool deviceIsOpen, isStarted, buffersCreated;
bool volatile calledback;
bool volatile littleEndian, postOutput, needToReset;
bool volatile insideControlPanelModalLoop;
bool volatile shouldUsePreferredSize;
bool deviceIsOpen = false, isStarted = false, buffersCreated = false;
std::atomic<bool> calledback { false };
bool littleEndian = false, postOutput = true, needToReset = false;
bool insideControlPanelModalLoop = false;
bool shouldUsePreferredSize = false;
int xruns = 0;
//==============================================================================
static String convertASIOString (char* const text, int length)
static String convertASIOString (char* text, int length)
{
if (CharPointer_UTF8::isValidString (text, length))
return String::fromUTF8 (text, length);
WCHAR wideVersion [64] = { 0 };
WCHAR wideVersion[64] = {};
MultiByteToWideChar (CP_ACP, 0, text, length, wideVersion, numElementsInArray (wideVersion));
return wideVersion;
}
@@ -867,7 +836,7 @@ private:
if (shouldUsePreferredSize)
{
JUCE_ASIO_LOG ("Using preferred size for buffer..");
long err = refreshBufferSizes();
auto err = refreshBufferSizes();
if (err == ASE_OK)
{
@@ -890,8 +859,8 @@ private:
{
numActiveInputChans = 0;
numActiveOutputChans = 0;
auto* info = bufferInfos.get();
ASIOBufferInfo* info = bufferInfos;
for (int i = 0; i < totalNumInputChans; ++i)
{
if (inputChannels[i])
@@ -952,7 +921,7 @@ private:
double getSampleRate() const
{
double cr = 0;
long err = asioObject->getSampleRate (&cr);
auto err = asioObject->getSampleRate (&cr);
JUCE_ASIO_LOG_ERROR ("getSampleRate", err);
return cr;
}
@@ -962,7 +931,7 @@ private:
if (currentSampleRate != newRate)
{
JUCE_ASIO_LOG ("rate change: " + String (currentSampleRate) + " to " + String (newRate));
long err = asioObject->setSampleRate (newRate);
auto err = asioObject->setSampleRate (newRate);
if (err == ASE_NoClock && numClockSources > 0)
{
@@ -970,7 +939,6 @@ private:
Thread::sleep (10);
err = asioObject->setClockSource (clocks[0].index);
JUCE_ASIO_LOG_ERROR ("setClockSource2", err);
Thread::sleep (10);
err = asioObject->setSampleRate (newRate);
}
@@ -1009,7 +977,7 @@ private:
if (numClockSources > 1 && ! isSourceSet)
{
JUCE_ASIO_LOG ("setting clock source");
long err = asioObject->setClockSource (clocks[0].index);
auto err = asioObject->setClockSource (clocks[0].index);
JUCE_ASIO_LOG_ERROR ("setClockSource1", err);
Thread::sleep (20);
}
@@ -1035,7 +1003,7 @@ private:
numActiveInputChans = 0;
numActiveOutputChans = 0;
ASIOBufferInfo* info = bufferInfos;
auto* info = bufferInfos.get();
int numChans = 0;
for (int i = 0; i < jmin (2, (int) totalNumInputChans); ++i)
@@ -1064,7 +1032,7 @@ private:
if (preferredSize > 0)
{
long err = asioObject->createBuffers (bufferInfos, numChans, preferredSize, &callbacks);
auto err = asioObject->createBuffers (bufferInfos, numChans, preferredSize, &callbacks);
JUCE_ASIO_LOG_ERROR ("dummy buffers", err);
}
@@ -1094,8 +1062,8 @@ private:
if (i < 2)
{
// clear the channels that are used with the dummy stuff
outputFormat[i].clear (bufferInfos [outputBufferIndex + i].buffers[0], preferredBufferSize);
outputFormat[i].clear (bufferInfos [outputBufferIndex + i].buffers[1], preferredBufferSize);
outputFormat[i].clear (bufferInfos[outputBufferIndex + i].buffers[0], preferredBufferSize);
outputFormat[i].clear (bufferInfos[outputBufferIndex + i].buffers[1], preferredBufferSize);
}
}
}
@@ -1140,7 +1108,7 @@ private:
String getLastDriverError() const
{
jassert (asioObject != nullptr);
char buffer [512] = { 0 };
char buffer[512] = {};
asioObject->getErrorMessage (buffer);
return String (buffer, sizeof (buffer) - 1);
}
@@ -1163,7 +1131,7 @@ private:
if (driverError.isEmpty())
{
char buffer [512];
char buffer[512] = {};
asioObject->getDriverName (buffer); // just in case any flimsy drivers expect this to be called..
}
@@ -1187,7 +1155,6 @@ private:
numActiveOutputChans = 0;
xruns = 0;
currentCallback = nullptr;
error.clear();
if (getName().isEmpty())
@@ -1220,7 +1187,7 @@ private:
{
addBufferSizes (minBufferSize, maxBufferSize, preferredBufferSize, bufferGranularity);
double currentRate = getSampleRate();
auto currentRate = getSampleRate();
if (currentRate < 1.0 || currentRate > 192001.0)
{
@@ -1232,13 +1199,12 @@ private:
}
currentSampleRate = currentRate;
postOutput = (asioObject->outputReady() == 0);
if (postOutput)
JUCE_ASIO_LOG ("outputReady true");
updateSampleRates();
readLatencies(); // ..doing these steps because cubase does so at this stage
createDummyBuffers (preferredBufferSize); // in initialisation, and some devices fail if we don't.
readLatencies();
@@ -1294,12 +1260,11 @@ private:
}
//==============================================================================
void JUCE_ASIOCALLBACK callback (const long index)
void JUCE_ASIOCALLBACK callback (long index)
{
if (isStarted)
{
bufferIndex = index;
processBuffer();
processBuffer (index);
}
else
{
@@ -1310,23 +1275,21 @@ private:
calledback = true;
}
void processBuffer()
void processBuffer (long bufferIndex)
{
const ASIOBufferInfo* const infos = bufferInfos;
const int bi = bufferIndex;
const ScopedLock sl (callbackLock);
if (bi >= 0)
if (bufferIndex >= 0)
{
const int samps = currentBlockSizeSamples;
auto* infos = bufferInfos.get();
auto samps = currentBlockSizeSamples;
if (currentCallback != nullptr)
{
for (int i = 0; i < numActiveInputChans; ++i)
{
jassert (inBuffers[i] != nullptr);
inputFormat[i].convertToFloat (infos[i].buffers[bi], inBuffers[i], samps);
inputFormat[i].convertToFloat (infos[i].buffers[bufferIndex], inBuffers[i], samps);
}
currentCallback->audioDeviceIOCallback (const_cast<const float**> (inBuffers.getData()), numActiveInputChans,
@@ -1335,13 +1298,13 @@ private:
for (int i = 0; i < numActiveOutputChans; ++i)
{
jassert (outBuffers[i] != nullptr);
outputFormat[i].convertFromFloat (outBuffers[i], infos [numActiveInputChans + i].buffers[bi], samps);
outputFormat[i].convertFromFloat (outBuffers[i], infos[numActiveInputChans + i].buffers[bufferIndex], samps);
}
}
else
{
for (int i = 0; i < numActiveOutputChans; ++i)
outputFormat[i].clear (infos[numActiveInputChans + i].buffers[bi], samps);
outputFormat[i].clear (infos[numActiveInputChans + i].buffers[bufferIndex], samps);
}
}
@@ -1359,15 +1322,15 @@ private:
return 1;
break;
case kAsioBufferSizeChange: JUCE_ASIO_LOG ("kAsioBufferSizeChange"); resetRequest(); return 1;
case kAsioResetRequest: JUCE_ASIO_LOG ("kAsioResetRequest"); resetRequest(); return 1;
case kAsioResyncRequest: JUCE_ASIO_LOG ("kAsioResyncRequest"); resetRequest(); return 1;
case kAsioLatenciesChanged: JUCE_ASIO_LOG ("kAsioLatenciesChanged"); return 1;
case kAsioEngineVersion: return 2;
case kAsioBufferSizeChange: JUCE_ASIO_LOG ("kAsioBufferSizeChange"); resetRequest(); return 1;
case kAsioResetRequest: JUCE_ASIO_LOG ("kAsioResetRequest"); resetRequest(); return 1;
case kAsioResyncRequest: JUCE_ASIO_LOG ("kAsioResyncRequest"); resetRequest(); return 1;
case kAsioLatenciesChanged: JUCE_ASIO_LOG ("kAsioLatenciesChanged"); return 1;
case kAsioEngineVersion: return 2;
case kAsioSupportsTimeInfo:
case kAsioSupportsTimeCode: return 0;
case kAsioOverload: xruns++; return 1;
case kAsioOverload: ++xruns; return 1;
}
return 0;
@@ -1379,29 +1342,30 @@ private:
{
static ASIOTime* JUCE_ASIOCALLBACK bufferSwitchTimeInfoCallback (ASIOTime*, long index, long)
{
if (currentASIODev[deviceIndex] != nullptr)
currentASIODev[deviceIndex]->callback (index);
if (auto* d = currentASIODev[deviceIndex])
d->callback (index);
return nullptr;
return {};
}
static void JUCE_ASIOCALLBACK bufferSwitchCallback (long index, long)
{
if (currentASIODev[deviceIndex] != nullptr)
currentASIODev[deviceIndex]->callback (index);
if (auto* d = currentASIODev[deviceIndex])
d->callback (index);
}
static long JUCE_ASIOCALLBACK asioMessagesCallback (long selector, long value, void*, double*)
{
return currentASIODev[deviceIndex] != nullptr
? currentASIODev[deviceIndex]->asioMessagesCallback (selector, value)
: 0;
if (auto* d = currentASIODev[deviceIndex])
return d->asioMessagesCallback (selector, value);
return {};
}
static void JUCE_ASIOCALLBACK sampleRateChangedCallback (ASIOSampleRate)
{
if (currentASIODev[deviceIndex] != nullptr)
currentASIODev[deviceIndex]->resetRequest();
if (auto* d = currentASIODev[deviceIndex])
d->resetRequest();
}
static void setCallbacks (ASIOCallbacks& callbacks) noexcept
@@ -1430,7 +1394,7 @@ private:
};
template <>
struct ASIOAudioIODevice::ASIOCallbackFunctions <sizeof(currentASIODev) / sizeof(currentASIODev[0])>
struct ASIOAudioIODevice::ASIOCallbackFunctions<maxNumASIODevices>
{
static void setCallbacksForDevice (ASIOCallbacks&, ASIOAudioIODevice*) noexcept {}
};
@@ -1442,10 +1406,9 @@ public:
ASIOAudioIODeviceType() : AudioIODeviceType ("ASIO") {}
//==============================================================================
void scanForDevices()
void scanForDevices() override
{
hasScanned = true;
deviceNames.clear();
classIds.clear();
@@ -1454,7 +1417,7 @@ public:
if (RegOpenKey (HKEY_LOCAL_MACHINE, _T("software\\asio"), &hk) == ERROR_SUCCESS)
{
TCHAR name [256];
TCHAR name[256] = {};
while (RegEnumKey (hk, index++, name, numElementsInArray (name)) == ERROR_SUCCESS)
addDriverInfo (name, hk);
@@ -1463,14 +1426,13 @@ public:
}
}
StringArray getDeviceNames (bool /*wantInputNames*/) const
StringArray getDeviceNames (bool /*wantInputNames*/) const override
{
jassert (hasScanned); // need to call scanForDevices() before doing this
return deviceNames;
}
int getDefaultDeviceIndex (bool) const
int getDefaultDeviceIndex (bool) const override
{
jassert (hasScanned); // need to call scanForDevices() before doing this
@@ -1489,8 +1451,8 @@ public:
static int findFreeSlot()
{
for (int i = 0; i < numElementsInArray (currentASIODev); ++i)
if (currentASIODev[i] == 0)
for (int i = 0; i < maxNumASIODevices; ++i)
if (currentASIODev[i] == nullptr)
return i;
jassertfalse; // unfortunately you can only have a finite number
@@ -1498,29 +1460,29 @@ public:
return -1;
}
int getIndexOfDevice (AudioIODevice* d, bool /*asInput*/) const
int getIndexOfDevice (AudioIODevice* d, bool /*asInput*/) const override
{
jassert (hasScanned); // need to call scanForDevices() before doing this
return d == nullptr ? -1 : deviceNames.indexOf (d->getName());
}
bool hasSeparateInputsAndOutputs() const { return false; }
bool hasSeparateInputsAndOutputs() const override { return false; }
AudioIODevice* createDevice (const String& outputDeviceName,
const String& inputDeviceName)
const String& inputDeviceName) override
{
// ASIO can't open two different devices for input and output - they must be the same one.
jassert (inputDeviceName == outputDeviceName || outputDeviceName.isEmpty() || inputDeviceName.isEmpty());
jassert (hasScanned); // need to call scanForDevices() before doing this
const String deviceName (outputDeviceName.isNotEmpty() ? outputDeviceName
: inputDeviceName);
const int index = deviceNames.indexOf (deviceName);
auto deviceName = outputDeviceName.isNotEmpty() ? outputDeviceName
: inputDeviceName;
auto index = deviceNames.indexOf (deviceName);
if (index >= 0)
{
const int freeSlot = findFreeSlot();
auto freeSlot = findFreeSlot();
if (freeSlot >= 0)
return new ASIOAudioIODevice (this, deviceName,
@@ -1552,7 +1514,7 @@ private:
if (RegOpenKey (HKEY_CLASSES_ROOT, _T("clsid"), &hk) == ERROR_SUCCESS)
{
int index = 0;
TCHAR name [512];
TCHAR name[512] = {};
while (RegEnumKey (hk, index++, name, numElementsInArray (name)) == ERROR_SUCCESS)
{
@@ -1564,7 +1526,7 @@ private:
{
if (RegOpenKeyEx (subKey, _T("InprocServer32"), 0, KEY_READ, &pathKey) == ERROR_SUCCESS)
{
TCHAR pathName [1024] = { 0 };
TCHAR pathName[1024] = {};
DWORD dtype = REG_SZ;
DWORD dsize = sizeof (pathName);
@@ -1596,7 +1558,7 @@ private:
if (RegOpenKeyEx (hk, keyName.toWideCharPointer(), 0, KEY_READ, &subKey) == ERROR_SUCCESS)
{
TCHAR buf [256] = { 0 };
TCHAR buf[256] = {};
DWORD dtype = REG_SZ;
DWORD dsize = sizeof (buf);
@@ -1605,6 +1567,7 @@ private:
if (dsize > 0 && checkClassIsOk (buf))
{
CLSID classId;
if (CLSIDFromString ((LPOLESTR) buf, &classId) == S_OK)
{
dtype = REG_SZ;


+ 87
- 97
modules/juce_audio_devices/native/juce_win32_WASAPI.cpp 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));


+ 3
- 3
modules/juce_audio_devices/sources/juce_AudioTransportSource.h View File

@@ -166,11 +166,11 @@ private:
AudioSource* masterSource = nullptr;
CriticalSection callbackLock;
float volatile gain = 1.0f, lastGain = 1.0f;
bool volatile playing = false, stopped = true;
float gain = 1.0f, lastGain = 1.0f;
bool playing = false, stopped = true;
double sampleRate = 44100.0, sourceSampleRate = 0;
int blockSize = 128, readAheadBufferSize = 0;
bool volatile isPrepared = false, inputStreamEOF = false;
bool isPrepared = false, inputStreamEOF = false;
void releaseMasterResources();


+ 2
- 2
modules/juce_audio_formats/format/juce_AudioFormatReaderSource.h View File

@@ -93,8 +93,8 @@ private:
//==============================================================================
OptionalScopedPointer<AudioFormatReader> reader;
int64 volatile nextPlayPos;
bool volatile looping;
int64 nextPlayPos;
bool looping;
JUCE_DECLARE_NON_COPYABLE_WITH_LEAK_DETECTOR (AudioFormatReaderSource)
};


+ 8
- 12
modules/juce_audio_formats/format/juce_AudioFormatWriter.cpp View File

@@ -170,7 +170,7 @@ bool AudioFormatWriter::writeFromFloatArrays (const float* const* channels, int
while (numSamples > 0)
{
const int numToDo = jmin (numSamples, maxSamples);
auto numToDo = jmin (numSamples, maxSamples);
for (int i = 0; i < numSourceChannels; ++i)
convertFloatsToInts (chans[i], channels[i] + startSample, numToDo);
@@ -217,12 +217,7 @@ public:
: fifo (numSamples),
buffer (channels, numSamples),
timeSliceThread (tst),
writer (w),
receiver (nullptr),
samplesWritten (0),
samplesPerFlush (0),
flushSampleCounter (0),
isRunning (true)
writer (w)
{
timeSliceThread.addTimeSliceClient (this);
}
@@ -267,7 +262,7 @@ public:
int writePendingData()
{
const int numToDo = fifo.getTotalSize() / 4;
auto numToDo = fifo.getTotalSize() / 4;
int start1, size1, start2, size2;
fifo.prepareToRead (numToDo, start1, size1, start2, size2);
@@ -278,6 +273,7 @@ public:
writer->writeFromAudioSampleBuffer (buffer, start1, size1);
const ScopedLock sl (thumbnailLock);
if (receiver != nullptr)
receiver->addBlock (samplesWritten, buffer, start1, size1);
@@ -330,10 +326,10 @@ private:
TimeSliceThread& timeSliceThread;
std::unique_ptr<AudioFormatWriter> writer;
CriticalSection thumbnailLock;
IncomingDataReceiver* receiver;
int64 samplesWritten;
int samplesPerFlush, flushSampleCounter;
volatile bool isRunning;
IncomingDataReceiver* receiver = {};
int64 samplesWritten = 0;
int samplesPerFlush = 0, flushSampleCounter = 0;
std::atomic<bool> isRunning { true };
JUCE_DECLARE_NON_COPYABLE (Buffer)
};


+ 167
- 167
modules/juce_core/native/java/AndroidCamera.java View File

@@ -1,169 +1,169 @@
$$CameraApi21
//==============================================================================
public class CameraDeviceStateCallback extends CameraDevice.StateCallback
{
private native void cameraDeviceStateClosed (long host, CameraDevice camera);
private native void cameraDeviceStateDisconnected (long host, CameraDevice camera);
private native void cameraDeviceStateError (long host, CameraDevice camera, int error);
private native void cameraDeviceStateOpened (long host, CameraDevice camera);
CameraDeviceStateCallback (long hostToUse)
{
host = hostToUse;
}
@Override
public void onClosed (CameraDevice camera)
{
cameraDeviceStateClosed (host, camera);
}
@Override
public void onDisconnected (CameraDevice camera)
{
cameraDeviceStateDisconnected (host, camera);
}
@Override
public void onError (CameraDevice camera, int error)
{
cameraDeviceStateError (host, camera, error);
}
@Override
public void onOpened (CameraDevice camera)
{
cameraDeviceStateOpened (host, camera);
}
private long host;
}
//==============================================================================
public class CameraCaptureSessionStateCallback extends CameraCaptureSession.StateCallback
{
private native void cameraCaptureSessionActive (long host, CameraCaptureSession session);
private native void cameraCaptureSessionClosed (long host, CameraCaptureSession session);
private native void cameraCaptureSessionConfigureFailed (long host, CameraCaptureSession session);
private native void cameraCaptureSessionConfigured (long host, CameraCaptureSession session);
private native void cameraCaptureSessionReady (long host, CameraCaptureSession session);
CameraCaptureSessionStateCallback (long hostToUse)
{
host = hostToUse;
}
@Override
public void onActive (CameraCaptureSession session)
{
cameraCaptureSessionActive (host, session);
}
@Override
public void onClosed (CameraCaptureSession session)
{
cameraCaptureSessionClosed (host, session);
}
@Override
public void onConfigureFailed (CameraCaptureSession session)
{
cameraCaptureSessionConfigureFailed (host, session);
}
@Override
public void onConfigured (CameraCaptureSession session)
{
cameraCaptureSessionConfigured (host, session);
}
@Override
public void onReady (CameraCaptureSession session)
{
cameraCaptureSessionReady (host, session);
}
private long host;
}
//==============================================================================
public class CameraCaptureSessionCaptureCallback extends CameraCaptureSession.CaptureCallback
{
private native void cameraCaptureSessionCaptureCompleted (long host, boolean isPreview, CameraCaptureSession session, CaptureRequest request, TotalCaptureResult result);
private native void cameraCaptureSessionCaptureFailed (long host, boolean isPreview, CameraCaptureSession session, CaptureRequest request, CaptureFailure failure);
private native void cameraCaptureSessionCaptureProgressed (long host, boolean isPreview, CameraCaptureSession session, CaptureRequest request, CaptureResult partialResult);
private native void cameraCaptureSessionCaptureStarted (long host, boolean isPreview, CameraCaptureSession session, CaptureRequest request, long timestamp, long frameNumber);
private native void cameraCaptureSessionCaptureSequenceAborted (long host, boolean isPreview, CameraCaptureSession session, int sequenceId);
private native void cameraCaptureSessionCaptureSequenceCompleted (long host, boolean isPreview, CameraCaptureSession session, int sequenceId, long frameNumber);
CameraCaptureSessionCaptureCallback (long hostToUse, boolean shouldBePreview)
{
host = hostToUse;
preview = shouldBePreview;
}
@Override
public void onCaptureCompleted (CameraCaptureSession session, CaptureRequest request,
TotalCaptureResult result)
{
cameraCaptureSessionCaptureCompleted (host, preview, session, request, result);
}
@Override
public void onCaptureFailed (CameraCaptureSession session, CaptureRequest request, CaptureFailure failure)
{
cameraCaptureSessionCaptureFailed (host, preview, session, request, failure);
}
@Override
public void onCaptureProgressed (CameraCaptureSession session, CaptureRequest request,
CaptureResult partialResult)
{
cameraCaptureSessionCaptureProgressed (host, preview, session, request, partialResult);
}
@Override
public void onCaptureSequenceAborted (CameraCaptureSession session, int sequenceId)
{
cameraCaptureSessionCaptureSequenceAborted (host, preview, session, sequenceId);
}
@Override
public void onCaptureSequenceCompleted (CameraCaptureSession session, int sequenceId, long frameNumber)
{
cameraCaptureSessionCaptureSequenceCompleted (host, preview, session, sequenceId, frameNumber);
}
@Override
public void onCaptureStarted (CameraCaptureSession session, CaptureRequest request, long timestamp,
long frameNumber)
{
cameraCaptureSessionCaptureStarted (host, preview, session, request, timestamp, frameNumber);
}
private long host;
private boolean preview;
}
//==============================================================================
public class JuceOrientationEventListener extends OrientationEventListener
{
private native void deviceOrientationChanged (long host, int orientation);
public JuceOrientationEventListener (long hostToUse, Context context, int rate)
{
super (context, rate);
host = hostToUse;
}
@Override
public void onOrientationChanged (int orientation)
{
deviceOrientationChanged (host, orientation);
}
private long host;
}
$$CameraApi21
//==============================================================================
public class CameraDeviceStateCallback extends CameraDevice.StateCallback
{
private native void cameraDeviceStateClosed (long host, CameraDevice camera);
private native void cameraDeviceStateDisconnected (long host, CameraDevice camera);
private native void cameraDeviceStateError (long host, CameraDevice camera, int error);
private native void cameraDeviceStateOpened (long host, CameraDevice camera);
CameraDeviceStateCallback (long hostToUse)
{
host = hostToUse;
}
@Override
public void onClosed (CameraDevice camera)
{
cameraDeviceStateClosed (host, camera);
}
@Override
public void onDisconnected (CameraDevice camera)
{
cameraDeviceStateDisconnected (host, camera);
}
@Override
public void onError (CameraDevice camera, int error)
{
cameraDeviceStateError (host, camera, error);
}
@Override
public void onOpened (CameraDevice camera)
{
cameraDeviceStateOpened (host, camera);
}
private long host;
}
//==============================================================================
public class CameraCaptureSessionStateCallback extends CameraCaptureSession.StateCallback
{
private native void cameraCaptureSessionActive (long host, CameraCaptureSession session);
private native void cameraCaptureSessionClosed (long host, CameraCaptureSession session);
private native void cameraCaptureSessionConfigureFailed (long host, CameraCaptureSession session);
private native void cameraCaptureSessionConfigured (long host, CameraCaptureSession session);
private native void cameraCaptureSessionReady (long host, CameraCaptureSession session);
CameraCaptureSessionStateCallback (long hostToUse)
{
host = hostToUse;
}
@Override
public void onActive (CameraCaptureSession session)
{
cameraCaptureSessionActive (host, session);
}
@Override
public void onClosed (CameraCaptureSession session)
{
cameraCaptureSessionClosed (host, session);
}
@Override
public void onConfigureFailed (CameraCaptureSession session)
{
cameraCaptureSessionConfigureFailed (host, session);
}
@Override
public void onConfigured (CameraCaptureSession session)
{
cameraCaptureSessionConfigured (host, session);
}
@Override
public void onReady (CameraCaptureSession session)
{
cameraCaptureSessionReady (host, session);
}
private long host;
}
//==============================================================================
public class CameraCaptureSessionCaptureCallback extends CameraCaptureSession.CaptureCallback
{
private native void cameraCaptureSessionCaptureCompleted (long host, boolean isPreview, CameraCaptureSession session, CaptureRequest request, TotalCaptureResult result);
private native void cameraCaptureSessionCaptureFailed (long host, boolean isPreview, CameraCaptureSession session, CaptureRequest request, CaptureFailure failure);
private native void cameraCaptureSessionCaptureProgressed (long host, boolean isPreview, CameraCaptureSession session, CaptureRequest request, CaptureResult partialResult);
private native void cameraCaptureSessionCaptureStarted (long host, boolean isPreview, CameraCaptureSession session, CaptureRequest request, long timestamp, long frameNumber);
private native void cameraCaptureSessionCaptureSequenceAborted (long host, boolean isPreview, CameraCaptureSession session, int sequenceId);
private native void cameraCaptureSessionCaptureSequenceCompleted (long host, boolean isPreview, CameraCaptureSession session, int sequenceId, long frameNumber);
CameraCaptureSessionCaptureCallback (long hostToUse, boolean shouldBePreview)
{
host = hostToUse;
preview = shouldBePreview;
}
@Override
public void onCaptureCompleted (CameraCaptureSession session, CaptureRequest request,
TotalCaptureResult result)
{
cameraCaptureSessionCaptureCompleted (host, preview, session, request, result);
}
@Override
public void onCaptureFailed (CameraCaptureSession session, CaptureRequest request, CaptureFailure failure)
{
cameraCaptureSessionCaptureFailed (host, preview, session, request, failure);
}
@Override
public void onCaptureProgressed (CameraCaptureSession session, CaptureRequest request,
CaptureResult partialResult)
{
cameraCaptureSessionCaptureProgressed (host, preview, session, request, partialResult);
}
@Override
public void onCaptureSequenceAborted (CameraCaptureSession session, int sequenceId)
{
cameraCaptureSessionCaptureSequenceAborted (host, preview, session, sequenceId);
}
@Override
public void onCaptureSequenceCompleted (CameraCaptureSession session, int sequenceId, long frameNumber)
{
cameraCaptureSessionCaptureSequenceCompleted (host, preview, session, sequenceId, frameNumber);
}
@Override
public void onCaptureStarted (CameraCaptureSession session, CaptureRequest request, long timestamp,
long frameNumber)
{
cameraCaptureSessionCaptureStarted (host, preview, session, request, timestamp, frameNumber);
}
private long host;
private boolean preview;
}
//==============================================================================
public class JuceOrientationEventListener extends OrientationEventListener
{
private native void deviceOrientationChanged (long host, int orientation);
public JuceOrientationEventListener (long hostToUse, Context context, int rate)
{
super (context, rate);
host = hostToUse;
}
@Override
public void onOrientationChanged (int orientation)
{
deviceOrientationChanged (host, orientation);
}
private long host;
}
CameraApi21$$

+ 61
- 65
modules/juce_core/native/juce_posix_SharedCode.h View File

@@ -41,7 +41,7 @@ bool CriticalSection::tryEnter() const noexcept { return pthread_mutex_trylo
void CriticalSection::exit() const noexcept { pthread_mutex_unlock (&lock); }
//==============================================================================
WaitableEvent::WaitableEvent (const bool useManualReset) noexcept
WaitableEvent::WaitableEvent (bool useManualReset) noexcept
: triggered (false), manualReset (useManualReset)
{
pthread_cond_init (&condition, 0);
@@ -61,7 +61,7 @@ WaitableEvent::~WaitableEvent() noexcept
pthread_mutex_destroy (&mutex);
}
bool WaitableEvent::wait (const int timeOutMillisecs) const noexcept
bool WaitableEvent::wait (int timeOutMillisecs) const noexcept
{
pthread_mutex_lock (&mutex);
@@ -152,6 +152,7 @@ void JUCE_CALLTYPE Process::terminate()
bool Process::setMaxNumberOfFileHandles (int newMaxNumber) noexcept
{
rlimit lim;
if (getrlimit (RLIMIT_NOFILE, &lim) == 0)
{
if (newMaxNumber <= 0 && lim.rlim_cur == RLIM_INFINITY && lim.rlim_max == RLIM_INFINITY)
@@ -201,8 +202,8 @@ File File::getCurrentWorkingDirectory()
{
HeapBlock<char> heapBuffer;
char localBuffer [1024];
char* cwd = getcwd (localBuffer, sizeof (localBuffer) - 1);
char localBuffer[1024];
auto cwd = getcwd (localBuffer, sizeof (localBuffer) - 1);
size_t bufferSize = 4096;
while (cwd == nullptr && errno == ERANGE)
@@ -221,9 +222,9 @@ bool File::setAsCurrentWorkingDirectory() const
}
#if JUCE_ANDROID
typedef unsigned long juce_sigactionflags_type;
using juce_sigactionflags_type = unsigned long;
#else
typedef int juce_sigactionflags_type;
using juce_sigactionflags_type = int;
#endif
//==============================================================================
@@ -245,11 +246,11 @@ int juce_siginterrupt (int sig, int flag)
namespace
{
#if JUCE_LINUX || (JUCE_IOS && ! __DARWIN_ONLY_64_BIT_INO_T) // (this iOS stuff is to avoid a simulator bug)
typedef struct stat64 juce_statStruct;
#define JUCE_STAT stat64
using juce_statStruct = struct stat64;
#define JUCE_STAT stat64
#else
typedef struct stat juce_statStruct;
#define JUCE_STAT stat
using juce_statStruct = struct stat;
#define JUCE_STAT stat
#endif
bool juce_stat (const String& fileName, juce_statStruct& info)
@@ -278,8 +279,8 @@ namespace
static int64 getCreationTime (const juce_statStruct& s) noexcept { return (int64) s.st_ctime; }
#endif
void updateStatInfoForFile (const String& path, bool* const isDir, int64* const fileSize,
Time* const modTime, Time* const creationTime, bool* const isReadOnly)
void updateStatInfoForFile (const String& path, bool* isDir, int64* fileSize,
Time* modTime, Time* creationTime, bool* isReadOnly)
{
if (isDir != nullptr || fileSize != nullptr || modTime != nullptr || creationTime != nullptr)
{
@@ -344,7 +345,7 @@ uint64 File::getFileIdentifier() const
static bool hasEffectiveRootFilePermissions()
{
#if JUCE_LINUX
return (geteuid() == 0);
return geteuid() == 0;
#else
return false;
#endif
@@ -475,7 +476,7 @@ int64 juce_fileSetPosition (void* handle, int64 pos)
void FileInputStream::openHandle()
{
const int f = open (file.getFullPathName().toUTF8(), O_RDONLY, 00644);
auto f = open (file.getFullPathName().toUTF8(), O_RDONLY, 00644);
if (f != -1)
fileHandle = fdToVoidPointer (f);
@@ -489,7 +490,7 @@ FileInputStream::~FileInputStream()
close (getFD (fileHandle));
}
size_t FileInputStream::readInternal (void* const buffer, const size_t numBytes)
size_t FileInputStream::readInternal (void* buffer, size_t numBytes)
{
ssize_t result = 0;
@@ -512,7 +513,7 @@ void FileOutputStream::openHandle()
{
if (file.exists())
{
const int f = open (file.getFullPathName().toUTF8(), O_RDWR, 00644);
auto f = open (file.getFullPathName().toUTF8(), O_RDWR, 00644);
if (f != -1)
{
@@ -535,7 +536,7 @@ void FileOutputStream::openHandle()
}
else
{
const int f = open (file.getFullPathName().toUTF8(), O_RDWR + O_CREAT, 00644);
auto f = open (file.getFullPathName().toUTF8(), O_RDWR + O_CREAT, 00644);
if (f != -1)
fileHandle = fdToVoidPointer (f);
@@ -553,19 +554,17 @@ void FileOutputStream::closeHandle()
}
}
ssize_t FileOutputStream::writeInternal (const void* const data, const size_t numBytes)
ssize_t FileOutputStream::writeInternal (const void* data, size_t numBytes)
{
ssize_t result = 0;
if (fileHandle == 0)
return 0;
if (fileHandle != 0)
{
result = ::write (getFD (fileHandle), data, numBytes);
auto result = ::write (getFD (fileHandle), data, numBytes);
if (result == -1)
status = getResultForErrno();
}
if (result == -1)
status = getResultForErrno();
return result;
return (ssize_t) result;
}
#ifndef JUCE_ANDROID
@@ -588,7 +587,7 @@ Result FileOutputStream::truncate()
//==============================================================================
String SystemStats::getEnvironmentVariable (const String& name, const String& defaultValue)
{
if (const char* s = ::getenv (name.toUTF8()))
if (auto s = ::getenv (name.toUTF8()))
return String::fromUTF8 (s);
return defaultValue;
@@ -601,7 +600,7 @@ void MemoryMappedFile::openInternal (const File& file, AccessMode mode, bool exc
if (range.getStart() > 0)
{
const long pageSize = sysconf (_SC_PAGE_SIZE);
auto pageSize = sysconf (_SC_PAGE_SIZE);
range.setStart (range.getStart() - (range.getStart() % pageSize));
}
@@ -649,7 +648,7 @@ File juce_getExecutableFile()
{
Dl_info exeInfo;
void* localSymbol = (void*) juce_getExecutableFile;
auto localSymbol = (void*) juce_getExecutableFile;
dladdr (localSymbol, &exeInfo);
return CharPointer_UTF8 (exeInfo.dli_fname);
}
@@ -664,6 +663,7 @@ File juce_getExecutableFile()
int64 File::getBytesFreeOnVolume() const
{
struct statfs buf;
if (juce_doStatFS (*this, buf))
return (int64) buf.f_bsize * (int64) buf.f_bavail; // Note: this returns space available to non-super user
@@ -673,6 +673,7 @@ int64 File::getBytesFreeOnVolume() const
int64 File::getVolumeTotalSize() const
{
struct statfs buf;
if (juce_doStatFS (*this, buf))
return (int64) buf.f_bsize * (int64) buf.f_blocks;
@@ -686,11 +687,11 @@ String File::getVolumeLabel() const
{
u_int32_t length;
attrreference_t mountPointRef;
char mountPointSpace [MAXPATHLEN];
char mountPointSpace[MAXPATHLEN];
} attrBuf;
struct attrlist attrList;
zerostruct (attrList); // (can't use "= { 0 }" on this object because it's typedef'ed as a C struct)
zerostruct (attrList); // (can't use "= {}" on this object because it's a C struct)
attrList.bitmapcount = ATTR_BIT_MAP_COUNT;
attrList.volattr = ATTR_VOL_INFO | ATTR_VOL_NAME;
@@ -702,7 +703,7 @@ String File::getVolumeLabel() const
return String::fromUTF8 (((const char*) &attrBuf.mountPointRef) + attrBuf.mountPointRef.attr_dataoffset,
(int) attrBuf.mountPointRef.attr_length);
const File parent (f.getParentDirectory());
auto parent = f.getParentDirectory();
if (f == parent)
break;
@@ -719,7 +720,7 @@ int File::getVolumeSerialNumber() const
int result = 0;
/* int fd = open (getFullPathName().toUTF8(), O_RDONLY | O_NONBLOCK);
char info [512];
char info[512];
#ifndef HDIO_GET_IDENTITY
#define HDIO_GET_IDENTITY 0x030d
@@ -748,12 +749,12 @@ String juce_getOutputFromCommand (const String&);
String juce_getOutputFromCommand (const String& command)
{
// slight bodge here, as we just pipe the output into a temp file and read it...
const File tempFile (File::getSpecialLocation (File::tempDirectory)
.getNonexistentChildFile (String::toHexString (Random::getSystemRandom().nextInt()), ".tmp", false));
auto tempFile = File::getSpecialLocation (File::tempDirectory)
.getNonexistentChildFile (String::toHexString (Random::getSystemRandom().nextInt()), ".tmp", false);
juce_runSystemCommand (command + " > " + tempFile.getFullPathName());
String result (tempFile.loadFileAsString());
auto result = tempFile.loadFileAsString();
tempFile.deleteFile();
return result;
}
@@ -764,12 +765,9 @@ String juce_getOutputFromCommand (const String& command)
class InterProcessLock::Pimpl
{
public:
Pimpl (const String&, int)
: handle (1), refCount (1) // On iOS just fake success..
{
}
Pimpl (const String&, int) {}
int handle, refCount;
int handle = 1, refCount = 1; // On iOS just fake success..
};
#else
@@ -777,8 +775,7 @@ public:
class InterProcessLock::Pimpl
{
public:
Pimpl (const String& lockName, const int timeOutMillisecs)
: handle (0), refCount (1)
Pimpl (const String& lockName, int timeOutMillisecs)
{
#if JUCE_MAC
if (! createLockFile (File ("~/Library/Caches/com.juce.locks").getChildFile (lockName), timeOutMillisecs))
@@ -787,6 +784,7 @@ public:
#else
File tempFolder ("/var/tmp");
if (! tempFolder.isDirectory())
tempFolder = "/tmp";
@@ -799,7 +797,7 @@ public:
closeFile();
}
bool createLockFile (const File& file, const int timeOutMillisecs)
bool createLockFile (const File& file, int timeOutMillisecs)
{
file.create();
handle = open (file.getFullPathName().toUTF8(), O_RDWR);
@@ -812,16 +810,16 @@ public:
fl.l_whence = SEEK_SET;
fl.l_type = F_WRLCK;
const int64 endTime = Time::currentTimeMillis() + timeOutMillisecs;
auto endTime = Time::currentTimeMillis() + timeOutMillisecs;
for (;;)
{
const int result = fcntl (handle, F_SETLK, &fl);
auto result = fcntl (handle, F_SETLK, &fl);
if (result >= 0)
return true;
const int error = errno;
auto error = errno;
if (error != EINTR)
{
@@ -859,7 +857,7 @@ public:
}
}
int handle, refCount;
int handle = 0, refCount = 1;
};
#endif
@@ -871,7 +869,7 @@ InterProcessLock::~InterProcessLock()
{
}
bool InterProcessLock::enter (const int timeOutMillisecs)
bool InterProcessLock::enter (int timeOutMillisecs)
{
const ScopedLock sl (lock);
@@ -964,7 +962,6 @@ void Thread::launchThread()
if (pthread_attr_init (&attr) == 0)
{
attrPtr = &attr;
pthread_attr_setstacksize (attrPtr, threadStackSize);
}
@@ -1054,7 +1051,7 @@ void JUCE_CALLTYPE Thread::yield()
#define SUPPORT_AFFINITIES 1
#endif
void JUCE_CALLTYPE Thread::setCurrentThreadAffinityMask (const uint32 affinityMask)
void JUCE_CALLTYPE Thread::setCurrentThreadAffinityMask (uint32 affinityMask)
{
#if SUPPORT_AFFINITIES
cpu_set_t affinity;
@@ -1109,7 +1106,7 @@ void* DynamicLibrary::getFunction (const String& functionName) noexcept
//==============================================================================
static inline String readPosixConfigFileValue (const char* file, const char* const key)
static inline String readPosixConfigFileValue (const char* file, const char* key)
{
StringArray lines;
File (file).readLines (lines);
@@ -1267,7 +1264,7 @@ bool ChildProcess::start (const StringArray& args, int streamFlags)
//==============================================================================
struct HighResolutionTimer::Pimpl
{
Pimpl (HighResolutionTimer& t) : owner (t), thread (0), destroyThread (false), isRunning (false)
Pimpl (HighResolutionTimer& t) : owner (t)
{
pthread_condattr_t attr;
pthread_condattr_init (&attr);
@@ -1338,15 +1335,13 @@ struct HighResolutionTimer::Pimpl
}
HighResolutionTimer& owner;
int volatile periodMs;
std::atomic<int> periodMs;
private:
pthread_t thread;
pthread_t thread = {};
pthread_cond_t stopCond;
pthread_mutex_t timerMutex;
bool volatile destroyThread;
bool volatile isRunning;
std::atomic<bool> destroyThread { false }, isRunning { false };
static void* timerThread (void* param)
{
@@ -1369,7 +1364,7 @@ private:
void timerThread()
{
int lastPeriod = periodMs;
auto lastPeriod = periodMs.load();
Clock clock (lastPeriod);
pthread_mutex_lock (&timerMutex);
@@ -1385,15 +1380,16 @@ private:
if (isRunning)
owner.hiResTimerCallback();
if (lastPeriod != periodMs)
auto newPeriod = periodMs.load();
if (lastPeriod != newPeriod)
{
lastPeriod = periodMs;
lastPeriod = newPeriod;
clock = Clock (lastPeriod);
}
}
periodMs = 0;
pthread_mutex_unlock (&timerMutex);
pthread_exit (nullptr);
}
@@ -1421,7 +1417,7 @@ private:
uint64_t time, delta;
mach_timebase_info_data_t timebase;
bool hasExpired(struct timespec& time_left) noexcept
bool hasExpired (struct timespec& time_left) noexcept
{
uint64_t now = mach_absolute_time();
@@ -1457,11 +1453,11 @@ private:
uint64 time, delta;
bool hasExpired(struct timespec& expiryTime) noexcept
bool hasExpired (struct timespec& expiryTime) noexcept
{
struct timespec t;
clock_gettime (CLOCK_MONOTONIC, &t);
uint64 now = (uint64) (1000000000 * (int64) t.tv_sec + (int64) t.tv_nsec);
auto now = (uint64) (1000000000 * (int64) t.tv_sec + (int64) t.tv_nsec);
if (now < time)
{


+ 30
- 34
modules/juce_core/network/juce_Socket.cpp View File

@@ -94,10 +94,10 @@ namespace SocketHelpers
: setOption (handle, IPPROTO_TCP, TCP_NODELAY, (int) 1));
}
static void closeSocket (volatile int& handle, CriticalSection& readLock,
bool isListener, int portNumber, bool& connected) noexcept
static void closeSocket (std::atomic<int>& handle, CriticalSection& readLock,
bool isListener, int portNumber, std::atomic<bool>& connected) noexcept
{
const SocketHandle h = handle;
const SocketHandle h = handle.load();
handle = -1;
#if JUCE_WINDOWS
@@ -187,8 +187,8 @@ namespace SocketHelpers
}
static int readSocket (SocketHandle handle,
void* const destBuffer, const int maxBytesToRead,
bool volatile& connected,
void* destBuffer, int maxBytesToRead,
std::atomic<bool>& connected,
bool blockUntilSpecifiedAmountHasArrived,
CriticalSection& readLock,
String* senderIP = nullptr,
@@ -242,8 +242,8 @@ namespace SocketHelpers
return (int) bytesRead;
}
static int waitForReadiness (const volatile int& handle, CriticalSection& readLock,
const bool forReading, const int timeoutMsecs) noexcept
static int waitForReadiness (std::atomic<int>& handle, CriticalSection& readLock,
bool forReading, int timeoutMsecs) noexcept
{
// avoid race-condition
CriticalSection::ScopedTryLockType lock (readLock);
@@ -251,7 +251,7 @@ namespace SocketHelpers
if (! lock.isLocked())
return -1;
int h = handle;
int h = handle.load();
struct timeval timeout;
struct timeval* timeoutp;
@@ -293,7 +293,7 @@ namespace SocketHelpers
#endif
// we are closing
if (handle < 0)
if (handle.load() < 0)
return -1;
{
@@ -308,7 +308,7 @@ namespace SocketHelpers
return FD_ISSET (h, forReading ? &rset : &wset) ? 1 : 0;
}
static bool setSocketBlockingState (SocketHandle handle, const bool shouldBlock) noexcept
static bool setSocketBlockingState (SocketHandle handle, bool shouldBlock) noexcept
{
#if JUCE_WINDOWS
u_long nonBlocking = shouldBlock ? 0 : (u_long) 1;
@@ -328,7 +328,7 @@ namespace SocketHelpers
#endif
}
static addrinfo* getAddressInfo (const bool isDatagram, const String& hostName, int portNumber)
static addrinfo* getAddressInfo (bool isDatagram, const String& hostName, int portNumber)
{
struct addrinfo hints;
zerostruct (hints);
@@ -345,11 +345,11 @@ namespace SocketHelpers
return nullptr;
}
static bool connectSocket (int volatile& handle,
static bool connectSocket (std::atomic<int>& handle,
CriticalSection& readLock,
const String& hostName,
const int portNumber,
const int timeOutMillisecs) noexcept
int portNumber,
int timeOutMillisecs) noexcept
{
bool success = false;
@@ -373,7 +373,7 @@ namespace SocketHelpers
if (errno == EINPROGRESS)
#endif
{
const volatile int cvHandle = (int) newHandle;
std::atomic<int> cvHandle { (int) newHandle };
if (waitForReadiness (cvHandle, readLock, false, timeOutMillisecs) == 1)
success = true;
@@ -454,14 +454,14 @@ StreamingSocket::~StreamingSocket()
}
//==============================================================================
int StreamingSocket::read (void* destBuffer, const int maxBytesToRead, bool shouldBlock)
int StreamingSocket::read (void* destBuffer, int maxBytesToRead, bool shouldBlock)
{
return (connected && ! isListener) ? SocketHelpers::readSocket (handle, destBuffer, maxBytesToRead,
connected, shouldBlock, readLock)
: -1;
}
int StreamingSocket::write (const void* sourceBuffer, const int numBytesToWrite)
int StreamingSocket::write (const void* sourceBuffer, int numBytesToWrite)
{
if (isListener || ! connected)
return -1;
@@ -470,20 +470,19 @@ int StreamingSocket::write (const void* sourceBuffer, const int numBytesToWrite)
}
//==============================================================================
int StreamingSocket::waitUntilReady (const bool readyForReading,
const int timeoutMsecs) const
int StreamingSocket::waitUntilReady (bool readyForReading, int timeoutMsecs)
{
return connected ? SocketHelpers::waitForReadiness (handle, readLock, readyForReading, timeoutMsecs)
: -1;
}
//==============================================================================
bool StreamingSocket::bindToPort (const int port)
bool StreamingSocket::bindToPort (int port)
{
return bindToPort (port, String());
}
bool StreamingSocket::bindToPort (const int port, const String& addr)
bool StreamingSocket::bindToPort (int port, const String& addr)
{
jassert (SocketHelpers::isValidPortNumber (port));
@@ -495,9 +494,7 @@ int StreamingSocket::getBoundPort() const noexcept
return SocketHelpers::getBoundPort (handle);
}
bool StreamingSocket::connect (const String& remoteHostName,
const int remotePortNumber,
const int timeOutMillisecs)
bool StreamingSocket::connect (const String& remoteHostName, int remotePortNumber, int timeOutMillisecs)
{
jassert (SocketHelpers::isValidPortNumber (remotePortNumber));
@@ -537,7 +534,7 @@ void StreamingSocket::close()
}
//==============================================================================
bool StreamingSocket::createListener (const int newPortNumber, const String& localHostName)
bool StreamingSocket::createListener (int newPortNumber, const String& localHostName)
{
jassert (SocketHelpers::isValidPortNumber (newPortNumber));
@@ -633,18 +630,18 @@ void DatagramSocket::shutdown()
if (handle < 0)
return;
auto copyOfHandle = handle;
std::atomic<int> handleCopy { handle.load() };
handle = -1;
bool connected = false;
SocketHelpers::closeSocket (copyOfHandle, readLock, false, 0, connected);
std::atomic<bool> connected { false };
SocketHelpers::closeSocket (handleCopy, readLock, false, 0, connected);
}
bool DatagramSocket::bindToPort (const int port)
bool DatagramSocket::bindToPort (int port)
{
return bindToPort (port, String());
}
bool DatagramSocket::bindToPort (const int port, const String& addr)
bool DatagramSocket::bindToPort (int port, const String& addr)
{
jassert (SocketHelpers::isValidPortNumber (port));
@@ -664,8 +661,7 @@ int DatagramSocket::getBoundPort() const noexcept
}
//==============================================================================
int DatagramSocket::waitUntilReady (const bool readyForReading,
const int timeoutMsecs) const
int DatagramSocket::waitUntilReady (bool readyForReading, int timeoutMsecs)
{
if (handle < 0)
return -1;
@@ -678,7 +674,7 @@ int DatagramSocket::read (void* destBuffer, int maxBytesToRead, bool shouldBlock
if (handle < 0 || ! isBound)
return -1;
bool connected = true;
std::atomic<bool> connected { true };
SocketHelpers::setSocketBlockingState (handle, shouldBlock);
return SocketHelpers::readSocket (handle, destBuffer, maxBytesToRead,
@@ -690,7 +686,7 @@ int DatagramSocket::read (void* destBuffer, int maxBytesToRead, bool shouldBlock
if (handle < 0 || ! isBound)
return -1;
bool connected = true;
std::atomic<bool> connected { true };
SocketHelpers::setSocketBlockingState (handle, shouldBlock);
return SocketHelpers::readSocket (handle, destBuffer, maxBytesToRead, connected,


+ 6
- 10
modules/juce_core/network/juce_Socket.h View File

@@ -122,8 +122,7 @@ public:
If the socket is ready on return, this returns 1. If it times-out before
the socket becomes ready, it returns 0. If an error occurs, it returns -1.
*/
int waitUntilReady (bool readyForReading,
int timeoutMsecs) const;
int waitUntilReady (bool readyForReading, int timeoutMsecs);
/** Reads bytes from the socket.
@@ -177,8 +176,9 @@ public:
private:
//==============================================================================
String hostName;
int volatile portNumber = 0, handle = -1;
bool connected = false, isListener = false;
std::atomic<int> portNumber { 0 }, handle { -1 };
std::atomic<bool> connected { false };
bool isListener = false;
mutable CriticalSection readLock;
StreamingSocket (const String& hostname, int portNumber, int handle);
@@ -263,8 +263,7 @@ public:
If the socket is ready on return, this returns 1. If it times-out before
the socket becomes ready, it returns 0. If an error occurs, it returns -1.
*/
int waitUntilReady (bool readyForReading,
int timeoutMsecs) const;
int waitUntilReady (bool readyForReading, int timeoutMsecs);
/** Reads bytes from the socket.
@@ -320,19 +319,16 @@ public:
//==============================================================================
/** Join a multicast group.
@returns true if it succeeds.
*/
bool joinMulticast (const String& multicastIPAddress);
/** Leave a multicast group.
@returns true if it succeeds.
*/
bool leaveMulticast (const String& multicastIPAddress);
/** Enables or disables multicast loopback.
@returns true if it succeeds.
*/
bool setMulticastLoopbackEnabled (bool enableLoopback);
@@ -350,7 +346,7 @@ public:
private:
//==============================================================================
int handle = -1;
std::atomic<int> handle { -1 };
bool isBound = false;
String lastBindAddress, lastServerHost;
int lastServerPort = -1;


+ 3
- 4
modules/juce_core/threads/juce_ThreadPool.cpp View File

@@ -23,9 +23,8 @@
namespace juce
{
class ThreadPool::ThreadPoolThread : public Thread
struct ThreadPool::ThreadPoolThread : public Thread
{
public:
ThreadPoolThread (ThreadPool& p, size_t stackSize)
: Thread ("Pool", stackSize), pool (p)
{
@@ -38,7 +37,7 @@ public:
wait (500);
}
ThreadPoolJob* volatile currentJob = nullptr;
std::atomic<ThreadPoolJob*> currentJob { nullptr };
ThreadPool& pool;
JUCE_DECLARE_NON_COPYABLE_WITH_LEAK_DETECTOR (ThreadPoolThread)
@@ -85,7 +84,7 @@ void ThreadPoolJob::removeListener (Thread::Listener* listener)
ThreadPoolJob* ThreadPoolJob::getCurrentThreadPoolJob()
{
if (auto* t = dynamic_cast<ThreadPool::ThreadPoolThread*> (Thread::getCurrentThread()))
return t->currentJob;
return t->currentJob.load();
return nullptr;
}


+ 2
- 5
modules/juce_core/threads/juce_ThreadPool.h View File

@@ -24,8 +24,6 @@ namespace juce
{
class ThreadPool;
class ThreadPoolThread;
//==============================================================================
/**
@@ -134,7 +132,6 @@ public:
//==============================================================================
private:
friend class ThreadPool;
friend class ThreadPoolThread;
String jobName;
ThreadPool* pool = nullptr;
bool shouldStop = false, isActive = false, shouldBeDeleted = false;
@@ -323,9 +320,9 @@ private:
//==============================================================================
Array<ThreadPoolJob*> jobs;
class ThreadPoolThread;
struct ThreadPoolThread;
friend class ThreadPoolJob;
friend class ThreadPoolThread;
friend struct ThreadPoolThread;
friend struct ContainerDeletePolicy<ThreadPoolThread>;
OwnedArray<ThreadPoolThread> threads;


+ 2
- 2
modules/juce_events/messages/juce_MessageManager.cpp View File

@@ -155,7 +155,7 @@ public:
}
WaitableEvent finished;
void* volatile result = nullptr;
std::atomic<void*> result { nullptr };
private:
MessageCallbackFunction* const func;
@@ -177,7 +177,7 @@ void* MessageManager::callFunctionOnMessageThread (MessageCallbackFunction* cons
if (message->post())
{
message->finished.wait();
return message->result;
return message->result.load();
}
jassertfalse; // the OS message queue failed to send the message!


Loading…
Cancel
Save