├── .gitignore ├── CMakeLists.txt ├── ChangeLog ├── LICENSE ├── README ├── TRANSLATORS ├── debian ├── changelog ├── compat ├── control ├── copyright ├── docs ├── qsampler.1 └── rules ├── rpm └── qsampler.spec └── src ├── CMakeLists.txt ├── appdata ├── org.rncbc.qsampler.desktop └── org.rncbc.qsampler.metainfo.xml ├── config.h.cmake ├── images ├── audio1.png ├── audio2.png ├── channelsArrange.png ├── deviceCreate.png ├── deviceDelete.png ├── displaybg1.png ├── editAddChannel.png ├── editEditChannel.png ├── editRemoveChannel.png ├── editResetAllChannels.png ├── editResetChannel.png ├── editSetupChannel.png ├── fileNew.png ├── fileOpen.png ├── fileReset.png ├── fileRestart.png ├── fileSave.png ├── formAccept.png ├── formEdit.png ├── formOpen.png ├── formRefresh.png ├── formReject.png ├── formRemove.png ├── formSave.png ├── itemFile.png ├── itemGroup.png ├── itemGroupNew.png ├── itemGroupOpen.png ├── itemNew.png ├── itemReset.png ├── ledoff1.png ├── ledon1.png ├── midi1.png ├── midi2.png ├── qsampler.icns ├── qsampler.png ├── qsampler.svg ├── qsamplerChannel.png ├── qsamplerDevice.png └── qsamplerInstrument.png ├── man1 ├── qsampler.1 └── qsampler.fr.1 ├── mimetypes ├── org.rncbc.qsampler.application-x-qsampler-session.png ├── org.rncbc.qsampler.application-x-qsampler-session.svg └── org.rncbc.qsampler.xml ├── palette ├── KXStudio.conf └── Wonton Soup.conf ├── qsampler.cpp ├── qsampler.h ├── qsampler.qrc ├── qsamplerAbout.h ├── qsamplerChannel.cpp ├── qsamplerChannel.h ├── qsamplerChannelForm.cpp ├── qsamplerChannelForm.h ├── qsamplerChannelForm.ui ├── qsamplerChannelFxForm.cpp ├── qsamplerChannelFxForm.h ├── qsamplerChannelFxForm.ui ├── qsamplerChannelStrip.cpp ├── qsamplerChannelStrip.h ├── qsamplerChannelStrip.ui ├── qsamplerDevice.cpp ├── qsamplerDevice.h ├── qsamplerDeviceForm.cpp ├── qsamplerDeviceForm.h ├── qsamplerDeviceForm.ui ├── qsamplerDeviceStatusForm.cpp ├── qsamplerDeviceStatusForm.h ├── qsamplerFxSend.cpp ├── qsamplerFxSend.h ├── qsamplerFxSendsModel.cpp ├── qsamplerFxSendsModel.h ├── qsamplerInstrument.cpp ├── qsamplerInstrument.h ├── qsamplerInstrumentForm.cpp ├── qsamplerInstrumentForm.h ├── qsamplerInstrumentForm.ui ├── qsamplerInstrumentList.cpp ├── qsamplerInstrumentList.h ├── qsamplerInstrumentListForm.cpp ├── qsamplerInstrumentListForm.h ├── qsamplerInstrumentListForm.ui ├── qsamplerMainForm.cpp ├── qsamplerMainForm.h ├── qsamplerMainForm.ui ├── qsamplerMessages.cpp ├── qsamplerMessages.h ├── qsamplerOptions.cpp ├── qsamplerOptions.h ├── qsamplerOptionsForm.cpp ├── qsamplerOptionsForm.h ├── qsamplerOptionsForm.ui ├── qsamplerPaletteForm.cpp ├── qsamplerPaletteForm.h ├── qsamplerPaletteForm.ui ├── qsamplerUtilities.cpp ├── qsamplerUtilities.h └── translations ├── qsampler_cs.ts ├── qsampler_fr.ts └── qsampler_ru.ts /.gitignore: -------------------------------------------------------------------------------- 1 | build* 2 | *.txt.user 3 | -------------------------------------------------------------------------------- /CMakeLists.txt: -------------------------------------------------------------------------------- 1 | cmake_minimum_required (VERSION 3.13) 2 | 3 | project (Qsampler 4 | VERSION 1.0.0 5 | DESCRIPTION "A LinuxSampler Qt GUI Interface" 6 | HOMEPAGE_URL "https://qsampler.sourceforge.io" 7 | LANGUAGES C CXX) 8 | 9 | set (PROJECT_TITLE "${PROJECT_NAME}") 10 | string (TOLOWER "${PROJECT_TITLE}" PROJECT_NAME) 11 | 12 | set (PROJECT_COPYRIGHT "Copyright (C) 2004-2025, rncbc aka Rui Nuno Capela. All rights reserved.") 13 | set (PROJECT_COPYRIGHT2 "Copyright (C) 2007-2019, Christian Schoenebeck") 14 | set (PROJECT_DOMAIN "linuxsampler.org") 15 | 16 | execute_process ( 17 | COMMAND git describe --tags --dirty --abbrev=6 18 | WORKING_DIRECTORY ${CMAKE_SOURCE_DIR} 19 | OUTPUT_VARIABLE GIT_DESCRIBE_OUTPUT 20 | RESULT_VARIABLE GIT_DESCRIBE_RESULT 21 | OUTPUT_STRIP_TRAILING_WHITESPACE) 22 | if (GIT_DESCRIBE_RESULT EQUAL 0) 23 | set (GIT_VERSION "${GIT_DESCRIBE_OUTPUT}") 24 | string (REGEX REPLACE "^[^0-9]+" "" GIT_VERSION "${GIT_VERSION}") 25 | string (REGEX REPLACE "-g" "git." GIT_VERSION "${GIT_VERSION}") 26 | string (REGEX REPLACE "[_|-]" "." GIT_VERSION "${GIT_VERSION}") 27 | execute_process ( 28 | COMMAND git rev-parse --abbrev-ref HEAD 29 | WORKING_DIRECTORY ${CMAKE_SOURCE_DIR} 30 | OUTPUT_VARIABLE GIT_REVPARSE_OUTPUT 31 | RESULT_VARIABLE GIT_REVPARSE_RESULT 32 | OUTPUT_STRIP_TRAILING_WHITESPACE) 33 | if (GIT_REVPARSE_RESULT EQUAL 0 AND NOT GIT_REVPARSE_OUTPUT STREQUAL "main") 34 | set (GIT_VERSION "${GIT_VERSION} [${GIT_REVPARSE_OUTPUT}]") 35 | endif () 36 | set (PROJECT_VERSION "${GIT_VERSION}") 37 | endif () 38 | 39 | 40 | if (CMAKE_BUILD_TYPE MATCHES "Debug") 41 | set (CONFIG_DEBUG 1) 42 | set (CONFIG_BUILD_TYPE "debug") 43 | else () 44 | set (CONFIG_DEBUG 0) 45 | set (CONFIG_BUILD_TYPE "release") 46 | set (CMAKE_BUILD_TYPE "Release") 47 | endif () 48 | 49 | set (CONFIG_PREFIX "${CMAKE_INSTALL_PREFIX}") 50 | 51 | include (GNUInstallDirs) 52 | set (CONFIG_BINDIR "${CONFIG_PREFIX}/${CMAKE_INSTALL_BINDIR}") 53 | set (CONFIG_LIBDIR "${CONFIG_PREFIX}/${CMAKE_INSTALL_LIBDIR}") 54 | set (CONFIG_DATADIR "${CONFIG_PREFIX}/${CMAKE_INSTALL_DATADIR}") 55 | set (CONFIG_MANDIR "${CONFIG_PREFIX}/${CMAKE_INSTALL_MANDIR}") 56 | 57 | 58 | # Enable libgig availability. 59 | option (CONFIG_LIBGIG "Enable libgig interface (default=yes)" 1) 60 | 61 | # Enable unique/single instance. 62 | option (CONFIG_XUNIQUE "Enable unique/single instance (default=yes)" 1) 63 | 64 | # Enable debugger stack-trace option (assumes --enable-debug). 65 | option (CONFIG_STACKTRACE "Enable debugger stack-trace (default=no)" 0) 66 | 67 | # Enable Wayland support option. 68 | option (CONFIG_WAYLAND "Enable Wayland support (EXPERIMENTAL) (default=no)" 0) 69 | 70 | # Enable Qt6 build preference. 71 | option (CONFIG_QT6 "Enable Qt6 build (default=yes)" 1) 72 | 73 | 74 | # Fix for new CMAKE_REQUIRED_LIBRARIES policy. 75 | if (POLICY CMP0075) 76 | cmake_policy (SET CMP0075 NEW) 77 | endif () 78 | 79 | # Check for Qt... 80 | if (CONFIG_QT6) 81 | find_package (Qt6 QUIET) 82 | if (NOT Qt6_FOUND) 83 | set (CONFIG_QT6 0) 84 | endif () 85 | endif () 86 | 87 | if (CONFIG_QT6) 88 | find_package (QT QUIET NAMES Qt6) 89 | else () 90 | find_package (QT QUIET NAMES Qt5) 91 | endif () 92 | 93 | find_package (Qt${QT_VERSION_MAJOR} REQUIRED COMPONENTS Core Gui Widgets Svg) 94 | 95 | if (CONFIG_XUNIQUE) 96 | find_package (Qt${QT_VERSION_MAJOR} REQUIRED COMPONENTS Network) 97 | endif () 98 | 99 | find_package (Qt${QT_VERSION_MAJOR}LinguistTools) 100 | 101 | include (CheckIncludeFile) 102 | include (CheckIncludeFiles) 103 | include (CheckIncludeFileCXX) 104 | include (CheckFunctionExists) 105 | include (CheckLibraryExists) 106 | 107 | # Checks for libraries. 108 | if (WIN32) 109 | check_function_exists (lroundf CONFIG_ROUND) 110 | else () 111 | find_library (MATH_LIBRARY m) 112 | # Check for round math function. 113 | if (MATH_LIBRARY) 114 | set (CMAKE_REQUIRED_LIBRARIES "${MATH_LIBRARY};${CMAKE_REQUIRED_LIBRARIES}") 115 | check_function_exists (lroundf CONFIG_ROUND) 116 | else () 117 | message (FATAL_ERROR "*** math library not found.") 118 | endif () 119 | endif () 120 | 121 | # Checks for header files. 122 | if (UNIX AND NOT APPLE) 123 | check_include_files ("fcntl.h;unistd.h;signal.h" HAVE_SIGNAL_H) 124 | endif () 125 | 126 | 127 | # Find package modules 128 | include (FindPkgConfig) 129 | 130 | # Check for LSCP libraries. 131 | pkg_check_modules (LSCP REQUIRED IMPORTED_TARGET lscp>=1.0.0) 132 | if (LSCP_FOUND) 133 | find_library(LSCP_LIBRARY NAMES ${LSCP_LIBRARIES} HINTS ${LSCP_LIBDIR}) 134 | endif () 135 | if (LSCP_LIBRARY) 136 | set (CONFIG_LIBLSCP 1) 137 | set (CONFIG_INSTRUMENT_NAME 1) 138 | set (CONFIG_AUDIO_ROUTING 1) 139 | set (CONFIG_EVENT_CHANNEL_MIDI 1) 140 | set (CONFIG_EVENT_DEVICE_MIDI 1) 141 | set (CMAKE_REQUIRED_LIBRARIES "${LSCP_LIBRARY};${CMAKE_REQUIRED_LIBRARIES}") 142 | # Check if MUE/SOLO functions are available. 143 | check_function_exists (lscp_set_channel_mute CONFIG_MUTE_SOLO) 144 | check_function_exists (lscp_set_channel_solo CONFIG_MUTE_SOLO) 145 | # Check if MIDI instrument mapping is available. 146 | check_function_exists (lscp_map_midi_instrument CONFIG_MIDI_INSTRUMENT) 147 | # Check if FX sends is available. 148 | check_function_exists (lscp_create_fxsend CONFIG_FXSEND) 149 | if (CONFIG_FXSEND) 150 | check_function_exists (lscp_set_fxsend_name CONFIG_FXSEND_RENAME) 151 | set (CONFIG_FXSEND_LEVEL 1) 152 | else () 153 | set (CONFIG_FXSEND_LEVEL 0) 154 | endif () 155 | # Check if global volume is available. 156 | check_function_exists (lscp_set_volume CONFIG_VOLUME) 157 | # Check if instrument editing is available. 158 | check_function_exists (lscp_edit_channel_instrument CONFIG_EDIT_INSTRUMENT) 159 | # Check if max. voices / streams is available. 160 | check_function_exists (lscp_get_voices CONFIG_MAX_VOICES) 161 | else () 162 | message (FATAL_ERROR "*** LSCP library not found.") 163 | set (CONFIG_LIBLSCP 0) 164 | set (CONFIG_INSTRUMENT_NAME 0) 165 | set (CONFIG_AUDIO_ROUTING 0) 166 | set (CONFIG_EVENT_CHANNEL_MIDI 0) 167 | set (CONFIG_EVENT_DEVICE_MIDI 0) 168 | endif () 169 | 170 | # Check for GIG libraries. 171 | if (CONFIG_LIBGIG) 172 | pkg_check_modules (GIG IMPORTED_TARGET gig>=4.0.0) 173 | if (GIG_FOUND) 174 | find_library(GIG_LIBRARY NAMES ${GIG_LIBRARIES} HINTS ${GIG_LIBDIR}) 175 | endif () 176 | if (GIG_LIBRARY) 177 | set (CONFIG_LIBGIG 1) 178 | #set (CMAKE_REQUIRED_LIBRARIES "${GIG_LIBRARY};${CMAKE_REQUIRED_LIBRARIES}") 179 | # liggig supports fast information retrieval. 180 | set (CONFIG_LIBGIG_SETAUTOLOAD 1) 181 | # libgig also suppoert SF2 . 182 | set (CONFIG_LIBGIG_SF2 1) 183 | else () 184 | message (WARNING "*** GIG library not found.") 185 | set (CONFIG_LIBGIG 0) 186 | set (CONFIG_LIBGIG_SETAUTOLOAD 0) 187 | set (CONFIG_LIBGIG_SF2 0) 188 | endif () 189 | endif () 190 | 191 | 192 | add_subdirectory (src) 193 | 194 | 195 | # Finally check whether Qt is statically linked. 196 | if (QT_FEATURE_static) 197 | set(QT_VERSION "${QT_VERSION}-static") 198 | endif () 199 | 200 | # Configuration status 201 | macro (SHOW_OPTION text value) 202 | if (${value}) 203 | message ("${text}: yes") 204 | else () 205 | message ("${text}: no") 206 | endif () 207 | endmacro () 208 | 209 | message ("\n ${PROJECT_TITLE} ${PROJECT_VERSION} (Qt ${QT_VERSION})") 210 | message ("\n Build target . . . . . . . . . . . . . . . . . . .: ${CONFIG_BUILD_TYPE}\n") 211 | show_option (" LSCP instrument name support . . . . . . . . . . ." CONFIG_INSTRUMENT_NAME) 212 | show_option (" LSCP mute/solo support . . . . . . . . . . . . . ." CONFIG_MUTE_SOLO) 213 | show_option (" LSCP MIDI instrument support . . . . . . . . . . ." CONFIG_MIDI_INSTRUMENT) 214 | show_option (" LSCP FX send support . . . . . . . . . . . . . . ." CONFIG_FXSEND) 215 | show_option (" LSCP FX send level support . . . . . . . . . . . ." CONFIG_FXSEND_LEVEL) 216 | show_option (" LSCP FX send rename support . . . . . . . . . . ." CONFIG_FXSEND_RENAME) 217 | show_option (" LSCP audio routing support . . . . . . . . . . . ." CONFIG_AUDIO_ROUTING) 218 | show_option (" LSCP volume support . . . . . . . . . . . . . . ." CONFIG_VOLUME) 219 | show_option (" LSCP edit instrument support . . . . . . . . . . ." CONFIG_EDIT_INSTRUMENT) 220 | show_option (" GigaSampler instrument file support (libgig) . . ." CONFIG_LIBGIG) 221 | if (CONFIG_LIBGIG) 222 | show_option (" libgig supports fast information retrieval . . . ." CONFIG_LIBGIG_SETAUTOLOAD) 223 | show_option (" libgig supports SoundFont2 instruments files . . ." CONFIG_LIBGIG_SF2) 224 | endif () 225 | show_option (" LSCP channel MIDI event support . . . . . . . . ." CONFIG_EVENT_CHANNEL_MIDI) 226 | show_option (" LSCP device MIDI event support . . . . . . . . . ." CONFIG_EVENT_DEVICE_MIDI) 227 | show_option (" LSCP runtime max. voices / disk streams support ." CONFIG_MAX_VOICES) 228 | message ("") 229 | show_option (" Unique/Single instance support . . . . . . . . . ." CONFIG_XUNIQUE) 230 | show_option (" Debugger stack-trace (gdb) . . . . . . . . . . . ." CONFIG_STACKTRACE) 231 | message ("\n Install prefix . . . . . . . . . . . . . . . . . .: ${CONFIG_PREFIX}\n") 232 | -------------------------------------------------------------------------------- /README: -------------------------------------------------------------------------------- 1 | Qsampler - A LinuxSampler Qt GUI Interface 2 | ------------------------------------------ 3 | 4 | Qsampler is a LinuxSampler GUI front-end application written in C++ around 5 | the Qt framework using Qt Designer. At the moment it just wraps as a client 6 | reference interface for the LinuxSampler Control Protocol (LSCP). 7 | 8 | LinuxSampler is a work in progress. The goal is to produce a free, open source 9 | pure software audio sampler with professional grade features, comparable to 10 | both hardware and commercial Windows/Mac software samplers. 11 | 12 | The initial platform will be Linux because it is one of the most promising 13 | open source multimedia operating systems. Thanks to various kernel patches 14 | and the Jack Audio Connection Kit, Linux is currently able to deliver rock 15 | solid sub-5 millisecond MIDI-to-Audio response. 16 | 17 | Homepage: https://qsampler.sourceforge.io 18 | http://qsampler.sourceforge.net 19 | 20 | See also: https://www.linuxsampler.org 21 | 22 | License: GNU General Public License (GPL) 23 | 24 | 25 | Requirements 26 | ------------ 27 | 28 | The software requirements for build and runtime are listed as follows: 29 | 30 | Mandatory: 31 | 32 | - Qt framework, C++ class library and tools for 33 | cross-platform application and UI development 34 | https://qt.io/ 35 | 36 | - liblscp, C library for LinuxSampler control protocol API. 37 | https://www.linuxsampler.org/ 38 | 39 | Optional (opted-in at build time): 40 | 41 | - libgig, C++ library for loading and modifying Gigasampler and DLS files. 42 | https://www.linuxsampler.org/libgig/ 43 | 44 | 45 | Installation 46 | ------------ 47 | 48 | Unpack the tarball and in the extracted source directory: 49 | 50 | cmake [-DCMAKE_INSTALL_PREFIX=] -B build 51 | cmake --build build [--parallel ] 52 | 53 | and optionally, as root: 54 | 55 | [sudo] cmake --install build 56 | 57 | Note that the default installation path () is /usr/local . 58 | 59 | 60 | Configuration 61 | ------------- 62 | 63 | Qsampler holds its settings and configuration state per user, in a 64 | file located as $HOME/.config/linuxsampler.org/Qsampler.conf . 65 | Normally, there's no need to edit this file, as it is recreated and 66 | rewritten everytime qsampler is run. 67 | 68 | 69 | Bugs 70 | ---- 71 | 72 | Plenty as this is still alpha software. Bug reports should be posted on 73 | LinuxSampler bug tracker (https://bugs.linuxsampler.org). 74 | 75 | 76 | Support 77 | ------- 78 | 79 | Qsampler is open source free software. For bug reports, feature requests, 80 | discussion forums, mailling lists, or any other matter related to the 81 | development of this piece of software, please use the LinuxSampler project 82 | site (https://www.linuxsampler.org). 83 | 84 | 85 | Enjoy. 86 | 87 | rncbc aka Rui Nuno Capela 88 | rncbc at rncbc dot org 89 | https://www.rncbc.org 90 | -------------------------------------------------------------------------------- /TRANSLATORS: -------------------------------------------------------------------------------- 1 | Czech (cs) 2 | Pavel Fric 3 | 4 | French (fr) 5 | Olivier Humbert 6 | 7 | Russian (ru) 8 | Alexandre Prokoudine 9 | -------------------------------------------------------------------------------- /debian/changelog: -------------------------------------------------------------------------------- 1 | qsampler (1.0.1-2.1) unstable; urgency=low 2 | 3 | * An Early Spring'25 release. 4 | 5 | -- Rui Nuno Capela Thu, 27 Mar 2025 20:00:00 +0000 6 | 7 | qsampler (1.0.0-1.1) unstable; urgency=low 8 | 9 | * An Unthinkable release. 10 | 11 | -- Rui Nuno Capela Wed, 19 Jun 2024 18:00:00 +0100 12 | -------------------------------------------------------------------------------- /debian/compat: -------------------------------------------------------------------------------- 1 | 11 2 | -------------------------------------------------------------------------------- /debian/control: -------------------------------------------------------------------------------- 1 | Source: qsampler 2 | Section: sound 3 | Priority: optional 4 | Maintainer: Rui Nuno Capela 5 | Build-Depends: debhelper (>= 11), cmake, pkg-config, 6 | qt6-base-dev (>= 6.1) | qtbase5-dev (>= 5.1), 7 | qt6-base-dev-tools (>= 6.1) | qtbase5-dev-tools (>= 5.1), 8 | qt6-tools-dev (>= 6.1) | qttools5-dev (>= 5.1), 9 | qt6-tools-dev-tools (>= 6.1) | qttools5-dev-tools (>= 5.1), 10 | qt6-l10n-tools (>= 6.1) | base-files (<< 12), 11 | qt6-svg-dev | libqt6svg6-dev | libqt5svg5-dev, 12 | libxkbcommon-dev, libgl-dev, 13 | liblscp-dev, libgig-dev (>= 3.3.0) 14 | Standards-Version: 4.6.2 15 | Rules-Requires-Root: no 16 | 17 | Package: qsampler 18 | Architecture: any 19 | Depends: ${shlibs:Depends}, ${misc:Depends}, 20 | libqt6svg6 (>= 6.1) | libqt5svg5 (>= 5.1), 21 | qt6-qpa-plugins | base-files (<< 12) 22 | Description: LinuxSampler GUI frontend based on the Qt toolkit 23 | Qsampler is a LinuxSampler GUI front-end application written in C++ around 24 | the Qt framework using Qt Designer. At the moment it just wraps as a client 25 | reference interface for the LinuxSampler Control Protocol (LSCP). 26 | -------------------------------------------------------------------------------- /debian/copyright: -------------------------------------------------------------------------------- 1 | Format: https://www.debian.org/doc/packaging-manuals/copyright-format/1.0/ 2 | Upstream-Name: Qsampler 3 | Upstream-Contact: Rui Nuno Capela 4 | Source: https://qsampler.sourceforge.io 5 | 6 | Files: * 7 | Copyright: 2004-2025 Rui Nuno Capela 8 | 2007,2008,2015 Christian Schoenebeck 9 | License: GPL-2+ 10 | This package is free software; you can redistribute it and/or modify 11 | it under the terms of the GNU General Public License as published by 12 | the Free Software Foundation; either version 2 of the License, or (at 13 | your option) any later version. 14 | . 15 | This package is distributed in the hope that it will be useful, but 16 | WITHOUT ANY WARRANTY; without even the implied warranty of 17 | MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU 18 | General Public License for more details. 19 | . 20 | On Debian systems, the complete text of the GNU General Public 21 | License can be found in /usr/share/common-licenses/GPL-2. 22 | 23 | Files: src/appdata/* 24 | Copyright: 2004-2025 Rui Nuno Capela 25 | License: FSFAP 26 | Copying and distribution of this file, with or without modification, 27 | are permitted in any medium without royalty provided the copyright 28 | notice and this notice are preserved. This file is offered as-is, 29 | without any warranty. 30 | -------------------------------------------------------------------------------- /debian/docs: -------------------------------------------------------------------------------- 1 | README 2 | TRANSLATORS 3 | ChangeLog 4 | -------------------------------------------------------------------------------- /debian/qsampler.1: -------------------------------------------------------------------------------- 1 | .\" Hey, EMACS: -*- nroff -*- 2 | .\" First parameter, NAME, should be all caps 3 | .\" Second parameter, SECTION, should be 1-8, maybe w/ subsection 4 | .\" other parameters are allowed: see man(7), man(1) 5 | .TH QSAMPLER 1 "November 21, 2007" 6 | .\" Please adjust this date whenever revising the manpage. 7 | .\" 8 | .\" Some roff macros, for reference: 9 | .\" .nh disable hyphenation 10 | .\" .hy enable hyphenation 11 | .\" .ad l left justify 12 | .\" .ad b justify to both left and right margins 13 | .\" .nf disable filling 14 | .\" .fi enable filling 15 | .\" .br insert line break 16 | .\" .sp insert n+1 empty lines 17 | .\" for manpage-specific macros, see man(7) 18 | .SH NAME 19 | qsampler \- LinuxSampler GUI frontend based on the Qt toolkit 20 | .SH SYNOPSIS 21 | .B qsampler 22 | .RI [ options ] " file" 23 | .SH DESCRIPTION 24 | This manual page documents briefly the 25 | .B qsampler 26 | command. 27 | .PP 28 | .\" TeX users may be more comfortable with the \fB\fP and 29 | .\" \fI\fP escape sequences to invode bold face and italics, 30 | .\" respectively. 31 | \fBqsampler\fP is a LinuxSampler GUI front-end application written in C++ around the Qt4 toolkit using Qt Designer. At the moment it just wraps as a client reference interface for the LinuxSampler Control Protocol (LSCP). 32 | .SH OPTIONS 33 | These programs follow the usual GNU command line syntax, with long 34 | options starting with two dashes (`-'). 35 | A summary of options is included below. 36 | For a complete description, see the Info files. 37 | .TP 38 | .B \-?, \-\-help 39 | Show summary of options. 40 | .TP 41 | .B \-s, \-\-start 42 | Start linuxsampler server locally 43 | .TP 44 | .B \-h, \-\-hostname 45 | Specify linuxsampler server hostname 46 | .TP 47 | .B \-p, \-\-port 48 | Specify linuxsampler server port number 49 | .TP 50 | .B \-v, \-\-version 51 | Show version of program. 52 | .SH SEE ALSO 53 | .BR linuxsampler (1), 54 | .BR gigtools (1). 55 | .br 56 | .SH AUTHOR 57 | qsampler was written by Rui Nuno Capela. 58 | .PP 59 | This manual page was written by Matt Flax , 60 | for the Debian project (but may be used by others). 61 | -------------------------------------------------------------------------------- /debian/rules: -------------------------------------------------------------------------------- 1 | #!/usr/bin/make -f 2 | %: 3 | dh $@ 4 | 5 | override_dh_auto_configure: 6 | # Add here commands to configure the package. 7 | cmake -DCMAKE_INSTALL_PREFIX=/usr . 8 | # --- end custom part for configure 9 | -------------------------------------------------------------------------------- /rpm/qsampler.spec: -------------------------------------------------------------------------------- 1 | # 2 | # spec file for package qsampler 3 | # 4 | # Copyright (C) 2004-2025, rncbc aka Rui Nuno Capela. All rights reserved. 5 | # Copyright (C) 2007,2008,2015 Christian Schoenebeck 6 | # 7 | # All modifications and additions to the file contributed by third parties 8 | # remain the property of their copyright owners, unless otherwise agreed 9 | # upon. The license for this file, and modifications and additions to the 10 | # file, is the same license as for the pristine package itself (unless the 11 | # license for the pristine package is not an Open Source License, in which 12 | # case the license is the MIT License). An "Open Source License" is a 13 | # license that conforms to the Open Source Definition (Version 1.9) 14 | # published by the Open Source Initiative. 15 | 16 | # Please submit bugfixes or comments via http://bugs.opensuse.org/ 17 | # 18 | 19 | Summary: A LinuxSampler Qt GUI interface 20 | Name: qsampler 21 | Version: 1.0.1 22 | Release: 2.1 23 | License: GPL-2.0-or-later 24 | Group: Productivity/Multimedia/Sound/Midi 25 | Source: %{name}-%{version}.tar.gz 26 | URL: https://qsampler.sourceforge.io/ 27 | #Packager: rncbc.org 28 | 29 | 30 | %if 0%{?fedora_version} >= 34 || 0%{?suse_version} > 1500 || ( 0%{?sle_version} == 150200 && 0%{?is_opensuse} ) 31 | %define qt_major_version 6 32 | %else 33 | %define qt_major_version 5 34 | %endif 35 | 36 | BuildRequires: coreutils 37 | BuildRequires: pkgconfig 38 | BuildRequires: glibc-devel 39 | BuildRequires: cmake >= 3.15 40 | %if 0%{?sle_version} >= 150200 && 0%{?is_opensuse} 41 | BuildRequires: gcc10 >= 10 42 | BuildRequires: gcc10-c++ >= 10 43 | %define _GCC /usr/bin/gcc-10 44 | %define _GXX /usr/bin/g++-10 45 | %else 46 | BuildRequires: gcc >= 10 47 | BuildRequires: gcc-c++ >= 10 48 | %define _GCC /usr/bin/gcc 49 | %define _GXX /usr/bin/g++ 50 | %endif 51 | %if 0%{qt_major_version} == 6 52 | %if 0%{?sle_version} == 150200 && 0%{?is_opensuse} 53 | BuildRequires: qtbase6.9-static >= 6.9 54 | BuildRequires: qttools6.9-static 55 | BuildRequires: qttranslations6.9-static 56 | BuildRequires: qtsvg6.9-static 57 | %else 58 | BuildRequires: cmake(Qt6LinguistTools) 59 | BuildRequires: pkgconfig(Qt6Core) 60 | BuildRequires: pkgconfig(Qt6Gui) 61 | BuildRequires: pkgconfig(Qt6Widgets) 62 | BuildRequires: pkgconfig(Qt6Svg) 63 | BuildRequires: pkgconfig(Qt6Network) 64 | %endif 65 | %else 66 | BuildRequires: cmake(Qt5LinguistTools) 67 | BuildRequires: pkgconfig(Qt5Core) 68 | BuildRequires: pkgconfig(Qt5Gui) 69 | BuildRequires: pkgconfig(Qt5Widgets) 70 | BuildRequires: pkgconfig(Qt5Svg) 71 | BuildRequires: pkgconfig(Qt5Network) 72 | %endif 73 | BuildRequires: liblscp-devel >= 0.5.6 74 | BuildRequires: libgig-devel >= 3.3.0 75 | 76 | %description 77 | Qsampler is a LinuxSampler GUI front-end application written in C++ around 78 | the Qt framework using Qt Designer. For the moment it just wraps the client 79 | interface of LinuxSampler Control Protocol (LSCP) (http://www.linuxsampler.org). 80 | 81 | 82 | %prep 83 | %setup -q 84 | 85 | %build 86 | %if 0%{?sle_version} == 150200 && 0%{?is_opensuse} 87 | source /opt/qt6.9-static/bin/qt6.9-static-env.sh 88 | %endif 89 | CXX=%{_GXX} CC=%{_GCC} \ 90 | cmake -DCMAKE_INSTALL_PREFIX=%{_prefix} -Wno-dev -B build 91 | cmake --build build %{?_smp_mflags} 92 | 93 | %install 94 | DESTDIR="%{buildroot}" \ 95 | cmake --install build 96 | 97 | 98 | %files 99 | %license LICENSE 100 | %doc README TRANSLATORS ChangeLog 101 | #dir %{_datadir}/mime 102 | #dir %{_datadir}/mime/packages 103 | #dir %{_datadir}/applications 104 | %dir %{_datadir}/icons/hicolor 105 | %dir %{_datadir}/icons/hicolor/32x32 106 | %dir %{_datadir}/icons/hicolor/32x32/apps 107 | %dir %{_datadir}/icons/hicolor/32x32/mimetypes 108 | %dir %{_datadir}/icons/hicolor/scalable 109 | %dir %{_datadir}/icons/hicolor/scalable/apps 110 | %dir %{_datadir}/icons/hicolor/scalable/mimetypes 111 | %dir %{_datadir}/%{name} 112 | %dir %{_datadir}/%{name}/translations 113 | %dir %{_datadir}/%{name}/palette 114 | %dir %{_datadir}/metainfo 115 | #dir %{_datadir}/man 116 | #dir %{_datadir}/man/man1 117 | #dir %{_datadir}/man/fr 118 | #dir %{_datadir}/man/fr/man1 119 | %{_bindir}/%{name} 120 | %{_datadir}/mime/packages/org.rncbc.%{name}.xml 121 | %{_datadir}/applications/org.rncbc.%{name}.desktop 122 | %{_datadir}/icons/hicolor/32x32/apps/org.rncbc.%{name}.png 123 | %{_datadir}/icons/hicolor/scalable/apps/org.rncbc.%{name}.svg 124 | %{_datadir}/icons/hicolor/32x32/mimetypes/org.rncbc.%{name}.application-x-%{name}*.png 125 | %{_datadir}/icons/hicolor/scalable/mimetypes/org.rncbc.%{name}.application-x-%{name}*.svg 126 | %{_datadir}/%{name}/translations/%{name}_*.qm 127 | %{_datadir}/metainfo/org.rncbc.%{name}.metainfo.xml 128 | %{_datadir}/man/man1/%{name}.1.gz 129 | %{_datadir}/man/fr/man1/%{name}.1.gz 130 | %{_datadir}/%{name}/palette/*.conf 131 | 132 | 133 | %changelog 134 | * Thu Mar 27 2025 Rui Nuno Capela 1.0.1 135 | - An Early Spring'25 Release. 136 | * Wed Jun 19 2024 Rui Nuno Capela 1.0.0 137 | - An Unthinkable Release. 138 | -------------------------------------------------------------------------------- /src/CMakeLists.txt: -------------------------------------------------------------------------------- 1 | # project (qsampler) 2 | 3 | set (CMAKE_INCLUDE_CURRENT_DIR ON) 4 | 5 | set (CMAKE_AUTOUIC ON) 6 | set (CMAKE_AUTOMOC ON) 7 | set (CMAKE_AUTORCC ON) 8 | 9 | if (EXISTS ${CMAKE_CURRENT_SOURCE_DIR}/config.h) 10 | file (REMOVE ${CMAKE_CURRENT_SOURCE_DIR}/config.h) 11 | endif () 12 | configure_file (config.h.cmake ${CMAKE_CURRENT_BINARY_DIR}/config.h) 13 | 14 | set (HEADERS 15 | qsampler.h 16 | qsamplerAbout.h 17 | qsamplerOptions.h 18 | qsamplerChannel.h 19 | qsamplerMessages.h 20 | qsamplerInstrument.h 21 | qsamplerInstrumentList.h 22 | qsamplerDevice.h 23 | qsamplerFxSend.h 24 | qsamplerFxSendsModel.h 25 | qsamplerUtilities.h 26 | qsamplerInstrumentForm.h 27 | qsamplerInstrumentListForm.h 28 | qsamplerDeviceForm.h 29 | qsamplerDeviceStatusForm.h 30 | qsamplerChannelStrip.h 31 | qsamplerChannelForm.h 32 | qsamplerChannelFxForm.h 33 | qsamplerOptionsForm.h 34 | qsamplerPaletteForm.h 35 | qsamplerMainForm.h 36 | ) 37 | 38 | set (SOURCES 39 | qsampler.cpp 40 | qsamplerOptions.cpp 41 | qsamplerChannel.cpp 42 | qsamplerMessages.cpp 43 | qsamplerInstrument.cpp 44 | qsamplerInstrumentList.cpp 45 | qsamplerDevice.cpp 46 | qsamplerFxSend.cpp 47 | qsamplerFxSendsModel.cpp 48 | qsamplerUtilities.cpp 49 | qsamplerInstrumentForm.cpp 50 | qsamplerInstrumentListForm.cpp 51 | qsamplerDeviceForm.cpp 52 | qsamplerDeviceStatusForm.cpp 53 | qsamplerChannelStrip.cpp 54 | qsamplerChannelForm.cpp 55 | qsamplerChannelFxForm.cpp 56 | qsamplerOptionsForm.cpp 57 | qsamplerPaletteForm.cpp 58 | qsamplerMainForm.cpp 59 | ) 60 | 61 | set (FORMS 62 | qsamplerInstrumentForm.ui 63 | qsamplerInstrumentListForm.ui 64 | qsamplerDeviceForm.ui 65 | qsamplerChannelStrip.ui 66 | qsamplerChannelForm.ui 67 | qsamplerChannelFxForm.ui 68 | qsamplerOptionsForm.ui 69 | qsamplerPaletteForm.ui 70 | qsamplerMainForm.ui 71 | ) 72 | 73 | set (RESOURCES 74 | qsampler.qrc 75 | ) 76 | 77 | set (TRANSLATIONS 78 | translations/qsampler_cs.ts 79 | translations/qsampler_fr.ts 80 | translations/qsampler_ru.ts 81 | ) 82 | 83 | if (QT_VERSION VERSION_LESS 5.15.0) 84 | qt5_add_translation (QM_FILES ${TRANSLATIONS}) 85 | else () 86 | qt_add_translation (QM_FILES ${TRANSLATIONS}) 87 | endif () 88 | 89 | add_custom_target (translations ALL DEPENDS ${QM_FILES}) 90 | 91 | if (APPLE) 92 | set (ICON_FILE ${CMAKE_CURRENT_SOURCE_DIR}/images/${PROJECT_NAME}.icns) 93 | list (APPEND SOURCES ${ICON_FILE}) 94 | set (MACOSX_BUNDLE_ICON_FILE ${PROJECT_NAME}.icns) 95 | set_source_files_properties (${ICON_FILE} PROPERTIES 96 | MACOSX_PACKAGE_LOCATION Resources) 97 | endif () 98 | 99 | 100 | add_executable (${PROJECT_NAME} 101 | ${HEADERS} 102 | ${SOURCES} 103 | ${FORMS} 104 | ${RESOURCES} 105 | ) 106 | 107 | # Add some debugger flags. 108 | if (CONFIG_DEBUG AND UNIX AND NOT APPLE) 109 | set (CONFIG_DEBUG_OPTIONS -g -fsanitize=address -fno-omit-frame-pointer) 110 | target_compile_options (${PROJECT_NAME} PRIVATE ${CONFIG_DEBUG_OPTIONS}) 111 | target_link_options (${PROJECT_NAME} PRIVATE ${CONFIG_DEBUG_OPTIONS}) 112 | endif () 113 | 114 | set_target_properties (${PROJECT_NAME} PROPERTIES CXX_STANDARD 17) 115 | 116 | if (WIN32) 117 | set_target_properties (${PROJECT_NAME} PROPERTIES WIN32_EXECUTABLE true) 118 | endif () 119 | 120 | if (APPLE) 121 | set_target_properties (${PROJECT_NAME} PROPERTIES MACOSX_BUNDLE true) 122 | endif () 123 | 124 | target_link_libraries (${PROJECT_NAME} PRIVATE Qt${QT_VERSION_MAJOR}::Widgets Qt${QT_VERSION_MAJOR}::Svg) 125 | 126 | if (CONFIG_XUNIQUE) 127 | target_link_libraries (${PROJECT_NAME} PRIVATE Qt${QT_VERSION_MAJOR}::Network) 128 | endif () 129 | 130 | if (CONFIG_LIBLSCP) 131 | target_link_libraries (${PROJECT_NAME} PRIVATE PkgConfig::LSCP) 132 | endif () 133 | 134 | if (CONFIG_LIBGIG) 135 | target_link_libraries (${PROJECT_NAME} PRIVATE PkgConfig::GIG) 136 | endif () 137 | 138 | if (MICROSOFT) 139 | target_link_libraries(${PROJECT_NAME} PRIVATE ws2_32.lib) 140 | elseif (MINGW) 141 | target_link_libraries(${PROJECT_NAME} PRIVATE wsock32 ws2_32) 142 | endif() 143 | 144 | if (UNIX AND NOT APPLE) 145 | install (TARGETS ${PROJECT_NAME} RUNTIME 146 | DESTINATION ${CMAKE_INSTALL_BINDIR}) 147 | install (FILES ${QM_FILES} 148 | DESTINATION ${CMAKE_INSTALL_DATADIR}/${PROJECT_NAME}/translations) 149 | install (FILES images/${PROJECT_NAME}.png 150 | RENAME org.rncbc.${PROJECT_NAME}.png 151 | DESTINATION ${CMAKE_INSTALL_DATADIR}/icons/hicolor/32x32/apps) 152 | install (FILES images/${PROJECT_NAME}.svg 153 | RENAME org.rncbc.${PROJECT_NAME}.svg 154 | DESTINATION ${CMAKE_INSTALL_DATADIR}/icons/hicolor/scalable/apps) 155 | install (FILES appdata/org.rncbc.${PROJECT_NAME}.desktop 156 | DESTINATION ${CMAKE_INSTALL_DATADIR}/applications) 157 | install (FILES appdata/org.rncbc.${PROJECT_NAME}.metainfo.xml 158 | DESTINATION ${CMAKE_INSTALL_DATADIR}/metainfo) 159 | install (FILES mimetypes/org.rncbc.${PROJECT_NAME}.xml 160 | DESTINATION ${CMAKE_INSTALL_DATADIR}/mime/packages) 161 | install (FILES mimetypes/org.rncbc.${PROJECT_NAME}.application-x-${PROJECT_NAME}-session.png 162 | DESTINATION ${CMAKE_INSTALL_DATADIR}/icons/hicolor/32x32/mimetypes) 163 | install (FILES mimetypes/org.rncbc.${PROJECT_NAME}.application-x-${PROJECT_NAME}-session.svg 164 | DESTINATION ${CMAKE_INSTALL_DATADIR}/icons/hicolor/scalable/mimetypes) 165 | install (FILES man1/${PROJECT_NAME}.1 166 | DESTINATION ${CMAKE_INSTALL_MANDIR}/man1) 167 | install (FILES man1/${PROJECT_NAME}.fr.1 168 | DESTINATION ${CMAKE_INSTALL_MANDIR}/fr/man1 RENAME ${PROJECT_NAME}.1) 169 | install (FILES palette/KXStudio.conf palette/Wonton\ Soup.conf 170 | DESTINATION ${CMAKE_INSTALL_DATADIR}/${PROJECT_NAME}/palette) 171 | endif () 172 | 173 | if (WIN32) 174 | install (TARGETS ${PROJECT_NAME} RUNTIME 175 | DESTINATION ${CMAKE_CURRENT_BINARY_DIR}) 176 | install (FILES ${QM_FILES} 177 | DESTINATION ${CMAKE_INSTALL_DATADIR}/${PROJECT_NAME}/translations) 178 | endif () 179 | -------------------------------------------------------------------------------- /src/appdata/org.rncbc.qsampler.desktop: -------------------------------------------------------------------------------- 1 | [Desktop Entry] 2 | Name=Qsampler 3 | Version=1.0 4 | GenericName=LinuxSampler GUI 5 | GenericName[fr]=Interface graphique pour LinuxSampler 6 | Comment=Qsampler is a LinuxSampler Qt GUI Interface 7 | Comment[fr]=Qsampler est une interface graphique Qt pour LinuxSampler 8 | Exec=qsampler %f 9 | Icon=org.rncbc.qsampler 10 | Categories=Audio;AudioVideo;Midi;X-Alsa;X-Jack;Qt; 11 | MimeType=application/x-qsampler-session; 12 | Keywords=Audio;MIDI;ALSA;JACK;LinuxSampler;GigaSampler;SoundFont;Synthesizer;Sampler;GIG;SF2;SFZ;Qt; 13 | Terminal=false 14 | Type=Application 15 | StartupWMClass=qsampler 16 | X-Window-Icon=qsampler 17 | X-SuSE-translate=true 18 | -------------------------------------------------------------------------------- /src/appdata/org.rncbc.qsampler.metainfo.xml: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | org.rncbc.qsampler 5 | FSFAP 6 | GPL-2.0+ 7 | Qsampler 8 | A LinuxSampler Qt GUI interface 9 | 10 |

QSampler is a LinuxSampler GUI front-end application written in C++ around 11 | the Qt framework using Qt Designer. For the moment it just wraps the client 12 | interface of LinuxSampler Control Protocol (LSCP) (http\://www.linuxsampler.org).

13 |
14 | 15 | 16 | https://qsampler.sourceforge.io/image/qsampler-screenshot1.png 17 | The main window showing the application in action 18 | 19 | 20 | org.rncbc.qsampler.desktop 21 | 22 | qsampler 23 | 24 | 25 | Audio 26 | MIDI 27 | ALSA 28 | JACK 29 | LinuxSampler 30 | GigaSampler 31 | SoundFont 32 | Synthesizer 33 | Sampler 34 | GIG 35 | SF2 36 | SFZ 37 | Qt 38 | 39 | https://qsampler.sourceforge.io 40 | linuxsampler.org 41 | rncbc aka. Rui Nuno Capela 42 | rncbc@rncbc.org 43 | 44 | 45 | 46 | 47 | 48 |
49 | -------------------------------------------------------------------------------- /src/config.h.cmake: -------------------------------------------------------------------------------- 1 | #ifndef CONFIG_H 2 | #define CONFIG_H 3 | 4 | /* Define to the title of this package. */ 5 | #cmakedefine PROJECT_TITLE "@PROJECT_TITLE@" 6 | 7 | /* Define to the name of this package. */ 8 | #cmakedefine PROJECT_NAME "@PROJECT_NAME@" 9 | 10 | /* Define to the version of this package. */ 11 | #cmakedefine PROJECT_VERSION "@PROJECT_VERSION@" 12 | 13 | /* Define to the description of this package. */ 14 | #cmakedefine PROJECT_DESCRIPTION "@PROJECT_DESCRIPTION@" 15 | 16 | /* Define to the homepage of this package. */ 17 | #cmakedefine PROJECT_HOMEPAGE_URL "@PROJECT_HOMEPAGE_URL@" 18 | 19 | /* Define to the copyright of this package. */ 20 | #cmakedefine PROJECT_COPYRIGHT "@PROJECT_COPYRIGHT@" 21 | #cmakedefine PROJECT_COPYRIGHT2 "@PROJECT_COPYRIGHT2@" 22 | 23 | /* Define to the domain of this package. */ 24 | #cmakedefine PROJECT_DOMAIN "@PROJECT_DOMAIN@" 25 | 26 | 27 | /* Default installation prefix. */ 28 | #cmakedefine CONFIG_PREFIX "@CONFIG_PREFIX@" 29 | 30 | /* Define to target installation dirs. */ 31 | #cmakedefine CONFIG_BINDIR "@CONFIG_BINDIR@" 32 | #cmakedefine CONFIG_LIBDIR "@CONFIG_LIBDIR@" 33 | #cmakedefine CONFIG_DATADIR "@CONFIG_DATADIR@" 34 | #cmakedefine CONFIG_MANDIR "@CONFIG_MANDIR@" 35 | 36 | /* Define if debugging is enabled. */ 37 | #cmakedefine CONFIG_DEBUG @CONFIG_DEBUG@ 38 | 39 | /* Define to 1 if you have the header file. */ 40 | #cmakedefine HAVE_SIGNAL_H @HAVE_SIGNAL_H@ 41 | 42 | /* Define if round is available. */ 43 | #cmakedefine CONFIG_ROUND @CONFIG_ROUND@ 44 | 45 | /* Define if liblscp is available. */ 46 | #cmakedefine CONFIG_LIBLSCP @CONFIG_LIBLSCP@ 47 | 48 | /* Define if instrument_name is available. */ 49 | #cmakedefine CONFIG_INSTRUMENT_NAME @CONFIG_INSTRUMENT_NAME@ 50 | 51 | /* Define if mute/solo is available. */ 52 | #cmakedefine CONFIG_MUTE_SOLO @CONFIG_MUTE_SOLO@ 53 | 54 | /* Define if MIDI instrument mapping is available. */ 55 | #cmakedefine CONFIG_MIDI_INSTRUMENT @CONFIG_MIDI_INSTRUMENT@ 56 | 57 | /* Define if FX sends is available. */ 58 | #cmakedefine CONFIG_FXSEND @CONFIG_FXSEND@ 59 | 60 | /* Define if FX send level is available. */ 61 | #cmakedefine CONFIG_FXSEND_LEVEL @CONFIG_FXSEND_LEVEL@ 62 | 63 | /* Define if FX send rename is available. */ 64 | #cmakedefine CONFIG_FXSEND_RENAME @CONFIG_FXSEND_RENAME@ 65 | 66 | /* Define if audio_routing is an integer array. */ 67 | #cmakedefine CONFIG_AUDIO_ROUTING @CONFIG_AUDIO_ROUTING@ 68 | 69 | /* Define if global volume is available. */ 70 | #cmakedefine CONFIG_VOLUME @CONFIG_VOLUME@ 71 | 72 | /* Define if instrument editing is available. */ 73 | #cmakedefine CONFIG_EDIT_INSTRUMENT @CONFIG_EDIT_INSTRUMENT@ 74 | 75 | /* Define if LSCP CHANNEL_MIDI event support is available. */ 76 | #cmakedefine CONFIG_EVENT_CHANNEL_MIDI @CONFIG_EVENT_CHANNEL_MIDI@ 77 | 78 | /* Define if LSCP DEVICE_MIDI event support is available. */ 79 | #cmakedefine CONFIG_EVENT_DEVICE_MIDI @CONFIG_EVENT_DEVICE_MIDI@ 80 | 81 | /* Define if max. voices / streams is available. */ 82 | #cmakedefine CONFIG_MAX_VOICES @CONFIG_MAX_VOICES@ 83 | 84 | /* Define if libgig is available. */ 85 | #cmakedefine CONFIG_LIBGIG @CONFIG_LIBGIG@ 86 | 87 | /* Define if libgig provides gig::File::SetAutoLoad() method. */ 88 | #cmakedefine CONFIG_LIBGIG_SETAUTOLOAD @CONFIG_LIBGIG_SETAUTOLOAD@ 89 | 90 | /* Define if round is available. */ 91 | #cmakedefine CONFIG_ROUND @CONFIG_ROUND@ 92 | 93 | /* Define if libgig/SF.h is available. */ 94 | #cmakedefine CONFIG_LIBGIG_SF2 @CONFIG_LIBGIG_SF2@ 95 | 96 | /* Define if unique/single instance is enabled. */ 97 | #cmakedefine CONFIG_XUNIQUE @CONFIG_XUNIQUE@ 98 | 99 | /* Define if debugger stack-trace is enabled. */ 100 | #cmakedefine CONFIG_STACKTRACE @CONFIG_STACKTRACE@ 101 | 102 | /* Define if Wayland is supported */ 103 | #cmakedefine CONFIG_WAYLAND @CONFIG_WAYLAND@ 104 | 105 | 106 | #endif /* CONFIG_H */ 107 | -------------------------------------------------------------------------------- /src/images/audio1.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/rncbc/qsampler/cb092b43e03568b58b6d94d101bd9e4d66e809c6/src/images/audio1.png -------------------------------------------------------------------------------- /src/images/audio2.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/rncbc/qsampler/cb092b43e03568b58b6d94d101bd9e4d66e809c6/src/images/audio2.png -------------------------------------------------------------------------------- /src/images/channelsArrange.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/rncbc/qsampler/cb092b43e03568b58b6d94d101bd9e4d66e809c6/src/images/channelsArrange.png -------------------------------------------------------------------------------- /src/images/deviceCreate.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/rncbc/qsampler/cb092b43e03568b58b6d94d101bd9e4d66e809c6/src/images/deviceCreate.png -------------------------------------------------------------------------------- /src/images/deviceDelete.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/rncbc/qsampler/cb092b43e03568b58b6d94d101bd9e4d66e809c6/src/images/deviceDelete.png -------------------------------------------------------------------------------- /src/images/displaybg1.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/rncbc/qsampler/cb092b43e03568b58b6d94d101bd9e4d66e809c6/src/images/displaybg1.png -------------------------------------------------------------------------------- /src/images/editAddChannel.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/rncbc/qsampler/cb092b43e03568b58b6d94d101bd9e4d66e809c6/src/images/editAddChannel.png -------------------------------------------------------------------------------- /src/images/editEditChannel.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/rncbc/qsampler/cb092b43e03568b58b6d94d101bd9e4d66e809c6/src/images/editEditChannel.png -------------------------------------------------------------------------------- /src/images/editRemoveChannel.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/rncbc/qsampler/cb092b43e03568b58b6d94d101bd9e4d66e809c6/src/images/editRemoveChannel.png -------------------------------------------------------------------------------- /src/images/editResetAllChannels.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/rncbc/qsampler/cb092b43e03568b58b6d94d101bd9e4d66e809c6/src/images/editResetAllChannels.png -------------------------------------------------------------------------------- /src/images/editResetChannel.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/rncbc/qsampler/cb092b43e03568b58b6d94d101bd9e4d66e809c6/src/images/editResetChannel.png -------------------------------------------------------------------------------- /src/images/editSetupChannel.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/rncbc/qsampler/cb092b43e03568b58b6d94d101bd9e4d66e809c6/src/images/editSetupChannel.png -------------------------------------------------------------------------------- /src/images/fileNew.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/rncbc/qsampler/cb092b43e03568b58b6d94d101bd9e4d66e809c6/src/images/fileNew.png -------------------------------------------------------------------------------- /src/images/fileOpen.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/rncbc/qsampler/cb092b43e03568b58b6d94d101bd9e4d66e809c6/src/images/fileOpen.png -------------------------------------------------------------------------------- /src/images/fileReset.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/rncbc/qsampler/cb092b43e03568b58b6d94d101bd9e4d66e809c6/src/images/fileReset.png -------------------------------------------------------------------------------- /src/images/fileRestart.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/rncbc/qsampler/cb092b43e03568b58b6d94d101bd9e4d66e809c6/src/images/fileRestart.png -------------------------------------------------------------------------------- /src/images/fileSave.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/rncbc/qsampler/cb092b43e03568b58b6d94d101bd9e4d66e809c6/src/images/fileSave.png -------------------------------------------------------------------------------- /src/images/formAccept.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/rncbc/qsampler/cb092b43e03568b58b6d94d101bd9e4d66e809c6/src/images/formAccept.png -------------------------------------------------------------------------------- /src/images/formEdit.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/rncbc/qsampler/cb092b43e03568b58b6d94d101bd9e4d66e809c6/src/images/formEdit.png -------------------------------------------------------------------------------- /src/images/formOpen.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/rncbc/qsampler/cb092b43e03568b58b6d94d101bd9e4d66e809c6/src/images/formOpen.png -------------------------------------------------------------------------------- /src/images/formRefresh.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/rncbc/qsampler/cb092b43e03568b58b6d94d101bd9e4d66e809c6/src/images/formRefresh.png -------------------------------------------------------------------------------- /src/images/formReject.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/rncbc/qsampler/cb092b43e03568b58b6d94d101bd9e4d66e809c6/src/images/formReject.png -------------------------------------------------------------------------------- /src/images/formRemove.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/rncbc/qsampler/cb092b43e03568b58b6d94d101bd9e4d66e809c6/src/images/formRemove.png -------------------------------------------------------------------------------- /src/images/formSave.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/rncbc/qsampler/cb092b43e03568b58b6d94d101bd9e4d66e809c6/src/images/formSave.png -------------------------------------------------------------------------------- /src/images/itemFile.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/rncbc/qsampler/cb092b43e03568b58b6d94d101bd9e4d66e809c6/src/images/itemFile.png -------------------------------------------------------------------------------- /src/images/itemGroup.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/rncbc/qsampler/cb092b43e03568b58b6d94d101bd9e4d66e809c6/src/images/itemGroup.png -------------------------------------------------------------------------------- /src/images/itemGroupNew.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/rncbc/qsampler/cb092b43e03568b58b6d94d101bd9e4d66e809c6/src/images/itemGroupNew.png -------------------------------------------------------------------------------- /src/images/itemGroupOpen.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/rncbc/qsampler/cb092b43e03568b58b6d94d101bd9e4d66e809c6/src/images/itemGroupOpen.png -------------------------------------------------------------------------------- /src/images/itemNew.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/rncbc/qsampler/cb092b43e03568b58b6d94d101bd9e4d66e809c6/src/images/itemNew.png -------------------------------------------------------------------------------- /src/images/itemReset.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/rncbc/qsampler/cb092b43e03568b58b6d94d101bd9e4d66e809c6/src/images/itemReset.png -------------------------------------------------------------------------------- /src/images/ledoff1.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/rncbc/qsampler/cb092b43e03568b58b6d94d101bd9e4d66e809c6/src/images/ledoff1.png -------------------------------------------------------------------------------- /src/images/ledon1.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/rncbc/qsampler/cb092b43e03568b58b6d94d101bd9e4d66e809c6/src/images/ledon1.png -------------------------------------------------------------------------------- /src/images/midi1.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/rncbc/qsampler/cb092b43e03568b58b6d94d101bd9e4d66e809c6/src/images/midi1.png -------------------------------------------------------------------------------- /src/images/midi2.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/rncbc/qsampler/cb092b43e03568b58b6d94d101bd9e4d66e809c6/src/images/midi2.png -------------------------------------------------------------------------------- /src/images/qsampler.icns: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/rncbc/qsampler/cb092b43e03568b58b6d94d101bd9e4d66e809c6/src/images/qsampler.icns -------------------------------------------------------------------------------- /src/images/qsampler.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/rncbc/qsampler/cb092b43e03568b58b6d94d101bd9e4d66e809c6/src/images/qsampler.png -------------------------------------------------------------------------------- /src/images/qsampler.svg: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | 6 | 7 | 8 | 9 | 10 | 11 | 12 | 13 | 14 | 15 | 16 | 17 | 18 | 19 | 20 | 21 | 22 | 23 | 24 | 25 | 26 | 27 | 28 | 29 | 30 | 31 | 32 | 33 | 34 | 35 | 36 | 37 | 38 | 39 | -------------------------------------------------------------------------------- /src/images/qsamplerChannel.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/rncbc/qsampler/cb092b43e03568b58b6d94d101bd9e4d66e809c6/src/images/qsamplerChannel.png -------------------------------------------------------------------------------- /src/images/qsamplerDevice.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/rncbc/qsampler/cb092b43e03568b58b6d94d101bd9e4d66e809c6/src/images/qsamplerDevice.png -------------------------------------------------------------------------------- /src/images/qsamplerInstrument.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/rncbc/qsampler/cb092b43e03568b58b6d94d101bd9e4d66e809c6/src/images/qsamplerInstrument.png -------------------------------------------------------------------------------- /src/man1/qsampler.1: -------------------------------------------------------------------------------- 1 | .TH QSAMPLER 1 "June 17, 2014" 2 | .SH NAME 3 | Qsampler \- A LinuxSampler Qt GUI Interface 4 | .SH SYNOPSIS 5 | .B qsampler 6 | [\fIoptions\fR] [\fIsession-file\fR] 7 | .SH DESCRIPTION 8 | This manual page documents briefly the 9 | .B qsampler 10 | command. 11 | .PP 12 | \fBQsampler\fP is a LinuxSampler GUI front-end application written 13 | in C++ around the Qt framework using Qt Designer. At the moment it 14 | just wraps as a client reference interface for the LinuxSampler 15 | Control Protocol (LSCP). 16 | .PP 17 | \fBLinuxSampler\fP is a work in progress. The goal is to produce a free, 18 | open source pure software audio sampler with professional grade 19 | features, comparable to both hardware and commercial Windows/Mac 20 | software samplers. 21 | .PP 22 | The initial platform will be Linux because it is one of the most 23 | promising open source multimedia operating systems. Thanks to various 24 | kernel patches and the Jack Audio Connection Kit, Linux is currently 25 | able to deliver rock solid sub-5 millisecond MIDI-to-Audio response. 26 | .SH OPTIONS 27 | .HP 28 | \fB\-s, \fB\-\-start\fR 29 | .IP 30 | Start linuxsampler server locally 31 | .HP 32 | \fB\-h, \fB\-\-hostname\fR=[\fIhost\fR] 33 | .IP 34 | Specify linuxsampler server hostname (default = localhost) 35 | .HP 36 | \fB\-p, \fB\-\-port\fR=[\fIport\fR] 37 | .IP 38 | Specify linuxsampler server port number (default = 8888) 39 | .HP 40 | \fB\-?, \fB\-\-help\fR 41 | .IP 42 | Show help about command line options 43 | .HP 44 | \fB\-v, \fB\-\-version\fR 45 | .IP 46 | Show version information 47 | .SH FILES 48 | Configuration settings are stored in ~/.config/rncbc.org/Qsampler.conf 49 | .SH SEE ALSO 50 | .BR linuxsampler (1) 51 | .SH AUTHOR 52 | Qsampler was written by Rui Nuno Capela, Christian Schoenebeck. 53 | .PP 54 | This manual page was written by Matt Flax , 55 | for the Debian project (but may be used by others). 56 | -------------------------------------------------------------------------------- /src/man1/qsampler.fr.1: -------------------------------------------------------------------------------- 1 | .TH QSAMPLER 1 "Juin 17, 2014" 2 | .SH NOM 3 | Qsampler \- une interface graphique Qt pour LinuxSampler 4 | .SH SYNOPSIS 5 | .B qsampler 6 | [\fIoptions\fR] [\fIfichier-session\fR] 7 | .SH DESCRIPTION 8 | Cette page de manuel documente rapidement la commande 9 | .B qsampler 10 | . 11 | .PP 12 | \fBQsampler\fP est une interface graphique pour LinuxSampler, écrite en C++ 13 | autour des outils Qt, en utilisant Qt Designer. Pour le moment, c'est simplement 14 | un emballage en tant que client de référence pour le protocole de contrôle de 15 | LinuxSampler (LSCP). 16 | .PP 17 | \fBLinuxSampler\fP est un travail en cours. Le but est de produire un 18 | échantillonneur audio logiciel pur à source ouverte et gratuit avec des 19 | fonctionnalités de niveau professionnel, comparable aux échantillonneurs 20 | matériels et aux logiciels d'échantillonnage commerciaux pour Windows/Mac. 21 | .PP 22 | La plateforme initiale sera Linux car elle est l'un système d'exploitation 23 | multimédia à source ouverte des plus prometteurs. Grâce aux rustines du noyau 24 | et au kit de connexion Jack, Linux est actuellement capable de fournir une 25 | réponse MIDI-vers-audio en dessous de 5 millisecondes, à toute épreuve. 26 | .SH OPTIONS 27 | .HP 28 | \fB\-s, \fB\-\-start\fR 29 | .IP 30 | Démarre le serveur linuxsampler localement 31 | .HP 32 | \fB\-h, \fB\-\-hostname\fR=[\fIhôte\fR] 33 | .IP 34 | Spécifie le nom d'hôte du serveur linuxsampler (par défaut = localhost) 35 | .HP 36 | \fB\-p, \fB\-\-port\fR=[\fIport\fR] 37 | .IP 38 | Spécifie le numéro de port du serveur linuxsampler (par défaut = 8888) 39 | .HP 40 | \fB\-?, \fB\-\-help\fR 41 | .IP 42 | Affiche de l'aide à propos des options de ligne de commande 43 | .HP 44 | \fB\-v, \fB\-\-version\fR 45 | .IP 46 | Affiche des informations de version 47 | .SH FICHIERS 48 | Les paramètres de configuration sont stockés dans ~/.config/rncbc.org/Qsampler.conf 49 | .SH VOIR ÉGALEMENT 50 | .BR linuxsampler (1) 51 | .SH AUTEUR 52 | Qsampler a été écrit par Rui Nuno Capela et Christian Schoenebeck. 53 | .PP 54 | Cette page de manuel a été écrite par Matt Flax , pour le 55 | projet Debian (mais peut être utilisée par d'autres). 56 | .PP 57 | La version française a été traduite par Olivier Humbert , 58 | pour le projet LibraZiK (mais peut être utilisée par d'autres). 59 | -------------------------------------------------------------------------------- /src/mimetypes/org.rncbc.qsampler.application-x-qsampler-session.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/rncbc/qsampler/cb092b43e03568b58b6d94d101bd9e4d66e809c6/src/mimetypes/org.rncbc.qsampler.application-x-qsampler-session.png -------------------------------------------------------------------------------- /src/mimetypes/org.rncbc.qsampler.application-x-qsampler-session.svg: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | 6 | 7 | 8 | 9 | 10 | 11 | 12 | 13 | 14 | 15 | 16 | 17 | 18 | 19 | 20 | 21 | 22 | 23 | 24 | 25 | 26 | 27 | 28 | 29 | 30 | 31 | 32 | 33 | 34 | 35 | 36 | 37 | 38 | 39 | 40 | 41 | 42 | 43 | 44 | 45 | 46 | 47 | 48 | 49 | 50 | 51 | 52 | 53 | 54 | 55 | 56 | 57 | 58 | 59 | 60 | 61 | 62 | 63 | 64 | -------------------------------------------------------------------------------- /src/mimetypes/org.rncbc.qsampler.xml: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | Qsampler session (LSCP) 6 | 7 | 8 | 9 | -------------------------------------------------------------------------------- /src/palette/KXStudio.conf: -------------------------------------------------------------------------------- 1 | [ColorThemes] 2 | KXStudio\AlternateBase=#0e0e0e, #0e0e0e, #0c0c0c 3 | KXStudio\Base=#070707, #070707, #060606 4 | KXStudio\BrightText=#ffffff, #ffffff, #ffffff 5 | KXStudio\Button=#1c1c1c, #1c1c1c, #181818 6 | KXStudio\ButtonText=#f0f0f0, #f0f0f0, #5a5a5a 7 | KXStudio\Dark=#818181, #818181, #818181 8 | KXStudio\Highlight=#3c3c3c, #222222, #0e0e0e 9 | KXStudio\HighlightedText=#ffffff, #f0f0f0, #535353 10 | KXStudio\Light=#bfbfbf, #bfbfbf, #bfbfbf 11 | KXStudio\Link=#6464e6, #6464e6, #22224a 12 | KXStudio\LinkVisited=#e664e6, #e664e6, #4a224a 13 | KXStudio\Mid=#5e5e5e, #5e5e5e, #5e5e5e 14 | KXStudio\Midlight=#9b9b9b, #9b9b9b, #9b9b9b 15 | KXStudio\NoRole=#000000, #000000, #000000 16 | KXStudio\PlaceholderText=#000000, #000000, #000000 17 | KXStudio\Shadow=#9b9b9b, #9b9b9b, #9b9b9b 18 | KXStudio\Text=#e6e6e6, #e6e6e6, #4a4a4a 19 | KXStudio\ToolTipBase=#040404, #040404, #040404 20 | KXStudio\ToolTipText=#e6e6e6, #e6e6e6, #e6e6e6 21 | KXStudio\Window=#111111, #111111, #0e0e0e 22 | KXStudio\WindowText=#f0f0f0, #f0f0f0, #535353 23 | -------------------------------------------------------------------------------- /src/palette/Wonton Soup.conf: -------------------------------------------------------------------------------- 1 | [ColorThemes] 2 | Wonton%20Soup\AlternateBase=#434750, #434750, #3b3e46 3 | Wonton%20Soup\Base=#3c4048, #3c4048, #34383f 4 | Wonton%20Soup\BrightText=#ffffff, #ffffff, #ffffff 5 | Wonton%20Soup\Button=#525863, #525863, #484d57 6 | Wonton%20Soup\ButtonText=#d2def0, #d2def0, #6f7682 7 | Wonton%20Soup\Dark=#282b31, #282b31, #23262b 8 | Wonton%20Soup\Highlight=#78889c, #515a67, #40444d 9 | Wonton%20Soup\HighlightedText=#d1e1f4, #b6c1d0, #616872 10 | Wonton%20Soup\Light=#5f6572, #5f6572, #565c68 11 | Wonton%20Soup\Link=#9cd4ff, #9cd4ff, #526677 12 | Wonton%20Soup\LinkVisited=#4080ff, #4080ff, #364c77 13 | Wonton%20Soup\Mid=#3f444c, #3f444c, #383b43 14 | Wonton%20Soup\Midlight=#545a65, #545a65, #4b515b 15 | Wonton%20Soup\NoRole=#000000, #000000, #000000 16 | Wonton%20Soup\PlaceholderText=#000000, #000000, #000000 17 | Wonton%20Soup\Shadow=#1d1f23, #1d1f23, #191b1e 18 | Wonton%20Soup\Text=#d2def0, #d2def0, #636973 19 | Wonton%20Soup\ToolTipBase=#b6c1d0, #b6c1d0, #b6c1d0 20 | Wonton%20Soup\ToolTipText=#2a2c30, #2a2c30, #2a2c30 21 | Wonton%20Soup\Window=#494e58, #494e58, #40444d 22 | Wonton%20Soup\WindowText=#b6c1d0, #b6c1d0, #616872 23 | -------------------------------------------------------------------------------- /src/qsampler.h: -------------------------------------------------------------------------------- 1 | // qsampler.h 2 | // 3 | /**************************************************************************** 4 | Copyright (C) 2003-2025, rncbc aka Rui Nuno Capela. All rights reserved. 5 | Copyright (C) 2007,2008,2015,2019 Christian Schoenebeck 6 | 7 | This program is free software; you can redistribute it and/or 8 | modify it under the terms of the GNU General Public License 9 | as published by the Free Software Foundation; either version 2 10 | of the License, or (at your option) any later version. 11 | 12 | This program is distributed in the hope that it will be useful, 13 | but WITHOUT ANY WARRANTY; without even the implied warranty of 14 | MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the 15 | GNU General Public License for more details. 16 | 17 | You should have received a copy of the GNU General Public License along 18 | with this program; if not, write to the Free Software Foundation, Inc., 19 | 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA. 20 | 21 | *****************************************************************************/ 22 | 23 | #ifndef __qsampler_h 24 | #define __qsampler_h 25 | 26 | #include "qsamplerAbout.h" 27 | 28 | #include 29 | 30 | #if QT_VERSION < QT_VERSION_CHECK(5, 0, 0) 31 | #if defined(Q_WS_X11) 32 | #define CONFIG_X11 33 | #endif 34 | #endif 35 | 36 | 37 | // Forward decls. 38 | class QWidget; 39 | class QTranslator; 40 | 41 | #if QT_VERSION < QT_VERSION_CHECK(5, 0, 0) 42 | #ifdef CONFIG_XUNIQUE 43 | #ifdef CONFIG_X11 44 | #include 45 | typedef unsigned long Window; 46 | typedef unsigned long Atom; 47 | #endif // CONFIG_X11 48 | #endif // CONFIG_XUNIQUE 49 | #else 50 | #ifdef CONFIG_XUNIQUE 51 | class QSharedMemory; 52 | class QLocalServer; 53 | #endif // CONFIG_XUNIQUE 54 | #endif 55 | 56 | 57 | //------------------------------------------------------------------------- 58 | // Singleton application instance stuff (Qt/X11 only atm.) 59 | // 60 | 61 | class qsamplerApplication : public QApplication 62 | { 63 | Q_OBJECT 64 | 65 | public: 66 | 67 | // Constructor. 68 | qsamplerApplication(int& argc, char **argv); 69 | 70 | // Destructor. 71 | ~qsamplerApplication(); 72 | 73 | // Main application widget accessors. 74 | void setMainWidget(QWidget *pWidget); 75 | QWidget *mainWidget() const 76 | { return m_pWidget; } 77 | 78 | // Check if another instance is running, 79 | // and raise its proper main widget... 80 | bool setup(); 81 | 82 | #if QT_VERSION < QT_VERSION_CHECK(5, 0, 0) 83 | #ifdef CONFIG_XUNIQUE 84 | #ifdef CONFIG_X11 85 | void x11PropertyNotify(Window w); 86 | bool x11EventFilter(XEvent *pEv) 87 | #endif // CONFIG_X11 88 | #endif // CONFIG_XUNIQUE 89 | #else 90 | #ifdef CONFIG_XUNIQUE 91 | protected slots: 92 | // Local server slots. 93 | void newConnectionSlot(); 94 | void readyReadSlot(); 95 | protected: 96 | // Local server/shmem setup/cleanup. 97 | bool setupServer(); 98 | void clearServer(); 99 | #endif // CONFIG_XUNIQUE 100 | #endif 101 | 102 | private: 103 | 104 | // Translation support. 105 | QTranslator *m_pQtTranslator; 106 | QTranslator *m_pMyTranslator; 107 | 108 | // Instance variables. 109 | QWidget *m_pWidget; 110 | 111 | #ifdef CONFIG_XUNIQUE 112 | #if QT_VERSION < QT_VERSION_CHECK(5, 0, 0) 113 | #ifdef CONFIG_X11 114 | Display *m_pDisplay; 115 | Atom m_aUnique; 116 | Window m_wOwner; 117 | #endif // CONFIG_X11 118 | #else 119 | QString m_sUnique; 120 | QSharedMemory *m_pMemory; 121 | QLocalServer *m_pServer; 122 | #endif 123 | #endif // CONFIG_XUNIQUE 124 | }; 125 | 126 | 127 | #endif // __qsampler_h 128 | 129 | // end of qsampler.h 130 | -------------------------------------------------------------------------------- /src/qsampler.qrc: -------------------------------------------------------------------------------- 1 | 2 | 3 | images/qsampler.png 4 | images/qsampler.svg 5 | images/audio1.png 6 | images/audio2.png 7 | images/channelsArrange.png 8 | images/deviceCreate.png 9 | images/deviceDelete.png 10 | images/displaybg1.png 11 | images/editAddChannel.png 12 | images/editEditChannel.png 13 | images/editRemoveChannel.png 14 | images/editResetAllChannels.png 15 | images/editResetChannel.png 16 | images/editSetupChannel.png 17 | images/fileNew.png 18 | images/fileOpen.png 19 | images/fileReset.png 20 | images/fileRestart.png 21 | images/fileSave.png 22 | images/formAccept.png 23 | images/formEdit.png 24 | images/formOpen.png 25 | images/formRefresh.png 26 | images/formReject.png 27 | images/formRemove.png 28 | images/formSave.png 29 | images/itemFile.png 30 | images/itemGroup.png 31 | images/itemGroupNew.png 32 | images/itemGroupOpen.png 33 | images/itemNew.png 34 | images/itemReset.png 35 | images/ledoff1.png 36 | images/ledon1.png 37 | images/midi1.png 38 | images/midi2.png 39 | images/qsamplerChannel.png 40 | images/qsamplerDevice.png 41 | images/qsamplerInstrument.png 42 | 43 | 44 | -------------------------------------------------------------------------------- /src/qsamplerAbout.h: -------------------------------------------------------------------------------- 1 | // qsamplerAbout.h 2 | // 3 | /**************************************************************************** 4 | Copyright (C) 2004-2025, rncbc aka Rui Nuno Capela. All rights reserved. 5 | 6 | This program is free software; you can redistribute it and/or 7 | modify it under the terms of the GNU General Public License 8 | as published by the Free Software Foundation; either version 2 9 | of the License, or (at your option) any later version. 10 | 11 | This program is distributed in the hope that it will be useful, 12 | but WITHOUT ANY WARRANTY; without even the implied warranty of 13 | MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the 14 | GNU General Public License for more details. 15 | 16 | You should have received a copy of the GNU General Public License along 17 | with this program; if not, write to the Free Software Foundation, Inc., 18 | 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA. 19 | 20 | *****************************************************************************/ 21 | 22 | #ifndef __qsamplerAbout_h 23 | #define __qsamplerAbout_h 24 | 25 | #include "config.h" 26 | 27 | #define QSAMPLER_TITLE PROJECT_TITLE 28 | 29 | #define QSAMPLER_SUBTITLE PROJECT_DESCRIPTION 30 | #define QSAMPLER_WEBSITE PROJECT_HOMEPAGE_URL 31 | 32 | #define QSAMPLER_COPYRIGHT PROJECT_COPYRIGHT 33 | #define QSAMPLER_COPYRIGHT2 PROJECT_COPYRIGHT2 34 | #define QSAMPLER_DOMAIN PROJECT_DOMAIN 35 | 36 | #endif // __qsamplerAbout_h 37 | 38 | 39 | // end of qsamplerAbout.h 40 | 41 | -------------------------------------------------------------------------------- /src/qsamplerChannel.h: -------------------------------------------------------------------------------- 1 | // qsamplerChannel.h 2 | // 3 | /**************************************************************************** 4 | Copyright (C) 2004-2023, rncbc aka Rui Nuno Capela. All rights reserved. 5 | Copyright (C) 2007, Christian Schoenebeck 6 | 7 | This program is free software; you can redistribute it and/or 8 | modify it under the terms of the GNU General Public License 9 | as published by the Free Software Foundation; either version 2 10 | of the License, or (at your option) any later version. 11 | 12 | This program is distributed in the hope that it will be useful, 13 | but WITHOUT ANY WARRANTY; without even the implied warranty of 14 | MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the 15 | GNU General Public License for more details. 16 | 17 | You should have received a copy of the GNU General Public License along 18 | with this program; if not, write to the Free Software Foundation, Inc., 19 | 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA. 20 | 21 | *****************************************************************************/ 22 | 23 | #ifndef __qsamplerChannel_h 24 | #define __qsamplerChannel_h 25 | 26 | #include 27 | #include 28 | 29 | #include 30 | #include 31 | 32 | #include "qsamplerOptions.h" 33 | 34 | namespace QSampler { 35 | 36 | class Device; 37 | 38 | // Typedef'd QMap. 39 | typedef QMap ChannelRoutingMap; 40 | 41 | 42 | //------------------------------------------------------------------------- 43 | // QSampler::Channel - Sampler channel structure. 44 | // 45 | 46 | class Channel 47 | { 48 | public: 49 | 50 | // Constructor. 51 | Channel(int iChannelID = -1); 52 | // Default destructor. 53 | ~Channel(); 54 | 55 | // Add/remove sampler channel methods. 56 | bool addChannel(); 57 | bool removeChannel(); 58 | 59 | // Sampler channel ID accessors. 60 | int channelID() const; 61 | void setChannelID(int iChannelID); 62 | 63 | // Readable channel name. 64 | QString channelName() const; 65 | 66 | // Engine name property. 67 | const QString& engineName() const; 68 | bool loadEngine(const QString& sEngineName); 69 | 70 | // Instrument file and index. 71 | const QString& instrumentFile() const; 72 | int instrumentNr() const; 73 | const QString& instrumentName() const; 74 | int instrumentStatus() const; 75 | 76 | // Instrument file loader. 77 | bool loadInstrument(const QString& sInstrumentFile, int iInstrumentNr); 78 | // Special instrument file/name/number settler. 79 | bool setInstrument(const QString& sInstrumentFile, int iInstrumentNr); 80 | 81 | // MIDI input driver (DEPRECATED). 82 | const QString& midiDriver() const; 83 | bool setMidiDriver(const QString& sMidiDriver); 84 | 85 | // MIDI input device. 86 | int midiDevice() const; 87 | bool setMidiDevice(int iMidiDevice); 88 | 89 | // MIDI input port. 90 | int midiPort() const; 91 | bool setMidiPort(int iMidiPort); 92 | 93 | // MIDI input channel. 94 | int midiChannel() const; 95 | bool setMidiChannel(int iMidiChannel); 96 | 97 | // MIDI instrument map. 98 | int midiMap() const; 99 | bool setMidiMap(int iMidiMap); 100 | 101 | // Audio output driver (DEPRECATED). 102 | const QString& audioDriver() const; 103 | bool setAudioDriver(const QString& sAudioDriver); 104 | 105 | // Audio output device. 106 | int audioDevice() const; 107 | bool setAudioDevice(int iAudioDevice); 108 | 109 | // Sampler channel volume. 110 | float volume() const; 111 | bool setVolume(float fVolume); 112 | 113 | // Sampler channel mute state. 114 | bool channelMute() const; 115 | bool setChannelMute(bool bMute); 116 | 117 | // Sampler channel solo state. 118 | bool channelSolo() const; 119 | bool setChannelSolo(bool bSolo); 120 | 121 | // Audio routing accessors. 122 | int audioChannel(int iAudioOut) const; 123 | bool setAudioChannel(int iAudioOut, int iAudioIn); 124 | // The audio routing map itself. 125 | const ChannelRoutingMap& audioRouting() const; 126 | 127 | // Istrument name remapper. 128 | void updateInstrumentName(); 129 | 130 | // Channel info structure map executive. 131 | bool updateChannelInfo(); 132 | 133 | // Channel setup dialog form. 134 | bool channelSetup(QWidget *pParent); 135 | 136 | // Reset channel method. 137 | bool channelReset(); 138 | 139 | // Spawn instrument editor method. 140 | bool editChannel(); 141 | 142 | // Message logging methods (brainlessly mapped to main form's). 143 | void appendMessages (const QString & s) const; 144 | void appendMessagesColor (const QString & s, const QColor& rgb) const; 145 | void appendMessagesText (const QString & s) const; 146 | void appendMessagesError (const QString & s) const; 147 | void appendMessagesClient (const QString & s) const; 148 | 149 | // Context menu event handler. 150 | void contextMenuEvent(QContextMenuEvent *pEvent); 151 | 152 | // Common (invalid) name-helpers. 153 | static QString noEngineName(); 154 | static QString noInstrumentName(); 155 | static QString loadingInstrument(); 156 | 157 | // Check whether a given file is an instrument file. 158 | static bool isDlsInstrumentFile (const QString& sInstrumentFile); 159 | static bool isSf2InstrumentFile (const QString& sInstrumentFile); 160 | 161 | // Retrieve the available instrument name(s) of an instrument file (.gig). 162 | static QString getInstrumentName (const QString& sInstrumentFile, 163 | int iInstrumentNr, bool bInstrumentNames); 164 | static QStringList getInstrumentList (const QString& sInstrumentFile, 165 | bool bInstrumentNames); 166 | 167 | private: 168 | 169 | // Unique channel identifier. 170 | int m_iChannelID; 171 | 172 | // Sampler channel info map. 173 | QString m_sEngineName; 174 | QString m_sInstrumentName; 175 | QString m_sInstrumentFile; 176 | int m_iInstrumentNr; 177 | int m_iInstrumentStatus; 178 | QString m_sMidiDriver; 179 | int m_iMidiDevice; 180 | int m_iMidiPort; 181 | int m_iMidiChannel; 182 | int m_iMidiMap; 183 | QString m_sAudioDriver; 184 | int m_iAudioDevice; 185 | float m_fVolume; 186 | bool m_bMute; 187 | bool m_bSolo; 188 | 189 | // The audio routing mapping. 190 | ChannelRoutingMap m_audioRouting; 191 | }; 192 | 193 | 194 | //------------------------------------------------------------------------- 195 | // QSampler::ChannelRoutingModel - data model for audio routing 196 | // (used for QTableView) 197 | // 198 | 199 | struct ChannelRoutingItem { 200 | QStringList options; 201 | int selection; 202 | }; 203 | 204 | class ChannelRoutingModel : public QAbstractTableModel 205 | { 206 | Q_OBJECT 207 | public: 208 | 209 | ChannelRoutingModel(QObject* pParent = nullptr); 210 | 211 | // overridden methods from subclass(es) 212 | int rowCount(const QModelIndex& parent = QModelIndex()) const; 213 | int columnCount(const QModelIndex& parent = QModelIndex()) const; 214 | Qt::ItemFlags flags(const QModelIndex& index) const; 215 | bool setData(const QModelIndex& index, const QVariant& value, 216 | int role = Qt::EditRole); 217 | QVariant data(const QModelIndex &index, int role) const; 218 | QVariant headerData(int section, Qt::Orientation orientation, 219 | int role = Qt::DisplayRole) const; 220 | 221 | // own methods 222 | ChannelRoutingMap routingMap() const { return m_routing; } 223 | 224 | void clear() { m_routing.clear(); } 225 | 226 | public slots: 227 | 228 | void refresh(Device *pDevice, 229 | const ChannelRoutingMap& routing); 230 | 231 | private: 232 | 233 | Device *m_pDevice; 234 | ChannelRoutingMap m_routing; 235 | }; 236 | 237 | 238 | //------------------------------------------------------------------------- 239 | // QSampler::ChannelRoutingDelegate - table cell renderer for audio routing 240 | // 241 | 242 | class ChannelRoutingDelegate : public QItemDelegate 243 | { 244 | Q_OBJECT 245 | 246 | public: 247 | 248 | ChannelRoutingDelegate(QObject* pParent = nullptr); 249 | 250 | QWidget* createEditor(QWidget *pParent, 251 | const QStyleOptionViewItem& option, const QModelIndex& index) const; 252 | void setEditorData(QWidget *pEditor, const QModelIndex& index) const; 253 | void setModelData(QWidget *pEditor, QAbstractItemModel* model, 254 | const QModelIndex& index) const; 255 | void updateEditorGeometry(QWidget *pEditor, 256 | const QStyleOptionViewItem& option, const QModelIndex& index) const; 257 | }; 258 | 259 | } // namespace QSampler 260 | 261 | // So we can use it i.e. through QVariant 262 | Q_DECLARE_METATYPE(QSampler::ChannelRoutingItem) 263 | 264 | #endif // __qsamplerChannel_h 265 | 266 | 267 | // end of qsamplerChannel.h 268 | -------------------------------------------------------------------------------- /src/qsamplerChannelForm.h: -------------------------------------------------------------------------------- 1 | // qsamplerChannelForm.h 2 | // 3 | /**************************************************************************** 4 | Copyright (C) 2004-2020, rncbc aka Rui Nuno Capela. All rights reserved. 5 | Copyright (C) 2007, Christian Schoenebeck 6 | 7 | This program is free software; you can redistribute it and/or 8 | modify it under the terms of the GNU General Public License 9 | as published by the Free Software Foundation; either version 2 10 | of the License, or (at your option) any later version. 11 | 12 | This program is distributed in the hope that it will be useful, 13 | but WITHOUT ANY WARRANTY; without even the implied warranty of 14 | MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the 15 | GNU General Public License for more details. 16 | 17 | You should have received a copy of the GNU General Public License along 18 | with this program; if not, write to the Free Software Foundation, Inc., 19 | 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA. 20 | 21 | *****************************************************************************/ 22 | 23 | #ifndef __qsamplerChannelForm_h 24 | #define __qsamplerChannelForm_h 25 | 26 | #include "ui_qsamplerChannelForm.h" 27 | 28 | #include "qsamplerDevice.h" 29 | #include "qsamplerChannel.h" 30 | #include "qsamplerDeviceForm.h" 31 | 32 | #include 33 | 34 | 35 | namespace QSampler { 36 | 37 | //------------------------------------------------------------------------- 38 | // QSampler::Channelform -- Channel form interface. 39 | // 40 | 41 | class ChannelForm : public QDialog 42 | { 43 | Q_OBJECT 44 | 45 | public: 46 | 47 | ChannelForm(QWidget* pParent = nullptr); 48 | ~ChannelForm(); 49 | 50 | void setup(Channel* pChannel); 51 | 52 | void setupDevice(Device* pDevice, 53 | Device::DeviceType deviceTypeMode, 54 | const QString& sDriverName); 55 | 56 | void selectMidiDriverItem(const QString& sMidiDriver); 57 | void selectMidiDeviceItem(int iMidiItem); 58 | void selectAudioDriverItem(const QString& sAudioDriver); 59 | void selectAudioDeviceItem(int iAudioItem); 60 | 61 | protected slots: 62 | 63 | void accept(); 64 | void reject(); 65 | void openInstrumentFile(); 66 | void updateInstrumentName(); 67 | void selectMidiDriver(const QString& sMidiDriver); 68 | void selectMidiDevice(int iMidiItem); 69 | void setupMidiDevice(); 70 | void selectAudioDriver(const QString& sAudioDriver); 71 | void selectAudioDevice(int iAudioItem); 72 | void setupAudioDevice(); 73 | void updateDevices(); 74 | void optionsChanged(); 75 | void stabilizeForm(); 76 | 77 | void updateTableCellRenderers(); 78 | void updateTableCellRenderers( 79 | const QModelIndex& topLeft, const QModelIndex& bottomRight); 80 | 81 | private: 82 | 83 | Ui::qsamplerChannelForm m_ui; 84 | 85 | Channel* m_pChannel; 86 | int m_iDirtySetup; 87 | int m_iDirtyCount; 88 | QHash m_audioDevices; 89 | QHash m_midiDevices; 90 | DeviceForm* m_pDeviceForm; 91 | ChannelRoutingModel m_routingModel; 92 | ChannelRoutingDelegate m_routingDelegate; 93 | }; 94 | 95 | } // namespace QSampler 96 | 97 | #endif // __qsamplerChannelForm_h 98 | 99 | 100 | // end of qsamplerChannelForm.h 101 | -------------------------------------------------------------------------------- /src/qsamplerChannelFxForm.h: -------------------------------------------------------------------------------- 1 | // qsamplerChannelFxForm.h 2 | // 3 | /**************************************************************************** 4 | Copyright (C) 2010-2021, rncbc aka Rui Nuno Capela. All rights reserved. 5 | Copyright (C) 2008, Christian Schoenebeck 6 | 7 | This program is free software; you can redistribute it and/or 8 | modify it under the terms of the GNU General Public License 9 | as published by the Free Software Foundation; either version 2 10 | of the License, or (at your option) any later version. 11 | 12 | This program is distributed in the hope that it will be useful, 13 | but WITHOUT ANY WARRANTY; without even the implied warranty of 14 | MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the 15 | GNU General Public License for more details. 16 | 17 | You should have received a copy of the GNU General Public License along 18 | with this program; if not, write to the Free Software Foundation, Inc., 19 | 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA. 20 | 21 | *****************************************************************************/ 22 | 23 | #ifndef __qsamplerChannelFxForm_h 24 | #define __qsamplerChannelFxForm_h 25 | 26 | #include "ui_qsamplerChannelFxForm.h" 27 | 28 | #include "qsamplerChannel.h" 29 | #include "qsamplerDevice.h" 30 | 31 | #include 32 | 33 | namespace QSampler { 34 | 35 | class ChannelFxForm : public QDialog { 36 | Q_OBJECT 37 | public: 38 | ChannelFxForm(Channel *pSamplerChannel, QWidget *pParent = nullptr); 39 | ~ChannelFxForm(); 40 | 41 | protected slots: 42 | void onFxSendSelection(const QModelIndex& index); 43 | void onButtonClicked(QAbstractButton* button); 44 | void onCreateFxSend(); 45 | void onDestroyFxSend(); 46 | void onDepthCtrlChanged(int iMidiCtrl); 47 | void onCurrentSendDepthChanged(int depthPercent); 48 | void onRoutingTableChanged(); 49 | void updateTableCellRenderers(); 50 | void updateTableCellRenderers(const QModelIndex& topLeft, 51 | const QModelIndex& bottomRight); 52 | 53 | private: 54 | Ui::qsamplerChannelFxForm m_ui; 55 | 56 | Channel* m_pSamplerChannel; 57 | //int m_SamplerChannelID; 58 | Device* m_pAudioDevice; 59 | }; 60 | 61 | } // namespace QSampler 62 | 63 | #endif // __qsamplerChannelFxForm_h 64 | 65 | // end of qsamplerChannelFxForm.h 66 | -------------------------------------------------------------------------------- /src/qsamplerChannelFxForm.ui: -------------------------------------------------------------------------------- 1 | 2 | Christian Schoenebeck 3 | 4 | 5 | Copyright (C) 2010-2021, rncbc aka Rui Nuno Capela. All rights reserved. 6 | Copyright (C) 2008, Christian Schoenebeck 7 | 8 | This program is free software; you can redistribute it and/or 9 | modify it under the terms of the GNU General Public License 10 | as published by the Free Software Foundation; either version 2 11 | of the License, or (at your option) any later version. 12 | 13 | This program is distributed in the hope that it will be useful, 14 | but WITHOUT ANY WARRANTY; without even the implied warranty of 15 | MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the 16 | GNU General Public License for more details. 17 | 18 | You should have received a copy of the GNU General Public License along 19 | with this program; if not, write to the Free Software Foundation, Inc., 20 | 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA. 21 | 22 | 23 | qsamplerChannelFxForm 24 | 25 | 26 | 27 | 0 28 | 0 29 | 518 30 | 370 31 | 32 | 33 | 34 | Channel Effects 35 | 36 | 37 | 38 | 39 | 40 | 41 | 42 | FX Send Selection 43 | 44 | 45 | 46 | 47 | 48 | 49 | 0 50 | 0 51 | 52 | 53 | 54 | true 55 | 56 | 57 | 58 | 59 | 60 | 61 | 62 | 63 | Qt::Horizontal 64 | 65 | 66 | 67 | 40 68 | 20 69 | 70 | 71 | 72 | 73 | 74 | 75 | 76 | Creates a new FX Send. 77 | You have to select 'Apply' afterwards 78 | to actually create it on sampler side. 79 | 80 | 81 | Create 82 | 83 | 84 | :/images/itemNew.png 85 | 86 | 87 | 88 | 89 | 90 | 91 | Schedules the selected FX send for deletion. 92 | You have to select 'Apply' afterwards to 93 | actually destroy it on sampler side. 94 | 95 | 96 | Destroy 97 | 98 | 99 | :/images/formRemove.png 100 | 101 | 102 | 103 | 104 | 105 | 106 | 107 | 108 | 109 | 110 | 111 | 112 | 113 | 114 | 0 115 | 0 116 | 117 | 118 | 119 | FX Send's Parameters 120 | 121 | 122 | 123 | 124 | 125 | Send Depth 126 | MIDI Controller: 127 | 128 | 129 | 130 | 131 | 132 | 133 | 134 | 135 | 136 | Current Depth: 137 | 138 | 139 | 140 | 141 | 142 | 143 | Qt::AlignRight|Qt::AlignTrailing|Qt::AlignVCenter 144 | 145 | 146 | % 147 | 148 | 149 | 300 150 | 151 | 152 | 153 | 154 | 155 | 156 | 157 | 158 | 159 | 160 | 0 161 | 0 162 | 163 | 164 | 165 | Audio Routing 166 | 167 | 168 | 169 | 170 | 171 | 172 | 173 | 174 | 175 | 176 | 177 | 178 | 179 | 180 | 181 | Qt::Horizontal 182 | 183 | 184 | QDialogButtonBox::Apply|QDialogButtonBox::Cancel|QDialogButtonBox::NoButton|QDialogButtonBox::Ok|QDialogButtonBox::Reset 185 | 186 | 187 | 188 | 189 | 190 | 191 | 192 | 193 | 194 | 195 | buttonBox 196 | accepted() 197 | qsamplerChannelFxForm 198 | accept() 199 | 200 | 201 | 248 202 | 254 203 | 204 | 205 | 157 206 | 274 207 | 208 | 209 | 210 | 211 | buttonBox 212 | rejected() 213 | qsamplerChannelFxForm 214 | reject() 215 | 216 | 217 | 316 218 | 260 219 | 220 | 221 | 286 222 | 274 223 | 224 | 225 | 226 | 227 | 228 | -------------------------------------------------------------------------------- /src/qsamplerChannelStrip.h: -------------------------------------------------------------------------------- 1 | // qsamplerChannelStrip.h 2 | // 3 | /**************************************************************************** 4 | Copyright (C) 2004-2021, rncbc aka Rui Nuno Capela. All rights reserved. 5 | Copyright (C) 2007, 2008, 2014 Christian Schoenebeck 6 | 7 | This program is free software; you can redistribute it and/or 8 | modify it under the terms of the GNU General Public License 9 | as published by the Free Software Foundation; either version 2 10 | of the License, or (at your option) any later version. 11 | 12 | This program is distributed in the hope that it will be useful, 13 | but WITHOUT ANY WARRANTY; without even the implied warranty of 14 | MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the 15 | GNU General Public License for more details. 16 | 17 | You should have received a copy of the GNU General Public License along 18 | with this program; if not, write to the Free Software Foundation, Inc., 19 | 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA. 20 | 21 | *****************************************************************************/ 22 | 23 | #ifndef __qsamplerChannelStrip_h 24 | #define __qsamplerChannelStrip_h 25 | 26 | #include "ui_qsamplerChannelStrip.h" 27 | 28 | #include "qsamplerChannel.h" 29 | 30 | class QDragEnterEvent; 31 | class QTimer; 32 | class QMenu; 33 | 34 | 35 | namespace QSampler { 36 | 37 | //------------------------------------------------------------------------- 38 | // QSampler::ChannelStrip -- Channel strip form interface. 39 | // 40 | 41 | class ChannelStrip : public QWidget 42 | { 43 | Q_OBJECT 44 | 45 | public: 46 | 47 | ChannelStrip( QWidget *pParent = nullptr, Qt::WindowFlags wflags = Qt::WindowFlags()); 48 | ~ChannelStrip(); 49 | 50 | void setup(Channel *pChannel); 51 | 52 | Channel *channel() const; 53 | 54 | void setDisplayFont(const QFont& font); 55 | QFont displayFont() const; 56 | 57 | void setDisplayEffect(bool bDisplayEffect); 58 | 59 | void setMaxVolume(int iMaxVolume); 60 | 61 | bool updateInstrumentName(bool bForce); 62 | bool updateChannelVolume(); 63 | bool updateChannelInfo(); 64 | bool updateChannelUsage(); 65 | 66 | void resetErrorCount(); 67 | 68 | // Channel strip activation/selection. 69 | void setSelected(bool bSelected); 70 | bool isSelected() const; 71 | 72 | signals: 73 | 74 | void channelChanged(ChannelStrip*); 75 | 76 | public slots: 77 | 78 | bool channelSetup(); 79 | bool channelMute(bool bMute); 80 | bool channelSolo(bool bSolo); 81 | void channelEdit(); 82 | bool channelFxEdit(); 83 | bool channelReset(); 84 | void volumeChanged(int iVolume); 85 | 86 | void midiActivityLedOn(); 87 | 88 | protected: 89 | 90 | void dragEnterEvent(QDragEnterEvent* pDragEnterEvent); 91 | void dropEvent(QDropEvent* pDropEvent); 92 | void contextMenuEvent(QContextMenuEvent* pEvent); 93 | 94 | protected slots: 95 | 96 | void midiActivityLedOff(); 97 | void instrumentListPopupItemClicked(QAction* action); 98 | 99 | private: 100 | 101 | Ui::qsamplerChannelStrip m_ui; 102 | 103 | Channel *m_pChannel; 104 | int m_iDirtyChange; 105 | int m_iErrorCount; 106 | QMenu* m_instrumentListPopupMenu; 107 | 108 | QTimer *m_pMidiActivityTimer; 109 | 110 | // MIDI activity pixmap common resources. 111 | static int g_iMidiActivityRefCount; 112 | static QPixmap *g_pMidiActivityLedOn; 113 | static QPixmap *g_pMidiActivityLedOff; 114 | 115 | // Channel strip activation/selection. 116 | static ChannelStrip *g_pSelectedStrip; 117 | }; 118 | 119 | } // namespace QSampler 120 | 121 | #endif // __qsamplerChannelStrip_h 122 | 123 | 124 | // end of qsamplerChannelStrip.h 125 | -------------------------------------------------------------------------------- /src/qsamplerDevice.h: -------------------------------------------------------------------------------- 1 | // qsamplerDevice.h 2 | // 3 | /**************************************************************************** 4 | Copyright (C) 2004-2020, rncbc aka Rui Nuno Capela. All rights reserved. 5 | Copyright (C) 2007, 2008 Christian Schoenebeck 6 | 7 | This program is free software; you can redistribute it and/or 8 | modify it under the terms of the GNU General Public License 9 | as published by the Free Software Foundation; either version 2 10 | of the License, or (at your option) any later version. 11 | 12 | This program is distributed in the hope that it will be useful, 13 | but WITHOUT ANY WARRANTY; without even the implied warranty of 14 | MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the 15 | GNU General Public License for more details. 16 | 17 | You should have received a copy of the GNU General Public License along 18 | with this program; if not, write to the Free Software Foundation, Inc., 19 | 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA. 20 | 21 | *****************************************************************************/ 22 | 23 | #ifndef __qsamplerDevice_h 24 | #define __qsamplerDevice_h 25 | 26 | #include 27 | #include 28 | #include 29 | #include 30 | #include 31 | #include 32 | #include 33 | #include 34 | #include 35 | #include 36 | #include 37 | #include 38 | 39 | #include 40 | #include 41 | 42 | #include "qsamplerOptions.h" 43 | 44 | namespace QSampler { 45 | 46 | class DevicePort; 47 | 48 | // Special QListViewItem::rtti() unique return value. 49 | #define QSAMPLER_DEVICE_ITEM 1001 50 | 51 | 52 | //------------------------------------------------------------------------- 53 | // QSampler::DeviceParam - MIDI/Audio Device parameter structure. 54 | // 55 | 56 | class DeviceParam 57 | { 58 | public: 59 | 60 | // Constructor. 61 | DeviceParam(lscp_param_info_t *pParamInfo = nullptr, 62 | const char *pszValue = nullptr); 63 | 64 | // Initializer. 65 | void setParam(lscp_param_info_t *pParamInfo, 66 | const char *pszValue = nullptr); 67 | 68 | // Info structure field members. 69 | lscp_type_t type; 70 | QString description; 71 | bool mandatory; 72 | bool fix; 73 | bool multiplicity; 74 | QStringList depends; 75 | QString defaultv; 76 | QString range_min; 77 | QString range_max; 78 | QStringList possibilities; 79 | // The current parameter value. 80 | QString value; 81 | }; 82 | 83 | // Typedef'd parameter QMap. 84 | typedef QMap DeviceParamMap; 85 | 86 | // Typedef'd device port/channels QList. 87 | typedef QList DevicePortList; 88 | 89 | 90 | //------------------------------------------------------------------------- 91 | // QSampler::Device - MIDI/Audio Device structure. 92 | // 93 | 94 | class Device 95 | { 96 | public: 97 | 98 | // We use the same class for MIDI and audio device management 99 | enum DeviceType { None, Midi, Audio }; 100 | 101 | // Constructor. 102 | Device(DeviceType deviceType, int iDeviceID = -1); 103 | // Copy constructor. 104 | Device(const Device& device); 105 | 106 | // Default destructor. 107 | ~Device(); 108 | 109 | // Initializer. 110 | void setDevice(DeviceType deviceType, int iDeviceID = -1); 111 | 112 | // Driver name initializer. 113 | void setDriver(const QString& sDriverName); 114 | 115 | // Device property accessors. 116 | int deviceID() const; 117 | DeviceType deviceType() const; 118 | const QString& deviceTypeName() const; 119 | const QString& driverName() const; 120 | 121 | // Special device name formatter. 122 | QString deviceName() const; 123 | 124 | // Set the proper device parameter value. 125 | bool setParam (const QString& sParam, const QString& sValue); 126 | 127 | // Device parameters accessor. 128 | const DeviceParamMap& params() const; 129 | 130 | // Device port/channel list accessor. 131 | DevicePortList& ports(); 132 | 133 | // Device parameter dependency list refreshner. 134 | int refreshParams(); 135 | // Device port/channel list refreshner. 136 | int refreshPorts(); 137 | // Refresh/set dependencies given that some parameter has changed. 138 | int refreshDepends(const QString& sParam); 139 | 140 | // Create/destroy device methods. 141 | bool createDevice(); 142 | bool deleteDevice(); 143 | 144 | // Message logging methods (brainlessly mapped to main form's). 145 | void appendMessages (const QString& s) const; 146 | void appendMessagesColor (const QString& s, const QColor& rgb) const; 147 | void appendMessagesText (const QString& s) const; 148 | void appendMessagesError (const QString& s) const; 149 | void appendMessagesClient (const QString& s) const; 150 | 151 | // Device ids enumerator. 152 | static int *getDevices(lscp_client_t *pClient, 153 | DeviceType deviceType); 154 | static std::set getDeviceIDs(lscp_client_t *pClient, 155 | DeviceType deviceType); 156 | 157 | // Driver names enumerator. 158 | static QStringList getDrivers(lscp_client_t *pClient, 159 | DeviceType deviceType); 160 | 161 | private: 162 | 163 | // Refresh/set given parameter based on driver supplied dependencies. 164 | int refreshParam(const QString& sParam); 165 | 166 | // Instance variables. 167 | int m_iDeviceID; 168 | DeviceType m_deviceType; 169 | QString m_sDeviceType; 170 | QString m_sDriverName; 171 | QString m_sDeviceName; 172 | 173 | // Device parameter list. 174 | DeviceParamMap m_params; 175 | 176 | // Device port/channel list. 177 | DevicePortList m_ports; 178 | }; 179 | 180 | 181 | //------------------------------------------------------------------------- 182 | // QSampler::DevicePort - MIDI/Audio Device port/channel structure. 183 | // 184 | 185 | class DevicePort 186 | { 187 | public: 188 | 189 | // Constructor. 190 | DevicePort(Device& device, int iPortID); 191 | // Default destructor. 192 | ~DevicePort(); 193 | 194 | // Initializer. 195 | void setDevicePort(int iPortID); 196 | 197 | // Device port property accessors. 198 | int portID() const; 199 | const QString& portName() const; 200 | 201 | // Device port parameters accessor. 202 | const DeviceParamMap& params() const; 203 | 204 | // Set the proper device port/channel parameter value. 205 | bool setParam (const QString& sParam, const QString& sValue); 206 | 207 | private: 208 | 209 | // Device reference. 210 | Device& m_device; 211 | 212 | // Instance variables. 213 | int m_iPortID; 214 | QString m_sPortName; 215 | 216 | // Device port parameter list. 217 | DeviceParamMap m_params; 218 | }; 219 | 220 | 221 | //------------------------------------------------------------------------- 222 | // QSampler::DeviceItem - QTreeWidget device item. 223 | // 224 | 225 | class DeviceItem : public QTreeWidgetItem 226 | { 227 | public: 228 | 229 | // Constructors. 230 | DeviceItem(QTreeWidget *pTreeWidget, 231 | Device::DeviceType deviceType); 232 | DeviceItem(QTreeWidgetItem *pItem, 233 | Device::DeviceType deviceType, int iDeviceID); 234 | 235 | // Default destructor. 236 | ~DeviceItem(); 237 | 238 | // Instance accessors. 239 | Device& device(); 240 | 241 | private: 242 | 243 | // Instance variables. 244 | Device m_device; 245 | }; 246 | 247 | 248 | struct DeviceParameterRow { 249 | QString name; 250 | DeviceParam param; 251 | bool alive; // whether these params refer to an existing device 252 | // or for a device that is yet to be created 253 | }; 254 | 255 | 256 | //------------------------------------------------------------------------- 257 | // QSampler::AbstractDeviceParamModel - data model base class for device parameters 258 | // 259 | 260 | class AbstractDeviceParamModel : public QAbstractTableModel 261 | { 262 | Q_OBJECT 263 | 264 | public: 265 | 266 | AbstractDeviceParamModel(QObject *pParent = nullptr); 267 | 268 | // Overridden methods from subclass(es) 269 | int rowCount(const QModelIndex& parent = QModelIndex()) const; 270 | int columnCount(const QModelIndex& parent = QModelIndex() ) const; 271 | QVariant headerData(int section, 272 | Qt::Orientation orientation, int role = Qt::DisplayRole) const; 273 | Qt::ItemFlags flags(const QModelIndex& index) const; 274 | 275 | virtual void clear(); 276 | 277 | void refresh(const DeviceParamMap* params, bool bEditable); 278 | 279 | protected: 280 | 281 | const DeviceParamMap *m_pParams; 282 | bool m_bEditable; 283 | }; 284 | 285 | 286 | //------------------------------------------------------------------------- 287 | // QSampler::DeviceParamModel - data model for device parameters 288 | // (used for QTableView) 289 | 290 | class DeviceParamModel : public AbstractDeviceParamModel 291 | { 292 | Q_OBJECT 293 | 294 | public: 295 | 296 | DeviceParamModel(QObject *pParent = nullptr); 297 | 298 | // Overridden methods from subclass(es) 299 | QVariant data(const QModelIndex &index, int role) const; 300 | bool setData(const QModelIndex& index, 301 | const QVariant& value, int role = Qt::EditRole); 302 | 303 | void clear(); 304 | 305 | public slots: 306 | 307 | void refresh(Device* pDevice, bool bEditable); 308 | 309 | private: 310 | 311 | Device *m_pDevice; 312 | }; 313 | 314 | 315 | //------------------------------------------------------------------------- 316 | // QSampler::PortParamModel - data model for port parameters 317 | // (used for QTableView) 318 | 319 | class PortParamModel : public AbstractDeviceParamModel 320 | { 321 | Q_OBJECT 322 | 323 | public: 324 | 325 | PortParamModel(QObject *pParent = 0); 326 | 327 | // overridden methods from subclass(es) 328 | QVariant data(const QModelIndex &index, int role) const; 329 | bool setData(const QModelIndex& index, 330 | const QVariant& value, int role = Qt::EditRole); 331 | 332 | void clear(); 333 | 334 | public slots: 335 | 336 | void refresh(DevicePort* pPort, bool bEditable); 337 | 338 | private: 339 | 340 | DevicePort* m_pPort; 341 | }; 342 | 343 | 344 | //------------------------------------------------------------------------- 345 | // QSampler::DeviceParamDelegate - table cell renderer for device/port parameters 346 | // 347 | 348 | class DeviceParamDelegate : public QItemDelegate 349 | { 350 | Q_OBJECT 351 | 352 | public: 353 | 354 | DeviceParamDelegate(QObject *pParent = nullptr); 355 | 356 | QWidget* createEditor(QWidget *pParent, 357 | const QStyleOptionViewItem& option, const QModelIndex& index) const; 358 | void setEditorData(QWidget *pEditor, const QModelIndex& index) const; 359 | void setModelData(QWidget *pEditor, QAbstractItemModel *pModel, 360 | const QModelIndex& index) const; 361 | void updateEditorGeometry(QWidget* pEditor, 362 | const QStyleOptionViewItem& option, const QModelIndex& index) const; 363 | }; 364 | 365 | } // namespace QSampler 366 | 367 | // so we can use it i.e. through QVariant 368 | Q_DECLARE_METATYPE(QSampler::DeviceParameterRow) 369 | 370 | #endif // __qsamplerDevice_h 371 | 372 | 373 | // end of qsamplerDevice.h 374 | -------------------------------------------------------------------------------- /src/qsamplerDeviceForm.h: -------------------------------------------------------------------------------- 1 | // qsamplerDeviceForm.h 2 | // 3 | /**************************************************************************** 4 | Copyright (C) 2004-2020, rncbc aka Rui Nuno Capela. All rights reserved. 5 | Copyright (C) 2007, Christian Schoenebeck 6 | 7 | This program is free software; you can redistribute it and/or 8 | modify it under the terms of the GNU General Public License 9 | as published by the Free Software Foundation; either version 2 10 | of the License, or (at your option) any later version. 11 | 12 | This program is distributed in the hope that it will be useful, 13 | but WITHOUT ANY WARRANTY; without even the implied warranty of 14 | MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the 15 | GNU General Public License for more details. 16 | 17 | You should have received a copy of the GNU General Public License along 18 | with this program; if not, write to the Free Software Foundation, Inc., 19 | 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA. 20 | 21 | *****************************************************************************/ 22 | 23 | #ifndef __qsamplerDeviceForm_h 24 | #define __qsamplerDeviceForm_h 25 | 26 | #include "ui_qsamplerDeviceForm.h" 27 | 28 | #include "qsamplerDevice.h" 29 | 30 | 31 | namespace QSampler { 32 | 33 | //------------------------------------------------------------------------- 34 | // QSampler::DeviceForm -- Device form interface. 35 | // 36 | 37 | class DeviceForm : public QDialog 38 | { 39 | Q_OBJECT 40 | 41 | public: 42 | 43 | DeviceForm(QWidget *pParent = nullptr, Qt::WindowFlags wflags = Qt::WindowFlags()); 44 | ~DeviceForm(); 45 | 46 | void setDeviceTypeMode(Device::DeviceType deviceType); 47 | void setDriverName(const QString& sDriverName); 48 | void setDevice(Device *pDevice); 49 | 50 | public slots: 51 | 52 | void createDevice(); 53 | void deleteDevice(); 54 | void refreshDevices(); 55 | void selectDriver(int iDriver); 56 | void selectDevice(); 57 | void selectDevicePort(int iPort); 58 | void changeDeviceParam(int iRow, int iCol); 59 | void changeDevicePortParam(int iRow, int iCol); 60 | void deviceListViewContextMenu(const QPoint& pos); 61 | void stabilizeForm(); 62 | 63 | void updateCellRenderers(); 64 | void updateCellRenderers( 65 | const QModelIndex& topLeft, const QModelIndex& bottomRight); 66 | void updatePortCellRenderers(); 67 | void updatePortCellRenderers( 68 | const QModelIndex& topLeft, const QModelIndex& bottomRight); 69 | 70 | signals: 71 | 72 | void devicesChanged(); 73 | 74 | protected: 75 | 76 | void showEvent(QShowEvent* pShowEvent); 77 | void hideEvent(QHideEvent* pHideEvent); 78 | 79 | private: 80 | 81 | Ui::qsamplerDeviceForm m_ui; 82 | 83 | DeviceParamModel m_deviceParamModel; 84 | DeviceParamDelegate m_deviceParamDelegate; 85 | 86 | PortParamModel m_devicePortParamModel; 87 | DeviceParamDelegate m_devicePortParamDelegate; 88 | 89 | lscp_client_t *m_pClient; 90 | int m_iDirtySetup; 91 | int m_iDirtyCount; 92 | bool m_bNewDevice; 93 | Device::DeviceType m_deviceType; 94 | Device::DeviceType m_deviceTypeMode; 95 | DeviceItem *m_pAudioItems; 96 | DeviceItem *m_pMidiItems; 97 | }; 98 | 99 | } // namespace QSampler 100 | 101 | 102 | #endif // __qsamplerDeviceForm_h 103 | 104 | 105 | // end of qsamplerDeviceForm.h 106 | -------------------------------------------------------------------------------- /src/qsamplerDeviceStatusForm.cpp: -------------------------------------------------------------------------------- 1 | // qsamplerDeviceStatusForm.cpp 2 | // 3 | /**************************************************************************** 4 | Copyright (C) 2010-2020, rncbc aka Rui Nuno Capela. All rights reserved. 5 | Copyright (C) 2008,2019 Christian Schoenebeck 6 | 7 | This program is free software; you can redistribute it and/or 8 | modify it under the terms of the GNU General Public License 9 | as published by the Free Software Foundation; either version 2 10 | of the License, or (at your option) any later version. 11 | 12 | This program is distributed in the hope that it will be useful, 13 | but WITHOUT ANY WARRANTY; without even the implied warranty of 14 | MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the 15 | GNU General Public License for more details. 16 | 17 | You should have received a copy of the GNU General Public License along 18 | with this program; if not, write to the Free Software Foundation, Inc., 19 | 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA. 20 | 21 | *****************************************************************************/ 22 | 23 | #include "qsamplerAbout.h" 24 | #include "qsamplerDeviceStatusForm.h" 25 | 26 | #include "qsamplerMainForm.h" 27 | 28 | #include 29 | 30 | #if QT_VERSION < QT_VERSION_CHECK(4, 5, 0) 31 | namespace Qt { 32 | const WindowFlags WindowCloseButtonHint = WindowFlags(0x08000000); 33 | } 34 | #endif 35 | 36 | 37 | namespace QSampler { 38 | 39 | //------------------------------------------------------------------------- 40 | // QSampler::MidiActivityLED -- Graphical indicator for MIDI activity. 41 | // 42 | 43 | // MIDI activity pixmap common resources. 44 | int MidiActivityLED::g_iMidiActivityRefCount = 0; 45 | QPixmap *MidiActivityLED::g_pMidiActivityLedOn = nullptr; 46 | QPixmap *MidiActivityLED::g_pMidiActivityLedOff = nullptr; 47 | 48 | 49 | MidiActivityLED::MidiActivityLED ( QString sText, QWidget *pParent ) 50 | : QLabel(sText, pParent) 51 | { 52 | if (++g_iMidiActivityRefCount == 1) { 53 | g_pMidiActivityLedOn = new QPixmap(":/images/ledon1.png"); 54 | g_pMidiActivityLedOff = new QPixmap(":/images/ledoff1.png"); 55 | } 56 | 57 | setPixmap(*g_pMidiActivityLedOff); 58 | #ifndef CONFIG_EVENT_DEVICE_MIDI 59 | setToolTip("MIDI Activity disabled"); 60 | #endif 61 | m_timer.setSingleShot(true); 62 | 63 | QObject::connect(&m_timer, 64 | SIGNAL(timeout()), 65 | SLOT(midiActivityLedOff()) 66 | ); 67 | } 68 | 69 | MidiActivityLED::~MidiActivityLED (void) 70 | { 71 | if (--g_iMidiActivityRefCount == 0) { 72 | if (g_pMidiActivityLedOn) 73 | delete g_pMidiActivityLedOn; 74 | g_pMidiActivityLedOn = nullptr; 75 | if (g_pMidiActivityLedOff) 76 | delete g_pMidiActivityLedOff; 77 | g_pMidiActivityLedOff = nullptr; 78 | } 79 | } 80 | 81 | 82 | void MidiActivityLED::midiActivityLedOn (void) 83 | { 84 | setPixmap(*g_pMidiActivityLedOn); 85 | m_timer.start(100); 86 | } 87 | 88 | 89 | void MidiActivityLED::midiActivityLedOff (void) 90 | { 91 | setPixmap(*g_pMidiActivityLedOff); 92 | } 93 | 94 | 95 | //------------------------------------------------------------------------- 96 | // QSampler::DeviceStatusForm -- Device status informations window. 97 | // 98 | 99 | std::map DeviceStatusForm::g_instances; 100 | 101 | 102 | DeviceStatusForm::DeviceStatusForm ( 103 | int DeviceID, QWidget *pParent, Qt::WindowFlags wflags ) 104 | : QWidget(pParent, wflags) 105 | { 106 | m_pDevice = new Device(Device::Midi, DeviceID); 107 | 108 | setLayout(new QGridLayout(/*this*/)); 109 | updateGUIPorts(); // build the GUI 110 | 111 | m_pVisibleAction = new QAction(this); 112 | m_pVisibleAction->setCheckable(true); 113 | m_pVisibleAction->setChecked(false); 114 | m_pVisibleAction->setText(m_pDevice->deviceName()); 115 | m_pVisibleAction->setToolTip( 116 | QString("MIDI Device ID: ") + 117 | QString::number(m_pDevice->deviceID()) 118 | ); 119 | 120 | QObject::connect(m_pVisibleAction, 121 | SIGNAL(toggled(bool)), 122 | SLOT(setVisible(bool)) 123 | ); 124 | 125 | setWindowTitle(tr("%1 Status").arg(m_pDevice->deviceName())); 126 | } 127 | 128 | 129 | void DeviceStatusForm::updateGUIPorts (void) 130 | { 131 | // refresh device informations 132 | m_pDevice->setDevice(m_pDevice->deviceType(), m_pDevice->deviceID()); 133 | DevicePortList ports = m_pDevice->ports(); 134 | 135 | // clear the GUI 136 | QGridLayout *pLayout = static_cast (layout()); 137 | for (int i = pLayout->count() - 1; i >= 0; --i) { 138 | QLayoutItem *pItem = pLayout->itemAt(i); 139 | if (pItem) { 140 | pLayout->removeItem(pItem); 141 | if (pItem->widget()) 142 | delete pItem->widget(); 143 | delete pItem; 144 | } 145 | } 146 | 147 | m_midiActivityLEDs.clear(); 148 | 149 | // rebuild the GUI 150 | for (int i = 0; i < ports.size(); ++i) { 151 | MidiActivityLED *pLED = new MidiActivityLED(); 152 | m_midiActivityLEDs.push_back(pLED); 153 | pLayout->addWidget(pLED, i, 0); 154 | QLabel *pLabel = new QLabel( 155 | m_pDevice->deviceTypeName() 156 | + ' ' + m_pDevice->driverName() 157 | + ' ' + ports[i]->portName()); 158 | pLayout->addWidget(pLabel, i, 1, Qt::AlignLeft); 159 | } 160 | } 161 | 162 | 163 | DeviceStatusForm::~DeviceStatusForm (void) 164 | { 165 | if (m_pDevice) delete m_pDevice; 166 | } 167 | 168 | 169 | QAction* DeviceStatusForm::visibleAction (void) 170 | { 171 | return m_pVisibleAction; 172 | } 173 | 174 | void DeviceStatusForm::closeEvent ( QCloseEvent *pCloseEvent ) 175 | { 176 | m_pVisibleAction->setChecked(false); 177 | 178 | pCloseEvent->accept(); 179 | } 180 | 181 | 182 | void DeviceStatusForm::midiArrived ( int iPort ) 183 | { 184 | if (uint(iPort) >= m_midiActivityLEDs.size()) 185 | return; 186 | 187 | m_midiActivityLEDs[iPort]->midiActivityLedOn(); 188 | } 189 | 190 | 191 | DeviceStatusForm *DeviceStatusForm::getInstance ( int iDeviceID ) 192 | { 193 | std::map::iterator iter 194 | = g_instances.find(iDeviceID); 195 | return ((iter != g_instances.end()) ? iter->second : nullptr); 196 | } 197 | 198 | 199 | const std::map& DeviceStatusForm::getInstances (void) 200 | { 201 | return g_instances; 202 | } 203 | 204 | void DeviceStatusForm::deleteAllInstances (void) 205 | { 206 | std::map::iterator iter = g_instances.begin(); 207 | for ( ; iter != g_instances.end(); ++iter) { 208 | iter->second->hide(); 209 | delete iter->second; 210 | } 211 | 212 | g_instances.clear(); 213 | } 214 | 215 | 216 | void DeviceStatusForm::onDevicesChanged (void) 217 | { 218 | MainForm* pMainForm = MainForm::getInstance(); 219 | if (pMainForm && pMainForm->client()) { 220 | std::set deviceIDs 221 | = Device::getDeviceIDs(pMainForm->client(), Device::Midi); 222 | // hide and delete status forms whose device has been destroyed 223 | std::map::iterator iter = g_instances.begin(); 224 | while (iter != g_instances.end()) { 225 | if (deviceIDs.find(iter->first) == deviceIDs.end()) { 226 | iter->second->hide(); 227 | delete iter->second; 228 | // postfix increment here to avoid iterator invalidation (crash) 229 | g_instances.erase(iter++); 230 | } else ++iter; 231 | } 232 | // create status forms for new devices 233 | std::set::iterator it = deviceIDs.begin(); 234 | for ( ; it != deviceIDs.end(); ++it) { 235 | if (g_instances.find(*it) == g_instances.end()) { 236 | // What style do we create these forms? 237 | Qt::WindowFlags wflags = Qt::Window 238 | | Qt::CustomizeWindowHint 239 | | Qt::WindowTitleHint 240 | | Qt::WindowSystemMenuHint 241 | | Qt::WindowMinMaxButtonsHint 242 | | Qt::WindowCloseButtonHint; 243 | Options *pOptions = pMainForm->options(); 244 | if (pOptions && pOptions->bKeepOnTop) 245 | wflags |= Qt::Tool; 246 | // Create the form, giving it the device id. 247 | DeviceStatusForm *pStatusForm 248 | = new DeviceStatusForm(*it, nullptr, wflags); 249 | g_instances[*it] = pStatusForm; 250 | } 251 | } 252 | } 253 | } 254 | 255 | 256 | void DeviceStatusForm::onDeviceChanged ( int iDeviceID ) 257 | { 258 | DeviceStatusForm *pStatusForm 259 | = DeviceStatusForm::getInstance(iDeviceID); 260 | if (pStatusForm) 261 | pStatusForm->updateGUIPorts(); 262 | } 263 | 264 | 265 | } // namespace QSampler 266 | 267 | // end of qsamplerDeviceStatusForm.cpp 268 | -------------------------------------------------------------------------------- /src/qsamplerDeviceStatusForm.h: -------------------------------------------------------------------------------- 1 | // qsamplerDeviceStatusForm.h 2 | // 3 | /**************************************************************************** 4 | Copyright (C) 2010-2020, rncbc aka Rui Nuno Capela. All rights reserved. 5 | Copyright (C) 2008,2019 Christian Schoenebeck 6 | 7 | This program is free software; you can redistribute it and/or 8 | modify it under the terms of the GNU General Public License 9 | as published by the Free Software Foundation; either version 2 10 | of the License, or (at your option) any later version. 11 | 12 | This program is distributed in the hope that it will be useful, 13 | but WITHOUT ANY WARRANTY; without even the implied warranty of 14 | MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the 15 | GNU General Public License for more details. 16 | 17 | You should have received a copy of the GNU General Public License along 18 | with this program; if not, write to the Free Software Foundation, Inc., 19 | 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA. 20 | 21 | *****************************************************************************/ 22 | 23 | #ifndef __qsamplerDeviceStatusForm_h 24 | #define __qsamplerDeviceStatusForm_h 25 | 26 | #include "qsamplerDevice.h" 27 | 28 | #include 29 | #include 30 | #include 31 | #include 32 | #include 33 | 34 | #include 35 | 36 | 37 | namespace QSampler { 38 | 39 | class MidiActivityLED : public QLabel 40 | { 41 | Q_OBJECT 42 | 43 | public: 44 | 45 | MidiActivityLED(QString sText = QString(), QWidget *pParent = nullptr); 46 | ~MidiActivityLED(); 47 | 48 | void midiActivityLedOn(); 49 | 50 | protected slots: 51 | 52 | void midiActivityLedOff(); 53 | 54 | private: 55 | 56 | QTimer m_timer; 57 | 58 | // MIDI activity pixmap common resources. 59 | static int g_iMidiActivityRefCount; 60 | static QPixmap *g_pMidiActivityLedOn; 61 | static QPixmap *g_pMidiActivityLedOff; 62 | }; 63 | 64 | 65 | class DeviceStatusForm : public QWidget 66 | { 67 | Q_OBJECT 68 | 69 | public: 70 | 71 | DeviceStatusForm(int DeviceID, QWidget *pParent = nullptr, 72 | Qt::WindowFlags wflags = Qt::WindowFlags()); 73 | ~DeviceStatusForm(); 74 | 75 | QAction *visibleAction(); 76 | 77 | void midiArrived(int iPort); 78 | 79 | static DeviceStatusForm *getInstance(int iDeviceID); 80 | static const std::map& getInstances(); 81 | 82 | static void onDevicesChanged(); 83 | static void onDeviceChanged(int iDeviceID); 84 | 85 | static void deleteAllInstances(); 86 | 87 | protected: 88 | 89 | void closeEvent(QCloseEvent *pCloseEvent); 90 | void updateGUIPorts(); 91 | 92 | private: 93 | 94 | int m_DeviceID; 95 | Device *m_pDevice; 96 | QAction *m_pVisibleAction; 97 | 98 | std::vector m_midiActivityLEDs; 99 | 100 | static std::map g_instances; 101 | }; 102 | 103 | } // namespace QSampler 104 | 105 | 106 | #endif // __qsamplerDeviceStatusForm_h 107 | 108 | // end of qsamplerDeviceStatusForm.h 109 | -------------------------------------------------------------------------------- /src/qsamplerFxSend.cpp: -------------------------------------------------------------------------------- 1 | // qsamplerFxSend.cpp 2 | // 3 | /**************************************************************************** 4 | Copyright (C) 2004-2019, rncbc aka Rui Nuno Capela. All rights reserved. 5 | Copyright (C) 2008, Christian Schoenebeck 6 | 7 | This program is free software; you can redistribute it and/or 8 | modify it under the terms of the GNU General Public License 9 | as published by the Free Software Foundation; either version 2 10 | of the License, or (at your option) any later version. 11 | 12 | This program is distributed in the hope that it will be useful, 13 | but WITHOUT ANY WARRANTY; without even the implied warranty of 14 | MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the 15 | GNU General Public License for more details. 16 | 17 | You should have received a copy of the GNU General Public License along 18 | with this program; if not, write to the Free Software Foundation, Inc., 19 | 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA. 20 | 21 | *****************************************************************************/ 22 | 23 | #include "qsamplerAbout.h" 24 | #include "qsamplerFxSend.h" 25 | #include "qsamplerUtilities.h" 26 | #include "qsamplerOptions.h" 27 | #include "qsamplerMainForm.h" 28 | 29 | namespace QSampler { 30 | 31 | // marks FxSend objects which don't exist on sampler side yet 32 | #define NEW_FX_SEND -1 33 | 34 | FxSend::FxSend(int SamplerChannelID, int FxSendID) : 35 | m_iSamplerChannelID(SamplerChannelID), 36 | m_iFxSendID(FxSendID), m_bDelete(false), m_bModified(false) 37 | { 38 | m_MidiCtrl = 91; 39 | m_Depth = 0.0f; 40 | } 41 | 42 | FxSend::FxSend(int SamplerChannelID) : 43 | m_iSamplerChannelID(SamplerChannelID), 44 | m_iFxSendID(NEW_FX_SEND), m_bDelete(false), m_bModified(true) 45 | { 46 | m_MidiCtrl = 91; 47 | m_Depth = 0.0f; 48 | } 49 | 50 | FxSend::~FxSend() { 51 | } 52 | 53 | int FxSend::id() const { 54 | return m_iFxSendID; 55 | } 56 | 57 | bool FxSend::isNew() const { 58 | return m_iFxSendID == NEW_FX_SEND; 59 | } 60 | 61 | void FxSend::setDeletion(bool bDelete) { 62 | m_bDelete = bDelete; 63 | m_bModified = true; 64 | } 65 | 66 | bool FxSend::deletion() const { 67 | return m_bDelete; 68 | } 69 | 70 | void FxSend::setName(const QString& sName) { 71 | m_FxSendName = sName; 72 | m_bModified = true; 73 | } 74 | 75 | bool FxSend::isModified() const { 76 | return m_bModified; 77 | } 78 | 79 | const QString& FxSend::name() const { 80 | return m_FxSendName; 81 | } 82 | 83 | void FxSend::setSendDepthMidiCtrl(int iMidiController) { 84 | m_MidiCtrl = iMidiController; 85 | m_bModified = true; 86 | } 87 | 88 | int FxSend::sendDepthMidiCtrl() const { 89 | return m_MidiCtrl; 90 | } 91 | 92 | void FxSend::setCurrentDepth(float depth) { 93 | m_Depth = depth; 94 | m_bModified = true; 95 | } 96 | 97 | float FxSend::currentDepth() const { 98 | return m_Depth; 99 | } 100 | 101 | int FxSend::audioChannel(int iAudioSrc) const { 102 | if (iAudioSrc < 0 || iAudioSrc >= m_AudioRouting.size()) 103 | return -1; 104 | 105 | return m_AudioRouting[iAudioSrc]; 106 | } 107 | 108 | bool FxSend::setAudioChannel(int iAudioSrc, int iAudioDst) { 109 | if (iAudioSrc < 0 || iAudioSrc >= m_AudioRouting.size()) 110 | return false; 111 | 112 | m_AudioRouting[iAudioSrc] = iAudioDst; 113 | m_bModified = true; 114 | 115 | return true; 116 | } 117 | 118 | const FxSendRoutingMap& FxSend::audioRouting() const { 119 | return m_AudioRouting; 120 | } 121 | 122 | bool FxSend::getFromSampler() { 123 | #if CONFIG_FXSEND 124 | m_bModified = false; 125 | 126 | // in case this is a new, actually not yet existing FX send, ignore update 127 | if (isNew()) 128 | return true; 129 | 130 | MainForm *pMainForm = MainForm::getInstance(); 131 | if (!pMainForm || !pMainForm->client()) 132 | return false; 133 | 134 | lscp_fxsend_info_t* pFxSendInfo = 135 | ::lscp_get_fxsend_info( 136 | pMainForm->client(), 137 | m_iSamplerChannelID, 138 | m_iFxSendID); 139 | 140 | if (!pFxSendInfo) { 141 | pMainForm->appendMessagesClient("lscp_get_fxsend_info"); 142 | return false; 143 | } 144 | 145 | m_FxSendName = qsamplerUtilities::lscpEscapedTextToRaw(pFxSendInfo->name); 146 | m_MidiCtrl = pFxSendInfo->midi_controller; 147 | m_Depth = pFxSendInfo->level; 148 | 149 | m_AudioRouting.clear(); 150 | if (pFxSendInfo->audio_routing) 151 | for (int i = 0; pFxSendInfo->audio_routing[i] != -1; ++i) 152 | m_AudioRouting[i] = pFxSendInfo->audio_routing[i]; 153 | 154 | return true; 155 | #else // CONFIG_FXSEND 156 | return false; 157 | #endif // CONFIG_FXSEND 158 | } 159 | 160 | bool FxSend::applyToSampler() { 161 | #if CONFIG_FXSEND 162 | MainForm *pMainForm = MainForm::getInstance(); 163 | if (!pMainForm || !pMainForm->client()) 164 | return false; 165 | 166 | // in case FX send doesn't exist on sampler side yet, create it 167 | if (isNew()) { 168 | // doesn't exist and scheduled for deletion? nothing to do 169 | if (deletion()) { 170 | m_bModified = false; 171 | return true; 172 | } 173 | 174 | int result = 175 | ::lscp_create_fxsend( 176 | pMainForm->client(), 177 | m_iSamplerChannelID, 178 | m_MidiCtrl, nullptr 179 | ); 180 | if (result == -1) { 181 | pMainForm->appendMessagesClient("lscp_create_fxsend"); 182 | return false; 183 | } 184 | m_iFxSendID = result; 185 | } 186 | 187 | lscp_status_t result; 188 | 189 | // delete FX send on sampler side 190 | if (deletion()) { 191 | result = 192 | ::lscp_destroy_fxsend( 193 | pMainForm->client(), m_iSamplerChannelID, m_iFxSendID 194 | ); 195 | if (result != LSCP_OK) { 196 | pMainForm->appendMessagesClient("lscp_destroy_fxsend"); 197 | return false; 198 | } 199 | m_bModified = false; 200 | return true; 201 | } 202 | 203 | // set FX send depth MIDI controller 204 | result = 205 | ::lscp_set_fxsend_midi_controller( 206 | pMainForm->client(), 207 | m_iSamplerChannelID, m_iFxSendID, m_MidiCtrl 208 | ); 209 | if (result != LSCP_OK) { 210 | pMainForm->appendMessagesClient("lscp_set_fxsend_midi_controller"); 211 | return false; 212 | } 213 | 214 | #if CONFIG_FXSEND_RENAME 215 | // set FX send's name 216 | result = 217 | ::lscp_set_fxsend_name( 218 | pMainForm->client(), 219 | m_iSamplerChannelID, m_iFxSendID, 220 | qsamplerUtilities::lscpEscapeText( 221 | m_FxSendName 222 | ).constData() 223 | ); 224 | if (result != LSCP_OK) { 225 | pMainForm->appendMessagesClient("lscp_set_fxsend_name"); 226 | return false; 227 | } 228 | #endif // CONFIG_FXSEND_RENAME 229 | 230 | // set FX send current send level 231 | result = 232 | ::lscp_set_fxsend_level( 233 | pMainForm->client(), 234 | m_iSamplerChannelID, m_iFxSendID, m_Depth 235 | ); 236 | if (result != LSCP_OK) { 237 | pMainForm->appendMessagesClient("lscp_set_fxsend_level"); 238 | return false; 239 | } 240 | 241 | // set FX send's audio routing 242 | for (int i = 0; i < m_AudioRouting.size(); ++i) { 243 | result = 244 | ::lscp_set_fxsend_audio_channel( 245 | pMainForm->client(), m_iSamplerChannelID, m_iFxSendID, 246 | i, /*audio source*/ 247 | m_AudioRouting[i] /*audio destination*/ 248 | ); 249 | if (result != LSCP_OK) { 250 | pMainForm->appendMessagesClient("lscp_set_fxsend_audio_channel"); 251 | return false; 252 | } 253 | } 254 | 255 | m_bModified = false; 256 | return true; 257 | #else // CONFIG_FXSEND 258 | return false; 259 | #endif // CONFIG_FXSEND 260 | } 261 | 262 | QList FxSend::allFxSendsOfSamplerChannel(int samplerChannelID) { 263 | QList sends; 264 | 265 | MainForm *pMainForm = MainForm::getInstance(); 266 | if (!pMainForm || !pMainForm->client()) 267 | return sends; 268 | 269 | #ifdef CONFIG_FXSEND 270 | int *piSends = ::lscp_list_fxsends(pMainForm->client(), samplerChannelID); 271 | if (!piSends) { 272 | if (::lscp_client_get_errno(pMainForm->client())) 273 | pMainForm->appendMessagesClient("lscp_list_fxsends"); 274 | } else { 275 | for (int iSend = 0; piSends[iSend] >= 0; ++iSend) 276 | sends.append(piSends[iSend]); 277 | } 278 | #endif // CONFIG_FXSEND 279 | 280 | return sends; 281 | } 282 | 283 | } // namespace QSampler 284 | 285 | // end of qsamplerFxSend.cpp 286 | -------------------------------------------------------------------------------- /src/qsamplerFxSend.h: -------------------------------------------------------------------------------- 1 | // qsamplerFxSend.h 2 | // 3 | /**************************************************************************** 4 | Copyright (C) 2004-2019, rncbc aka Rui Nuno Capela. All rights reserved. 5 | Copyright (C) 2008, Christian Schoenebeck 6 | 7 | This program is free software; you can redistribute it and/or 8 | modify it under the terms of the GNU General Public License 9 | as published by the Free Software Foundation; either version 2 10 | of the License, or (at your option) any later version. 11 | 12 | This program is distributed in the hope that it will be useful, 13 | but WITHOUT ANY WARRANTY; without even the implied warranty of 14 | MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the 15 | GNU General Public License for more details. 16 | 17 | You should have received a copy of the GNU General Public License along 18 | with this program; if not, write to the Free Software Foundation, Inc., 19 | 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA. 20 | 21 | *****************************************************************************/ 22 | 23 | #ifndef __qsamplerFxSend_h 24 | #define __qsamplerFxSend_h 25 | 26 | #include 27 | #include 28 | #include 29 | 30 | namespace QSampler { 31 | 32 | // Typedef'd QMap. 33 | typedef QMap FxSendRoutingMap; 34 | 35 | class FxSend { 36 | public: 37 | // retrieve existing FX send 38 | FxSend(int SamplerChannelID, int FxSendID); 39 | 40 | // create a new FX send 41 | FxSend(int SamplerChannelID); 42 | 43 | ~FxSend(); 44 | 45 | int id() const; 46 | 47 | // whether FX send exists on sampler side yet 48 | bool isNew() const; 49 | 50 | // whether scheduled for deletion 51 | bool deletion() const; 52 | void setDeletion(bool bDelete); 53 | 54 | bool isModified() const; 55 | 56 | void setName(const QString& sName); 57 | const QString& name() const; 58 | 59 | void setSendDepthMidiCtrl(int iMidiController); 60 | int sendDepthMidiCtrl() const; 61 | 62 | void setCurrentDepth(float depth); 63 | float currentDepth() const; 64 | 65 | // Audio routing accessors. 66 | int audioChannel(int iAudioSrc) const; 67 | bool setAudioChannel(int iAudioSrc, int iAudioDst); 68 | // The audio routing map itself. 69 | const FxSendRoutingMap& audioRouting() const; 70 | 71 | bool getFromSampler(); 72 | bool applyToSampler(); 73 | 74 | static QList allFxSendsOfSamplerChannel(int samplerChannelID); 75 | 76 | private: 77 | int m_iSamplerChannelID; 78 | int m_iFxSendID; 79 | bool m_bDelete; 80 | bool m_bModified; 81 | 82 | QString m_FxSendName; 83 | int m_MidiCtrl; 84 | float m_Depth; 85 | FxSendRoutingMap m_AudioRouting; 86 | }; 87 | 88 | } // namespace QSampler 89 | 90 | #endif // __qsamplerFxSend_h 91 | 92 | // end of __qsamplerFxSend.h 93 | -------------------------------------------------------------------------------- /src/qsamplerFxSendsModel.cpp: -------------------------------------------------------------------------------- 1 | // qsamplerFxSendList.cpp 2 | // 3 | /**************************************************************************** 4 | Copyright (C) 2010-2019, rncbc aka Rui Nuno Capela. All rights reserved. 5 | Copyright (C) 2008, Christian Schoenebeck 6 | 7 | This program is free software; you can redistribute it and/or 8 | modify it under the terms of the GNU General Public License 9 | as published by the Free Software Foundation; either version 2 10 | of the License, or (at your option) any later version. 11 | 12 | This program is distributed in the hope that it will be useful, 13 | but WITHOUT ANY WARRANTY; without even the implied warranty of 14 | MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the 15 | GNU General Public License for more details. 16 | 17 | You should have received a copy of the GNU General Public License 18 | along with this program; if not, write to the Free Software 19 | Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. 20 | 21 | *****************************************************************************/ 22 | 23 | #include "qsamplerAbout.h" 24 | #include "qsamplerFxSendsModel.h" 25 | #include "qsamplerFxSend.h" 26 | 27 | #include 28 | #include 29 | #include 30 | 31 | namespace QSampler { 32 | 33 | 34 | FxSendsModel::FxSendsModel ( int iChannelID, QObject* pParent ) 35 | : QAbstractListModel(pParent) 36 | { 37 | m_iChannelID = iChannelID; 38 | cleanRefresh(); 39 | } 40 | 41 | 42 | int FxSendsModel::rowCount ( const QModelIndex& /*parent*/ ) const 43 | { 44 | return m_fxSends.size(); 45 | } 46 | 47 | 48 | QVariant FxSendsModel::data ( const QModelIndex& index, int role ) const 49 | { 50 | if (!index.isValid()) 51 | return QVariant(); 52 | 53 | switch (role) { 54 | case Qt::DisplayRole: 55 | return m_fxSends[index.row()].name(); 56 | break; 57 | case Qt::ToolTipRole: 58 | if (m_fxSends[index.row()].deletion()) 59 | return QString( 60 | "Scheduled for deletion. Click on 'Apply' to actually " 61 | "destroy FX Send." 62 | ); 63 | return (m_fxSends[index.row()].isNew()) ? 64 | QString( 65 | "New FX send. Click on 'Apply' to actually " 66 | "perform creation." 67 | ) : 68 | QString("FX Send ID ") + 69 | QString::number(m_fxSends.at(index.row()).id()); 70 | break; 71 | case Qt::ForegroundRole: 72 | if (m_fxSends.at(index.row()).deletion()) 73 | return QBrush(Qt::red); 74 | if (m_fxSends.at(index.row()).isNew()) 75 | return QBrush(Qt::green); 76 | break; 77 | case Qt::DecorationRole: 78 | if (m_fxSends.at(index.row()).deletion()) 79 | return QIcon(":/images/formRemove.png"); 80 | if (m_fxSends.at(index.row()).isNew()) 81 | return QIcon(":/images/itemNew.png"); 82 | if (m_fxSends.at(index.row()).isModified()) 83 | return QIcon(":/images/formEdit.png"); 84 | return QIcon(":/images/itemFile.png"); 85 | case Qt::FontRole: { 86 | if (m_fxSends.at(index.row()).isModified()) { 87 | QFont font; 88 | font.setBold(true); 89 | return font; 90 | } 91 | break; 92 | } 93 | default: 94 | return QVariant(); 95 | } 96 | 97 | return QVariant(); 98 | } 99 | 100 | 101 | bool FxSendsModel::setData ( 102 | const QModelIndex& index, const QVariant& value, int /*role*/ ) 103 | { 104 | if (!index.isValid()) 105 | return false; 106 | 107 | m_fxSends[index.row()].setName(value.toString()); 108 | emit dataChanged(index, index); 109 | emit fxSendsDirtyChanged(true); 110 | 111 | return true; 112 | } 113 | 114 | 115 | QVariant FxSendsModel::headerData ( 116 | int section, Qt::Orientation /*orientation*/, int role ) const 117 | { 118 | if (role == Qt::DisplayRole && section == 0) 119 | return QString("FX Send Name"); 120 | else 121 | return QVariant(); 122 | } 123 | 124 | 125 | Qt::ItemFlags FxSendsModel::flags ( const QModelIndex& /*index*/) const 126 | { 127 | return Qt::ItemIsEditable | Qt::ItemIsEnabled; 128 | } 129 | 130 | 131 | FxSend *FxSendsModel::addFxSend (void) 132 | { 133 | #if CONFIG_FXSEND 134 | FxSend fxSend(m_iChannelID); 135 | fxSend.setName("New FX Send"); 136 | m_fxSends.push_back(fxSend); 137 | createIndex(m_fxSends.size() - 1, 0); 138 | #if QT_VERSION < QT_VERSION_CHECK(5, 0, 0) 139 | QAbstractListModel::reset(); 140 | #else 141 | QAbstractListModel::beginResetModel(); 142 | QAbstractListModel::endResetModel(); 143 | #endif 144 | emit fxSendsDirtyChanged(true); 145 | return &m_fxSends.last(); 146 | #else 147 | return nullptr; 148 | #endif // CONFIG_FXSEND 149 | } 150 | 151 | 152 | FxSend *FxSendsModel::fxSend ( const QModelIndex& index ) 153 | { 154 | if (!index.isValid()) 155 | return nullptr; 156 | 157 | return &m_fxSends[index.row()]; 158 | } 159 | 160 | 161 | void FxSendsModel::removeFxSend ( const QModelIndex& index ) 162 | { 163 | FxSend *pFxSend = fxSend(index); 164 | if (!pFxSend) return; 165 | pFxSend->setDeletion(true); 166 | #if QT_VERSION < QT_VERSION_CHECK(5, 0, 0) 167 | QAbstractListModel::reset(); 168 | #else 169 | QAbstractListModel::beginResetModel(); 170 | QAbstractListModel::endResetModel(); 171 | #endif 172 | emit fxSendsDirtyChanged(true); 173 | } 174 | 175 | 176 | void FxSendsModel::cleanRefresh (void) 177 | { 178 | m_fxSends.clear(); 179 | const QList& sends = FxSend::allFxSendsOfSamplerChannel(m_iChannelID); 180 | for (int i = 0; i < sends.size(); ++i) { 181 | const int iFxSendId = sends.at(i); 182 | FxSend fxSend(m_iChannelID, iFxSendId); 183 | fxSend.getFromSampler(); 184 | m_fxSends.push_back(fxSend); 185 | } 186 | #if QT_VERSION < QT_VERSION_CHECK(5, 0, 0) 187 | QAbstractListModel::reset(); 188 | #else 189 | QAbstractListModel::beginResetModel(); 190 | QAbstractListModel::endResetModel(); 191 | #endif 192 | emit fxSendsDirtyChanged(false); 193 | } 194 | 195 | 196 | void FxSendsModel::onExternalModifiication ( const QModelIndex& index ) 197 | { 198 | if (!index.isValid()) return; 199 | emit dataChanged(index, index); 200 | emit fxSendsDirtyChanged(true); 201 | } 202 | 203 | 204 | void FxSendsModel::applyToSampler (void) 205 | { 206 | for (int i = 0; i < m_fxSends.size(); ++i) 207 | m_fxSends[i].applyToSampler(); 208 | 209 | // make a clean refresh 210 | // (throws out all FxSend objects marked for deletion) 211 | cleanRefresh(); 212 | } 213 | 214 | 215 | } // namespace QSampler 216 | 217 | 218 | // end of qsamplerFxSendList.cpp 219 | -------------------------------------------------------------------------------- /src/qsamplerFxSendsModel.h: -------------------------------------------------------------------------------- 1 | // qsamplerFxSendList.h 2 | // 3 | /**************************************************************************** 4 | Copyright (C) 2010-2019, rncbc aka Rui Nuno Capela. All rights reserved. 5 | Copyright (C) 2008, Christian Schoenebeck 6 | 7 | This program is free software; you can redistribute it and/or 8 | modify it under the terms of the GNU General Public License 9 | as published by the Free Software Foundation; either version 2 10 | of the License, or (at your option) any later version. 11 | 12 | This program is distributed in the hope that it will be useful, 13 | but WITHOUT ANY WARRANTY; without even the implied warranty of 14 | MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the 15 | GNU General Public License for more details. 16 | 17 | You should have received a copy of the GNU General Public License 18 | along with this program; if not, write to the Free Software 19 | Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. 20 | 21 | *****************************************************************************/ 22 | 23 | #ifndef __qsamplerFxSendList_h 24 | #define __qsamplerFxSendList_h 25 | 26 | #include "qsamplerFxSend.h" 27 | 28 | #include 29 | 30 | #include 31 | 32 | namespace QSampler { 33 | 34 | class FxSendsModel : public QAbstractListModel 35 | { 36 | Q_OBJECT 37 | 38 | public: 39 | 40 | FxSendsModel(int iChannelID, QObject *pParent = nullptr); 41 | 42 | // Overridden methods from subclass(es) 43 | int rowCount(const QModelIndex& parent) const; 44 | QVariant data(const QModelIndex& index, int role) const; 45 | bool setData(const QModelIndex& index, 46 | const QVariant& value, int role = Qt::EditRole); 47 | QVariant headerData(int section, Qt::Orientation orientation, 48 | int role = Qt::DisplayRole) const; 49 | Qt::ItemFlags flags(const QModelIndex& index) const; 50 | 51 | // Own methods 52 | FxSend *addFxSend(); 53 | FxSend *fxSend(const QModelIndex& index); 54 | void removeFxSend(const QModelIndex& index); 55 | 56 | signals: 57 | 58 | void fxSendsDirtyChanged(bool); 59 | 60 | public slots: 61 | 62 | void cleanRefresh(); 63 | void applyToSampler(); 64 | 65 | // not pretty, but more efficient than wiring connections for each element 66 | void onExternalModifiication(const QModelIndex& index); 67 | 68 | private: 69 | 70 | typedef QList FxSendsList; 71 | 72 | int m_iChannelID; 73 | FxSendsList m_fxSends; 74 | }; 75 | 76 | } // namespace QSampler 77 | 78 | #endif // __qsamplerFxSendList_h 79 | 80 | // end of qsamplerFxSendList.h 81 | -------------------------------------------------------------------------------- /src/qsamplerInstrument.cpp: -------------------------------------------------------------------------------- 1 | // qsamplerInstrument.cpp 2 | // 3 | /**************************************************************************** 4 | Copyright (C) 2004-2019, rncbc aka Rui Nuno Capela. All rights reserved. 5 | Copyright (C) 2007, Christian Schoenebeck 6 | 7 | This program is free software; you can redistribute it and/or 8 | modify it under the terms of the GNU General Public License 9 | as published by the Free Software Foundation; either version 2 10 | of the License, or (at your option) any later version. 11 | 12 | This program is distributed in the hope that it will be useful, 13 | but WITHOUT ANY WARRANTY; without even the implied warranty of 14 | MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the 15 | GNU General Public License for more details. 16 | 17 | You should have received a copy of the GNU General Public License along 18 | with this program; if not, write to the Free Software Foundation, Inc., 19 | 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA. 20 | 21 | *****************************************************************************/ 22 | 23 | #include "qsamplerAbout.h" 24 | #include "qsamplerInstrument.h" 25 | #include "qsamplerUtilities.h" 26 | 27 | #include "qsamplerOptions.h" 28 | #include "qsamplerMainForm.h" 29 | 30 | 31 | namespace QSampler { 32 | 33 | //------------------------------------------------------------------------- 34 | // QSampler::Instrument - MIDI instrument map structure. 35 | // 36 | 37 | // Constructor. 38 | Instrument::Instrument ( int iMap, int iBank, int iProg ) 39 | { 40 | m_iMap = iMap; 41 | m_iBank = iBank; 42 | m_iProg = iProg; 43 | m_iInstrumentNr = 0; 44 | m_fVolume = 1.0f; 45 | m_iLoadMode = 0; 46 | } 47 | 48 | // Default destructor. 49 | Instrument::~Instrument (void) 50 | { 51 | } 52 | 53 | 54 | // Instrument accessors. 55 | void Instrument::setMap ( int iMap ) 56 | { 57 | m_iMap = iMap; 58 | } 59 | 60 | int Instrument::map (void) const 61 | { 62 | return m_iMap; 63 | } 64 | 65 | 66 | void Instrument::setBank ( int iBank ) 67 | { 68 | m_iBank = iBank; 69 | } 70 | 71 | int Instrument::bank (void) const 72 | { 73 | return m_iBank; 74 | } 75 | 76 | 77 | void Instrument::setProg ( int iProg ) 78 | { 79 | m_iProg = iProg; 80 | } 81 | 82 | int Instrument::prog (void) const 83 | { 84 | return m_iProg; 85 | } 86 | 87 | 88 | void Instrument::setName ( const QString& sName ) 89 | { 90 | m_sName = sName; 91 | } 92 | 93 | const QString& Instrument::name (void) const 94 | { 95 | return m_sName; 96 | } 97 | 98 | 99 | void Instrument::setEngineName ( const QString& sEngineName ) 100 | { 101 | m_sEngineName = sEngineName; 102 | } 103 | 104 | const QString& Instrument::engineName (void) const 105 | { 106 | return m_sEngineName; 107 | } 108 | 109 | 110 | void Instrument::setInstrumentFile ( const QString& sInstrumentFile ) 111 | { 112 | m_sInstrumentFile = sInstrumentFile; 113 | } 114 | 115 | const QString& Instrument::instrumentFile (void) const 116 | { 117 | return m_sInstrumentFile; 118 | } 119 | 120 | 121 | const QString& Instrument::instrumentName (void) const 122 | { 123 | return m_sInstrumentName; 124 | } 125 | 126 | 127 | void Instrument::setInstrumentNr ( int iInstrumentNr ) 128 | { 129 | m_iInstrumentNr = iInstrumentNr; 130 | } 131 | 132 | int Instrument::instrumentNr (void) const 133 | { 134 | return m_iInstrumentNr; 135 | } 136 | 137 | 138 | void Instrument::setVolume ( float fVolume ) 139 | { 140 | m_fVolume = fVolume; 141 | } 142 | 143 | float Instrument::volume (void) const 144 | { 145 | return m_fVolume; 146 | } 147 | 148 | 149 | void Instrument::setLoadMode ( int iLoadMode ) 150 | { 151 | m_iLoadMode = iLoadMode; 152 | } 153 | 154 | int Instrument::loadMode (void) const 155 | { 156 | return m_iLoadMode; 157 | } 158 | 159 | 160 | // Sync methods. 161 | bool Instrument::mapInstrument (void) 162 | { 163 | #ifdef CONFIG_MIDI_INSTRUMENT 164 | 165 | MainForm *pMainForm = MainForm::getInstance(); 166 | if (pMainForm == nullptr) 167 | return false; 168 | if (pMainForm->client() == nullptr) 169 | return false; 170 | 171 | if (m_iMap < 0 || m_iBank < 0 || m_iProg < 0) 172 | return false; 173 | 174 | lscp_midi_instrument_t instr; 175 | 176 | instr.map = m_iMap; 177 | instr.bank = (m_iBank & 0x0fff); 178 | instr.prog = (m_iProg & 0x7f); 179 | 180 | lscp_load_mode_t load_mode; 181 | switch (m_iLoadMode) { 182 | case 3: 183 | load_mode = LSCP_LOAD_PERSISTENT; 184 | break; 185 | case 2: 186 | load_mode = LSCP_LOAD_ON_DEMAND_HOLD; 187 | break; 188 | case 1: 189 | load_mode = LSCP_LOAD_ON_DEMAND; 190 | break; 191 | case 0: 192 | default: 193 | load_mode = LSCP_LOAD_DEFAULT; 194 | break; 195 | } 196 | 197 | if (::lscp_map_midi_instrument(pMainForm->client(), &instr, 198 | m_sEngineName.toUtf8().constData(), 199 | qsamplerUtilities::lscpEscapePath( 200 | m_sInstrumentFile).constData(), 201 | m_iInstrumentNr, m_fVolume, load_mode, 202 | m_sName.toUtf8().constData()) != LSCP_OK) { 203 | pMainForm->appendMessagesClient("lscp_map_midi_instrument"); 204 | return false; 205 | } 206 | 207 | return true; 208 | 209 | #else 210 | 211 | return false; 212 | 213 | #endif 214 | } 215 | 216 | 217 | bool Instrument::unmapInstrument (void) 218 | { 219 | #ifdef CONFIG_MIDI_INSTRUMENT 220 | 221 | if (m_iMap < 0 || m_iBank < 0 || m_iProg < 0) 222 | return false; 223 | 224 | MainForm *pMainForm = MainForm::getInstance(); 225 | if (pMainForm == nullptr) 226 | return false; 227 | if (pMainForm->client() == nullptr) 228 | return false; 229 | 230 | lscp_midi_instrument_t instr; 231 | 232 | instr.map = m_iMap; 233 | instr.bank = (m_iBank & 0x0fff); 234 | instr.prog = (m_iProg & 0x7f); 235 | 236 | if (::lscp_unmap_midi_instrument(pMainForm->client(), &instr) != LSCP_OK) { 237 | pMainForm->appendMessagesClient("lscp_unmap_midi_instrument"); 238 | return false; 239 | } 240 | 241 | return true; 242 | 243 | #else 244 | 245 | return false; 246 | 247 | #endif 248 | } 249 | 250 | 251 | bool Instrument::getInstrument (void) 252 | { 253 | #ifdef CONFIG_MIDI_INSTRUMENT 254 | 255 | if (m_iMap < 0 || m_iBank < 0 || m_iProg < 0) 256 | return false; 257 | 258 | MainForm *pMainForm = MainForm::getInstance(); 259 | if (pMainForm == nullptr) 260 | return false; 261 | if (pMainForm->client() == nullptr) 262 | return false; 263 | 264 | lscp_midi_instrument_t instr; 265 | 266 | instr.map = m_iMap; 267 | instr.bank = (m_iBank & 0x0fff); 268 | instr.prog = (m_iProg & 0x7f); 269 | 270 | lscp_midi_instrument_info_t *pInstrInfo 271 | = ::lscp_get_midi_instrument_info(pMainForm->client(), &instr); 272 | if (pInstrInfo == nullptr) { 273 | pMainForm->appendMessagesClient("lscp_get_midi_instrument_info"); 274 | return false; 275 | } 276 | 277 | m_sName = qsamplerUtilities::lscpEscapedTextToRaw(pInstrInfo->name); 278 | m_sEngineName = pInstrInfo->engine_name; 279 | m_sInstrumentName = qsamplerUtilities::lscpEscapedTextToRaw( 280 | pInstrInfo->instrument_name); 281 | m_sInstrumentFile = qsamplerUtilities::lscpEscapedPathToPosix( 282 | pInstrInfo->instrument_file); 283 | m_iInstrumentNr = pInstrInfo->instrument_nr; 284 | m_fVolume = pInstrInfo->volume; 285 | 286 | switch (pInstrInfo->load_mode) { 287 | case LSCP_LOAD_PERSISTENT: 288 | m_iLoadMode = 3; 289 | break; 290 | case LSCP_LOAD_ON_DEMAND_HOLD: 291 | m_iLoadMode = 2; 292 | break; 293 | case LSCP_LOAD_ON_DEMAND: 294 | m_iLoadMode = 1; 295 | break; 296 | case LSCP_LOAD_DEFAULT: 297 | default: 298 | m_iLoadMode = 0; 299 | break; 300 | } 301 | 302 | // Fix something. 303 | if (m_sName.isEmpty()) 304 | m_sName = m_sInstrumentName; 305 | 306 | return true; 307 | 308 | #else 309 | 310 | return false; 311 | 312 | #endif 313 | } 314 | 315 | 316 | // Instrument map name enumerator. 317 | QStringList Instrument::getMapNames (void) 318 | { 319 | QStringList maps; 320 | 321 | MainForm *pMainForm = MainForm::getInstance(); 322 | if (pMainForm == nullptr) 323 | return maps; 324 | if (pMainForm->client() == nullptr) 325 | return maps; 326 | 327 | #ifdef CONFIG_MIDI_INSTRUMENT 328 | int *piMaps = ::lscp_list_midi_instrument_maps(pMainForm->client()); 329 | if (piMaps == nullptr) { 330 | if (::lscp_client_get_errno(pMainForm->client())) 331 | pMainForm->appendMessagesClient("lscp_list_midi_instruments"); 332 | } else { 333 | for (int iMap = 0; piMaps[iMap] >= 0; iMap++) { 334 | const QString& sMapName = getMapName(piMaps[iMap]); 335 | if (!sMapName.isEmpty()) 336 | maps.append(sMapName); 337 | } 338 | } 339 | #endif 340 | 341 | return maps; 342 | } 343 | 344 | // Instrument map name enumerator. 345 | QString Instrument::getMapName ( int iMidiMap ) 346 | { 347 | QString sMapName; 348 | 349 | MainForm *pMainForm = MainForm::getInstance(); 350 | if (pMainForm == nullptr) 351 | return sMapName; 352 | if (pMainForm->client() == nullptr) 353 | return sMapName; 354 | 355 | #ifdef CONFIG_MIDI_INSTRUMENT 356 | const char *pszMapName 357 | = ::lscp_get_midi_instrument_map_name(pMainForm->client(), iMidiMap); 358 | if (pszMapName == nullptr) { 359 | pszMapName = " -"; 360 | if (::lscp_client_get_errno(pMainForm->client())) 361 | pMainForm->appendMessagesClient("lscp_get_midi_instrument_name"); 362 | } 363 | sMapName = QString("%1 - %2").arg(iMidiMap) 364 | .arg(qsamplerUtilities::lscpEscapedTextToRaw(pszMapName)); 365 | #endif 366 | 367 | return sMapName; 368 | } 369 | 370 | } // namespace QSampler 371 | 372 | // end of qsamplerInstrument.cpp 373 | -------------------------------------------------------------------------------- /src/qsamplerInstrument.h: -------------------------------------------------------------------------------- 1 | // qsamplerInstrument.h 2 | // 3 | /**************************************************************************** 4 | Copyright (C) 2004-2019, rncbc aka Rui Nuno Capela. All rights reserved. 5 | Copyright (C) 2007, Christian Schoenebeck 6 | 7 | This program is free software; you can redistribute it and/or 8 | modify it under the terms of the GNU General Public License 9 | as published by the Free Software Foundation; either version 2 10 | of the License, or (at your option) any later version. 11 | 12 | This program is distributed in the hope that it will be useful, 13 | but WITHOUT ANY WARRANTY; without even the implied warranty of 14 | MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the 15 | GNU General Public License for more details. 16 | 17 | You should have received a copy of the GNU General Public License along 18 | with this program; if not, write to the Free Software Foundation, Inc., 19 | 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA. 20 | 21 | *****************************************************************************/ 22 | 23 | #ifndef __qsamplerInstrument_h 24 | #define __qsamplerInstrument_h 25 | 26 | #include 27 | 28 | namespace QSampler { 29 | 30 | //------------------------------------------------------------------------- 31 | // QSampler::Instrument - MIDI instrument map structure. 32 | // 33 | 34 | class Instrument 35 | { 36 | public: 37 | 38 | // Constructor. 39 | Instrument(int iMap = 0, int iBank = -1, int iProg = -1); 40 | 41 | // Default destructor. 42 | ~Instrument(); 43 | 44 | // Instrument accessors. 45 | void setMap(int iMap); 46 | int map() const; 47 | 48 | void setBank(int iBank); 49 | int bank() const; 50 | 51 | void setProg(int iProg); 52 | int prog() const; 53 | 54 | void setName(const QString& sName); 55 | const QString& name() const; 56 | 57 | void setEngineName(const QString& sEngineName); 58 | const QString& engineName() const; 59 | 60 | void setInstrumentFile(const QString& sInstrumentFile); 61 | const QString& instrumentFile() const; 62 | 63 | const QString& instrumentName() const; 64 | 65 | void setInstrumentNr(int InstrumentNr); 66 | int instrumentNr() const; 67 | 68 | void setVolume(float fVolume); 69 | float volume() const; 70 | 71 | void setLoadMode(int iLoadMode); 72 | int loadMode() const; 73 | 74 | // Sync methods. 75 | bool getInstrument(); 76 | bool mapInstrument(); 77 | bool unmapInstrument(); 78 | 79 | // Instrument map names initialization... 80 | static QStringList getMapNames(); 81 | static QString getMapName(int iMidiMap); 82 | 83 | private: 84 | 85 | // Instance variables. 86 | int m_iMap; 87 | int m_iBank; 88 | int m_iProg; 89 | QString m_sName; 90 | QString m_sEngineName; 91 | QString m_sInstrumentFile; 92 | QString m_sInstrumentName; 93 | int m_iInstrumentNr; 94 | float m_fVolume; 95 | int m_iLoadMode; 96 | }; 97 | 98 | } // namespace QSampler 99 | 100 | #endif // __qsamplerInstrument_h 101 | 102 | 103 | // end of qsamplerInstrument.h 104 | -------------------------------------------------------------------------------- /src/qsamplerInstrumentForm.h: -------------------------------------------------------------------------------- 1 | // qsamplerInstrumentForm.h 2 | // 3 | /**************************************************************************** 4 | Copyright (C) 2003-2021, rncbc aka Rui Nuno Capela. All rights reserved. 5 | Copyright (C) 2007, Christian Schoenebeck 6 | 7 | This program is free software; you can redistribute it and/or 8 | modify it under the terms of the GNU General Public License 9 | as published by the Free Software Foundation; either version 2 10 | of the License, or (at your option) any later version. 11 | 12 | This program is distributed in the hope that it will be useful, 13 | but WITHOUT ANY WARRANTY; without even the implied warranty of 14 | MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the 15 | GNU General Public License for more details. 16 | 17 | You should have received a copy of the GNU General Public License 18 | along with this program; if not, write to the Free Software 19 | Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. 20 | 21 | *****************************************************************************/ 22 | 23 | #ifndef __qsamplerInstrumentForm_h 24 | #define __qsamplerInstrumentForm_h 25 | 26 | #include "ui_qsamplerInstrumentForm.h" 27 | 28 | #include "qsamplerInstrument.h" 29 | 30 | 31 | namespace QSampler { 32 | 33 | //------------------------------------------------------------------------- 34 | // QSampler::InstrumentForm -- Instrument map item form interface. 35 | // 36 | 37 | class InstrumentForm : public QDialog 38 | { 39 | Q_OBJECT 40 | 41 | public: 42 | 43 | InstrumentForm(QWidget *pParent = nullptr); 44 | ~InstrumentForm(); 45 | 46 | void setup(Instrument* pInstrument); 47 | 48 | public slots: 49 | 50 | void nameChanged(const QString& sName); 51 | void openInstrumentFile(); 52 | void updateInstrumentName(); 53 | void instrumentNrChanged(); 54 | void accept(); 55 | void reject(); 56 | void changed(); 57 | void stabilizeForm(); 58 | 59 | private: 60 | 61 | Ui::qsamplerInstrumentForm m_ui; 62 | 63 | Instrument *m_pInstrument; 64 | 65 | int m_iDirtySetup; 66 | int m_iDirtyCount; 67 | int m_iDirtyName; 68 | }; 69 | 70 | } // namespace QSampler 71 | 72 | #endif // __qsamplerInstrumentForm_h 73 | 74 | 75 | // end of qsamplerInstrumentForm.h 76 | -------------------------------------------------------------------------------- /src/qsamplerInstrumentList.h: -------------------------------------------------------------------------------- 1 | // qsamplerInstrumentList.h 2 | // 3 | /**************************************************************************** 4 | Copyright (C) 2003-2019, rncbc aka Rui Nuno Capela. All rights reserved. 5 | Copyright (C) 2007, Christian Schoenebeck 6 | 7 | This program is free software; you can redistribute it and/or 8 | modify it under the terms of the GNU General Public License 9 | as published by the Free Software Foundation; either version 2 10 | of the License, or (at your option) any later version. 11 | 12 | This program is distributed in the hope that it will be useful, 13 | but WITHOUT ANY WARRANTY; without even the implied warranty of 14 | MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the 15 | GNU General Public License for more details. 16 | 17 | You should have received a copy of the GNU General Public License 18 | along with this program; if not, write to the Free Software 19 | Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. 20 | 21 | *****************************************************************************/ 22 | 23 | #ifndef __qsamplerInstrumentList_h 24 | #define __qsamplerInstrumentList_h 25 | 26 | #include 27 | 28 | namespace QSampler { 29 | 30 | class Instrument; 31 | 32 | //------------------------------------------------------------------------- 33 | // QSampler:InstrumentListModel - data model for MIDI prog mappings 34 | // 35 | 36 | class InstrumentListModel : public QAbstractItemModel 37 | { 38 | Q_OBJECT 39 | 40 | public: 41 | 42 | // Constructor. 43 | InstrumentListModel(QObject *pParent = nullptr); 44 | 45 | // Destructor. 46 | ~InstrumentListModel(); 47 | 48 | // Overridden methods from subclass(es) 49 | int rowCount(const QModelIndex& parent) const; 50 | int columnCount(const QModelIndex& parent) const; 51 | 52 | QVariant data(const QModelIndex& index, int role) const; 53 | QVariant headerData(int section, Qt::Orientation orientation, 54 | int role = Qt::DisplayRole) const; 55 | 56 | // Map selector. 57 | void setMidiMap(int iMidiMap); 58 | int midiMap() const; 59 | 60 | // Own methods 61 | const Instrument *addInstrument(int iMap, int iBank, int iProg); 62 | void removeInstrument(Instrument *pInstrument); 63 | void updateInstrument(Instrument *pInstrument); 64 | void resortInstrument(Instrument *pInstrument); 65 | 66 | // General reloader. 67 | void refresh(); 68 | 69 | // Make the following method public 70 | void beginReset(); 71 | void endReset(); 72 | 73 | // Map clear. 74 | void clear(); 75 | 76 | protected: 77 | 78 | QModelIndex index(int row, int col, const QModelIndex& parent) const; 79 | QModelIndex parent(const QModelIndex& child) const; 80 | 81 | private: 82 | 83 | typedef QList InstrumentList; 84 | typedef QMap InstrumentMap; 85 | 86 | InstrumentMap m_instruments; 87 | 88 | // Current map selection. 89 | int m_iMidiMap; 90 | }; 91 | 92 | 93 | //------------------------------------------------------------------------- 94 | // QSampler::InstrumentListView - list view for MIDI prog mappings 95 | // 96 | 97 | class InstrumentListView : public QTreeView 98 | { 99 | Q_OBJECT 100 | 101 | public: 102 | 103 | // Constructor. 104 | InstrumentListView(QWidget *pParent = nullptr); 105 | 106 | // Destructor. 107 | ~InstrumentListView(); 108 | 109 | // Map selector. 110 | void setMidiMap(int iMidiMap); 111 | int midiMap() const; 112 | 113 | // Own methods 114 | const Instrument *addInstrument(int iMap, int iBank, int iProg); 115 | void removeInstrument(Instrument *pInstrument); 116 | void updateInstrument(Instrument *pInstrument); 117 | void resortInstrument(Instrument *pInstrument); 118 | 119 | // General reloader. 120 | void refresh(); 121 | 122 | private: 123 | 124 | // Instance variables. 125 | InstrumentListModel *m_pListModel; 126 | }; 127 | 128 | 129 | } // namespace QSampler 130 | 131 | #endif // __qsamplerInstrumentList_h 132 | 133 | 134 | // end of qsamplerInstrumentList.h 135 | -------------------------------------------------------------------------------- /src/qsamplerInstrumentListForm.cpp: -------------------------------------------------------------------------------- 1 | // qsamplerInstrumentListForm.cpp 2 | // 3 | /**************************************************************************** 4 | Copyright (C) 2003-2020, rncbc aka Rui Nuno Capela. All rights reserved. 5 | Copyright (C) 2007, Christian Schoenebeck 6 | 7 | This program is free software; you can redistribute it and/or 8 | modify it under the terms of the GNU General Public License 9 | as published by the Free Software Foundation; either version 2 10 | of the License, or (at your option) any later version. 11 | 12 | This program is distributed in the hope that it will be useful, 13 | but WITHOUT ANY WARRANTY; without even the implied warranty of 14 | MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the 15 | GNU General Public License for more details. 16 | 17 | You should have received a copy of the GNU General Public License 18 | along with this program; if not, write to the Free Software 19 | Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. 20 | 21 | *****************************************************************************/ 22 | 23 | #include "qsamplerAbout.h" 24 | #include "qsamplerInstrumentListForm.h" 25 | 26 | #include "qsamplerInstrumentList.h" 27 | 28 | #include "qsamplerInstrumentForm.h" 29 | 30 | #include "qsamplerOptions.h" 31 | #include "qsamplerInstrument.h" 32 | #include "qsamplerMainForm.h" 33 | 34 | #include 35 | #include 36 | #include 37 | 38 | #include 39 | 40 | 41 | namespace QSampler { 42 | 43 | //------------------------------------------------------------------------- 44 | // QSampler::InstrumentListForm -- Instrument map list form implementation. 45 | // 46 | 47 | InstrumentListForm::InstrumentListForm ( QWidget *pParent, Qt::WindowFlags wflags ) 48 | : QMainWindow(pParent, wflags) 49 | { 50 | m_ui.setupUi(this); 51 | 52 | m_pInstrumentListView = new InstrumentListView(this); 53 | QMainWindow::setCentralWidget(m_pInstrumentListView); 54 | 55 | // Setup toolbar widgets. 56 | m_pMapComboBox = new QComboBox(m_ui.instrumentToolbar); 57 | m_pMapComboBox->setMinimumWidth(120); 58 | m_pMapComboBox->setEnabled(false); 59 | m_pMapComboBox->setToolTip(tr("Instrument Map")); 60 | 61 | m_ui.instrumentToolbar->addWidget(m_pMapComboBox); 62 | m_ui.instrumentToolbar->addSeparator(); 63 | m_ui.instrumentToolbar->addAction(m_ui.newInstrumentAction); 64 | m_ui.instrumentToolbar->addAction(m_ui.editInstrumentAction); 65 | m_ui.instrumentToolbar->addAction(m_ui.deleteInstrumentAction); 66 | m_ui.instrumentToolbar->addSeparator(); 67 | m_ui.instrumentToolbar->addAction(m_ui.refreshInstrumentsAction); 68 | 69 | QObject::connect(m_pMapComboBox, 70 | SIGNAL(activated(int)), 71 | SLOT(activateMap(int))); 72 | QObject::connect(m_pInstrumentListView->selectionModel(), 73 | SIGNAL(currentRowChanged(const QModelIndex&,const QModelIndex&)), 74 | SLOT(stabilizeForm())); 75 | QObject::connect( 76 | m_pInstrumentListView, 77 | SIGNAL(activated(const QModelIndex&)), 78 | SLOT(editInstrument(const QModelIndex&))); 79 | QObject::connect( 80 | m_ui.newInstrumentAction, 81 | SIGNAL(triggered()), 82 | SLOT(newInstrument())); 83 | QObject::connect( 84 | m_ui.deleteInstrumentAction, 85 | SIGNAL(triggered()), 86 | SLOT(deleteInstrument())); 87 | QObject::connect( 88 | m_ui.editInstrumentAction, 89 | SIGNAL(triggered()), 90 | SLOT(editInstrument())); 91 | QObject::connect( 92 | m_ui.refreshInstrumentsAction, 93 | SIGNAL(triggered()), 94 | SLOT(refreshInstruments())); 95 | 96 | // Things must be stable from the start. 97 | stabilizeForm(); 98 | } 99 | 100 | 101 | InstrumentListForm::~InstrumentListForm (void) 102 | { 103 | delete m_pMapComboBox; 104 | delete m_pInstrumentListView; 105 | } 106 | 107 | 108 | // Notify our parent that we're emerging. 109 | void InstrumentListForm::showEvent ( QShowEvent *pShowEvent ) 110 | { 111 | MainForm* pMainForm = MainForm::getInstance(); 112 | if (pMainForm) 113 | pMainForm->stabilizeForm(); 114 | 115 | QWidget::showEvent(pShowEvent); 116 | } 117 | 118 | 119 | // Notify our parent that we're closing. 120 | void InstrumentListForm::hideEvent ( QHideEvent *pHideEvent ) 121 | { 122 | QWidget::hideEvent(pHideEvent); 123 | 124 | MainForm* pMainForm = MainForm::getInstance(); 125 | if (pMainForm) 126 | pMainForm->stabilizeForm(); 127 | } 128 | 129 | 130 | // Just about to notify main-window that we're closing. 131 | void InstrumentListForm::closeEvent ( QCloseEvent * /*pCloseEvent*/ ) 132 | { 133 | QWidget::hide(); 134 | 135 | MainForm *pMainForm = MainForm::getInstance(); 136 | if (pMainForm) 137 | pMainForm->stabilizeForm(); 138 | } 139 | 140 | 141 | // Refresh all instrument list and views. 142 | void InstrumentListForm::refreshInstruments (void) 143 | { 144 | MainForm* pMainForm = MainForm::getInstance(); 145 | if (pMainForm == nullptr) 146 | return; 147 | 148 | Options *pOptions = pMainForm->options(); 149 | if (pOptions == nullptr) 150 | return; 151 | 152 | // Get/save current map selection... 153 | int iMap = m_pMapComboBox->currentIndex(); 154 | if (iMap < 0 || m_pMapComboBox->count() < 2) 155 | iMap = pOptions->iMidiMap + 1; 156 | 157 | // Populate maps list. 158 | m_pMapComboBox->clear(); 159 | m_pMapComboBox->addItem(tr("(All)")); 160 | m_pMapComboBox->insertItems(1, Instrument::getMapNames()); 161 | 162 | // Adjust to saved selection... 163 | if (iMap < 0 || iMap >= m_pMapComboBox->count()) 164 | iMap = 0; 165 | m_pMapComboBox->setCurrentIndex(iMap); 166 | m_pMapComboBox->setEnabled(m_pMapComboBox->count() > 1); 167 | 168 | activateMap(iMap); 169 | } 170 | 171 | 172 | // Refresh instrument maps selector. 173 | void InstrumentListForm::activateMap ( int iMap ) 174 | { 175 | MainForm* pMainForm = MainForm::getInstance(); 176 | if (pMainForm == nullptr) 177 | return; 178 | 179 | Options *pOptions = pMainForm->options(); 180 | if (pOptions == nullptr) 181 | return; 182 | 183 | int iMidiMap = iMap - 1; 184 | if (iMidiMap >= 0) 185 | pOptions->iMidiMap = iMidiMap; 186 | 187 | m_pInstrumentListView->setMidiMap(iMidiMap); 188 | m_pInstrumentListView->refresh(); 189 | 190 | stabilizeForm(); 191 | } 192 | 193 | 194 | void InstrumentListForm::newInstrument (void) 195 | { 196 | Instrument instrument; 197 | 198 | InstrumentForm form(this); 199 | form.setup(&instrument); 200 | if (!form.exec()) 201 | return; 202 | 203 | // Commit... 204 | instrument.mapInstrument(); 205 | 206 | // add new item to the table model 207 | m_pInstrumentListView->addInstrument( 208 | instrument.map(), 209 | instrument.bank(), 210 | instrument.prog()); 211 | 212 | stabilizeForm(); 213 | } 214 | 215 | 216 | void InstrumentListForm::editInstrument (void) 217 | { 218 | editInstrument(m_pInstrumentListView->currentIndex()); 219 | } 220 | 221 | 222 | void InstrumentListForm::editInstrument ( const QModelIndex& index ) 223 | { 224 | if (!index.isValid()) 225 | return; 226 | 227 | Instrument *pInstrument 228 | = static_cast (index.internalPointer()); 229 | if (pInstrument == nullptr) 230 | return; 231 | 232 | // Save current key values... 233 | int iMap = pInstrument->map(); 234 | int iBank = pInstrument->bank(); 235 | int iProg = pInstrument->prog(); 236 | 237 | Instrument instrument(iMap, iBank, iProg); 238 | 239 | // Do the edit dance... 240 | InstrumentForm form(this); 241 | form.setup(pInstrument); 242 | if (!form.exec()) 243 | return; 244 | 245 | // Commit... 246 | pInstrument->mapInstrument(); 247 | 248 | // Check whether we changed instrument key... 249 | if (pInstrument->map() == iMap && 250 | pInstrument->bank() == iBank && 251 | pInstrument->prog() == iProg) { 252 | // Just update tree item... 253 | m_pInstrumentListView->updateInstrument(pInstrument); 254 | } else { 255 | // Unmap old instance... 256 | instrument.unmapInstrument(); 257 | // Correct the position of the instrument in the model 258 | m_pInstrumentListView->resortInstrument(pInstrument); 259 | } 260 | 261 | stabilizeForm(); 262 | } 263 | 264 | 265 | void InstrumentListForm::deleteInstrument (void) 266 | { 267 | const QModelIndex& index = m_pInstrumentListView->currentIndex(); 268 | if (!index.isValid()) 269 | return; 270 | 271 | Instrument *pInstrument 272 | = static_cast (index.internalPointer()); 273 | if (pInstrument == nullptr) 274 | return; 275 | 276 | MainForm *pMainForm = MainForm::getInstance(); 277 | if (pMainForm == nullptr) 278 | return; 279 | 280 | // Prompt user if this is for real... 281 | Options *pOptions = pMainForm->options(); 282 | if (pOptions && pOptions->bConfirmRemove) { 283 | const QString& sTitle = tr("Warning"); 284 | const QString& sText = tr( 285 | "About to delete instrument map entry:\n\n" 286 | "%1\n\n" 287 | "Are you sure?") 288 | .arg(pInstrument->name()); 289 | #if 0 290 | if (QMessageBox::warning(this, sTitle, sText, 291 | QMessageBox::Ok | QMessageBox::Cancel) == QMessageBox::Cancel) 292 | return; 293 | #else 294 | QMessageBox mbox(this); 295 | mbox.setIcon(QMessageBox::Warning); 296 | mbox.setWindowTitle(sTitle); 297 | mbox.setText(sText); 298 | mbox.setStandardButtons(QMessageBox::Ok | QMessageBox::Cancel); 299 | QCheckBox cbox(tr("Don't ask this again")); 300 | cbox.setChecked(false); 301 | cbox.blockSignals(true); 302 | mbox.addButton(&cbox, QMessageBox::ActionRole); 303 | if (mbox.exec() == QMessageBox::Cancel) 304 | return; 305 | if (cbox.isChecked()) 306 | pOptions->bConfirmRemove = false; 307 | #endif 308 | } 309 | 310 | pInstrument->unmapInstrument(); 311 | 312 | // Let the instrument vanish from the table model... 313 | m_pInstrumentListView->removeInstrument(pInstrument); 314 | 315 | stabilizeForm(); 316 | } 317 | 318 | 319 | // Update form actions enablement... 320 | void InstrumentListForm::stabilizeForm (void) 321 | { 322 | MainForm *pMainForm = MainForm::getInstance(); 323 | 324 | bool bEnabled = (pMainForm && pMainForm->client()); 325 | m_ui.newInstrumentAction->setEnabled(bEnabled); 326 | const QModelIndex& index = m_pInstrumentListView->currentIndex(); 327 | bEnabled = (bEnabled && index.isValid()); 328 | m_ui.editInstrumentAction->setEnabled(bEnabled); 329 | m_ui.deleteInstrumentAction->setEnabled(bEnabled); 330 | } 331 | 332 | 333 | // Context menu request. 334 | void InstrumentListForm::contextMenuEvent ( 335 | QContextMenuEvent *pContextMenuEvent ) 336 | { 337 | QMenu menu(this); 338 | 339 | menu.addAction(m_ui.newInstrumentAction); 340 | menu.addSeparator(); 341 | menu.addAction(m_ui.editInstrumentAction); 342 | menu.addAction(m_ui.deleteInstrumentAction); 343 | menu.addSeparator(); 344 | menu.addAction(m_ui.refreshInstrumentsAction); 345 | 346 | menu.exec(pContextMenuEvent->globalPos()); 347 | } 348 | 349 | 350 | } // namespace QSampler 351 | 352 | 353 | // end of qsamplerInstrumentListForm.cpp 354 | -------------------------------------------------------------------------------- /src/qsamplerInstrumentListForm.h: -------------------------------------------------------------------------------- 1 | // qsamplerInstrumentListForm.h 2 | // 3 | /**************************************************************************** 4 | Copyright (C) 2003-2020, rncbc aka Rui Nuno Capela. All rights reserved. 5 | Copyright (C) 2007, Christian Schoenebeck 6 | 7 | This program is free software; you can redistribute it and/or 8 | modify it under the terms of the GNU General Public License 9 | as published by the Free Software Foundation; either version 2 10 | of the License, or (at your option) any later version. 11 | 12 | This program is distributed in the hope that it will be useful, 13 | but WITHOUT ANY WARRANTY; without even the implied warranty of 14 | MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the 15 | GNU General Public License for more details. 16 | 17 | You should have received a copy of the GNU General Public License 18 | along with this program; if not, write to the Free Software 19 | Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. 20 | 21 | *****************************************************************************/ 22 | 23 | #ifndef __qsamplerInstrumentListForm_h 24 | #define __qsamplerInstrumentListForm_h 25 | 26 | #include "ui_qsamplerInstrumentListForm.h" 27 | 28 | class QModelIndex; 29 | class QComboBox; 30 | 31 | namespace QSampler { 32 | 33 | class InstrumentListView; 34 | 35 | //------------------------------------------------------------------------- 36 | // QSampler::InstrumentListForm -- Instrument map list form interface. 37 | // 38 | 39 | class InstrumentListForm : public QMainWindow 40 | { 41 | Q_OBJECT 42 | 43 | public: 44 | 45 | InstrumentListForm(QWidget *pParent = nullptr, Qt::WindowFlags wflags = Qt::WindowFlags()); 46 | ~InstrumentListForm(); 47 | 48 | public slots: 49 | 50 | void newInstrument(); 51 | void editInstrument(); 52 | void editInstrument(const QModelIndex& index); 53 | void deleteInstrument(); 54 | void refreshInstruments(); 55 | void activateMap(int); 56 | 57 | void stabilizeForm(); 58 | 59 | protected: 60 | 61 | void showEvent(QShowEvent *); 62 | void hideEvent(QHideEvent *); 63 | void closeEvent(QCloseEvent *); 64 | 65 | void contextMenuEvent(QContextMenuEvent *); 66 | 67 | private: 68 | 69 | Ui::qsamplerInstrumentListForm m_ui; 70 | 71 | QComboBox *m_pMapComboBox; 72 | 73 | InstrumentListView *m_pInstrumentListView; 74 | }; 75 | 76 | } // namespace QSampler 77 | 78 | #endif // __qsamplerInstrumentListForm_h 79 | 80 | 81 | // end of qsamplerInstrumentListForm.h 82 | -------------------------------------------------------------------------------- /src/qsamplerInstrumentListForm.ui: -------------------------------------------------------------------------------- 1 | 2 | 3 | rncbc aka Rui Nuno Capela 4 | qsampler - A LinuxSampler Qt GUI Interface. 5 | 6 | Copyright (C) 2004-2020, rncbc aka Rui Nuno Capela. All rights reserved. 7 | Copyright (C) 2007, Christian Schoenebeck 8 | 9 | This program is free software; you can redistribute it and/or 10 | modify it under the terms of the GNU General Public License 11 | as published by the Free Software Foundation; either version 2 12 | of the License, or (at your option) any later version. 13 | 14 | This program is distributed in the hope that it will be useful, 15 | but WITHOUT ANY WARRANTY; without even the implied warranty of 16 | MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the 17 | GNU General Public License for more details. 18 | 19 | You should have received a copy of the GNU General Public License along 20 | with this program; if not, write to the Free Software Foundation, Inc., 21 | 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA. 22 | 23 | 24 | qsamplerInstrumentListForm 25 | 26 | 27 | 28 | 0 29 | 0 30 | 720 31 | 340 32 | 33 | 34 | 35 | Instruments 36 | 37 | 38 | :/images/qsamplerInstrument.png 39 | 40 | 41 | 42 | 43 | Qt::Horizontal 44 | 45 | 46 | TopToolBarArea 47 | 48 | 49 | false 50 | 51 | 52 | 53 | 54 | :/images/itemNew.png 55 | 56 | 57 | New &Instrument... 58 | 59 | 60 | New 61 | 62 | 63 | Ins 64 | 65 | 66 | 67 | 68 | :/images/formEdit.png 69 | 70 | 71 | &Edit... 72 | 73 | 74 | Edit 75 | 76 | 77 | Enter 78 | 79 | 80 | 81 | 82 | :/images/formRemove.png 83 | 84 | 85 | &Delete 86 | 87 | 88 | Delete 89 | 90 | 91 | Del 92 | 93 | 94 | 95 | 96 | :/images/formRefresh.png 97 | 98 | 99 | &Refresh 100 | 101 | 102 | Refresh 103 | 104 | 105 | F5 106 | 107 | 108 | 109 | 110 | 111 | 112 | 113 | 114 | 115 | -------------------------------------------------------------------------------- /src/qsamplerMainForm.h: -------------------------------------------------------------------------------- 1 | // qsamplerMainForm.h 2 | // 3 | /**************************************************************************** 4 | Copyright (C) 2004-2025, rncbc aka Rui Nuno Capela. All rights reserved. 5 | Copyright (C) 2007-2019 Christian Schoenebeck 6 | 7 | This program is free software; you can redistribute it and/or 8 | modify it under the terms of the GNU General Public License 9 | as published by the Free Software Foundation; either version 2 10 | of the License, or (at your option) any later version. 11 | 12 | This program is distributed in the hope that it will be useful, 13 | but WITHOUT ANY WARRANTY; without even the implied warranty of 14 | MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the 15 | GNU General Public License for more details. 16 | 17 | You should have received a copy of the GNU General Public License along 18 | with this program; if not, write to the Free Software Foundation, Inc., 19 | 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA. 20 | 21 | *****************************************************************************/ 22 | 23 | #ifndef __qsamplerMainForm_h 24 | #define __qsamplerMainForm_h 25 | 26 | #include "ui_qsamplerMainForm.h" 27 | 28 | #include 29 | 30 | class QProcess; 31 | class QMdiSubWindow; 32 | class QSocketNotifier; 33 | class QSpinBox; 34 | class QSlider; 35 | class QLabel; 36 | 37 | namespace QSampler { 38 | 39 | class Workspace; 40 | class Options; 41 | class Messages; 42 | class Channel; 43 | class ChannelStrip; 44 | class DeviceForm; 45 | class InstrumentListForm; 46 | 47 | //------------------------------------------------------------------------- 48 | // QSampler::MainForm -- Main window form implementation. 49 | // 50 | 51 | class MainForm : public QMainWindow 52 | { 53 | Q_OBJECT 54 | 55 | public: 56 | 57 | MainForm(QWidget *pParent = nullptr); 58 | ~MainForm(); 59 | 60 | void setup(Options *pOptions); 61 | 62 | Options *options() const; 63 | lscp_client_t *client() const; 64 | 65 | QString sessionName(const QString& sFilename); 66 | 67 | void appendMessages(const QString& s); 68 | void appendMessagesColor(const QString& s, const QColor& rgb); 69 | void appendMessagesText(const QString& s); 70 | void appendMessagesError(const QString& s); 71 | void appendMessagesClient(const QString& s); 72 | 73 | ChannelStrip *createChannelStrip(Channel *pChannel); 74 | void destroyChannelStrip(ChannelStrip *pChannelStrip); 75 | ChannelStrip *activeChannelStrip(); 76 | ChannelStrip *channelStripAt(int iChannel); 77 | ChannelStrip *channelStrip(int iChannelID); 78 | 79 | void channelsArrangeAuto(); 80 | void contextMenuEvent(QContextMenuEvent *pEvent); 81 | void sessionDirty(); 82 | 83 | static MainForm *getInstance(); 84 | 85 | public slots: 86 | 87 | void fileNew(); 88 | void fileOpen(); 89 | void fileOpenRecent(); 90 | void fileSave(); 91 | void fileSaveAs(); 92 | void fileReset(); 93 | void fileRestart(); 94 | void fileExit(); 95 | void editAddChannel(); 96 | void editRemoveChannel(); 97 | void editSetupChannel(); 98 | void editEditChannel(); 99 | void editResetChannel(); 100 | void editResetAllChannels(); 101 | void viewMenubar(bool bOn); 102 | void viewToolbar(bool bOn); 103 | void viewStatusbar(bool bOn); 104 | void viewMessages(bool bOn); 105 | void viewInstruments(); 106 | void viewDevices(); 107 | void viewOptions(); 108 | void channelsArrange(); 109 | void channelsAutoArrange(bool bOn); 110 | void helpAboutQt(); 111 | void helpAbout(); 112 | 113 | void stabilizeForm(); 114 | 115 | protected slots: 116 | 117 | void updateRecentFilesMenu(); 118 | 119 | void volumeChanged(int iVolume); 120 | void channelStripChanged(ChannelStrip *pChannelStrip); 121 | void channelsMenuAboutToShow(); 122 | void channelsMenuActivated(); 123 | void timerSlot(); 124 | void readServerStdout(); 125 | void processServerExit(); 126 | void autoReconnectClient(); 127 | 128 | void handle_sigusr1(); 129 | void handle_sigterm(); 130 | 131 | // Channel strip activation/selection. 132 | void activateStrip(QMdiSubWindow *pMdiSubWindow); 133 | 134 | // Channel toolbar orientation change. 135 | void channelsToolbarOrientation(Qt::Orientation orientation); 136 | 137 | protected: 138 | 139 | void addChannelStrip(); 140 | void removeChannelStrip(); 141 | 142 | bool queryClose(); 143 | void closeEvent(QCloseEvent* pCloseEvent); 144 | void dragEnterEvent(QDragEnterEvent *pDragEnterEvent); 145 | void dropEvent(QDropEvent *pDropEvent); 146 | void customEvent(QEvent *pCustomEvent); 147 | bool newSession(); 148 | bool openSession(); 149 | bool saveSession(bool bPrompt); 150 | bool closeSession(bool bForce); 151 | bool loadSessionFile(const QString& sFilename); 152 | bool saveSessionFile(const QString& sFilename); 153 | void updateSession(); 154 | void updateRecentFiles(const QString& sFilename); 155 | void updateInstrumentNames(); 156 | void updateDisplayFont(); 157 | void updateDisplayEffect(); 158 | void updateMaxVolume(); 159 | void updateMessagesFont(); 160 | void updateMessagesLimit(); 161 | void updateMessagesCapture(); 162 | void updateViewMidiDeviceStatusMenu(); 163 | void updateAllChannelStrips(bool bRemoveDeadStrips); 164 | 165 | void startSchedule(int iStartDelay); 166 | void stopSchedule(); 167 | void startServer(); 168 | void stopServer(bool bInteractive = false); 169 | bool startClient(bool bReconnectOnly = false); 170 | void stopClient(); 171 | void startAutoReconnectClient(); 172 | 173 | private: 174 | 175 | Ui::qsamplerMainForm m_ui; 176 | 177 | Options *m_pOptions; 178 | Messages *m_pMessages; 179 | Workspace *m_pWorkspace; 180 | QSocketNotifier *m_pSigusr1Notifier; 181 | QSocketNotifier *m_pSigtermNotifier; 182 | QString m_sFilename; 183 | int m_iUntitled; 184 | int m_iDirtySetup; 185 | int m_iDirtyCount; 186 | lscp_client_t *m_pClient; 187 | QProcess *m_pServer; 188 | bool m_bForceServerStop; 189 | int m_iStartDelay; 190 | int m_iTimerDelay; 191 | int m_iTimerSlot; 192 | QLabel *m_statusItem[5]; 193 | QList m_changedStrips; 194 | InstrumentListForm *m_pInstrumentListForm; 195 | DeviceForm *m_pDeviceForm; 196 | static MainForm *g_pMainForm; 197 | QSlider *m_pVolumeSlider; 198 | QSpinBox *m_pVolumeSpinBox; 199 | int m_iVolumeChanging; 200 | }; 201 | 202 | } // namespace QSampler 203 | 204 | #endif // __qsamplerMainForm_h 205 | 206 | 207 | // end of qsamplerMainForm.h 208 | -------------------------------------------------------------------------------- /src/qsamplerMessages.h: -------------------------------------------------------------------------------- 1 | // qsamplerMessages.h 2 | // 3 | /**************************************************************************** 4 | Copyright (C) 2004-2021, rncbc aka Rui Nuno Capela. All rights reserved. 5 | Copyright (C) 2007, Christian Schoenebeck 6 | 7 | This program is free software; you can redistribute it and/or 8 | modify it under the terms of the GNU General Public License 9 | as published by the Free Software Foundation; either version 2 10 | of the License, or (at your option) any later version. 11 | 12 | This program is distributed in the hope that it will be useful, 13 | but WITHOUT ANY WARRANTY; without even the implied warranty of 14 | MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the 15 | GNU General Public License for more details. 16 | 17 | You should have received a copy of the GNU General Public License along 18 | with this program; if not, write to the Free Software Foundation, Inc., 19 | 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA. 20 | 21 | *****************************************************************************/ 22 | 23 | #ifndef __qsamplerMessages_h 24 | #define __qsamplerMessages_h 25 | 26 | #include 27 | 28 | class QSocketNotifier; 29 | class QTextBrowser; 30 | class QFile; 31 | 32 | namespace QSampler { 33 | 34 | //------------------------------------------------------------------------- 35 | // QSampler::Messages - Messages log dockable window. 36 | // 37 | 38 | class Messages : public QDockWidget 39 | { 40 | Q_OBJECT 41 | 42 | public: 43 | 44 | // Constructor. 45 | Messages(QWidget *pParent); 46 | // Destructor. 47 | ~Messages(); 48 | 49 | // Stdout/stderr capture accessors. 50 | bool isCaptureEnabled(); 51 | void setCaptureEnabled(bool bCapture); 52 | 53 | // Message font accessors. 54 | QFont messagesFont(); 55 | void setMessagesFont(const QFont& font); 56 | 57 | // Maximum number of message lines accessors. 58 | int messagesLimit(); 59 | void setMessagesLimit(int iMessagesLimit); 60 | 61 | // Logging settings. 62 | bool isLogging() const; 63 | void setLogging(bool bEnabled, const QString& sFilename = QString()); 64 | 65 | // The main utility methods. 66 | void appendMessages(const QString& s); 67 | void appendMessagesColor(const QString& s, const QColor& rgb); 68 | void appendMessagesText(const QString& s); 69 | 70 | // Stdout capture functions. 71 | void appendStdoutBuffer(const QString& s); 72 | void flushStdoutBuffer(); 73 | 74 | // History reset. 75 | void clear(); 76 | 77 | protected: 78 | 79 | // Message executives. 80 | void appendMessagesLine(const QString& s); 81 | void appendMessagesLog(const QString& s); 82 | 83 | // Set stdout/stderr blocking mode. 84 | bool stdoutBlock(int fd, bool bBlock) const; 85 | 86 | // Split stdout/stderr into separate lines... 87 | void processStdoutBuffer(); 88 | 89 | protected slots: 90 | 91 | // Stdout capture slot. 92 | void stdoutNotify(int fd); 93 | 94 | private: 95 | 96 | // The maximum number of message lines. 97 | int m_iMessagesLines; 98 | int m_iMessagesLimit; 99 | int m_iMessagesHigh; 100 | 101 | // The textview main widget. 102 | QTextBrowser *m_pMessagesTextView; 103 | 104 | // Stdout capture variables. 105 | QSocketNotifier *m_pStdoutNotifier; 106 | QString m_sStdoutBuffer; 107 | int m_fdStdout[2]; 108 | 109 | // Logging stuff. 110 | QFile *m_pMessagesLog; 111 | }; 112 | 113 | } // namespace QSampler 114 | 115 | #endif // __qsamplerMessages_h 116 | 117 | 118 | // end of qsamplerMessages.h 119 | -------------------------------------------------------------------------------- /src/qsamplerOptions.h: -------------------------------------------------------------------------------- 1 | // qsamplerOptions.h 2 | // 3 | /**************************************************************************** 4 | Copyright (C) 2004-2025, rncbc aka Rui Nuno Capela. All rights reserved. 5 | Copyright (C) 2007,2008,2015 Christian Schoenebeck 6 | 7 | This program is free software; you can redistribute it and/or 8 | modify it under the terms of the GNU General Public License 9 | as published by the Free Software Foundation; either version 2 10 | of the License, or (at your option) any later version. 11 | 12 | This program is distributed in the hope that it will be useful, 13 | but WITHOUT ANY WARRANTY; without even the implied warranty of 14 | MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the 15 | GNU General Public License for more details. 16 | 17 | You should have received a copy of the GNU General Public License along 18 | with this program; if not, write to the Free Software Foundation, Inc., 19 | 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA. 20 | 21 | *****************************************************************************/ 22 | 23 | #ifndef __qsamplerOptions_h 24 | #define __qsamplerOptions_h 25 | 26 | #include 27 | #include 28 | 29 | 30 | class QWidget; 31 | class QComboBox; 32 | 33 | namespace QSampler { 34 | 35 | //------------------------------------------------------------------------- 36 | // QSampler::Options - Prototype settings class. 37 | // 38 | 39 | class Options 40 | { 41 | public: 42 | 43 | // Constructor. 44 | Options(); 45 | // Default destructor. 46 | ~Options(); 47 | 48 | // The settings object accessor. 49 | QSettings& settings(); 50 | 51 | // explicit I/O methods. 52 | void loadOptions(); 53 | void saveOptions(); 54 | 55 | // Command line arguments parser. 56 | bool parse_args(const QStringList& args); 57 | #if QT_VERSION >= QT_VERSION_CHECK(5, 2, 0) 58 | void show_error(const QString& msg); 59 | #else 60 | // Command line usage helper. 61 | void print_usage(const QString& arg0); 62 | #endif 63 | 64 | // Startup supplied session file(s). 65 | QStringList sessionFiles; 66 | 67 | // Server options... 68 | QString sServerHost; 69 | int iServerPort; 70 | int iServerTimeout; 71 | bool bServerStart; 72 | QString sServerCmdLine; 73 | int iStartDelay; 74 | 75 | // Logging options... 76 | bool bMessagesLog; 77 | QString sMessagesLogPath; 78 | 79 | // Display options... 80 | QString sDisplayFont; 81 | bool bDisplayEffect; 82 | bool bAutoRefresh; 83 | int iAutoRefreshTime; 84 | int iMaxVolume; 85 | QString sMessagesFont; 86 | bool bMessagesLimit; 87 | int iMessagesLimitLines; 88 | bool bConfirmRemove; 89 | bool bConfirmReset; 90 | bool bConfirmRestart; 91 | bool bConfirmError; 92 | bool bKeepOnTop; 93 | bool bStdoutCapture; 94 | bool bCompletePath; 95 | bool bInstrumentNames; 96 | int iBaseFontSize; 97 | 98 | QString sCustomColorTheme; 99 | QString sCustomStyleTheme; 100 | 101 | // View options... 102 | bool bMenubar; 103 | bool bToolbar; 104 | bool bStatusbar; 105 | bool bAutoArrange; 106 | 107 | // Default options... 108 | QString sSessionDir; 109 | QString sInstrumentDir; 110 | QString sEngineName; 111 | QString sAudioDriver; 112 | QString sMidiDriver; 113 | int iMidiMap; 114 | int iMidiBank; 115 | int iMidiProg; 116 | int iVolume; 117 | int iLoadMode; 118 | 119 | // Recent file list. 120 | int iMaxRecentFiles; 121 | QStringList recentFiles; 122 | 123 | // Widget geometry persistence helper prototypes. 124 | void saveWidgetGeometry(QWidget *pWidget, bool bVisible = false); 125 | void loadWidgetGeometry(QWidget *pWidget, bool bVisible = false); 126 | 127 | // Combo box history persistence helper prototypes. 128 | void loadComboBoxHistory(QComboBox *pComboBox, int iLimit = 8); 129 | void saveComboBoxHistory(QComboBox *pComboBox, int iLimit = 8); 130 | 131 | int getMaxVoices(); 132 | int getEffectiveMaxVoices(); 133 | void setMaxVoices(int iMaxVoices); 134 | 135 | int getMaxStreams(); 136 | int getEffectiveMaxStreams(); 137 | void setMaxStreams(int iMaxStreams); 138 | 139 | void sendFineTuningSettings(); 140 | 141 | private: 142 | 143 | // Settings member variables. 144 | QSettings m_settings; 145 | 146 | // Tuning 147 | int iMaxVoices; 148 | int iMaxStreams; 149 | }; 150 | 151 | } // namespace QSampler 152 | 153 | 154 | #endif // __qsamplerOptions_h 155 | 156 | 157 | // end of qsamplerOptions.h 158 | 159 | -------------------------------------------------------------------------------- /src/qsamplerOptionsForm.h: -------------------------------------------------------------------------------- 1 | // qsamplerOptionsForm.h 2 | // 3 | /**************************************************************************** 4 | Copyright (C) 2004-2022, rncbc aka Rui Nuno Capela. All rights reserved. 5 | Copyright (C) 2007, Christian Schoenebeck 6 | 7 | This program is free software; you can redistribute it and/or 8 | modify it under the terms of the GNU General Public License 9 | as published by the Free Software Foundation; either version 2 10 | of the License, or (at your option) any later version. 11 | 12 | This program is distributed in the hope that it will be useful, 13 | but WITHOUT ANY WARRANTY; without even the implied warranty of 14 | MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the 15 | GNU General Public License for more details. 16 | 17 | You should have received a copy of the GNU General Public License along 18 | with this program; if not, write to the Free Software Foundation, Inc., 19 | 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA. 20 | 21 | *****************************************************************************/ 22 | 23 | #ifndef __qsamplerOptionsForm_h 24 | #define __qsamplerOptionsForm_h 25 | 26 | #include "ui_qsamplerOptionsForm.h" 27 | 28 | #include "qsamplerOptions.h" 29 | 30 | 31 | namespace QSampler { 32 | 33 | //------------------------------------------------------------------------- 34 | // QSampler::OptionsForm -- Options form interface. 35 | // 36 | 37 | class OptionsForm : public QDialog 38 | { 39 | Q_OBJECT 40 | 41 | public: 42 | 43 | OptionsForm(QWidget *pParent = nullptr); 44 | ~OptionsForm(); 45 | 46 | void setup(Options* pOptions); 47 | 48 | protected slots: 49 | 50 | void accept(); 51 | void reject(); 52 | 53 | void optionsChanged(); 54 | 55 | void browseMessagesLogPath(); 56 | void chooseDisplayFont(); 57 | void chooseMessagesFont(); 58 | void toggleDisplayEffect(bool bOn); 59 | 60 | void editCustomColorThemes(); 61 | 62 | void maxVoicesChanged(int iMaxVoices); 63 | void maxStreamsChanged(int iMaxStreams); 64 | 65 | protected: 66 | 67 | // Custom color/style themes settlers. 68 | void resetCustomColorThemes(const QString& sCustomColorTheme); 69 | void resetCustomStyleThemes(const QString& sCustomStyleTheme); 70 | 71 | void stabilizeForm(); 72 | 73 | private: 74 | 75 | Ui::qsamplerOptionsForm m_ui; 76 | 77 | Options* m_pOptions; 78 | 79 | int m_iDirtySetup; 80 | int m_iDirtyCount; 81 | 82 | bool bMaxVoicesModified; 83 | bool bMaxStreamsModified; 84 | }; 85 | 86 | } // namespace QSampler 87 | 88 | #endif // __qsamplerOptionsForm_h 89 | 90 | 91 | // end of qsamplerOptionsForm.h 92 | -------------------------------------------------------------------------------- /src/qsamplerPaletteForm.h: -------------------------------------------------------------------------------- 1 | // qsamplerPaletteForm.h 2 | // 3 | /**************************************************************************** 4 | Copyright (C) 2004-2024, rncbc aka Rui Nuno Capela. All rights reserved. 5 | Copyright (C) 2007, Christian Schoenebeck 6 | 7 | This program is free software; you can redistribute it and/or 8 | modify it under the terms of the GNU General Public License 9 | as published by the Free Software Foundation; either version 2 10 | of the License, or (at your option) any later version. 11 | 12 | This program is distributed in the hope that it will be useful, 13 | but WITHOUT ANY WARRANTY; without even the implied warranty of 14 | MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the 15 | GNU General Public License for more details. 16 | 17 | You should have received a copy of the GNU General Public License along 18 | with this program; if not, write to the Free Software Foundation, Inc., 19 | 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA. 20 | 21 | *****************************************************************************/ 22 | 23 | #ifndef __qsamplerPaletteForm_h 24 | #define __qsamplerPaletteForm_h 25 | 26 | #include 27 | #include 28 | #include 29 | #include 30 | #include 31 | #include 32 | 33 | 34 | // Forward decls. 35 | class QListView; 36 | class QLabel; 37 | class QToolButton; 38 | 39 | namespace Ui { class qsamplerPaletteForm; } 40 | 41 | 42 | namespace QSampler { 43 | 44 | //------------------------------------------------------------------------- 45 | // QSampler::PaletteForm 46 | 47 | class PaletteForm: public QDialog 48 | { 49 | Q_OBJECT 50 | 51 | public: 52 | 53 | PaletteForm(QWidget *parent = nullptr, 54 | const QPalette& pal = QPalette()); 55 | 56 | virtual ~PaletteForm(); 57 | 58 | void setPalette(const QPalette& pal); 59 | const QPalette& palette() const; 60 | 61 | void setSettings(QSettings *settings, bool owner = false); 62 | QSettings *settings() const; 63 | 64 | void setPaletteName(const QString& name); 65 | QString paletteName() const; 66 | 67 | bool isDirty() const; 68 | 69 | static bool namedPalette(QSettings *settings, 70 | const QString& name, QPalette& pal, bool fixup = false); 71 | static QStringList namedPaletteList(QSettings *settings); 72 | 73 | static QString namedPaletteConf( 74 | QSettings *settings, const QString& name); 75 | static void addNamedPaletteConf( 76 | QSettings *settings, const QString& name, const QString& filename); 77 | 78 | static QPalette::ColorRole colorRole(const QString& name); 79 | 80 | class PaletteModel; 81 | class ColorDelegate; 82 | class ColorButton; 83 | class ColorEditor; 84 | class RoleEditor; 85 | 86 | protected slots: 87 | 88 | void nameComboChanged(const QString& name); 89 | void saveButtonClicked(); 90 | void deleteButtonClicked(); 91 | 92 | void generateButtonChanged(); 93 | void resetButtonClicked(); 94 | void detailsCheckClicked(); 95 | void importButtonClicked(); 96 | void exportButtonClicked(); 97 | 98 | void paletteChanged(const QPalette& pal); 99 | 100 | void accept(); 101 | void reject(); 102 | 103 | protected: 104 | 105 | void setPalette(const QPalette& pal, const QPalette& parentPal); 106 | 107 | bool namedPalette(const QString& name, QPalette& pal) const; 108 | QStringList namedPaletteList() const; 109 | 110 | QString namedPaletteConf(const QString& name) const; 111 | void addNamedPaletteConf(const QString& name, const QString& filename); 112 | void deleteNamedPaletteConf(const QString& name); 113 | 114 | static bool loadNamedPaletteConf( 115 | const QString& name, const QString& filename, QPalette& pal); 116 | static bool saveNamedPaletteConf( 117 | const QString& name, const QString& filename, const QPalette& pal); 118 | 119 | static bool loadNamedPalette( 120 | QSettings *settings, const QString& name, QPalette& pal); 121 | static bool saveNamedPalette( 122 | QSettings *settings, const QString& name, const QPalette& pal); 123 | 124 | void updateNamedPaletteList(); 125 | void updateGenerateButton(); 126 | void updateDialogButtons(); 127 | 128 | void setDefaultDir(const QString& dir); 129 | QString defaultDir() const; 130 | 131 | void setShowDetails(bool on); 132 | bool isShowDetails() const; 133 | 134 | void showEvent(QShowEvent *event); 135 | void resizeEvent(QResizeEvent *event); 136 | 137 | private: 138 | 139 | Ui::qsamplerPaletteForm *p_ui; 140 | Ui::qsamplerPaletteForm& m_ui; 141 | 142 | QSettings *m_settings; 143 | bool m_owner; 144 | 145 | QPalette m_palette; 146 | QPalette m_parentPalette; 147 | PaletteModel *m_paletteModel; 148 | bool m_modelUpdated; 149 | bool m_paletteUpdated; 150 | int m_dirtyCount; 151 | int m_dirtyTotal; 152 | }; 153 | 154 | 155 | //------------------------------------------------------------------------- 156 | // QSampler::PaletteForm::PaletteModel 157 | 158 | class PaletteForm::PaletteModel : public QAbstractTableModel 159 | { 160 | Q_OBJECT 161 | Q_PROPERTY(QPalette::ColorRole colorRole READ colorRole) 162 | 163 | public: 164 | 165 | PaletteModel(QObject *parent = nullptr); 166 | 167 | int rowCount(const QModelIndex &parent = QModelIndex()) const; 168 | int columnCount(const QModelIndex &parent = QModelIndex()) const; 169 | QVariant data(const QModelIndex &index, int role) const; 170 | bool setData(const QModelIndex &index, const QVariant &value, int role); 171 | Qt::ItemFlags flags(const QModelIndex &index) const; 172 | QVariant headerData(int section, Qt::Orientation orientation, 173 | int role = Qt::DisplayRole) const; 174 | 175 | void setPalette(const QPalette &palette, const QPalette &parentPalette); 176 | const QPalette& palette() const; 177 | 178 | void setGenerate(bool on) { m_generate = on; } 179 | 180 | QPalette::ColorRole colorRole() const { return QPalette::NoRole; } 181 | 182 | signals: 183 | 184 | void paletteChanged(const QPalette &palette); 185 | 186 | protected: 187 | 188 | QPalette::ColorGroup columnToGroup(int index) const; 189 | int groupToColumn(QPalette::ColorGroup group) const; 190 | 191 | private: 192 | 193 | QPalette m_palette; 194 | QPalette m_parentPalette; 195 | QMap m_roleNames; 196 | int m_nrows; 197 | bool m_generate; 198 | }; 199 | 200 | 201 | //------------------------------------------------------------------------- 202 | // QSampler::PaletteForm::ColorDelegate 203 | 204 | class PaletteForm::ColorDelegate : public QItemDelegate 205 | { 206 | public: 207 | 208 | ColorDelegate(QObject *parent = nullptr) 209 | : QItemDelegate(parent) {} 210 | 211 | QWidget *createEditor(QWidget *parent, 212 | const QStyleOptionViewItem& option, 213 | const QModelIndex& index) const; 214 | 215 | void setEditorData(QWidget *editor, 216 | const QModelIndex& index) const; 217 | void setModelData(QWidget *editor, 218 | QAbstractItemModel *model, 219 | const QModelIndex& index) const; 220 | 221 | void updateEditorGeometry(QWidget *editor, 222 | const QStyleOptionViewItem& option, 223 | const QModelIndex &index) const; 224 | 225 | virtual void paint(QPainter *painter, 226 | const QStyleOptionViewItem& option, 227 | const QModelIndex& index) const; 228 | 229 | virtual QSize sizeHint(const QStyleOptionViewItem& option, 230 | const QModelIndex& index) const; 231 | }; 232 | 233 | 234 | //------------------------------------------------------------------------- 235 | // QSampler::PaletteForm::ColorButton 236 | 237 | class PaletteForm::ColorButton : public QPushButton 238 | { 239 | Q_OBJECT 240 | Q_PROPERTY(QBrush brush READ brush WRITE setBrush) 241 | 242 | public: 243 | 244 | ColorButton (QWidget *parent = nullptr); 245 | 246 | const QBrush& brush() const; 247 | void setBrush(const QBrush& b); 248 | 249 | signals: 250 | 251 | void changed(); 252 | 253 | protected slots: 254 | 255 | void chooseColor(); 256 | 257 | protected: 258 | 259 | void paintEvent(QPaintEvent *event); 260 | 261 | private: 262 | 263 | QBrush m_brush; 264 | }; 265 | 266 | 267 | //------------------------------------------------------------------------- 268 | // QSampler::PaleteEditor::ColorEditor 269 | 270 | class PaletteForm::ColorEditor : public QWidget 271 | { 272 | Q_OBJECT 273 | 274 | public: 275 | 276 | ColorEditor(QWidget *parent = nullptr); 277 | 278 | void setColor(const QColor &color); 279 | QColor color() const; 280 | bool changed() const; 281 | 282 | signals: 283 | 284 | void changed(QWidget *widget); 285 | 286 | protected slots: 287 | 288 | void colorChanged(); 289 | 290 | private: 291 | 292 | PaletteForm::ColorButton *m_button; 293 | bool m_changed; 294 | }; 295 | 296 | 297 | //------------------------------------------------------------------------- 298 | // QSampler::PaleteEditor::RoleEditor 299 | 300 | class PaletteForm::RoleEditor : public QWidget 301 | { 302 | Q_OBJECT 303 | 304 | public: 305 | 306 | RoleEditor(QWidget *parent = nullptr); 307 | 308 | void setLabel(const QString &label); 309 | void setEdited(bool on); 310 | bool edited() const; 311 | 312 | signals: 313 | 314 | void changed(QWidget *widget); 315 | 316 | protected slots: 317 | 318 | void resetProperty(); 319 | 320 | private: 321 | 322 | QLabel *m_label; 323 | QToolButton *m_button; 324 | bool m_edited; 325 | }; 326 | 327 | } // namespace QSampler 328 | 329 | #endif // __qsamplerPaletteForm_h 330 | 331 | // end of qsamplerPaletteForm.h 332 | -------------------------------------------------------------------------------- /src/qsamplerPaletteForm.ui: -------------------------------------------------------------------------------- 1 | 2 | 3 | rncbc aka Rui Nuno Capela 4 | qsampler - A LinuxSampler Qt GUI Interface. 5 | 6 | Copyright (C) 2005-2024, rncbc aka Rui Nuno Capela. All rights reserved. 7 | Copyright (C) 2007, Christian Schoenebeck 8 | 9 | This program is free software; you can redistribute it and/or 10 | modify it under the terms of the GNU General Public License 11 | as published by the Free Software Foundation; either version 2 12 | of the License, or (at your option) any later version. 13 | 14 | This program is distributed in the hope that it will be useful, 15 | but WITHOUT ANY WARRANTY; without even the implied warranty of 16 | MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the 17 | GNU General Public License for more details. 18 | 19 | You should have received a copy of the GNU General Public License along 20 | with this program; if not, write to the Free Software Foundation, Inc., 21 | 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA. 22 | 23 | 24 | qsamplerPaletteForm 25 | 26 | 27 | 28 | 0 29 | 0 30 | 534 31 | 640 32 | 33 | 34 | 35 | 36 | 0 37 | 0 38 | 39 | 40 | 41 | Color Themes 42 | 43 | 44 | 45 | 46 | 47 | Name 48 | 49 | 50 | 51 | 52 | 53 | 54 | 0 55 | 0 56 | 57 | 58 | 59 | 60 | 320 61 | 0 62 | 63 | 64 | 65 | Current color palette name 66 | 67 | 68 | true 69 | 70 | 71 | QComboBox::NoInsert 72 | 73 | 74 | 75 | 76 | 77 | 78 | Save current color palette name 79 | 80 | 81 | Save 82 | 83 | 84 | :/images/formSave.png 85 | 86 | 87 | 88 | 89 | 90 | 91 | Delete current color palette name 92 | 93 | 94 | Delete 95 | 96 | 97 | :/images/formRemove.png 98 | 99 | 100 | 101 | 102 | 103 | 104 | 105 | 106 | 107 | Palette 108 | 109 | 110 | 111 | 112 | 113 | 114 | 280 115 | 360 116 | 117 | 118 | 119 | Current color palette 120 | 121 | 122 | true 123 | 124 | 125 | 126 | 127 | 128 | 129 | Generate: 130 | 131 | 132 | 133 | 134 | 135 | 136 | 137 | 0 138 | 0 139 | 140 | 141 | 142 | Qt::StrongFocus 143 | 144 | 145 | Base color to generate palette 146 | 147 | 148 | 149 | 150 | 151 | 152 | Reset all current palette colors 153 | 154 | 155 | Reset 156 | 157 | 158 | :/images/itemReset.png 159 | 160 | 161 | 162 | 163 | 164 | 165 | Qt::Horizontal 166 | 167 | 168 | 169 | 8 170 | 20 171 | 172 | 173 | 174 | 175 | 176 | 177 | 178 | Import a custom color theme (palette) from file 179 | 180 | 181 | Import... 182 | 183 | 184 | :/images/formOpen.png 185 | 186 | 187 | 188 | 189 | 190 | 191 | Export a custom color theme (palette) to file 192 | 193 | 194 | Export... 195 | 196 | 197 | :/images/formSave.png 198 | 199 | 200 | 201 | 202 | 203 | 204 | Qt::Horizontal 205 | 206 | 207 | 208 | 8 209 | 20 210 | 211 | 212 | 213 | 214 | 215 | 216 | 217 | Show Details 218 | 219 | 220 | 221 | 222 | 223 | 224 | 225 | 226 | 227 | Qt::Horizontal 228 | 229 | 230 | QDialogButtonBox::Cancel|QDialogButtonBox::Ok 231 | 232 | 233 | 234 | 235 | 236 | 237 | 238 | QSampler::PaletteForm::ColorButton 239 | 240 | 241 | 242 | nameCombo 243 | saveButton 244 | deleteButton 245 | paletteView 246 | generateButton 247 | resetButton 248 | importButton 249 | exportButton 250 | detailsCheck 251 | dialogButtons 252 | 253 | 254 | 255 | 256 | 257 | 258 | -------------------------------------------------------------------------------- /src/qsamplerUtilities.cpp: -------------------------------------------------------------------------------- 1 | // qsamplerUtilities.cpp 2 | // 3 | /**************************************************************************** 4 | Copyright (C) 2004-2020, rncbc aka Rui Nuno Capela. All rights reserved. 5 | Copyright (C) 2007, 2008 Christian Schoenebeck 6 | 7 | This program is free software; you can redistribute it and/or 8 | modify it under the terms of the GNU General Public License 9 | as published by the Free Software Foundation; either version 2 10 | of the License, or (at your option) any later version. 11 | 12 | This program is distributed in the hope that it will be useful, 13 | but WITHOUT ANY WARRANTY; without even the implied warranty of 14 | MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the 15 | GNU General Public License for more details. 16 | 17 | You should have received a copy of the GNU General Public License along 18 | with this program; if not, write to the Free Software Foundation, Inc., 19 | 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA. 20 | 21 | *****************************************************************************/ 22 | 23 | #include "qsamplerUtilities.h" 24 | 25 | #include "qsamplerOptions.h" 26 | #include "qsamplerMainForm.h" 27 | 28 | #include 29 | 30 | 31 | using namespace QSampler; 32 | 33 | namespace qsamplerUtilities { 34 | 35 | static int _hexToNumber ( char hex_digit ) 36 | { 37 | switch (hex_digit) { 38 | case '0': return 0; 39 | case '1': return 1; 40 | case '2': return 2; 41 | case '3': return 3; 42 | case '4': return 4; 43 | case '5': return 5; 44 | case '6': return 6; 45 | case '7': return 7; 46 | case '8': return 8; 47 | case '9': return 9; 48 | 49 | case 'a': return 10; 50 | case 'b': return 11; 51 | case 'c': return 12; 52 | case 'd': return 13; 53 | case 'e': return 14; 54 | case 'f': return 15; 55 | 56 | case 'A': return 10; 57 | case 'B': return 11; 58 | case 'C': return 12; 59 | case 'D': return 13; 60 | case 'E': return 14; 61 | case 'F': return 15; 62 | 63 | default: return 0; 64 | } 65 | } 66 | 67 | static int _hexsToNumber ( char hex0, char hex1 ) 68 | { 69 | return _hexToNumber(hex1) * 16 + _hexToNumber(hex0); 70 | } 71 | 72 | static bool _isHex ( char hex_digit ) 73 | { 74 | return _hexToNumber ( hex_digit ) || hex_digit == '0'; 75 | } 76 | 77 | // returns true if the connected LSCP server supports escape sequences 78 | static bool _remoteSupportsEscapeSequences (void) 79 | { 80 | const lscpVersion_t version = getRemoteLscpVersion(); 81 | // LSCP v1.2 or younger required 82 | return (version.major > 1 || (version.major == 1 && version.minor >= 2)); 83 | } 84 | 85 | 86 | // converts the given file path into a path as expected by LSCP 1.2 87 | QByteArray lscpEscapePath ( const QString& sPath ) 88 | { 89 | QByteArray path = sPath.toUtf8(); 90 | if (!_remoteSupportsEscapeSequences()) return path; 91 | 92 | const char pathSeparator = '/'; 93 | int path_len = path.length(); 94 | char buf[5]; 95 | 96 | // Trying single pass to avoid redundant checks on extra run 97 | for ( int i = 0; i < path_len; i++ ) { 98 | // translate POSIX escape sequences 99 | if (path[i] == '%') { 100 | // replace POSIX path escape sequences (%HH) by LSCP escape sequences (\xHH) 101 | // TODO: missing code for other systems like Windows 102 | if (_isHex(path[i+1]) && _isHex(path[i+2])) { 103 | path.replace (i, 1, "\\x"); 104 | path_len++; 105 | i += 3; 106 | continue; 107 | } 108 | // replace POSIX path escape sequence (%%) by its raw character 109 | if (path[i+1] == '%') { 110 | path.remove (i, 1); 111 | path_len--; 112 | continue; 113 | } 114 | continue; 115 | } 116 | // replace all non-basic characters by LSCP escape sequences 117 | // 118 | // match all non-alphanumerics 119 | // (we could exclude much more characters here, but that way 120 | // we're sure it just works^TM) 121 | const char c = path[i]; 122 | if ( 123 | !(c >= '0' && c <= '9') && 124 | !(c >= 'a' && c <= 'z') && 125 | !(c >= 'A' && c <= 'Z') && 126 | #if defined(__WIN32__) || defined(_WIN32) || defined(WIN32) 127 | !(c == ':') && 128 | #endif 129 | !(c == pathSeparator) 130 | ) { 131 | // convertion 132 | ::snprintf(buf, sizeof(buf), "\\x%02x", static_cast(c)); 133 | path = path.replace(i, 1, buf); 134 | path_len += 3; 135 | i += 3; 136 | } 137 | } 138 | 139 | return path; 140 | } 141 | 142 | 143 | // converts a path returned by a LSCP command (and may contain escape 144 | // sequences) into the appropriate POSIX path 145 | QString lscpEscapedPathToPosix ( const char* sPath ) 146 | { 147 | if (!_remoteSupportsEscapeSequences()) return QString(sPath); 148 | 149 | QByteArray path(sPath); 150 | int path_len = path.length(); 151 | 152 | char cAscii[2] = "\0"; 153 | for ( int i = 0; i < path_len; i++) { 154 | // first escape all percent ('%') characters for POSIX 155 | if (path[i] == '%') { 156 | path.insert(i, '%'); 157 | path_len++; 158 | i++; 159 | continue; 160 | } 161 | // resolve LSCP hex escape sequences (\xHH) 162 | if (path[i] == '\\' && path[i+1] == 'x' && _isHex(path[i+2]) && _isHex(path[i+3])) { 163 | const QByteArray sHex = path.mid(i + 2, 2).toLower(); 164 | // the slash has to be escaped for POSIX as well 165 | if (sHex == "2f") { 166 | path.replace(i, 4, "%2f"); 167 | // all other characters we simply decode 168 | } else { 169 | cAscii[0] = _hexsToNumber(sHex[1], sHex[0]); 170 | path.replace(i, 4, cAscii); 171 | } 172 | path_len -= 3; 173 | continue; 174 | } 175 | } 176 | 177 | return QString(path); 178 | } 179 | 180 | 181 | // converts the given text as expected by LSCP 1.2 182 | // (that is by encoding special characters with LSCP escape sequences) 183 | QByteArray lscpEscapeText ( const QString& sText ) 184 | { 185 | QByteArray text = sText.toUtf8(); 186 | if (!_remoteSupportsEscapeSequences()) return text; 187 | 188 | int text_len = text.length(); 189 | char buf[5]; 190 | 191 | // replace all non-basic characters by LSCP escape sequences 192 | for (int i = 0; i < text_len; ++i) { 193 | // match all non-alphanumerics 194 | // (we could exclude much more characters here, but that way 195 | // we're sure it just works^TM) 196 | const char c = text[i]; 197 | if ( 198 | !(c >= '0' && c <= '9') && 199 | !(c >= 'a' && c <= 'z') && 200 | !(c >= 'A' && c <= 'Z') 201 | ) { 202 | // convert the non-basic character into a LSCP escape sequence 203 | ::snprintf(buf, sizeof(buf), "\\x%02x", static_cast(c)); 204 | text.replace(i, 1, buf); 205 | text_len += 3; 206 | i += 3; 207 | } 208 | } 209 | 210 | return text; 211 | } 212 | 213 | 214 | // converts a text returned by a LSCP command and may contain escape 215 | // sequences) into raw text, that is with all escape sequences decoded 216 | QString lscpEscapedTextToRaw ( const char* sText ) 217 | { 218 | if (!_remoteSupportsEscapeSequences()) return QString(sText); 219 | 220 | QByteArray text(sText); 221 | int text_len = text.length(); 222 | char sHex[2], cAscii[2] = "\0"; 223 | 224 | // resolve LSCP hex escape sequences (\xHH) 225 | for (int i = 0; i < text_len; i++) { 226 | if (text[i] != '\\' || text[i+1] != 'x') continue; 227 | 228 | sHex[0] = text[i+2], sHex[1] = text[i+3]; 229 | if (_isHex(sHex[0]) && _isHex(sHex[1])) { 230 | cAscii[0] = _hexsToNumber(sHex[1], sHex[0]); 231 | text.replace(i, 4, cAscii); 232 | text_len -= 3; 233 | } 234 | } 235 | 236 | return QString(text); 237 | } 238 | 239 | lscpVersion_t getRemoteLscpVersion (void) 240 | { 241 | lscpVersion_t result = { 0, 0 }; 242 | 243 | MainForm* pMainForm = MainForm::getInstance(); 244 | if (pMainForm == nullptr) 245 | return result; 246 | if (pMainForm->client() == nullptr) 247 | return result; 248 | 249 | lscp_server_info_t* pServerInfo = 250 | ::lscp_get_server_info(pMainForm->client()); 251 | if (pServerInfo && pServerInfo->protocol_version) 252 | ::sscanf(pServerInfo->protocol_version, "%d.%d", 253 | &result.major, &result.minor); 254 | 255 | return result; 256 | } 257 | 258 | } // namespace qsamplerUtilities 259 | 260 | 261 | // end of qsamplerUtilities.cpp 262 | -------------------------------------------------------------------------------- /src/qsamplerUtilities.h: -------------------------------------------------------------------------------- 1 | // qsamplerUtilities.h 2 | // 3 | /**************************************************************************** 4 | Copyright (C) 2004-2020, rncbc aka Rui Nuno Capela. All rights reserved. 5 | Copyright (C) 2007, 2008 Christian Schoenebeck 6 | 7 | This program is free software; you can redistribute it and/or 8 | modify it under the terms of the GNU General Public License 9 | as published by the Free Software Foundation; either version 2 10 | of the License, or (at your option) any later version. 11 | 12 | This program is distributed in the hope that it will be useful, 13 | but WITHOUT ANY WARRANTY; without even the implied warranty of 14 | MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the 15 | GNU General Public License for more details. 16 | 17 | You should have received a copy of the GNU General Public License along 18 | with this program; if not, write to the Free Software Foundation, Inc., 19 | 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA. 20 | 21 | *****************************************************************************/ 22 | 23 | #ifndef __qsamplerUtilities_h 24 | #define __qsamplerUtilities_h 25 | 26 | #include 27 | 28 | 29 | namespace qsamplerUtilities { 30 | 31 | struct lscpVersion_t { 32 | int major; 33 | int minor; 34 | }; 35 | 36 | QByteArray lscpEscapePath(const QString& sPath); 37 | QString lscpEscapedPathToPosix(const char* sPath); 38 | QByteArray lscpEscapeText(const QString& sText); 39 | QString lscpEscapedTextToRaw(const char* sText); 40 | 41 | lscpVersion_t getRemoteLscpVersion(); 42 | 43 | } // namespace qsamplerUtilities 44 | 45 | 46 | #endif // __qsamplerUtilities_h 47 | --------------------------------------------------------------------------------