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
6 changes: 0 additions & 6 deletions CMakeLists.txt
Original file line number Diff line number Diff line change
Expand Up @@ -131,12 +131,6 @@ option(MUE_ENABLE_ENGRAVING_RENDER_DEBUG "Enable rendering debug" OFF)
option(MUE_ENABLE_ENGRAVING_LD_ACCESS "Enable diagnostic engraving check layout data access" OFF)
option(MUE_ENABLE_ENGRAVING_LD_PASSES "Enable engraving layout by passes" OFF)

if (OS_IS_LIN)
option(MUSE_PIPEWIRE_AUDIO_DRIVER "Use PipeWire audio driver" OFF) # Turns ON on CI
elseif (OS_IS_FBSD)
option(MUSE_PIPEWIRE_AUDIO_DRIVER "Use PipeWire audio driver" OFF)
endif()

###########################################
# Setup Configure
###########################################
Expand Down
2 changes: 1 addition & 1 deletion ninja_build.sh
Original file line number Diff line number Diff line change
Expand Up @@ -102,7 +102,7 @@ function do_build() {
-DMUSE_MODULE_GLOBAL_LOGGER_DEBUGLEVEL="${MUSESCORE_DEBUGLEVEL_ENABLED}" \
-DMUSE_MODULE_VST="${MUSESCORE_BUILD_VST_MODULE}" \
-DMUSE_MODULE_NETWORK_WEBSOCKET="${MUSESCORE_BUILD_WEBSOCKET}" \
-DMUSE_PIPEWIRE_AUDIO_DRIVER="${MUSESCORE_BUILD_PIPEWIRE_AUDIO_DRIVER}" \
-DMUSE_MODULE_AUDIO_PIPEWIRE="${MUSESCORE_BUILD_PIPEWIRE_AUDIO_DRIVER}" \
-DCMAKE_SKIP_RPATH="${MUSESCORE_NO_RPATH}" \
-DMUSE_COMPILE_USE_UNITY="${MUSESCORE_COMPILE_USE_UNITY}"

Expand Down
4 changes: 2 additions & 2 deletions src/framework/audio/CMakeLists.txt
Original file line number Diff line number Diff line change
Expand Up @@ -81,7 +81,8 @@ else ()
find_package(ALSA REQUIRED)
set(MODULE_INCLUDE_PRIVATE ${MODULE_INCLUDE_PRIVATE} ${ALSA_INCLUDE_DIRS} )
set(MODULE_LINK ${MODULE_LINK} ${ALSA_LIBRARIES} pthread )
if (MUSE_PIPEWIRE_AUDIO_DRIVER)

if (MUSE_MODULE_AUDIO_PIPEWIRE)
find_package(PkgConfig)
pkg_check_modules(PipeWire libpipewire-0.3)
if (PipeWire_FOUND)
Expand All @@ -92,7 +93,6 @@ else ()
)
set(MODULE_INCLUDE ${MODULE_INCLUDE} ${PipeWire_INCLUDE_DIRS} )
set(MODULE_LINK ${MODULE_LINK} ${PipeWire_LIBRARIES})
set(MODULE_DEF ${MODULE_DEF} -DMUSE_PIPEWIRE_AUDIO_DRIVER)
else()
message(WARNING "Pipewire development files not found.\nPipewire support is disabled from the build.")
endif()
Expand Down
14 changes: 13 additions & 1 deletion src/framework/audio/common/audiotypes.h
Original file line number Diff line number Diff line change
Expand Up @@ -38,6 +38,8 @@

#include "mpe/events.h"

#include "log.h"

namespace muse::audio {
using msecs_t = int64_t;
using secs_t = muse::secs_t;
Expand Down Expand Up @@ -79,6 +81,7 @@ 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 Expand Up @@ -405,7 +408,16 @@ struct AudioSignalsNotifier {
}
}

AudioSignalChanges audioSignalChanges;
//! NOTE It would be nice if the driver callback was called in one thread.
//! But some drivers, for example PipeWire, use queues
//! And then the callback can be called in different threads.
//! If a score is open, we will change the audio API (change the driver)
//! then the number of threads used may increase...
//! Channels allow 10 threads by default. Here we're increasing that to the maximum...
//! If this is not enough, then we need to make sure that the callback is called in one thread,
//! or use something else here instead of channels, some kind of queues.
const int _max_threads = 100;
AudioSignalChanges audioSignalChanges = AudioSignalChanges(_max_threads);

private:
static constexpr volume_dbfs_t PRESSURE_MINIMAL_VALUABLE_DIFF = volume_dbfs_t::make(2.5f);
Expand Down
13 changes: 1 addition & 12 deletions src/framework/audio/driver/audio_driver.cmake
Original file line number Diff line number Diff line change
Expand Up @@ -23,19 +23,8 @@ include(GetPlatformInfo)
if (OS_IS_WIN)

set(AUDIO_DRIVER_SRC
#${CMAKE_CURRENT_LIST_DIR}/platform/win/winmmdriver.cpp
#${CMAKE_CURRENT_LIST_DIR}/platform/win/winmmdriver.h
#${CMAKE_CURRENT_LIST_DIR}/platform/win/wincoreaudiodriver.cpp
#${CMAKE_CURRENT_LIST_DIR}/platform/win/wincoreaudiodriver.h
${CMAKE_CURRENT_LIST_DIR}/platform/win/wasapiaudioclient.cpp
${CMAKE_CURRENT_LIST_DIR}/platform/win/wasapiaudioclient.h
${CMAKE_CURRENT_LIST_DIR}/platform/win/wasapitypes.h
${CMAKE_CURRENT_LIST_DIR}/platform/win/wasapiaudiodriver.cpp
${CMAKE_CURRENT_LIST_DIR}/platform/win/wasapiaudiodriver.h
${CMAKE_CURRENT_LIST_DIR}/platform/win/audiodeviceslistener.cpp
${CMAKE_CURRENT_LIST_DIR}/platform/win/audiodeviceslistener.h
${CMAKE_CURRENT_LIST_DIR}/platform/win/wasapiaudiodriver2.cpp
${CMAKE_CURRENT_LIST_DIR}/platform/win/wasapiaudiodriver2.h
)

if (MUSE_MODULE_AUDIO_ASIO)
Expand All @@ -60,7 +49,7 @@ elseif(OS_IS_LIN OR OS_IS_FBSD)
${CMAKE_CURRENT_LIST_DIR}/platform/lin/audiodeviceslistener.cpp
${CMAKE_CURRENT_LIST_DIR}/platform/lin/audiodeviceslistener.h
)
if (MUSE_PIPEWIRE_AUDIO_DRIVER)
if (MUSE_MODULE_AUDIO_PIPEWIRE)
# this is conditionally added to module source if
# pipewire is actually found on the system
set(PW_AUDIO_DRIVER_SRC
Expand Down
129 changes: 18 additions & 111 deletions src/framework/audio/driver/platform/lin/alsaaudiodriver.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -68,7 +68,7 @@ static void* alsaThread(void* aParam)
uint8_t* stream = (uint8_t*)data->buffer;
int len = data->samples * data->channels * sizeof(float);

data->callback(data->userdata, stream, len);
data->callback(stream, len);

snd_pcm_sframes_t pcm = snd_pcm_writei(data->alsaDeviceHandle, data->buffer, data->samples);
if (pcm != -EPIPE) {
Expand Down Expand Up @@ -107,7 +107,6 @@ static void alsaCleanup()

AlsaAudioDriver::AlsaAudioDriver()
{
m_deviceId = DEFAULT_DEVICE_ID;
}

AlsaAudioDriver::~AlsaAudioDriver()
Expand All @@ -128,21 +127,29 @@ void AlsaAudioDriver::init()

std::string AlsaAudioDriver::name() const
{
return "MUAUDIO(ALSA)";
return "ALSA";
}

AudioDeviceID AlsaAudioDriver::defaultDevice() const
{
return DEFAULT_DEVICE_ID;
}

bool AlsaAudioDriver::open(const Spec& spec, Spec* activeSpec)
{
IF_ASSERT_FAILED(!spec.deviceId.empty()) {
return false;
}

s_alsaData = new ALSAData();
s_alsaData->samples = spec.output.samplesPerChannel;
s_alsaData->channels = spec.output.audioChannelCount;
s_alsaData->callback = spec.callback;
s_alsaData->userdata = spec.userdata;

snd_pcm_t* handle;
int rc = snd_pcm_open(&handle, outputDevice().c_str(), SND_PCM_STREAM_PLAYBACK, 0);
int rc = snd_pcm_open(&handle, spec.deviceId.c_str(), SND_PCM_STREAM_PLAYBACK, 0);
if (rc < 0) {
LOGE() << "Unable to open device: " << outputDevice() << ", err code: " << rc;
LOGE() << "Unable to open device: " << spec.deviceId << ", err code: " << rc;
return false;
}

Expand Down Expand Up @@ -183,7 +190,6 @@ bool AlsaAudioDriver::open(const Spec& spec, Spec* activeSpec)
//_alsaData->sampleBuffer = new short[_alsaData->samples * _alsaData->channels];

s_format = spec;
s_format.format = Format::AudioF32;
s_format.output.sampleRate = aSamplerate;
m_activeSpecChanged.send(s_format);

Expand All @@ -199,7 +205,7 @@ bool AlsaAudioDriver::open(const Spec& spec, Spec* activeSpec)
return false;
}

LOGI() << "Connected to " << outputDevice()
LOGI() << "Connected to " << spec.deviceId
<< " with bufferSize " << s_format.output.samplesPerChannel
<< ", sampleRate " << s_format.output.sampleRate
<< ", channels: " << s_format.output.audioChannelCount;
Expand Down Expand Up @@ -227,43 +233,6 @@ async::Channel<IAudioDriver::Spec> AlsaAudioDriver::activeSpecChanged() const
return m_activeSpecChanged;
}

AudioDeviceID AlsaAudioDriver::outputDevice() const
{
return m_deviceId;
}

bool AlsaAudioDriver::selectOutputDevice(const AudioDeviceID& deviceId)
{
if (m_deviceId == deviceId) {
return true;
}

bool reopen = isOpened();
close();
m_deviceId = deviceId;

bool ok = true;
if (reopen) {
ok = open(s_format, &s_format);
}

if (ok) {
m_outputDeviceChanged.notify();
}

return ok;
}

bool AlsaAudioDriver::resetToDefaultOutputDevice()
{
return selectOutputDevice(DEFAULT_DEVICE_ID);
}

async::Notification AlsaAudioDriver::outputDeviceChanged() const
{
return m_outputDeviceChanged;
}

AudioDeviceList AlsaAudioDriver::availableOutputDevices() const
{
AudioDeviceList devices;
Expand All @@ -277,38 +246,11 @@ async::Notification AlsaAudioDriver::availableOutputDevicesChanged() const
return m_availableOutputDevicesChanged;
}

bool AlsaAudioDriver::setOutputDeviceBufferSize(unsigned int bufferSize)
std::vector<samples_t> AlsaAudioDriver::availableOutputDeviceBufferSizes() const
{
if (s_format.output.samplesPerChannel == bufferSize) {
return true;
}

bool reopen = isOpened();
close();
s_format.output.samplesPerChannel = bufferSize;

bool ok = true;
if (reopen) {
ok = open(s_format, &s_format);
}
std::vector<samples_t> result;

if (ok) {
m_bufferSizeChanged.notify();
}

return ok;
}

async::Notification AlsaAudioDriver::outputDeviceBufferSizeChanged() const
{
return m_bufferSizeChanged;
}

std::vector<unsigned int> AlsaAudioDriver::availableOutputDeviceBufferSizes() const
{
std::vector<unsigned int> result;

unsigned int n = MAXIMUM_BUFFER_SIZE;
samples_t n = MAXIMUM_BUFFER_SIZE;
while (n >= MINIMUM_BUFFER_SIZE) {
result.push_back(n);
n /= 2;
Expand All @@ -319,34 +261,7 @@ std::vector<unsigned int> AlsaAudioDriver::availableOutputDeviceBufferSizes() co
return result;
}

bool AlsaAudioDriver::setOutputDeviceSampleRate(unsigned int sampleRate)
{
if (s_format.output.sampleRate == sampleRate) {
return true;
}

bool reopen = isOpened();
close();
s_format.output.sampleRate = sampleRate;

bool ok = true;
if (reopen) {
ok = open(s_format, &s_format);
}

if (ok) {
m_sampleRateChanged.notify();
}

return ok;
}

async::Notification AlsaAudioDriver::outputDeviceSampleRateChanged() const
{
return m_sampleRateChanged;
}

std::vector<unsigned int> AlsaAudioDriver::availableOutputDeviceSampleRates() const
std::vector<sample_rate_t> AlsaAudioDriver::availableOutputDeviceSampleRates() const
{
// ALSA API is not of any help to get sample rates supported by the driver.
// (snd_pcm_hw_params_get_rate_[min|max] will return 1 to 384000 Hz)
Expand All @@ -358,11 +273,3 @@ std::vector<unsigned int> AlsaAudioDriver::availableOutputDeviceSampleRates() co
96000,
};
}

void AlsaAudioDriver::resume()
{
}

void AlsaAudioDriver::suspend()
{
}
30 changes: 5 additions & 25 deletions src/framework/audio/driver/platform/lin/alsaaudiodriver.h
Original file line number Diff line number Diff line change
Expand Up @@ -38,46 +38,26 @@ class AlsaAudioDriver : public IAudioDriver, public async::Asyncable
void init() override;

std::string name() const override;

AudioDeviceID defaultDevice() const override;

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

const Spec& activeSpec() const override;
async::Channel<Spec> activeSpecChanged() const override;

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

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

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

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

bool setOutputDeviceSampleRate(unsigned int sampleRate) override;
async::Notification outputDeviceSampleRateChanged() const override;

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

void resume() override;
void suspend() override;
std::vector<samples_t> availableOutputDeviceBufferSizes() const override;
std::vector<sample_rate_t> availableOutputDeviceSampleRates() const override;

private:
async::Channel<Spec> m_activeSpecChanged;

async::Notification m_outputDeviceChanged;

mutable std::mutex m_devicesMutex;
AudioDevicesListener m_devicesListener;
async::Notification m_availableOutputDevicesChanged;

std::string m_deviceId;

async::Notification m_bufferSizeChanged;
async::Notification m_sampleRateChanged;
};
}
Loading
Loading