Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

update_samplerate #23954

Merged
merged 5 commits into from
Aug 12, 2024
Merged
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
Original file line number Diff line number Diff line change
Expand Up @@ -44,6 +44,7 @@ void CommonAudioApiConfigurationModel::load()
audioDriver()->outputDeviceChanged().onNotify(this, [this]() {
emit currentDeviceIdChanged();
emit sampleRateChanged();
emit bufferSizeListChanged();
emit bufferSizeChanged();
});

Expand Down
2 changes: 2 additions & 0 deletions src/framework/audio/iaudiodriver.h
Original file line number Diff line number Diff line change
Expand Up @@ -65,6 +65,8 @@ class IAudioDriver : MODULE_EXPORT_INTERFACE
virtual void close() = 0;
virtual bool isOpened() const = 0;

virtual const Spec& activeSpec() const = 0;

virtual AudioDeviceID outputDevice() const = 0;
virtual bool selectOutputDevice(const AudioDeviceID& id) = 0;
virtual bool resetToDefaultOutputDevice() = 0;
Expand Down
27 changes: 22 additions & 5 deletions src/framework/audio/internal/audiooutputdevicecontroller.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -39,7 +39,10 @@ void AudioOutputDeviceController::init()

configuration()->audioOutputDeviceIdChanged().onNotify(this, [this]() {
AudioDeviceID deviceId = configuration()->audioOutputDeviceId();
audioDriver()->selectOutputDevice(deviceId);
bool ok = audioDriver()->selectOutputDevice(deviceId);
if (ok) {
onOutputDeviceChanged();
}
});

configuration()->driverBufferSizeChanged().onNotify(this, [this]() {
Expand Down Expand Up @@ -79,12 +82,26 @@ void AudioOutputDeviceController::checkConnection()
AudioDeviceID currentDeviceId = audioDriver()->outputDevice();
AudioDeviceList devices = audioDriver()->availableOutputDevices();

bool deviceChanged = false;

if (!preferredDeviceId.empty() && preferredDeviceId != currentDeviceId && containsDevice(devices, preferredDeviceId)) {
audioDriver()->selectOutputDevice(preferredDeviceId);
return;
deviceChanged = audioDriver()->selectOutputDevice(preferredDeviceId);
} else if (!containsDevice(devices, currentDeviceId)) {
deviceChanged = audioDriver()->resetToDefaultOutputDevice();
}

if (!containsDevice(devices, currentDeviceId)) {
audioDriver()->resetToDefaultOutputDevice();
if (deviceChanged) {
onOutputDeviceChanged();
}
}

void AudioOutputDeviceController::onOutputDeviceChanged()
{
IAudioDriver::Spec activeSpec = audioDriver()->activeSpec();

async::Async::call(this, [this, activeSpec]() {
audioEngine()->setAudioChannelsCount(activeSpec.channels);
audioEngine()->setSampleRate(activeSpec.sampleRate);
audioEngine()->setReadBufferSize(activeSpec.samples);
}, AudioThread::ID);
}
3 changes: 1 addition & 2 deletions src/framework/audio/internal/audiooutputdevicecontroller.h
Original file line number Diff line number Diff line change
Expand Up @@ -45,8 +45,7 @@ class AudioOutputDeviceController : public Injectable, public async::Asyncable

private:
void checkConnection();

void connectCurrentOutputDevice();
void onOutputDeviceChanged();
};
}

Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -192,6 +192,11 @@ bool JackAudioDriver::isOpened() const
return s_jackData != nullptr;
}

const JackAudioDriver::Spec& JackAudioDriver::activeSpec() const
{
return s_format2;
}

AudioDeviceID JackAudioDriver::outputDevice() const
{
return m_deviceId;
Expand Down
2 changes: 2 additions & 0 deletions src/framework/audio/internal/platform/jack/jackaudiodriver.h
Original file line number Diff line number Diff line change
Expand Up @@ -46,6 +46,8 @@ class JackAudioDriver : public IAudioDriver, public async::Asyncable
void close() override;
bool isOpened() const override;

const Spec& activeSpec() const override;

AudioDeviceID outputDevice() const override;
bool selectOutputDevice(const AudioDeviceID& deviceId) override;
bool resetToDefaultOutputDevice() override;
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -207,6 +207,11 @@ bool LinuxAudioDriver::isOpened() const
return s_alsaData != nullptr;
}

const LinuxAudioDriver::Spec& LinuxAudioDriver::activeSpec() const
{
return s_format;
}

AudioDeviceID LinuxAudioDriver::outputDevice() const
{
return m_deviceId;
Expand Down
2 changes: 2 additions & 0 deletions src/framework/audio/internal/platform/lin/linuxaudiodriver.h
Original file line number Diff line number Diff line change
Expand Up @@ -43,6 +43,8 @@ class LinuxAudioDriver : public IAudioDriver, public async::Asyncable
void close() override;
bool isOpened() const override;

const Spec& activeSpec() const override;

AudioDeviceID outputDevice() const override;
bool selectOutputDevice(const AudioDeviceID& deviceId) override;
bool resetToDefaultOutputDevice() override;
Expand Down
8 changes: 3 additions & 5 deletions src/framework/audio/internal/platform/osx/osxaudiodriver.h
Original file line number Diff line number Diff line change
Expand Up @@ -28,9 +28,6 @@

#include <MacTypes.h>

#include "global/modularity/ioc.h"
#include "iaudioconfiguration.h"

#include "iaudiodriver.h"

struct AudioTimeStamp;
Expand All @@ -40,8 +37,6 @@ struct OpaqueAudioQueue;
namespace muse::audio {
class OSXAudioDriver : public IAudioDriver
{
INJECT(IAudioConfiguration, configuration)

public:
OSXAudioDriver();
~OSXAudioDriver();
Expand All @@ -52,6 +47,9 @@ class OSXAudioDriver : public IAudioDriver
bool open(const Spec& spec, Spec* activeSpec) override;
void close() override;
bool isOpened() const override;

const Spec& activeSpec() const override;

void resume() override;
void suspend() override;

Expand Down
7 changes: 5 additions & 2 deletions src/framework/audio/internal/platform/osx/osxaudiodriver.mm
Original file line number Diff line number Diff line change
Expand Up @@ -26,8 +26,6 @@

#include <AudioToolbox/AudioToolbox.h>

#include <QTimer>

#include "translation.h"
#include "log.h"

Expand Down Expand Up @@ -185,6 +183,11 @@
return m_data->audioQueue != nullptr;
}

const OSXAudioDriver::Spec& OSXAudioDriver::activeSpec() const
{
return m_data->format;
}

AudioDeviceList OSXAudioDriver::availableOutputDevices() const
{
std::lock_guard lock(m_devicesMutex);
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -166,6 +166,11 @@ bool WasapiAudioDriver::isOpened() const
return m_isOpened;
}

const WasapiAudioDriver::Spec& WasapiAudioDriver::activeSpec() const
{
return m_activeSpec;
}

AudioDeviceID WasapiAudioDriver::outputDevice() const
{
return m_deviceId;
Expand Down
6 changes: 6 additions & 0 deletions src/framework/audio/internal/platform/win/wasapiaudiodriver.h
Original file line number Diff line number Diff line change
Expand Up @@ -37,20 +37,26 @@ class WasapiAudioDriver : public IAudioDriver, public async::Asyncable
WasapiAudioDriver();

void init() override;

std::string name() const override;
bool open(const Spec& spec, Spec* activeSpec) override;
void close() override;
bool isOpened() const override;

const Spec& activeSpec() const override;

AudioDeviceID outputDevice() const override;
bool selectOutputDevice(const AudioDeviceID& id) override;
bool resetToDefaultOutputDevice() override;
async::Notification outputDeviceChanged() const override;

AudioDeviceList availableOutputDevices() const override;
async::Notification availableOutputDevicesChanged() const override;

unsigned int outputDeviceBufferSize() const override;
bool setOutputDeviceBufferSize(unsigned int bufferSize) override;
async::Notification outputDeviceBufferSizeChanged() const override;

std::vector<unsigned int> availableOutputDeviceBufferSizes() const override;

unsigned int outputDeviceSampleRate() const override;
Expand Down
4 changes: 2 additions & 2 deletions src/framework/audio/internal/worker/audioengine.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -88,7 +88,7 @@ sample_rate_t AudioEngine::sampleRate() const
return m_sampleRate;
}

void AudioEngine::setSampleRate(sample_rate_t sampleRate)
void AudioEngine::setSampleRate(const sample_rate_t sampleRate)
{
ONLY_AUDIO_WORKER_THREAD;

Expand All @@ -108,7 +108,7 @@ void AudioEngine::setSampleRate(sample_rate_t sampleRate)
}
}

void AudioEngine::setReadBufferSize(uint16_t readBufferSize)
void AudioEngine::setReadBufferSize(const uint16_t readBufferSize)
{
ONLY_AUDIO_WORKER_THREAD;

Expand Down
6 changes: 3 additions & 3 deletions src/framework/audio/internal/worker/audioengine.h
Original file line number Diff line number Diff line change
Expand Up @@ -53,9 +53,9 @@ class AudioEngine : public IAudioEngine, public Injectable, public async::Asynca

sample_rate_t sampleRate() const override;

void setSampleRate(sample_rate_t sampleRate) override;
void setReadBufferSize(uint16_t readBufferSize) override;
void setAudioChannelsCount(const audioch_t count);
void setSampleRate(const sample_rate_t sampleRate) override;
void setReadBufferSize(const uint16_t readBufferSize) override;
void setAudioChannelsCount(const audioch_t count) override;

RenderMode mode() const override;
void setMode(const RenderMode newMode) override;
Expand Down
5 changes: 3 additions & 2 deletions src/framework/audio/internal/worker/iaudioengine.h
Original file line number Diff line number Diff line change
Expand Up @@ -38,8 +38,9 @@ class IAudioEngine : MODULE_EXPORT_INTERFACE

virtual sample_rate_t sampleRate() const = 0;

virtual void setSampleRate(sample_rate_t sampleRate) = 0;
virtual void setReadBufferSize(uint16_t readBufferSize) = 0;
virtual void setSampleRate(const sample_rate_t sampleRate) = 0;
virtual void setReadBufferSize(const uint16_t readBufferSize) = 0;
virtual void setAudioChannelsCount(const audioch_t count) = 0;

virtual RenderMode mode() const = 0;
virtual void setMode(const RenderMode newMode) = 0;
Expand Down
8 changes: 8 additions & 0 deletions src/framework/audio/internal/worker/mixer.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -162,6 +162,14 @@ void Mixer::setSampleRate(unsigned int sampleRate)
for (auto& channel : m_trackChannels) {
channel.second->setSampleRate(sampleRate);
}

for (AuxChannelInfo& aux : m_auxChannelInfoList) {
aux.channel->setSampleRate(sampleRate);
}

for (IFxProcessorPtr& fx : m_masterFxProcessors) {
fx->setSampleRate(sampleRate);
}
}

unsigned int Mixer::audioChannelsCount() const
Expand Down
7 changes: 7 additions & 0 deletions src/framework/musesampler/internal/libhandler.h
Original file line number Diff line number Diff line change
Expand Up @@ -167,6 +167,7 @@ struct MuseSamplerLibHandler
int versionMinor = getVersionMinor();

bool at_least_v_0_100 = (versionMajor == 0 && versionMinor >= 100) || versionMajor > 0;
m_supportsReinit = at_least_v_0_100;

containsInstrument = (ms_contains_instrument)muse::getLibFunc(m_lib, "ms_contains_instrument");
getMatchingInstrumentId = (ms_get_matching_instrument_id)muse::getLibFunc(m_lib, "ms_get_matching_instrument_id");
Expand Down Expand Up @@ -388,6 +389,11 @@ struct MuseSamplerLibHandler
&& allNotesOff;
}

bool supportsReinit() const
{
return m_supportsReinit;
}

private:
void printApiStatus() const
{
Expand Down Expand Up @@ -448,6 +454,7 @@ struct MuseSamplerLibHandler
}

MuseSamplerLib m_lib = nullptr;
bool m_supportsReinit = false;
};

using MuseSamplerLibHandlerPtr = std::shared_ptr<MuseSamplerLibHandler>;
Expand Down
50 changes: 37 additions & 13 deletions src/framework/musesampler/internal/musesamplerwrapper.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -58,24 +58,21 @@ MuseSamplerWrapper::~MuseSamplerWrapper()

void MuseSamplerWrapper::setSampleRate(unsigned int sampleRate)
{
m_sampleRate = sampleRate;

if (!m_sampler) {
m_sampler = m_samplerLib->create();

samples_t defaultSize = config()->samplesToPreallocate();
const bool isOffline = currentRenderMode() == RenderMode::OfflineMode;
const bool shouldUpdateSampleRate = m_samplerSampleRate != sampleRate && !isOffline;

if (!m_samplerLib->initSampler(m_sampler, m_sampleRate, defaultSize, AUDIO_CHANNELS_COUNT)) {
LOGE() << "Unable to init MuseSampler";
if (!m_sampler || shouldUpdateSampleRate) {
if (!initSampler(sampleRate, config()->samplesToPreallocate())) {
return;
} else {
LOGD() << "Successfully initialized sampler";
}

prepareOutputBuffer(defaultSize);
m_samplerSampleRate = sampleRate;
}

if (currentRenderMode() == RenderMode::OfflineMode) {
m_sampleRate = sampleRate;

if (isOffline) {
LOGD() << "Start offline mode, sampleRate: " << m_sampleRate;
m_samplerLib->startOfflineMode(m_sampler, m_sampleRate);
m_offlineModeStarted = true;
}
Expand Down Expand Up @@ -262,6 +259,33 @@ void MuseSamplerWrapper::setIsActive(bool arg)
}
}

bool MuseSamplerWrapper::initSampler(const sample_rate_t sampleRate, const samples_t blockSize)
{
TRACEFUNC;

const bool isFirstInit = m_sampler == nullptr;

if (isFirstInit) {
m_sampler = m_samplerLib->create();
IF_ASSERT_FAILED(m_sampler) {
return false;
}
}

if (isFirstInit || m_samplerLib->supportsReinit()) {
if (!m_samplerLib->initSampler(m_sampler, sampleRate, blockSize, AUDIO_CHANNELS_COUNT)) {
LOGE() << "Unable to init MuseSampler";
return false;
} else {
LOGD() << "Successfully initialized sampler, sampleRate: " << sampleRate << ", blockSize: " << blockSize;
}
}

prepareOutputBuffer(blockSize);

return true;
}

InstrumentInfo MuseSamplerWrapper::resolveInstrument(const mpe::PlaybackSetupData& setupData) const
{
IF_ASSERT_FAILED(m_samplerLib) {
Expand Down Expand Up @@ -316,7 +340,7 @@ std::string MuseSamplerWrapper::resolveDefaultPresetCode(const InstrumentInfo& i
return std::string();
}

void MuseSamplerWrapper::prepareOutputBuffer(const muse::audio::samples_t samples)
void MuseSamplerWrapper::prepareOutputBuffer(const samples_t samples)
{
if (m_leftChannel.size() < samples) {
m_leftChannel.resize(samples, 0.f);
Expand Down
3 changes: 3 additions & 0 deletions src/framework/musesampler/internal/musesamplerwrapper.h
Original file line number Diff line number Diff line change
Expand Up @@ -70,6 +70,8 @@ class MuseSamplerWrapper : public muse::audio::synth::AbstractSynthesizer, publi
bool isActive() const override;
void setIsActive(bool arg) override;

bool initSampler(const muse::audio::sample_rate_t sampleRate, const muse::audio::samples_t blockSize);

InstrumentInfo resolveInstrument(const mpe::PlaybackSetupData& setupData) const;
std::string resolveDefaultPresetCode(const InstrumentInfo& instrument) const;

Expand All @@ -87,6 +89,7 @@ class MuseSamplerWrapper : public muse::audio::synth::AbstractSynthesizer, publi
ms_OutputBuffer m_bus;

muse::audio::samples_t m_currentPosition = 0;
muse::audio::sample_rate_t m_samplerSampleRate = 0;

std::vector<float> m_leftChannel;
std::vector<float> m_rightChannel;
Expand Down
6 changes: 6 additions & 0 deletions src/framework/stubs/audio/audiodriverstub.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -47,6 +47,12 @@ bool AudioDriverStub::isOpened() const
return false;
}

const AudioDriverStub::Spec& AudioDriverStub::activeSpec() const
{
static IAudioDriver::Spec dummySpec;
return dummySpec;
}

std::string AudioDriverStub::outputDevice() const
{
return std::string();
Expand Down
Loading