diff options
| -rw-r--r-- | muse/ChangeLog | 4 | ||||
| -rw-r--r-- | muse/muse/audio.cpp | 12 | ||||
| -rw-r--r-- | muse/muse/ladspaplugin.cpp | 2 | ||||
| -rw-r--r-- | muse/muse/wave.cpp | 2 | ||||
| -rw-r--r-- | muse/synti/CMakeLists.txt | 2 | ||||
| -rw-r--r-- | muse/synti/README | 14 | ||||
| -rw-r--r-- | muse/synti/mus/CMakeLists.txt | 27 | ||||
| -rw-r--r-- | muse/synti/mus/mus.cpp | 252 | 
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(); +      } + | 
