Skip to content
Open
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
8 changes: 8 additions & 0 deletions src/framework/audio/common/audiotypes.h
Original file line number Diff line number Diff line change
Expand Up @@ -578,3 +578,11 @@ struct TransportEvent {
};
using TransportEvents = std::vector<TransportEvent>;
}

inline muse::logger::Stream& operator<<(muse::logger::Stream& s, const muse::audio::OutputSpec& spec)
{
s << "sampleRate: " << spec.sampleRate
<< ", channels: " << spec.audioChannelCount
<< ", samplesPerChannel: " << spec.samplesPerChannel;
return s;
}
8 changes: 8 additions & 0 deletions src/framework/audio/iaudiodriver.h
Original file line number Diff line number Diff line change
Expand Up @@ -28,6 +28,7 @@
#include <memory>

#include "global/async/notification.h"
#include "global/logstream.h"

#include "audio/common/audiotypes.h"

Expand Down Expand Up @@ -67,3 +68,10 @@ class IAudioDriver
};
using IAudioDriverPtr = std::shared_ptr<IAudioDriver>;
}

inline muse::logger::Stream& operator<<(muse::logger::Stream& s, const muse::audio::IAudioDriver::Spec& spec)
{
s << "deviceId: " << spec.deviceId
<< ", " << spec.output;
return s;
}
2 changes: 2 additions & 0 deletions src/framework/audio/main/internal/audioconfiguration.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -63,6 +63,8 @@ void AudioConfiguration::init()
settings()->setDefaultValue(AUDIO_API_KEY, Val("WASAPI"));
#elif defined(Q_OS_LINUX) || defined(Q_OS_FREEBSD)
settings()->setDefaultValue(AUDIO_API_KEY, Val("ALSA"));
#elif defined(Q_OS_MACOS)
settings()->setDefaultValue(AUDIO_API_KEY, Val("CoreAudio"));
#endif
settings()->valueChanged(AUDIO_API_KEY).onReceive(nullptr, [this](const Val&) {
m_currentAudioApiChanged.notify();
Expand Down
31 changes: 23 additions & 8 deletions src/framework/audio/main/internal/audiodrivercontroller.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -177,6 +177,10 @@ void AudioDriverController::setNewDriver(IAudioDriverPtr newDriver)
});

m_audioDriver->activeSpecChanged().onReceive(this, [this](const IAudioDriver::Spec& spec) {
if (spec.isValid()) {
m_lastValidSpec = spec;
}

m_activeSpecChanged.send(spec);

async::Async::call(this, [this, spec]() {
Expand Down Expand Up @@ -259,7 +263,7 @@ bool AudioDriverController::open(const IAudioDriver::Spec& spec, IAudioDriver::S
driver->init();
setNewDriver(driver);

LOGI() << "Trying to open audio driver: " << m_audioDriver->name() << ", device: " << spec.deviceId;
LOGI() << "Trying to open audio driver: " << m_audioDriver->name() << ", " << spec;
bool ok = m_audioDriver->open(spec, activeSpec);
if (!ok) {
// reset to default device
Expand All @@ -274,8 +278,7 @@ bool AudioDriverController::open(const IAudioDriver::Spec& spec, IAudioDriver::S
}

if (ok) {
LOGI() << "Opened audio driver: " << m_audioDriver->name()
<< ", device: " << m_audioDriver->activeSpec().deviceId;
LOGI() << "Opened audio driver: " << m_audioDriver->name() << ", " << m_audioDriver->activeSpec();
} else {
LOGE() << "Failed to open any audio driver, last tried: " << m_audioDriver->name();
}
Expand Down Expand Up @@ -332,15 +335,14 @@ bool AudioDriverController::selectOutputDevice(const AudioDeviceID& deviceId)
}

const IAudioDriver::Spec oldSpec = m_audioDriver->activeSpec();
LOGI() << "Trying to change output device"
<< " from: " << oldSpec.deviceId
<< ", to: " << deviceId;

IAudioDriver::Spec spec;
spec.deviceId = deviceId;
spec.callback = oldSpec.callback;
spec.output = configuration()->desiredOutputSpec();

LOGI() << "Trying to change output device from " << oldSpec << " to " << spec;

m_audioDriver->close();
bool ok = m_audioDriver->open(spec, nullptr);
if (!ok) {
Expand All @@ -364,8 +366,21 @@ void AudioDriverController::handleOutputDeviceChange()
return;
}

// Some drivers reset their internal spec to a blank state after a failed open attempt, so fall
// back to the last spec that was actually confirmed to work
IAudioDriver::Spec spec = m_audioDriver->activeSpec();
LOGI() << "Checking output device: " << spec.deviceId;
if (!spec.isValid()) {
if (m_lastValidSpec.isValid()) {
spec = m_lastValidSpec;
} else {
spec.deviceId = DEFAULT_DEVICE_ID;
spec.output = configuration()->defaultOutputSpec();
spec.callback = m_callback;
}
}

LOGI() << "Reopening output device, " << spec;

m_audioDriver->close();
bool ok = m_audioDriver->open(spec, nullptr);
if (!ok) {
Expand All @@ -375,7 +390,7 @@ void AudioDriverController::handleOutputDeviceChange()
ok = m_audioDriver->open(spec, nullptr);
if (!ok) {
LOGE() << "Failed to reopen default device on " << m_audioDriver->name() << ", switching to default audio driver";
switchToDefaultAudioDriver();
ok = switchToDefaultAudioDriver();
}
}

Expand Down
1 change: 1 addition & 0 deletions src/framework/audio/main/internal/audiodrivercontroller.h
Original file line number Diff line number Diff line change
Expand Up @@ -80,6 +80,7 @@ class AudioDriverController : public IAudioDriverController, public Contextable,

IAudioDriver::Callback m_callback;
IAudioDriverPtr m_audioDriver;
IAudioDriver::Spec m_lastValidSpec;
async::Notification m_currentAudioApiChanged;
async::Notification m_availableOutputDevicesChanged;
async::Channel<IAudioDriver::Spec> m_activeSpecChanged;
Expand Down
Loading