@@ -1055,7 +1055,7 @@ struct CoreAudioClasses
10551055
10561056 CoreAudioIODevice& owner;
10571057 int bitDepth = 32 ;
1058- int xruns = 0 ;
1058+ std::atomic< int > xruns { 0 } ;
10591059 Array<double > sampleRates;
10601060 Array<int > bufferSizes;
10611061 AudioDeviceID deviceID;
@@ -1158,12 +1158,12 @@ struct CoreAudioClasses
11581158 {
11591159 auto & intern = *static_cast <CoreAudioInternal*> (inClientData);
11601160
1161- const auto xruns = std::count_if (pa, pa + numAddresses, [] (const AudioObjectPropertyAddress& x)
1161+ const auto xruns = ( int ) std::count_if (pa, pa + numAddresses, [] (const AudioObjectPropertyAddress& x)
11621162 {
11631163 return x.mSelector == kAudioDeviceProcessorOverload ;
11641164 });
11651165
1166- intern.xruns += xruns;
1166+ intern.xruns . fetch_add ( xruns) ;
11671167
11681168 const auto detailsChanged = std::any_of (pa, pa + numAddresses, [] (const AudioObjectPropertyAddress& x)
11691169 {
@@ -1318,7 +1318,7 @@ struct CoreAudioClasses
13181318
13191319 int getCurrentBufferSizeSamples () override { return internal->getBufferSize (); }
13201320
1321- int getXRunCount () const noexcept override { return internal->xruns ; }
1321+ int getXRunCount () const noexcept override { return internal->xruns . load (std::memory_order_relaxed) ; }
13221322
13231323 int getIndexOfDevice (bool asInput) const { return deviceType->getDeviceNames (asInput).indexOf (getName ()); }
13241324
@@ -1341,7 +1341,7 @@ struct CoreAudioClasses
13411341 int bufferSizeSamples) override
13421342 {
13431343 isOpen_ = true ;
1344- internal->xruns = 0 ;
1344+ internal->xruns . store ( 0 ) ;
13451345
13461346 inputChannelsRequested = inputChannels;
13471347 outputChannelsRequested = outputChannels;
@@ -1650,10 +1650,12 @@ struct CoreAudioClasses
16501650 d->close ();
16511651 }
16521652
1653- void restart (AudioIODeviceCallback* cb )
1653+ void restart ( )
16541654 {
16551655 const ScopedLock sl (closeLock);
16561656
1657+ AudioIODeviceCallback* cb = previousCallback;
1658+
16571659 close ();
16581660
16591661 auto newSampleRate = sampleRateRequested;
@@ -1763,22 +1765,22 @@ struct CoreAudioClasses
17631765
17641766 int getXRunCount () const noexcept override
17651767 {
1766- return xruns.load ( );
1768+ return xruns.load (std::memory_order_relaxed );
17671769 }
17681770
17691771 private:
17701772 static constexpr auto invalidSampleTime = std::numeric_limits<std::uint64_t >::max();
17711773
17721774 WeakReference<CoreAudioIODeviceType> owner;
17731775 CriticalSection callbackLock;
1776+ CriticalSection closeLock;
17741777 AudioIODeviceCallback* callback = nullptr ;
17751778 AudioIODeviceCallback* previousCallback = nullptr ;
17761779 double currentSampleRate = 0 ;
17771780 int currentBufferSize = 0 ;
17781781 bool active = false ;
17791782 String lastError;
17801783 AudioSampleBuffer fifo, scratchBuffer;
1781- CriticalSection closeLock;
17821784 int targetLatency = 0 ;
17831785 std::atomic<int > xruns { -1 };
17841786 std::atomic<uint64_t > lastValidReadPosition { invalidSampleTime };
@@ -1791,7 +1793,7 @@ struct CoreAudioClasses
17911793 {
17921794 stopTimer ();
17931795
1794- restart (previousCallback );
1796+ restart ( );
17951797 }
17961798
17971799 void shutdown (const String& error)
@@ -1965,7 +1967,7 @@ struct CoreAudioClasses
19651967 for (auto & d : getDeviceWrappers ())
19661968 d->sampleTime .store (invalidSampleTime);
19671969
1968- ++ xruns;
1970+ xruns. fetch_add ( 1 ) ;
19691971 }
19701972
19711973 void handleAudioDeviceAboutToStart (AudioIODevice* device)
@@ -2132,8 +2134,7 @@ struct CoreAudioClasses
21322134 };
21332135
21342136 /* If the current AudioIODeviceCombiner::callback is nullptr, it sets itself as the callback
2135- and forwards error related callbacks to the provided callback
2136- */
2137+ and forwards error related callbacks to the provided callback. */
21372138 class ScopedErrorForwarder final : public AudioIODeviceCallback
21382139 {
21392140 public:
0 commit comments