8000 midi: add DLS (DownLoadable Sound) support by T-X · Pull Request #28350 · musescore/MuseScore · GitHub
[go: up one dir, main page]
More Web Proxy on the site http://driver.im/
Skip to content

midi: add DLS (DownLoadable Sound) support #28350

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

Open
wants to merge 7 commits into
base: master
Choose a base branch
from
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: 1 addition & 0 deletions buildscripts/ci/backend/docker/setup.sh
Original file line number Diff line number Diff line change
Expand Up @@ -37,6 +37,7 @@ apt_packages_standard=(
libfreetype6-dev
libfreetype6
libgl1-mesa-dev
libinstpatch-dev
libjack-dev
libmp3lame-dev
libnss3-dev
Expand Down
1 change: 1 addition & 0 deletions buildscripts/ci/linux/setup.sh
Original file line number Diff line number Diff line change
Expand Up @@ -72,6 +72,7 @@ apt_packages=(
libgl1-mesa-dev
libglib2.0-dev
libgpgme-dev # install for appimagetool
libinstpatch-dev
libjack-dev
libnss3-dev
libportmidi-dev
Expand Down
1 change: 1 addition & 0 deletions buildscripts/ci/withoutqt/setup.sh
Original file line number Diff line number Diff line change
Expand Up @@ -62,6 +62,7 @@ apt_packages_standard=(
libfreetype6-dev
libfreetype6
libgl1-mesa-dev
libinstpatch-dev
libjack-dev
libnss3-dev
libportmidi-dev
Expand Down
35 changes: 35 additions & 0 deletions buildscripts/cmake/SetupGlib.cmake
Original file line number Diff line number Diff line change
@@ -0,0 +1,35 @@
include(GetPlatformInfo)

if (OS_IS_WIN AND (NOT MINGW))
# TODO
return()

elseif (OS_IS_WASM)
# TODO
return()

else()
# Use pkg-config to get hints about paths
find_package(PkgConfig)
if(PKG_CONFIG_FOUND)
pkg_check_modules(GLIB_PKGCONF QUIET glib-2.0)
endif()

# Library
find_library(GLIB_LIBRARY
NAMES glib-2.0
PATHS ${GLIB_PKGCONF_LIBDIR}
NO_DEFAULT_PATH
)

if (GLIB_LIBRARY AND GLIB_PKGCONF_INCLUDE_DIRS)
set(GLIB_LIB ${GLIB_LIBRARY})
set(GLIB_INCDIRS ${GLIB_PKGCONF_INCLUDE_DIRS})
endif()
endif()

if (GLIB_INCDIRS)
message(STATUS "Found glib: ${GLIB_LIB}, ${GLIB_INCDIRS}")
else ()
message(FATAL_ERROR "Could not find: glib")
endif ()
35 changes: 35 additions & 0 deletions buildscripts/cmake/SetupGobject.cmake
Original file line number Diff line number Diff line change
@@ -0,0 +1,35 @@
include(GetPlatformInfo)

if (OS_IS_WIN AND (NOT MINGW))
# TODO
return()

elseif (OS_IS_WASM)
# TODO
return()

else()
# Use pkg-config to get hints about paths
find_package(PkgConfig)
if(PKG_CONFIG_FOUND)
pkg_check_modules(GOBJECT_PKGCONF QUIET gobject-2.0)
endif()

# Library
find_library(GOBJECT_LIBRARY
NAMES gobject-2.0
PATHS ${GOBJECT_PKGCONF_LIBDIR}
NO_DEFAULT_PATH
)

if (GOBJECT_LIBRARY AND GOBJECT_PKGCONF_INCLUDE_DIRS)
set(GOBJECT_LIB ${GOBJECT_LIBRARY})
set(GOBJECT_INCDIRS ${GOBJECT_PKGCONF_INCLUDE_DIRS})
endif()
endif()

if (GOBJECT_INCDIRS)
message(STATUS "Found gobject: ${GOBJECT_LIB}, ${GOBJECT_INCDIRS}")
else ()
message(FATAL_ERROR "Could not find: gobject")
endif ()
45 changes: 45 additions & 0 deletions buildscripts/cmake/SetupInstPatch.cmake
Original file line number Diff line number Diff line change
@@ -0,0 +1,45 @@
include(GetPlatformInfo)

if (OS_IS_WIN AND (NOT MINGW))
# TODO
return()

elseif (OS_IS_WASM)
# TODO
return()

else()
# Use pkg-config to get hints about paths
find_package(PkgConfig)
if(PKG_CONFIG_FOUND)
pkg_check_modules(LIBINSTPATCH_PKGCONF QUIET libinstpatch-1.0>=1.1.0)
endif()

# Include dir
find_path(LIBINSTPATCH_INCLUDE_DIR
NAMES libinstpatch/libinstpatch.h
PATHS ${LIBINSTPATCH_PKGCONF_INCLUDEDIR}
NO_DEFAULT_PATH
)

# Library
find_library(LIBINSTPATCH_LIBRARY
NAMES instpatch-1.0 libinstpatch-1.0
PATHS ${LIBINSTPATCH_PKGCONF_LIBDIR}
# On Debian Sid LIBINSTPATCH_PKGCONF_LIBDIR wrongly points to
# /usr/lib64, while the library actually is in /usr/lib/x86_64-linux-gnu
# (default path), therefore not using NO_DEFAULT_PATH
)

if (LIBINSTPATCH_LIBRARY)
set(INSTPATCH_LIB ${LIBINSTPATCH_LIBRARY})
set(INSTPATCH_INCDIR ${LIBINSTPATCH_INCLUDE_DIR})
set(LIBINSTPATCH_SUPPORT 1)
endif()
endif()

if (LIBINSTPATCH_SUPPORT)
message(STATUS "Found instpatch: ${INSTPATCH_LIB} ${INSTPATCH_INCDIR}")
else ()
message(FATAL_ERROR "Could not find: instpatch")
endif ()
5 changes: 5 additions & 0 deletions src/appshell/qml/Preferences/ImportPreferencesPage.qml
Original file line number Diff line number Diff line change
Expand Up @@ -121,6 +121,7 @@ PreferencesPage {
MidiSection {
shortestNotes: importPreferencesModel.shortestNotes()
currentShortestNote: importPreferencesModel.currentShortestNote
channel9isDrum: importPreferencesModel.currentChannel9isDrum

navigation.section: root.navigationSection
navigation.order: root.navigationOrderStart + 4
Expand All @@ -129,6 +130,10 @@ PreferencesPage {
importPreferencesModel.currentShortestNote = note
}

onCurrentChannel9isDrumChangeRequested: function(isDrum) {
importPreferencesModel.currentChannel9isDrum = isDrum
}

onFocusChanged: {
if (activeFocus) {
root.ensureContentVisibleRequested(Qt.rect(x, y, width, height))
Expand Down
17 changes: 17 additions & 0 deletions src/appshell/qml/Preferences/internal/MidiSection.qml
Original file line number Diff line number Diff line change
Expand Up @@ -29,9 +29,11 @@ BaseSection {
title: qsTrc("appshell/preferences", "MIDI")

property alias shortestNotes: shortestNotesBox.model
property alias channel9isDrum: channel9isDrumBox.checked
property int currentShortestNote: 0

signal currentShortestNoteChangeRequested(int note)
signal currentChannel9isDrumChangeRequested(bool isDrum)

ComboBoxWithTitle {
id: shortestNotesBox
Expand All @@ -52,4 +54,19 @@ BaseSection {
root.currentShortestNoteChangeRequested(newValue)
}
}

CheckBox {
id: channel9isDrumBox
width: parent.width

text: qsTrc("appshell/preferences", "Channel 9 is drum")

navigation.name: "Channel9isDrum"
navigation.panel: root.navigation
navigation.row: 1

onClicked: {
root.currentChannel9isDrumChangeRequested(!checked)
}
}
}
19 changes: 19 additions & 0 deletions src/appshell/view/preferences/importpreferencesmodel.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -64,6 +64,10 @@ void ImportPreferencesModel::load()
emit currentShortestNoteChanged(val);
});

midiImportExportConfiguration()->midiChannel9isDrumChanged().onReceive(this, [this](bool isDrum) {
emit currentChannel9isDrumChanged(isDrum);
});

meiConfiguration()->meiImportLayoutChanged().onReceive(this, [this](bool val) {
emit meiImportLayoutChanged(val);
});
Expand Down Expand Up @@ -155,6 +159,11 @@ int ImportPreferencesModel::currentShortestNote() const
return midiImportExportConfiguration()->midiShortestNote();
}

bool ImportPreferencesModel::currentChannel9isDrum() const
{
return midiImportExportConfiguration()->midiChannel9isDrum();
}

bool ImportPreferencesModel::needAskAboutApplyingNewStyle() const
{
return musicXmlConfiguration()->needAskAboutApplyingNewStyle();
Expand Down Expand Up @@ -235,6 +244,16 @@ void ImportPreferencesModel::setCurrentShortestNote(int note)
emit currentShortestNoteChanged(note);
}

void ImportPreferencesModel::setCurrentChannel9isDrum(bool isDrum)
{
if (isDrum == currentChannel9isDrum()) {
return;
}

midiImportExportConfiguration()->setMidiChannel9isDrum(isDrum);
emit currentChannel9isDrumChanged(isDrum);
}

void ImportPreferencesModel::setNeedAskAboutApplyingNewStyle(bool value)
{
if (value == needAskAboutApplyingNewStyle()) {
Expand Down
5 changes: 5 additions & 0 deletions src/appshell/view/preferences/importpreferencesmodel.h
Original file line number Diff line number Diff line change
Expand Up @@ -53,6 +53,8 @@ class ImportPreferencesModel : public QObject, public muse::Injectable, public m

Q_PROPERTY(int currentShortestNote READ currentShortestNote WRITE setCurrentShortestNote NOTIFY currentShortestNoteChanged)

Q_PROPERTY(bool currentChannel9isDrum READ currentChannel9isDrum WRITE setCurrentChannel9isDrum NOTIFY currentChannel9isDrumChanged)

Q_PROPERTY(
bool needAskAboutApplyingNewStyle READ needAskAboutApplyingNewStyle WRITE setNeedAskAboutApplyingNewStyle NOTIFY needAskAboutApplyingNewStyleChanged)

Expand Down Expand Up @@ -83,6 +85,7 @@ class ImportPreferencesModel : public QObject, public muse::Injectable, public m
bool inferTextType() const;

int currentShortestNote() const;
bool currentChannel9isDrum() const;

bool needAskAboutApplyingNewStyle() const;

Expand All @@ -98,6 +101,7 @@ public slots:
void setInferTextType(bool value);

void setCurrentShortestNote(int note);
void setCurrentChannel9isDrum(bool isDrum);

void setNeedAskAboutApplyingNewStyle(bool value);

Expand All @@ -111,6 +115,7 @@ public slots:
void needUseDefaultFontChanged(bool needUseDefaultFont);
void inferTextTypeChanged(bool inferTextType);
void currentShortestNoteChanged(int currentShortestNote);
void currentChannel9isDrumChanged(bool currentChannel9isDrum);
void needAskAboutApplyingNewStyleChanged(bool needAskAboutApplyingNewStyle);
void meiImportLayoutChanged(bool importLayout);
};
Expand Down
9 changes: 9 additions & 0 deletions src/framework/audio/CMakeLists.txt
Original file line number Diff line number Diff line change
Expand Up @@ -213,11 +213,20 @@ set(MODULE_SRC
${CMAKE_CURRENT_LIST_DIR}/internal/synthesizers/synthresolver.h
)

# instpatch dependancy
include(SetupGlib)
include(SetupGobject)

# fluidsynth dependency
include(SetupSndFile)
include(SetupInstPatch)

add_subdirectory(${CMAKE_CURRENT_LIST_DIR}/thirdparty/fluidsynth fluidsynth)

if (LIBINSTPATCH_SUPPORT)
list(APPEND MODULE_INCLUDE_PRIVATE ${GLIB_INCDIRS})
endif (LIBINSTPATCH_SUPPORT)

set(MODULE_LINK
fluidsynth
)
Expand Down
2 changes: 1 addition & 1 deletion src/framework/audio/internal/soundfontrepository.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -49,7 +49,7 @@ void SoundFontRepository::loadSoundFonts()
SoundFontsMap oldSoundFonts;
m_soundFonts.swap(oldSoundFonts);

static const std::vector<std::string> filters = { "*.sf2", "*.sf3" };
static const std::vector<std::string> filters = { "*.sf2", "*.sf3", "*.dls" };
io::paths_t dirs = configuration()->soundFontDirectories();

for (const io::path_t& dir : dirs) {
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -23,6 +23,7 @@
#include "fluidsoundfontparser.h"

#include <fluidsynth.h>
#include <fluid_instpatch.h>
#include <sfloader/fluid_sfont.h>
#include <sfloader/fluid_defsfont.h>

Expand All @@ -36,17 +37,17 @@
fluid_settings_t* settings = nullptr;
fluid_sfloader_t* loader = nullptr;
fluid_sfont_t* sfont = nullptr;
fluid_synth_t* synth = nullptr;

DEFER {
if (sfont) {
fluid_defsfont_sfont_delete(sfont);
sfont->free(sfont);
}
if (loader) {
delete_fluid_sfloader(loader);
}
if (settings) {
delete_fluid_settings(settings);
loader->free(loader);
}
delete_fluid_synth(synth);
delete_fluid_settings(settings);
};

settings = new_fluid_settings();
Expand All @@ -56,7 +57,33 @@

fluid_settings_setint(settings, "synth.dynamic-sample-loading", 1);

loader = new_fluid_defsfloader(settings);
#if defined(LIBINSTPATCH_SUPPORT)
// Try DLS first

// call new_fluid_synth() to invoke not exported
// fluid_instpatch_init() / fluid_instpatch_supports_multi_init()
synth = new_fluid_synth(settings);
if (!synth) {
return make_ret(Ret::Code::UnknownError);
}

loader = new_fluid_instpatch_loader(settings);
if (loader) {
sfont = fluid_sfloader_load(loader, path.c_str());
if (sfont) {
goto skip_sfloader;
} else {
loader->free(loader);
loader = nullptr;
}
}
#endif

if (!sfont) {
// Then try SoundFont
loader = new_fluid_defsfloader(settings);
}

if (!loader) {
return make_ret(Ret::Code::UnknownError);
}
Expand All @@ -66,16 +93,17 @@
return make_ret(Ret::Code::UnknownError);
}

skip_sfloader:

Check warning on line 96 in src/framework/audio/internal/synthesizers/fluidsynth/fluidsoundfontparser.cpp

View workflow job for this annotation

GitHub Actions / windows_x64

'skip_sfloader': unreferenced label
SoundFontMeta meta;
meta.path = path;

fluid_defsfont_sfont_iteration_start(sfont);
sfont->iteration_start(sfont);

fluid_preset_t* fluid_preset;
while ((fluid_preset = fluid_defsfont_sfont_iteration_next(sfont))) {
int bank = fluid_defpreset_preset_get_banknum(fluid_preset);
int program = fluid_defpreset_preset_get_num(fluid_preset);
const char* name = fluid_defpreset_preset_get_name(fluid_preset);
while ((fluid_preset = sfont->iteration_next(sfont))) {
int bank = fluid_preset->get_banknum(fluid_preset);
int program = fluid_preset->get_num(fluid_preset);
const char* name = fluid_preset->get_name(fluid_preset);

SoundFontPreset preset;
preset.program = midi::Program(bank, program);
Expand Down
2 changes: 1 addition & 1 deletion src/framework/audio/soundfonttypes.h
Original file line number Diff line number Diff line change
Expand Up @@ -37,7 +37,7 @@ using SoundFontPaths = std::vector<SoundFontPath>;
inline bool isSoundFont(const io::path_t& filePath)
{
std::string ext = io::suffix(filePath);
return ext == "sf2" || ext == "sf3";
return ext == "sf2" || ext == "sf3" || ext == "dls";
}

struct SoundFontPreset
Expand Down
Loading
Loading
0