summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorWerner Schweer <ws.seh.de>2006-10-17 14:49:42 +0000
committerWerner Schweer <ws.seh.de>2006-10-17 14:49:42 +0000
commit7e2777670f20dec0dce37f70351a3d16fbc1ed24 (patch)
tree42e4501a1cf2533db31543a90aa60964ed4b4069
parent16cfc4acee835b7e99233de0102357492215000f (diff)
added "mus" wrapper program for standalone MESS synthesizer
-rw-r--r--muse/ChangeLog4
-rw-r--r--muse/muse/audio.cpp12
-rw-r--r--muse/muse/ladspaplugin.cpp2
-rw-r--r--muse/muse/wave.cpp2
-rw-r--r--muse/synti/CMakeLists.txt2
-rw-r--r--muse/synti/README14
-rw-r--r--muse/synti/mus/CMakeLists.txt27
-rw-r--r--muse/synti/mus/mus.cpp252
8 files changed, 300 insertions, 15 deletions
diff --git a/muse/ChangeLog b/muse/ChangeLog
index 12f39d09..ca965719 100644
--- a/muse/ChangeLog
+++ b/muse/ChangeLog
@@ -1,3 +1,7 @@
+17.10 (ws)
+ - added new program "mus". Mus is a wrapper to operate MusE MESS
+ synthesizer standalone with JACK audio/midi interface. The
+ plan is to use them to test the upcoming jack midi implementation.
15.10 (ng)
- DeicsOnze 0.5, add FX send
- fix installation path for freeverb
diff --git a/muse/muse/audio.cpp b/muse/muse/audio.cpp
index ec8c6463..4e637278 100644
--- a/muse/muse/audio.cpp
+++ b/muse/muse/audio.cpp
@@ -218,14 +218,6 @@ bool Audio::start()
}
}
audioDriver->stopTransport();
-
- //
- // do connections
- //
-// done in seqStart
-// for (iTrack i = tl->begin(); i != tl->end(); ++i) {
-// (*i)->activate2();
-// }
return true;
}
@@ -702,10 +694,6 @@ void Audio::stopRolling()
unsigned int Audio::curFrame() const
{
-// return lrint((curTime() - syncTime) * AL::sampleRate) + syncFrame;
- //
- // this should be the same:
- //
return audioDriver->framePos();
}
diff --git a/muse/muse/ladspaplugin.cpp b/muse/muse/ladspaplugin.cpp
index ee8b0e14..85398d74 100644
--- a/muse/muse/ladspaplugin.cpp
+++ b/muse/muse/ladspaplugin.cpp
@@ -125,7 +125,7 @@ void LadspaPlugin::range(int i, double* min, double* max) const
LADSPA_PortRangeHint range = plugin->PortRangeHints[i];
LADSPA_PortRangeHintDescriptor desc = range.HintDescriptor;
if (desc & LADSPA_HINT_TOGGLED) {
- *min = 0.0;
+ *min = -1.0;
*max = 1.0;
return;
}
diff --git a/muse/muse/wave.cpp b/muse/muse/wave.cpp
index 9b40c967..280b291e 100644
--- a/muse/muse/wave.cpp
+++ b/muse/muse/wave.cpp
@@ -1,4 +1,4 @@
-//=============================================================================
+ //=============================================================================
// MusE
// Linux Music Editor
// $Id:$
diff --git a/muse/synti/CMakeLists.txt b/muse/synti/CMakeLists.txt
index 02babaf9..09d2f1b3 100644
--- a/muse/synti/CMakeLists.txt
+++ b/muse/synti/CMakeLists.txt
@@ -27,7 +27,7 @@ include_directories(
${PROJECT_SOURCE_DIR}/synti
)
-set (SubDirs libsynti s1 organ deicsonze simpledrums vam )
+set (SubDirs libsynti s1 organ deicsonze simpledrums vam mus)
if (ENABLE_FLUID)
set (SubDirs ${SubDirs} fluid fluidsynth )
diff --git a/muse/synti/README b/muse/synti/README
new file mode 100644
index 00000000..cbda0fd4
--- /dev/null
+++ b/muse/synti/README
@@ -0,0 +1,14 @@
+s1 is a simple demo of the MusE software synthesizer interface.
+ It has no gui and no parameters to set.
+
+organ is a demo synthesizer which shows how to implement
+ polyphony and a gui
+
+fluid is demo synthesizer utilizing the fluid sythesizer library
+
+mus is a program which can load any of the MusE synthsizer plugins
+ turning them into standalone synthesizer with a JACK audio and
+ midi interface
+
+
+
diff --git a/muse/synti/mus/CMakeLists.txt b/muse/synti/mus/CMakeLists.txt
new file mode 100644
index 00000000..98a0c74c
--- /dev/null
+++ b/muse/synti/mus/CMakeLists.txt
@@ -0,0 +1,27 @@
+#=============================================================================
+# MusE
+# Linux Music Editor
+# $Id:$
+#
+# Copyright (C) 2002-2006 by Werner Schweer and others
+#
+# This program is free software; you can redistribute it and/or modify
+# it under the terms of the GNU General Public License version 2.
+#
+# This program is distributed in the hope that it will be useful,
+# but WITHOUT ANY WARRANTY; without even the implied warranty of
+# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+# GNU General Public License for more details.
+#
+# You should have received a copy of the GNU General Public License
+# along with this program; if not, write to the Free Software
+# Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
+#=============================================================================
+
+add_executable ( mus mus.cpp )
+install_targets ( /bin mus )
+target_link_libraries(mus
+ ${QT_LIBRARIES}
+ ${JACK_LIB}
+ )
+
diff --git a/muse/synti/mus/mus.cpp b/muse/synti/mus/mus.cpp
new file mode 100644
index 00000000..5534dfab
--- /dev/null
+++ b/muse/synti/mus/mus.cpp
@@ -0,0 +1,252 @@
+//=============================================================================
+// MusE
+// Linux Music Editor
+// $Id:$
+//
+// Copyright (C) 2002-2006 by Werner Schweer and others
+//
+// This program is free software; you can redistribute it and/or modify
+// it under the terms of the GNU General Public License version 2.
+//
+// This program is distributed in the hope that it will be useful,
+// but WITHOUT ANY WARRANTY; without even the implied warranty of
+// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+// GNU General Public License for more details.
+//
+// You should have received a copy of the GNU General Public License
+// along with this program; if not, write to the Free Software
+// Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
+//=============================================================================
+
+#include "all.h"
+#include <stdio.h>
+#include <getopt.h>
+#include <dlfcn.h>
+
+#include "config.h"
+#include "libsynti/mess.h"
+#include "driver/jackaudio.h"
+#include <jack/midiport.h>
+
+static const char* versionString = "1.0";
+static bool debug = false;
+
+static int sampleRate;
+static int segmentSize;
+
+static Mess* mess;
+static const int MAX_OUTPORTS = 8;
+jack_port_t* inPort;
+jack_port_t* outPorts[MAX_OUTPORTS];
+float* outBuffer[MAX_OUTPORTS];
+
+//---------------------------------------------------------
+// processAudio
+// JACK callback
+//---------------------------------------------------------
+
+static int processAudio(jack_nframes_t nFrames, void*)
+ {
+ int nch = mess->channels();
+ for (int i = 0; i < nch; ++i)
+ outBuffer[i] = (float*)jack_port_get_buffer(outPorts[i], nFrames);
+ void* midi = jack_port_get_buffer(inPort, nFrames);
+ int n = jack_midi_port_get_info(midi, nFrames)->event_count;
+ unsigned offset = 0;
+ for (int i = 0; i < n; ++i) {
+ jack_midi_event_t event;
+ jack_midi_event_get(&event, midi, i, nFrames);
+ mess->process(outBuffer, offset, event.time - offset);
+ offset = event.time;
+ MidiEvent e;
+ e.setType(event.buffer[0] & 0xf0);
+ e.setChannel(event.buffer[0] & 0xf);
+ e.setA(event.buffer[1]);
+ e.setB(event.buffer[2]);
+ mess->processEvent(e);
+ }
+ if (offset < nFrames)
+ mess->process(outBuffer, offset, nFrames - offset);
+ return 0;
+ }
+
+//---------------------------------------------------------
+// jackError
+//---------------------------------------------------------
+
+static void jackError(const char* s)
+ {
+ fprintf(stderr, "JACK ERROR: %s\n", s);
+ }
+
+//---------------------------------------------------------
+// noJackError
+//---------------------------------------------------------
+
+static void noJackError(const char* /* s */)
+ {
+ }
+
+//---------------------------------------------------------
+// printVersion
+//---------------------------------------------------------
+
+static void printVersion(const char* programName)
+ {
+ printf("%s: Version %s\n", programName, versionString);
+ }
+
+//---------------------------------------------------------
+// usage
+//---------------------------------------------------------
+
+static void usage(const char* programName)
+ {
+ fprintf(stderr, "%s: usage <options> MusE-synthesizer-plugin-name\n"
+ " options: -v print version\n"
+ " -d debug mode on\n",
+ programName
+ );
+ }
+
+//---------------------------------------------------------
+// main
+//---------------------------------------------------------
+
+int main(int argc, char* argv[])
+ {
+ new QApplication(argc, argv);
+ int c;
+ while ((c = getopt(argc, argv, "vd")) != EOF) {
+ switch (c) {
+ case 'v':
+ printVersion(argv[0]);
+ return 0;
+ case 'd':
+ debug = true;
+ break;
+ default:
+ usage(argv[0]);
+ return -1;
+ }
+ }
+ argc -= optind;
+ if (argc != 1) {
+ usage(argv[0]);
+ return -1;
+ }
+ //
+ // load synthesizer plugin
+ //
+ QDir pluginDir(INSTPREFIX "/lib/" INSTALL_NAME "/synthi");
+ if (!pluginDir.exists()) {
+ fprintf(stderr, "plugin directory <%s> not found\n",
+ pluginDir.path().toLocal8Bit().data());
+ return -2;
+ }
+ QString pluginName(argv[1]);
+ if (!pluginName.endsWith(".so", Qt::CaseInsensitive))
+ pluginName += ".so";
+ if (!pluginDir.exists(pluginName)) {
+ fprintf(stderr, "plugin <%s> in directory <%s> not found\n",
+ pluginName.toLocal8Bit().data(),
+ pluginDir.path().toLocal8Bit().data());
+ return -3;
+ }
+ QString path = pluginDir.filePath(pluginName);
+ void* handle = dlopen(path.toLocal8Bit().data(), RTLD_LAZY);
+ if (handle == 0) {
+ fprintf(stderr, "%s: dlopen(%s) failed: %s\n",
+ argv[0], path.toLocal8Bit().data(), dlerror());
+ return -4;
+ }
+ typedef const MESS* (*MESS_Function)();
+ MESS_Function msynth = (MESS_Function)dlsym(handle, "mess_descriptor");
+ if (!msynth) {
+ fprintf(stderr,
+ "%s: Unable to find msynth_descriptor() function in plugin\n"
+ "Are you sure this is a MESS plugin file?\n%s",
+ argv[0], dlerror());
+ return -5;
+ }
+ const MESS* descr = msynth();
+ if (descr == 0) {
+ fprintf(stderr, "%s: instantiate: no MESS descr found\n",
+ argv[0]);
+ return 6;
+ }
+ //
+ // initialize JACK
+ //
+ if (debug) {
+ fprintf(stderr, "init JACK audio\n");
+ jack_set_error_function(jackError);
+ }
+ else
+ jack_set_error_function(noJackError);
+
+ jack_client_t* client = 0;
+ int i = 0;
+ QString instanceName;
+ QString s(pluginName.left(pluginName.size()-3));
+ s += "-%1";
+ static const int MAX_INSTANCES = 500;
+ for (i = 0; i < MAX_INSTANCES; ++i) {
+ instanceName = s.arg(i);
+ const char* jackIdString = instanceName.toLocal8Bit().data();
+ client = jack_client_new(jackIdString);
+ if (client)
+ break;
+ }
+ if (i == MAX_INSTANCES) {
+ fprintf(stderr, "%s: too many instances of the synth! (>%d)\n",
+ argv[0], MAX_INSTANCES);
+ return -7;
+ }
+ jack_set_error_function(jackError);
+ if (debug)
+ fprintf(stderr, "init Jack Audio: register device\n");
+ // jackAudio = new JackAudio(client, jackIdString);
+ if (debug)
+ fprintf(stderr, "init Jack Audio: register client\n");
+
+ jack_set_process_callback(client, processAudio, 0);
+// jack_set_sync_callback(_client, processSync, 0);
+// jack_on_shutdown(_client, processShutdown, 0);
+// jack_set_buffer_size_callback(_client, bufsize_callback, 0);
+// jack_set_sample_rate_callback(_client, srate_callback, 0);
+// jack_set_port_registration_callback(_client, registration_callback, 0);
+// jack_set_graph_order_callback(_client, graph_callback, 0);
+// jack_set_freewheel_callback (_client, freewheel_callback, 0);
+// jack_set_timebase_callback(_client, 0, timebase_callback, 0);
+
+ sampleRate = jack_get_sample_rate(client);
+ segmentSize = jack_get_buffer_size(client);
+ //
+ // instantiate Synthesizer
+ //
+ mess = descr->instantiate(sampleRate, 0, instanceName.toLocal8Bit().data());
+ if (mess == 0) {
+ fprintf(stderr, "%s: instantiate failed\n",
+ argv[0]);
+ }
+
+ int channels = mess->channels();
+ if (channels > MAX_OUTPORTS) {
+ channels = MAX_OUTPORTS;
+ fprintf(stderr, "%s: too many outports %d > %d\n",
+ argv[0], channels, MAX_OUTPORTS);
+ }
+ for (int i = 0; i < channels; ++i) {
+ char portName[64];
+ snprintf(portName, 64, "audioOut-%d", i);
+ outPorts[i] = jack_port_register(client, portName,
+ JACK_DEFAULT_AUDIO_TYPE, JackPortIsOutput, 0);
+ }
+ inPort = jack_port_register(client, "midiIn",
+ JACK_DEFAULT_MIDI_TYPE, JackPortIsInput, 0);
+ if (mess->hasGui())
+ mess->showGui(true);
+ qApp->exec();
+ }
+