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
1 change: 0 additions & 1 deletion src/framework/audio/common/audiotypes.h
Original file line number Diff line number Diff line change
Expand Up @@ -80,7 +80,6 @@ static constexpr samples_t MINIMUM_BUFFER_SIZE = 128;
#endif

static constexpr samples_t MAXIMUM_BUFFER_SIZE = 4096;
static constexpr samples_t DEFAULT_BUFFER_SIZE = 1024;

struct OutputSpec {
sample_rate_t sampleRate = 0;
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -592,9 +592,7 @@ void AsioAudioDriver::reset()
return;
}

Spec spec = s_adata.activeSpec;
close();
open(spec, nullptr);
m_availableOutputDevicesChanged.notify();
}

bool AsioAudioDriver::isOpened() const
Expand Down
1 change: 1 addition & 0 deletions src/framework/audio/main/iaudioconfiguration.h
Original file line number Diff line number Diff line change
Expand Up @@ -58,6 +58,7 @@ class IAudioConfiguration : MODULE_GLOBAL_INTERFACE
virtual void setSampleRate(unsigned int sampleRate) = 0;
virtual async::Notification sampleRateChanged() const = 0;

virtual OutputSpec defaultOutputSpec() const = 0;
virtual OutputSpec desiredOutputSpec() const = 0;

// synthesizers
Expand Down
17 changes: 14 additions & 3 deletions src/framework/audio/main/internal/audioconfiguration.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -36,7 +36,9 @@ using namespace muse;
using namespace muse::audio;
using namespace muse::audio::synth;

static const audioch_t AUDIO_CHANNELS = 2;
static constexpr audioch_t AUDIO_CHANNELS = 2;
static constexpr samples_t DEFAULT_BUFFER_SIZE = 1024;
static constexpr sample_rate_t DEFAULT_SAMPLE_RATE = 44100;

//TODO: add other setting: audio device etc
static const Settings::Key AUDIO_API_KEY("audio", "io/audioApi");
Expand All @@ -51,7 +53,7 @@ static const Settings::Key USER_SOUNDFONTS_PATHS("midi", "application/paths/mySo

void AudioConfiguration::init()
{
settings()->setDefaultValue(AUDIO_BUFFER_SIZE_KEY, Val(1024));
settings()->setDefaultValue(AUDIO_BUFFER_SIZE_KEY, Val(static_cast<int>(DEFAULT_BUFFER_SIZE)));
settings()->valueChanged(AUDIO_BUFFER_SIZE_KEY).onReceive(nullptr, [this](const Val&) {
m_driverBufferSizeChanged.notify();
});
Expand All @@ -70,7 +72,7 @@ void AudioConfiguration::init()
m_audioOutputDeviceIdChanged.notify();
});

settings()->setDefaultValue(AUDIO_SAMPLE_RATE_KEY, Val(44100));
settings()->setDefaultValue(AUDIO_SAMPLE_RATE_KEY, Val(static_cast<int>(DEFAULT_SAMPLE_RATE)));
settings()->setCanBeManuallyEdited(AUDIO_SAMPLE_RATE_KEY, false, Val(44100), Val(192000));
settings()->valueChanged(AUDIO_SAMPLE_RATE_KEY).onReceive(nullptr, [this](const Val&) {
m_driverSampleRateChanged.notify();
Expand Down Expand Up @@ -176,6 +178,15 @@ async::Notification AudioConfiguration::sampleRateChanged() const
return m_driverSampleRateChanged;
}

OutputSpec AudioConfiguration::defaultOutputSpec() const
{
OutputSpec spec;
spec.sampleRate = DEFAULT_SAMPLE_RATE;
spec.samplesPerChannel = DEFAULT_BUFFER_SIZE;
spec.audioChannelCount = AUDIO_CHANNELS;
return spec;
}
Comment thread
RomanPudashkin marked this conversation as resolved.

OutputSpec AudioConfiguration::desiredOutputSpec() const
{
OutputSpec spec;
Expand Down
1 change: 1 addition & 0 deletions src/framework/audio/main/internal/audioconfiguration.h
Original file line number Diff line number Diff line change
Expand Up @@ -63,6 +63,7 @@ class AudioConfiguration : public IAudioConfiguration, public Contextable
void setSampleRate(unsigned int sampleRate) override;
async::Notification sampleRateChanged() const override;

OutputSpec defaultOutputSpec() const override;
OutputSpec desiredOutputSpec() const override;

io::paths_t soundFontDirectories() const override;
Expand Down
100 changes: 67 additions & 33 deletions src/framework/audio/main/internal/audiodrivercontroller.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -190,16 +190,6 @@ void AudioDriverController::setNewDriver(IAudioDriverPtr newDriver)
}
}

IAudioDriver::Spec AudioDriverController::defaultSpec() const
{
IAudioDriver::Spec spec;
spec.deviceId = m_audioDriver ? m_audioDriver->defaultDevice() : AudioDeviceID();
spec.output.audioChannelCount = 2;
spec.output.sampleRate = 44100;
spec.output.samplesPerChannel = DEFAULT_BUFFER_SIZE;
return spec;
}

std::string AudioDriverController::currentAudioApi() const
{
return configuration()->currentAudioApi();
Expand All @@ -221,12 +211,16 @@ void AudioDriverController::changeCurrentAudioApi(const std::string& name)
LOGI() << "Used audio driver: " << m_audioDriver->name();

// reset to default
IAudioDriver::Spec spec = defaultSpec();
IAudioDriver::Spec spec;
spec.output = configuration()->defaultOutputSpec();
spec.callback = m_callback;

if (!spec.deviceId.empty()) {
if (m_audioDriver && !m_audioDriver->defaultDevice().empty()) {
spec.deviceId = DEFAULT_DEVICE_ID;
m_audioDriver->open(spec, nullptr);
bool ok = m_audioDriver->open(spec, nullptr);
if (!ok) {
LOGE() << "Failed to open audio driver: " << name;
}
} else {
LOGW() << "No devices for " << name;
}
Expand Down Expand Up @@ -263,33 +257,26 @@ 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;
bool ok = m_audioDriver->open(spec, activeSpec);
if (!ok) {
// reset to default device
IAudioDriver::Spec defaultDeviceSpec = spec;
defaultDeviceSpec.deviceId = m_audioDriver->defaultDevice();
LOGW() << "Failed to open device: " << spec.deviceId << ", falling back to default: " << defaultDeviceSpec.deviceId;
ok = m_audioDriver->open(defaultDeviceSpec, activeSpec);
}

if (!ok) {
const std::string defaultAudioApi = configuration()->defaultAudioApi();
if (defaultAudioApi != currentAudioApi) {
IAudioDriverPtr defaultDriver = createDriver(defaultAudioApi);
defaultDriver->init();
setNewDriver(defaultDriver);
// reset to default
IAudioDriver::Spec defSpec = defaultSpec();
defSpec.callback = spec.callback;
ok = m_audioDriver->open(defSpec, activeSpec);
if (ok) {
configuration()->setCurrentAudioApi(defaultAudioApi);
}
}
ok = switchToDefaultAudioDriver(activeSpec);
}

LOGI() << "Used audio driver: " << m_audioDriver->name()
<< ", opened: " << (ok ? "success" : "failed")
<< ", device: " << m_audioDriver->activeSpec().deviceId;
if (ok) {
LOGI() << "Opened audio driver: " << m_audioDriver->name()
<< ", device: " << m_audioDriver->activeSpec().deviceId;
} else {
LOGE() << "Failed to open any audio driver, last tried: " << m_audioDriver->name();
}

return ok;
}
Expand Down Expand Up @@ -355,8 +342,11 @@ bool AudioDriverController::selectOutputDevice(const AudioDeviceID& deviceId)
m_audioDriver->close();
bool ok = m_audioDriver->open(spec, nullptr);
if (!ok) {
LOGE() << "failed select device, return to old: " << oldSpec.deviceId;
m_audioDriver->open(oldSpec, nullptr);
LOGE() << "Failed to select device: " << deviceId << ", returning to: " << oldSpec.deviceId;
bool restored = m_audioDriver->open(oldSpec, nullptr);
if (!restored) {
LOGE() << "Failed to restore previous device: " << oldSpec.deviceId;
}
}
return ok;
}
Expand All @@ -373,15 +363,55 @@ void AudioDriverController::checkOutputDevice()
}

IAudioDriver::Spec spec = m_audioDriver->activeSpec();
LOGI() << "Checking output device: " << spec.deviceId;
m_audioDriver->close();
bool ok = m_audioDriver->open(spec, nullptr);
if (!ok) {
// reset to default device
spec.deviceId = m_audioDriver->defaultDevice();
m_audioDriver->open(spec, nullptr);
LOGW() << "Failed to reopen device: " << spec.deviceId << ", falling back to default";
spec.deviceId = DEFAULT_DEVICE_ID;
ok = m_audioDriver->open(spec, nullptr);
if (!ok) {
LOGE() << "Failed to reopen default device on " << m_audioDriver->name() << ", switching to default audio driver";
switchToDefaultAudioDriver();
}
}
}

bool AudioDriverController::switchToDefaultAudioDriver(IAudioDriver::Spec* activeSpec)
{
const std::string defaultAudioApi = configuration()->defaultAudioApi();
const std::string currentAudioApi = configuration()->currentAudioApi();

if (defaultAudioApi == currentAudioApi) {
LOGE() << "Already on the default audio driver: " << defaultAudioApi << ", cannot fall back further";
return false;
}

LOGW() << "Switching from " << currentAudioApi << " to default audio driver: " << defaultAudioApi;

IAudioDriverPtr defaultDriver = createDriver(defaultAudioApi);
defaultDriver->init();
setNewDriver(defaultDriver);

IAudioDriver::Spec defSpec;
defSpec.deviceId = DEFAULT_DEVICE_ID;
defSpec.output = configuration()->defaultOutputSpec();
defSpec.callback = m_callback;

bool ok = m_audioDriver->open(defSpec, activeSpec);
if (ok) {
configuration()->setCurrentAudioApi(defaultAudioApi);
m_currentAudioApiChanged.notify();
m_availableOutputDevicesChanged.notify();
LOGI() << "Successfully switched to default audio driver: " << defaultAudioApi;
} else {
LOGE() << "Failed to open default audio driver: " << defaultAudioApi;
}

return ok;
}

void AudioDriverController::updateOutputSpec()
{
if (!m_audioDriver->isOpened()) {
Expand Down Expand Up @@ -420,6 +450,8 @@ void AudioDriverController::changeBufferSize(samples_t samples)
updateOutputSpec();
configuration()->setDriverBufferSize(samples);
m_outputDeviceBufferSizeChanged.notify();
} else {
LOGE() << "Failed to change buffer size to: " << samples;
}
}

Expand Down Expand Up @@ -456,6 +488,8 @@ void AudioDriverController::changeSampleRate(sample_rate_t sampleRate)
updateOutputSpec();
configuration()->setSampleRate(sampleRate);
m_outputDeviceSampleRateChanged.notify();
} else {
LOGE() << "Failed to change sample rate to: " << sampleRate;
}
}

Expand Down
3 changes: 1 addition & 2 deletions src/framework/audio/main/internal/audiodrivercontroller.h
Original file line number Diff line number Diff line change
Expand Up @@ -74,9 +74,8 @@ class AudioDriverController : public IAudioDriverController, public Contextable,
IAudioDriverPtr createDriver(const std::string& name) const;
void setNewDriver(IAudioDriverPtr newDriver);

IAudioDriver::Spec defaultSpec() const;

void checkOutputDevice();
bool switchToDefaultAudioDriver(IAudioDriver::Spec* activeSpec = nullptr);
void updateOutputSpec();

IAudioDriver::Callback m_callback;
Expand Down
5 changes: 5 additions & 0 deletions src/framework/stubs/audio/audioconfigurationstub.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -95,6 +95,11 @@ async::Notification AudioConfigurationStub::sampleRateChanged() const
return async::Notification();
}

OutputSpec AudioConfigurationStub::defaultOutputSpec() const
{
return OutputSpec();
}

OutputSpec AudioConfigurationStub::desiredOutputSpec() const
{
return OutputSpec();
Expand Down
1 change: 1 addition & 0 deletions src/framework/stubs/audio/audioconfigurationstub.h
Original file line number Diff line number Diff line change
Expand Up @@ -48,6 +48,7 @@ class AudioConfigurationStub : public IAudioConfiguration
void setSampleRate(unsigned int sampleRate) override;
async::Notification sampleRateChanged() const override;

OutputSpec defaultOutputSpec() const override;
OutputSpec desiredOutputSpec() const override;

// synthesizers
Expand Down
Loading