Skip to content
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
81 changes: 42 additions & 39 deletions src/framework/audio/engine/internal/enginerpccontroller.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -188,60 +188,63 @@ void EngineRpcController::init()
channel()->addReceiveStream(StreamName::PlaybackDataMainStream, mainStreamId, playbackData.mainStream, mainExec);
channel()->addReceiveStream(StreamName::PlaybackDataOffStream, offStreamId, playbackData.offStream, offExec);

auto addTrackAndSendResponce = [this](const Msg& msg, const TrackSequenceId& seqId, const TrackName& trackName,
auto addTrackAndSendResponse = [this](const Msg& msg, const TrackSequenceId& seqId, const TrackName& trackName,
const mpe::PlaybackData& playbackData, const AudioParams& params) {
RetVal2<TrackId, AudioParams> ret = playback()->addTrack(seqId, trackName, playbackData, params);
channel()->send(rpc::make_response(msg, RpcPacker::pack(ret)));
};

AudioResourceType resourceType = params.in.resourceMeta.type;

// Not Fluid
if (resourceType != AudioResourceType::FluidSoundfont) {
addTrackAndSendResponce(msg, seqId, trackName, playbackData, params);
addTrackAndSendResponse(msg, seqId, trackName, playbackData, params);
return;
}
// Fluid
else {
std::string sfname = params.in.resourceMeta.attributeVal(synth::SOUNDFONT_NAME_ATTRIBUTE).toStdString();
if (sfname.empty()) {
sfname = params.in.resourceMeta.id;
}

if (soundFontRepository()->isSoundFontLoaded(sfname)) {
addTrackAndSendResponce(msg, seqId, trackName, playbackData, params);
}
// Waiting for SF to load
else {
LOGI() << "Waiting for SF to load, trackName: " << trackName << ", SF name: " << sfname;
m_pendingTracks[sfname].emplace_back(PendingTrack { msg, seqId, trackName, playbackData, params });

//! NOTE We subscribe for the first track for which a soundfont is not found.
//! When the notification is triggered, processing will be called for all tracks.
if (!m_soundFontsChangedSubscribed) {
m_soundFontsChangedSubscribed = true;
soundFontRepository()->soundFontsChanged().onNotify(this,
[this, addTrackAndSendResponce]() {
std::vector<std::string> toRemove;
for (auto& p : m_pendingTracks) {
const std::string& sfname = p.first;
if (soundFontRepository()->isSoundFontLoaded(sfname)) {
for (const PendingTrack& t : p.second) {
addTrackAndSendResponce(t.msg, t.seqId, t.trackName, t.playbackData, t.params);
}
toRemove.push_back(sfname);
// Fluid
std::string sfname = params.in.resourceMeta.attributeVal(synth::SOUNDFONT_NAME_ATTRIBUTE).toStdString();
if (sfname.empty()) {
sfname = params.in.resourceMeta.id;
}

if (soundFontRepository()->isSoundFontLoaded(sfname)) {
addTrackAndSendResponse(msg, seqId, trackName, playbackData, params);
}
// Waiting for SF to load
else if (soundFontRepository()->isLoadingSoundFonts()) {
LOGI() << "Waiting for SF to load, trackName: " << trackName << ", SF name: " << sfname;
m_pendingTracks[sfname].emplace_back(PendingTrack { msg, seqId, trackName, playbackData, params });

//! NOTE We subscribe for the first track for which a soundfont is not found.
//! When the notification is triggered, processing will be called for all tracks.
if (!m_soundFontsChangedSubscribed) {
m_soundFontsChangedSubscribed = true;
soundFontRepository()->soundFontsChanged().onNotify(this,
[this, addTrackAndSendResponse]() {
std::vector<std::string> toRemove;
for (auto& p : m_pendingTracks) {
const std::string& sfname = p.first;
if (soundFontRepository()->isSoundFontLoaded(sfname)) {
for (const PendingTrack& t : p.second) {
addTrackAndSendResponse(t.msg, t.seqId, t.trackName, t.playbackData, t.params);
}
toRemove.push_back(sfname);
}
}

for (const std::string& sf : toRemove) {
m_pendingTracks.erase(sf);
}
for (const std::string& sf : toRemove) {
m_pendingTracks.erase(sf);
}

if (m_pendingTracks.empty()) {
soundFontRepository()->soundFontsChanged().disconnect(this);
m_soundFontsChangedSubscribed = false;
}
});
}
if (m_pendingTracks.empty()) {
soundFontRepository()->soundFontsChanged().disconnect(this);
m_soundFontsChangedSubscribed = false;
}
});
}
} else { // Attempt to add it anyway (most likely fallback will be used)
addTrackAndSendResponse(msg, seqId, trackName, playbackData, params);
}
});

Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -24,6 +24,8 @@

#include "audio/common/audiosanitizer.h"

#include "audio/engine/internal/codecs/vorbisdecoder.h"

#include "log.h"

using namespace muse::audio;
Expand All @@ -36,13 +38,21 @@ FluidResolver::FluidResolver(const modularity::ContextPtr& iocCtx)
{
ONLY_AUDIO_ENGINE_THREAD;

fluid::FluidVorbisDecoder::decoder = new codec::VorbisDecoder();

soundFontRepository()->soundFontsChanged().onNotify(this, [this]() {
refresh();
});

refresh();
}

FluidResolver::~FluidResolver()
{
delete fluid::FluidVorbisDecoder::decoder;
fluid::FluidVorbisDecoder::decoder = nullptr;
}

ISynthesizerPtr FluidResolver::resolveSynth(const TrackId /*trackId*/, const AudioInputParams& params, const OutputSpec& spec) const
{
ONLY_AUDIO_ENGINE_THREAD;
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -41,6 +41,7 @@ class FluidResolver : public ISynthResolver::IResolver, public muse::Contextable

public:
explicit FluidResolver(const muse::modularity::ContextPtr& iocCtx = nullptr);
~FluidResolver() override;

ISynthesizerPtr resolveSynth(const audio::TrackId trackId, const audio::AudioInputParams& params,
const OutputSpec& spec) const override;
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -27,12 +27,9 @@
#include "audio/common/audioerrors.h"
#include "audio/common/audiotypes.h"

#include "audio/engine/internal/codecs/vorbisdecoder.h"

#include "sfcachedloader.h"

#include "log.h"
#include "thirdparty/fluidsynth/vorbis_decode.h"

using namespace muse;
using namespace muse::midi;
Expand Down Expand Up @@ -67,18 +64,9 @@ FluidSynth::FluidSynth(const AudioSourceParams& params, const modularity::Contex
: AbstractSynthesizer(params, iocCtx)
{
m_fluid = std::make_shared<Fluid>();

fluid::FluidVorbisDecoder::decoder = new codec::VorbisDecoder();

m_midiOutPort = midiOutPort();
}

FluidSynth::~FluidSynth()
{
delete fluid::FluidVorbisDecoder::decoder;
fluid::FluidVorbisDecoder::decoder = nullptr;
}

bool FluidSynth::isValid() const
{
return m_fluid->synth != nullptr;
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -43,7 +43,6 @@ class FluidSynth : public AbstractSynthesizer

public:
FluidSynth(const audio::AudioSourceParams& params, const modularity::ContextPtr& iocCtx);
~FluidSynth();

Ret init(const OutputSpec& spec);
Ret addSoundFonts(const std::vector<io::path_t>& sfonts);
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -47,6 +47,12 @@ bool SoundFontRepository::isSoundFontLoaded(const std::string& name) const
return false;
}

bool SoundFontRepository::isLoadingSoundFonts() const
{
ONLY_AUDIO_ENGINE_THREAD;
return m_loadingSoundFontCount > 0;
}

const SoundFontsMap& SoundFontRepository::soundFonts() const
{
ONLY_AUDIO_ENGINE_THREAD;
Expand All @@ -62,7 +68,10 @@ Notification SoundFontRepository::soundFontsChanged() const
void SoundFontRepository::addSoundFont(const SoundFontUri& uri)
{
ONLY_AUDIO_ENGINE_THREAD;

m_loadingSoundFontCount++;
doAddSoundFont(uri, nullptr, [this]() {
--m_loadingSoundFontCount;
m_soundFontsChanged.notify();
});
}
Expand Down Expand Up @@ -171,14 +180,15 @@ void SoundFontRepository::loadSoundFonts(const std::vector<SoundFontUri>& uris)
SoundFontsMap* cache = new SoundFontsMap();
m_soundFonts.swap(*cache);

size_t total = uris.size();
size_t count = 0;
m_loadingSoundFontCount = m_loadingSoundFontCount + uris.size();
const size_t total = m_loadingSoundFontCount;

for (const SoundFontUri& uri : uris) {
LOGI() << "try add sound font: " << uri.toString();
doAddSoundFont(uri, cache, [this, &count, total, cache]() {
++count;
LOGI() << "added: " << count << ", total: " << total;
if (count == total) {
doAddSoundFont(uri, cache, [this, total, cache]() {
--m_loadingSoundFontCount;
LOGI() << "remaining: " << m_loadingSoundFontCount << ", total: " << total;
if (m_loadingSoundFontCount == 0) {
delete cache;
m_soundFontsChanged.notify();
LOGI() << "all added notify about sound fonts changed";
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -19,32 +19,31 @@
* You should have received a copy of the GNU General Public License
* along with this program. If not, see <https://www.gnu.org/licenses/>.
*/
#ifndef MUSE_AUDIO_SOUNDFONTREPOSITORY_H
#define MUSE_AUDIO_SOUNDFONTREPOSITORY_H

#include "../../isoundfontrepository.h"
#pragma once

#include "audio/engine/isoundfontrepository.h"

namespace muse::audio::synth {
class SoundFontRepository : public ISoundFontRepository
{
public:
SoundFontRepository() = default;

void loadSoundFonts(const std::vector<SoundFontUri>& uris) override;
void addSoundFont(const SoundFontUri& uri) override;
void addSoundFontData(const SoundFontUri& uri, const ByteArray& data) override;

bool isSoundFontLoaded(const std::string& name) const override;
bool isLoadingSoundFonts() const override;

const SoundFontsMap& soundFonts() const override;
async::Notification soundFontsChanged() const override;

private:

void doAddSoundFont(const SoundFontUri& uri, const SoundFontsMap* cache = nullptr, std::function<void()> onFinished = nullptr);

SoundFontsMap m_soundFonts;
async::Notification m_soundFontsChanged;

size_t m_loadingSoundFontCount = 0;
};
}

#endif // MUSE_AUDIO_SOUNDFONTREPOSITORY_H
8 changes: 4 additions & 4 deletions src/framework/audio/engine/isoundfontrepository.h
Original file line number Diff line number Diff line change
Expand Up @@ -19,8 +19,8 @@
* You should have received a copy of the GNU General Public License
* along with this program. If not, see <https://www.gnu.org/licenses/>.
*/
#ifndef MUSE_AUDIO_ISOUNDFONTREPOSITORY_H
#define MUSE_AUDIO_ISOUNDFONTREPOSITORY_H

#pragma once

#include "modularity/imoduleinterface.h"

Expand All @@ -41,9 +41,9 @@ class ISoundFontRepository : MODULE_CONTEXT_INTERFACE
virtual void addSoundFontData(const SoundFontUri& uri, const ByteArray& data) = 0;

virtual bool isSoundFontLoaded(const std::string& name) const = 0;
virtual bool isLoadingSoundFonts() const = 0;

virtual const SoundFontsMap& soundFonts() const = 0;
virtual async::Notification soundFontsChanged() const = 0;
};
}

#endif // MUSE_AUDIO_ISOUNDFONTREPOSITORY_H
Loading