Re: [LAU] fluidjack

From: Lorenzo <lsutton@email-addr-hidden>
Date: Sun Oct 18 2009 - 15:18:11 EEST

On ubuntu 9.04 and jackd version 0.116.1 I managed to build a working
fluidjack binary with this patched source.

Kind regards,
Lorenzo

Lars-Erik Helander wrote:
> I got code from Nedko a couple of months ago that worked very well
> with jack (1.9.3).
>
> This is how I got it
>
> ////// You can get tarball of any commit through the web interface:
> //////
> ////// http://nedko.arnaudov.name/git/cgit.cgi/fluidjack/
>
> /Lars
>
>
>
> 2009/10/18 Jonathan E. Brickman <jeb@email-addr-hidden>:
>
>> Lars-Erik Helander wrote:
>>
>>> Have you tried fluidjack? It's a simple but nicely working frontend to
>>> fluidsynth created by Nedko. The source code is just a single C file
>>> which is easy to modify to include the settings you would need. I am
>>> not really sure if there is some official place to get the latest
>>> version but you could probably ask Nedko.
>>>
>>> /Lars
>>>
>>>
>> Alas, it appears to be behind the ball in Jack API:
>>
>> jeb@email-addr-hidden:~/fluidjack$ gcc fluidjack.c
>> fluidjack.c: In function ‘jack_process_cb’:
>> fluidjack.c:61: error: too many arguments to function
>> ‘jack_midi_get_event_count’
>> fluidjack.c:70: error: too many arguments to function ‘jack_midi_event_get’
>> jeb@email-addr-hidden:~/fluidjack$
>>
>> J.E.B.
>>
>> _______________________________________________
>> Linux-audio-user mailing list
>> Linux-audio-user@email-addr-hidden
>> http://lists.linuxaudio.org/mailman/listinfo/linux-audio-user
>>
>>
> _______________________________________________
> Linux-audio-user mailing list
> Linux-audio-user@email-addr-hidden
> http://lists.linuxaudio.org/mailman/listinfo/linux-audio-user
>
>

/* -*- Mode: C ; c-basic-offset: 2 -*- */
/*****************************************************************************
 *
 * fluidjack - sf2 synth (fluid) with JACK MIDI input and JACK audio outputs
 *
 * Copyright (C) 2007 Nedko Arnaudov <nedko@email-addr-hidden>
 *
 * This program is free software; you can redistribute it and/or modify
 * it under the terms of the GNU General Public License as published by
 * the Free Software Foundation; version 2 of the License
 *
 * 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., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
 *
 *****************************************************************************/

/* gcc `pkg-config --cflags --libs fluidsynth jack` main.c -o fluidjack */

#include <fluidsynth.h>
#include <jack/jack.h>
#include <jack/midiport.h>
#include <assert.h>

#define LOG_ERROR(format, arg...) fprintf(stderr, format "\n", ## arg)
#define LOG_NOTICE(format, arg...) printf(format "\n", ## arg)

struct fluidjack
{
  fluid_synth_t * synth;
  int sf_id;
  fluid_settings_t * settings;
  jack_client_t * jack_client;
  jack_port_t * in;
  jack_port_t * left;
  jack_port_t * right;
};

#define fluidjack_ptr ((struct fluidjack *)context_ptr)

int
jack_process_cb(
  jack_nframes_t nframes,
  void * context_ptr)
{
  int ret;
  float * left;
  float * right;
  void * input_buf;
  jack_midi_event_t input_event;
  jack_nframes_t input_event_count;
  jack_nframes_t i;
  jack_nframes_t offset;

  input_buf = jack_port_get_buffer(fluidjack_ptr->in, nframes);
// input_event_count = jack_midi_get_event_count(input_buf, nframes);
  input_event_count = jack_midi_get_event_count(input_buf);

  left = (float *)jack_port_get_buffer(fluidjack_ptr->left, nframes);
  right = (float *)jack_port_get_buffer(fluidjack_ptr->right, nframes);

  offset = 0;
  for (i = 0; i < input_event_count; i++)
  {
    /* retrieve JACK MIDI event */
// jack_midi_event_get(&input_event, input_buf, i, nframes);
    jack_midi_event_get(&input_event, input_buf, i);
    assert(input_event.time >= offset);
    if (input_event.time > offset)
    {
      /* generate audio up to event */
      fluid_synth_write_float(fluidjack_ptr->synth, input_event.time - offset, left + offset, 0, 1, right + offset, 0, 1);

      offset = input_event.time;
    }

    if (input_event.size == 3)
    {
      if ((input_event.buffer[0] >> 4) == 0x08)
      { /* note off */
        //LOG_NOTICE("note off");
        fluid_synth_noteoff(fluidjack_ptr->synth, input_event.buffer[0] & 0x0F, input_event.buffer[1]);
      }
      else if ((input_event.buffer[0] >> 4) == 0x09)
      { /* note on */
        //LOG_NOTICE("note on");
        fluid_synth_noteon(fluidjack_ptr->synth, input_event.buffer[0] & 0x0F, input_event.buffer[1], input_event.buffer[2]);
      }
      else if ((input_event.buffer[0] >> 4) == 0x0B)
      {
        fluid_synth_cc(fluidjack_ptr->synth, input_event.buffer[0] & 0x0F, input_event.buffer[1], input_event.buffer[2]);
      }
      else if ((input_event.buffer[0] >> 4) == 0x0E)
      {
        fluid_synth_pitch_bend(fluidjack_ptr->synth, input_event.buffer[0] & 0x0F, (input_event.buffer[2] << 7) | input_event.buffer[1]);
      }
    }
    if (input_event.size == 2)
    {
      if ((input_event.buffer[0] >> 4) == 0x0C)
      {
        fluid_synth_program_change(fluidjack_ptr->synth, input_event.buffer[0] & 0x0F, input_event.buffer[1]);
      }
    }
  }

  if (nframes > offset)
  {
    fluid_synth_write_float(fluidjack_ptr->synth, nframes - offset, left + offset, 0, 1, right + offset, 0, 1);
  }

  return 0;
}

#undef fluidjack_ptr

int main(int argc, char ** argv)
{
  int ret;
  struct fluidjack fluidjack;
  jack_nframes_t sample_rate;

  if (argc != 2)
  {
    LOG_ERROR("Usage: fluidjack <path_to_sf2_file>");
    ret = 1;
    goto exit;
  }

  /* Connect to JACK (with plugin name as client name) */
  fluidjack.jack_client = jack_client_open("fluidjack", JackNullOption, NULL);
  if (fluidjack.jack_client == NULL)
  {
    LOG_ERROR("Failed to connect to JACK.");
    ret = 1;
    goto exit;
  }

  fluidjack.settings = new_fluid_settings();
  if (fluidjack.settings == NULL)
  {
    LOG_ERROR("new_fluid_settings() failed.");
    ret = 1;
    goto exit_close_jack_client;
  }

  sample_rate = jack_get_sample_rate(fluidjack.jack_client);
  LOG_NOTICE("Sample rate is %u", (unsigned int)sample_rate);
  fluid_settings_setnum(fluidjack.settings, "synth.sample-rate", sample_rate);

  fluidjack.synth = new_fluid_synth(fluidjack.settings);
  if (fluidjack.synth == NULL)
  {
    LOG_ERROR("new_fluid_synth() failed.");
    ret = 1;
    goto exit_delete_settings;
  }

  LOG_NOTICE("Loading soundfont...", argv[1]);
  fluidjack.sf_id = fluid_synth_sfload(fluidjack.synth, argv[1], 1);
  if (fluidjack.sf_id == -1)
  {
    LOG_ERROR("Soundfont loading failed.");
    ret = 1;
    goto exit_delete_synth;
  }

  ret = jack_set_process_callback(fluidjack.jack_client, &jack_process_cb, &fluidjack);
  if (ret != 0)
  {
    LOG_ERROR("jack_set_process_callback() failed.");
    ret = 1;
    goto exit_delete_synth;
  }

  fluidjack.in = jack_port_register(fluidjack.jack_client, "in", JACK_DEFAULT_MIDI_TYPE, JackPortIsInput, 0);
  if (fluidjack.in == NULL)
  {
    LOG_ERROR("Failed to register JACK MIDI input port.");
    ret = 1;
    goto exit_delete_synth;
  }

  fluidjack.left = jack_port_register(fluidjack.jack_client, "left", JACK_DEFAULT_AUDIO_TYPE, JackPortIsOutput, 0);
  if (fluidjack.left == NULL)
  {
    LOG_ERROR("Failed to register JACK audio output left port.");
    ret = 1;
    goto exit_delete_synth;
  }

  fluidjack.right = jack_port_register(fluidjack.jack_client, "right", JACK_DEFAULT_AUDIO_TYPE, JackPortIsOutput, 0);
  if (fluidjack.right == NULL)
  {
    LOG_ERROR("Failed to register JACK audio output right port.");
    ret = 1;
    goto exit_delete_synth;
  }

  ret = jack_activate(fluidjack.jack_client);
  if (ret != 0)
  {
    LOG_ERROR("jack_activate() failed.");
    ret = 1;
    goto exit_delete_synth;
  }

  LOG_NOTICE("Press Enter key to exit");
  getchar();

  jack_deactivate(fluidjack.jack_client);

exit_delete_synth:
  delete_fluid_synth(fluidjack.synth);

exit_delete_settings:
  delete_fluid_settings(fluidjack.settings);

exit_close_jack_client:
  jack_client_close(fluidjack.jack_client);

exit:
  return ret;
}

_______________________________________________
Linux-audio-user mailing list
Linux-audio-user@email-addr-hidden
http://lists.linuxaudio.org/mailman/listinfo/linux-audio-user
Received on Sun Oct 18 16:15:05 2009

This archive was generated by hypermail 2.1.8 : Sun Oct 18 2009 - 16:15:05 EEST