Skip to content

Commit

Permalink
AudioUnitManager: Replace sleep loop with dispatch group
Browse files Browse the repository at this point in the history
  • Loading branch information
fwcd committed Nov 26, 2024
1 parent 10140c9 commit 8262c36
Show file tree
Hide file tree
Showing 2 changed files with 13 additions and 20 deletions.
1 change: 1 addition & 0 deletions src/effects/backends/audiounit/audiounitmanager.h
Original file line number Diff line number Diff line change
Expand Up @@ -45,6 +45,7 @@ class AudioUnitManager {
private:
QString m_name;
std::atomic<bool> m_isInstantiated;
dispatch_group_t _Nonnull m_instantiationGroup;
AudioUnit _Nullable m_audioUnit;

AudioUnitManager(AVAudioUnitComponent* _Nullable component);
Expand Down
32 changes: 12 additions & 20 deletions src/effects/backends/audiounit/audiounitmanager.mm
Original file line number Diff line number Diff line change
@@ -1,17 +1,17 @@
#import <AVFAudio/AVFAudio.h>
#import <AudioToolbox/AudioToolbox.h>
#include "util/assert.h"
#import <dispatch/dispatch.h>

#include <QElapsedTimer>
#include <QString>
#include <QThread>

#include "effects/backends/audiounit/audiounitmanager.h"
#include "util/assert.h"

AudioUnitManager::AudioUnitManager(AVAudioUnitComponent* _Nullable component)
: m_name(component != nil ? QString::fromNSString([component name])
: "Unknown"),
m_isInstantiated(false) {
m_isInstantiated(false),
m_instantiationGroup(dispatch_group_create()) {
}

AudioUnitManagerPointer AudioUnitManager::create(
Expand Down Expand Up @@ -59,22 +59,11 @@
}

bool AudioUnitManager::waitForAudioUnit(int timeoutMs) const {
// NOTE: We use a sleep loop here since both a QWaitCondition and GCD
// DispatchGroup-based implementation seem to result in spurious crashes.
// See https://github.com/mixxxdj/mixxx/pull/13887#issuecomment-2486459443
// TODO: Debug the precise issue

QElapsedTimer timer;
timer.start();

while (!m_isInstantiated.load()) {
if (timer.elapsed() > timeoutMs) {
return false;
}
QThread::msleep(10);
}

return true;
bool success =
dispatch_group_wait(m_instantiationGroup,
dispatch_time(DISPATCH_TIME_NOW, timeoutMs * 1000000)) == 0;
DEBUG_ASSERT(!success || m_isInstantiated.load());
return success;
}

void AudioUnitManager::instantiateAudioUnitAsync(
Expand All @@ -96,6 +85,8 @@
qDebug() << "Instantiating Audio Unit" << manager->m_name
<< "asynchronously";

dispatch_group_enter(manager->m_instantiationGroup);

// TODO: Fix the weird formatting of blocks
// clang-format off
AudioComponentInstantiate(component.audioComponent, options, ^(AudioUnit _Nullable audioUnit, OSStatus error) {
Expand All @@ -105,6 +96,7 @@
}

manager->initializeWith(audioUnit);
dispatch_group_leave(manager->m_instantiationGroup);
});
// clang-format on
}
Expand Down

0 comments on commit 8262c36

Please sign in to comment.