mirror of
https://github.com/juce-framework/JUCE.git
synced 2026-01-10 23:44:24 +00:00
Updated old code where the 'volatile' keyword was still being used
This commit is contained in:
parent
5faef29f3e
commit
e2dcc32f88
17 changed files with 580 additions and 649 deletions
|
|
@ -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);
|
||||
|
|
@ -164,7 +164,7 @@ private:
|
|||
int64 nextSampleNum = 0;
|
||||
|
||||
CriticalSection writerLock;
|
||||
AudioFormatWriter::ThreadedWriter* volatile activeWriter = nullptr;
|
||||
std::atomic<AudioFormatWriter::ThreadedWriter*> activeWriter { nullptr };
|
||||
};
|
||||
|
||||
//==============================================================================
|
||||
|
|
|
|||
|
|
@ -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,10 +166,10 @@ 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
|
||||
auto elapsed = (now >= startTime ? now - startTime
|
||||
: (std::numeric_limits<uint32>::max() - startTime) + now);
|
||||
|
||||
while (elapsed <= timeout)
|
||||
|
|
@ -179,15 +177,17 @@ bool BufferingAudioSource::waitForNextAudioBlockReady (const AudioSourceChannelI
|
|||
{
|
||||
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);
|
||||
|
|
|
|||
|
|
@ -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);
|
||||
|
|
|
|||
|
|
@ -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)
|
||||
};
|
||||
|
|
|
|||
|
|
@ -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()
|
||||
auto num = forInput ? MIDIGetNumberOfSources()
|
||||
: MIDIGetNumberOfDestinations();
|
||||
StringArray s;
|
||||
|
||||
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)
|
||||
|
|
|
|||
|
|
@ -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;
|
||||
long inputLatency = 0, outputLatency = 0;
|
||||
long minBufferSize = 0, maxBufferSize = 0, preferredBufferSize = 0, bufferGranularity = 0;
|
||||
ASIOClockSource clocks[32] = {};
|
||||
int numClockSources = 0;
|
||||
|
||||
int volatile currentBlockSizeSamples;
|
||||
int volatile currentBitDepth;
|
||||
double volatile currentSampleRate;
|
||||
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);
|
||||
}
|
||||
}
|
||||
|
||||
|
|
@ -1367,7 +1330,7 @@ private:
|
|||
|
||||
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;
|
||||
|
|
|
|||
|
|
@ -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));
|
||||
|
|
@ -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));
|
||||
|
||||
|
|
|
|||
|
|
@ -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();
|
||||
|
||||
|
|
|
|||
|
|
@ -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)
|
||||
};
|
||||
|
|
|
|||
|
|
@ -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)
|
||||
};
|
||||
|
|
|
|||
|
|
@ -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,10 +246,10 @@ 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;
|
||||
using juce_statStruct = struct stat64;
|
||||
#define JUCE_STAT stat64
|
||||
#else
|
||||
typedef struct stat juce_statStruct;
|
||||
using juce_statStruct = struct stat;
|
||||
#define JUCE_STAT stat
|
||||
#endif
|
||||
|
||||
|
|
@ -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();
|
||||
}
|
||||
|
||||
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)
|
||||
{
|
||||
|
|
|
|||
|
|
@ -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,
|
||||
|
|
|
|||
|
|
@ -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;
|
||||
|
|
|
|||
|
|
@ -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;
|
||||
}
|
||||
|
|
|
|||
|
|
@ -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;
|
||||
|
||||
|
|
|
|||
|
|
@ -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…
Add table
Add a link
Reference in a new issue