Ejemplo n.º 1
0
int main (int argc, char**argv) {
  int osc_port=0;
  void *pa = allocPreamp();
  initPreamp(pa, NULL);

  int c;
  const char *optstring = "hi:o:O:p:V";
  struct option long_options[] = {
    { "help",      no_argument,       0, 'h' },
    { "input",     no_argument,       0, 'i' },
    { "output",    no_argument,       0, 'o' },
    { "parameter", required_argument, 0, 'p' },
    { "version",   no_argument,       0, 'V' },
    { 0, 0, 0, 0 }
  };

  while ((c = getopt_long(argc, argv, optstring, long_options, NULL)) != -1) {
    switch (c) {
      case 'h':
	usage("jboverdrive", 0);
	return (0);
	break;
      case 'i':
	jack_inport_name=optarg;
	break;
      case 'o':
	jack_outport_name=optarg;
	break;
      case 'O':
	osc_port=atoi(optarg);
	break;
      case 'p':
	{
	  int ok=0;
	  char *t = strchr(optarg, '=');
	  if (t) {
	    *t='\0';
	    if (!strcasecmp(optarg, "bias"))       {ok=1; p_bias     =pp(t+1);}
	    if (!strcasecmp(optarg, "feedback"))   {ok=1; p_feedback =pp(t+1);}
	    if (!strcasecmp(optarg, "sagtobias"))  {ok=1; p_sagtobias=pp(t+1);}
	    if (!strcasecmp(optarg, "postfeed"))   {ok=1; p_postfeed =pp(t+1);}
	    if (!strcasecmp(optarg, "globfeed"))   {ok=1; p_globfeed =pp(t+1);}
	    if (!strcasecmp(optarg, "gainin"))     {ok=1; p_gainin   =pp(t+1);}
	    if (!strcasecmp(optarg, "gainout"))    {ok=1; p_gainout  =pp(t+1);}
	    *t='=';
	  }
	  if (!ok) {
	    fprintf(stderr, "invalid parameter '%s' given.\n", optarg);
	  }
	}
	break;
      case 'V':
	printf ("%s %s\n\n", "jboverdrive", VERSION);
	printf(
"Copyright (C) 2003-2004 Fredrik Kilander <*****@*****.**>\n"
"Copyright (C) 2012 Robin Gareus <*****@*****.**>\n"
"\n"
"This is free software; see the source for copying conditions.  There is NO\n"
"warranty; not even for MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.\n\n"
);
	return(0);
      default:
	fprintf(stderr, "invalid argument.\n");
	usage("jboverdrive", 1);
    }
  }

  if (osc_port) {
#ifdef HAVE_LIBLO
    if (init_osc(osc_port)) osc_port=0;
#else
    fprintf(stderr, "This version has not been compiled with liblo.\nOSC is not available.\n");
#endif
  }

  j_client = jack_client_open ("b_overdrive", JackNullOption, NULL);
  if (!j_client) {
    fprintf(stderr, "could not connect to jack.\n");
    return(1);
  }

  j_input_port = jack_port_register (j_client, "in", JACK_DEFAULT_AUDIO_TYPE, JackPortIsInput, 0);
  j_output_port = jack_port_register (j_client, "out", JACK_DEFAULT_AUDIO_TYPE, JackPortIsOutput, 0);

  if (!j_output_port || !j_input_port) {
    fprintf(stderr, "no more jack ports available.\n");
    jack_client_close (j_client);
    return(1);
  }

  jack_on_shutdown (j_client, jack_shutdown_callback, NULL);
  jack_set_process_callback(j_client,jack_audio_callback, pa);

#ifndef _WIN32
  signal (SIGHUP, catchsig);
  signal (SIGINT, catchsig);
#endif

  fctl_biased     (pa, p_bias);
  fctl_biased_fb  (pa, p_feedback);
  fctl_sagtoBias  (pa, p_sagtobias);
  fctl_biased_fb2 (pa, p_postfeed);
  fctl_biased_gfb (pa, p_globfeed);
  fsetInputGain   (pa, p_gainin);
  fsetOutputGain  (pa, p_gainout);

  jack_activate(j_client);
  connect_jack_ports();

  while (j_client) {
    // TODO interaction; allow to change parameters
    // via terminal I/O
    sleep (1);
  }

#ifdef HAVE_LIBLO
  if (osc_port) {
    shutdown_osc();
  }
#endif

  freePreamp(pa);
  return (0);
}
Ejemplo n.º 2
0
/*
 * Main program.
 */
int main (int argc, char * argv []) {
  int i,c,k;
  int doDefaultConfig = TRUE;
  int doDefaultProgram = TRUE;
  int printCCTable = FALSE;
  int doDefaultCC = TRUE;
  char * configOverride [NOF_CFG_OVERS];
  int configOverEnd = 0;
  int loadProgram = -1;
  unsigned int randomPreset[9];
  unsigned int defaultPreset[9] = {8,8,8, 0,0,0,0, 0,0};
  unsigned int * presetSelect = defaultPreset;
  char *midnam = NULL;

  char * alternateProgrammeFile = NULL;
  char * alternateConfigFile = NULL;

  memset(&inst, 0, sizeof(b_instance));

  srand ((unsigned int) time (NULL));

  for (i=0;i<AUDIO_CHANNELS; i++)
    jack_port[i] = NULL;
  jack_ports = strdup("system:playback_");

  const char *optstring = "c:CdDhHl:M:p:PrU:V";
  const struct option long_options[] = {
    { "help",       no_argument,       0, 'H' },
    { "program",    required_argument, 0, 'p' },
    { "config",     required_argument, 0, 'c' },
    { "noconfig",   no_argument,       0, 'C' },
    { "dumpcc",     no_argument,       0, 'd' },
    { "noCC",       no_argument,       0, 'D' },
    { "midnam",     required_argument, 0, 'M' },
    { "noprogram",  no_argument,       0, 'P' },
    { "randomize",  no_argument,       0, 'r' },
    { "upper",      required_argument, 0, 'U' },
    { "version",    no_argument,       0, 'V' },
    { 0, 0, 0, 0 }
  };

  while ((c = getopt_long(argc, argv, optstring, long_options, NULL)) != -1) {
    switch (c) {
      case 'c':
	alternateConfigFile = optarg;
	break;
      case 'C':
	doDefaultConfig = FALSE;
	break;
      case 'd':
	printCCTable = TRUE;
	break;
      case 'D':
	doDefaultCC = FALSE;
	break;
      case 'h':
	Usage(0);
	return (0);
	break;
      case 'H':
	Usage(1);
	return (0);
	break;
      case 'l':
	loadProgram = atoi(optarg);
	break;
      case 'M':
	midnam = optarg;
	break;
      case 'r':
	for (k = 0; k < 9; k++)
	  randomPreset[k] = rand () % 9;
	fprintf (stderr,
	    "Random Preset: "
	     "%d%d %d%d%d%d %d%d%d\n",
	     randomPreset[0],
	     randomPreset[1],
	     randomPreset[2],
	     randomPreset[3],
	     randomPreset[4],
	     randomPreset[5],
	     randomPreset[6],
	     randomPreset[7],
	     randomPreset[8]);
	presetSelect = randomPreset;
	break;
      case 'p':
	alternateProgrammeFile = optarg;
	break;
      case 'P':
	doDefaultProgram = FALSE;
	break;
      case 'U':
	parse_preset(defaultPreset, optarg);
	break;
      case 'V':
	PrintVersion();
	return(0);
      default:
	fprintf(stderr, "invalid argument.\n");
	Usage(0);
	return(1);
    }
  }

  for (i = optind; i < argc; ++i) {
    char * av = argv[i];
    if (strchr (av, '=') != NULL) {
      /* Remember this as a config parameter */
      if (configOverEnd < NOF_CFG_OVERS) {
	configOverride[configOverEnd++] = av;
      } else {
	fprintf (stderr,
	    "Too many configuration parameters (%d), please consider using a\n"
	    "configuration file instead of the commandline.\n",
	    NOF_CFG_OVERS);
	return(1);
      }
    }
  }

  /*
   * allocate data structures, instances.
   */
  allocAll();

  /*
   * evaluate configuration
   */

  if (getenv("XDG_CONFIG_HOME")) {
    size_t hl = strlen(getenv("XDG_CONFIG_HOME"));
    defaultConfigFile=(char*) malloc(hl+32);
    defaultProgrammeFile=(char*) malloc(hl+32);
    sprintf(defaultConfigFile, "%s/setBfree/default.cfg", getenv("XDG_CONFIG_HOME"));
    sprintf(defaultProgrammeFile, "%s/setBfree/default.pgm", getenv("XDG_CONFIG_HOME"));
  } else if (getenv("HOME")) {
    size_t hl = strlen(getenv("HOME"));
    defaultConfigFile=(char*) malloc(hl+30);
    defaultProgrammeFile=(char*) malloc(hl+30);
    sprintf(defaultConfigFile, "%s/.config/setBfree/default.cfg", getenv("HOME"));
    sprintf(defaultProgrammeFile, "%s/.config/setBfree/default.pgm", getenv("HOME"));
  }

  /*
   * Here we call modules that need to execute code in order to arrange
   * static initializations that is not practical to achieve in source code.
   */

  initControllerTable (inst.midicfg);
  if (doDefaultCC) {
    midiPrimeControllerMapping (inst.midicfg);
  }

  /*
   * Commandline arguments are parsed. If we are of a mind to try the
   * default configuration file we do that now.
   */

  if (doDefaultConfig == TRUE && defaultConfigFile) {
    if (access (defaultConfigFile, R_OK) == 0) {
      fprintf(stderr, "loading cfg: %s\n", defaultConfigFile);
      parseConfigurationFile (&inst, defaultConfigFile);
    }
  }

  if (alternateConfigFile) {
    if (access (alternateConfigFile, R_OK) == 0) {
      fprintf(stderr, "loading cfg: %s\n", alternateConfigFile);
      parseConfigurationFile (&inst, alternateConfigFile);
    }
  }

  /*
   * Then apply any configuration parameters collected from the commandline.
   * These must be applied last so that they can override the parameters
   * read from the files (if any).
   */

  for (i = 0; i < configOverEnd; i++) {
    parseConfigurationLine (&inst, "commandline argument",
			    0,
			    configOverride[i]);
  }

  /*
   * Having configured the initialization phase we can now actually do it.
   */
#ifndef _WIN32
  if (mlockall (MCL_CURRENT | MCL_FUTURE)) {
    fprintf(stderr, "Warning: Can not lock memory.\n");
  }
#endif

  initAll ();

  /*
   * We are initialized and now load the programme file.
   */

  if (doDefaultProgram == TRUE && defaultProgrammeFile) {
    if (access (defaultProgrammeFile, R_OK) == 0)
      loadProgrammeFile (inst.progs, defaultProgrammeFile);
  } else {
    walkProgrammes(inst.progs, 1); // clear built-in default program
  }
  if (alternateProgrammeFile != NULL)
    loadProgrammeFile (inst.progs, alternateProgrammeFile);

  if (walkProgrammes(inst.progs, 0)) {
    listProgrammes (inst.progs, stderr);
  }

  initMidiTables(inst.midicfg);

  if (printCCTable) {
    listCCAssignments(inst.midicfg, stderr);
  }

  if (midnam) {
    FILE *fp = fopen(midnam, "w");
    if (fp) {
      save_midname(&inst, fp);
      fclose(fp);
    } else {
      fprintf(stderr, "failed to write midnam to '%s'\n", midnam);
    }
  }

  /*
   * With the programmes eager and ready to go, we spawn off the MIDI
   * listener thread. The thread will initialize the MIDI device.
   */
#ifdef HAVE_ASEQ
  pthread_t t_midi;
  if (!use_jack_midi) {
    if (!aseq_open(midi_port)) {
      k = pthread_create(&t_midi, NULL, aseq_run, &inst);
      if (k != 0) {
	fprintf (stderr, "%d : %s\n", k, "pthread_create : MIDIInReader thread");
	return (1);
      }
    } else {
      return (1);
    }
  }
#endif

  setMIDINoteShift (inst.midicfg, 0);

  setDrawBars (&inst, 0, presetSelect);
#if 0 // initial values are assigned in tonegen.c initToneGenerator()
  setDrawBars (&inst, 1, presetSelect); /* 838 000 000 */
  setDrawBars (&inst, 2, presetSelect); /* 86 - */
#endif

  const int pgm_off = inst.progs->MIDIControllerPgmOffset;
  if (loadProgram >= 0 && loadProgram >= pgm_off) {
    installProgram(&inst, (loadProgram - pgm_off));
  }

#ifndef _WIN32
  signal (SIGHUP, catchsig);
  signal (SIGINT, catchsig);
#endif

  connect_jack_ports();

  synth_ready = 1;

  fprintf(stderr,"All systems go. press CTRL-C, or send SIGINT or SIGHUP to terminate\n");

  while (j_client)
  /* jack callback is doing this the work now */
#ifdef _WIN32
    Sleep (1000);
#else
    sleep (1);
#endif

  /* shutdown and cleanup */
#ifdef HAVE_ASEQ
  if (!use_jack_midi) {
    aseq_stop=1;
    pthread_join(t_midi, NULL);
    aseq_close();
  }
#endif

  free(defaultConfigFile);
  free(defaultProgrammeFile);

  free(j_output_bufferptrs);
  free(j_output_port);
  free(midi_port);
  free(jack_ports);
  for (i=0;i<AUDIO_CHANNELS; i++)
    free(jack_port[i]);

  freeAll();
#ifndef _WIN32
  munlockall();
#endif

  fprintf(stderr, "bye\n");
  return 0;
}
Ejemplo n.º 3
0
static int open_jack(out123_handle *ao)
{
	jack_handle_t *handle=NULL;
	jack_options_t jopt = JackNullOption|JackNoStartServer;
	jack_status_t jstat = 0;
	unsigned int i;
	char *realname;

	debug("jack open");
	if(!ao)
		return -1;

	/* Return if already open*/
	if(ao->userptr)
	{
		if(!AOQUIET)
			error("audio device is already open.");
		return -1;
	}

	/* The initial open lets me choose the settings. */
	if (ao->format==-1)
	{
		ao->format = MPG123_ENC_FLOAT_32;
		ao->channels = 2;
		/* Really need a framesize defined for callback. */
		ao->framesize = 2*4;
	}
	else if(!(ao->format & MPG123_ENC_FLOAT))
	{
		if(!AOQUIET)
			error("JACK only wants float!");
		return -1;
	}

	/* Create some storage for ourselves*/
	if((handle = alloc_jack_handle(ao)) == NULL)
		return -1;
	ao->userptr = (void*)handle;

	/* Register with Jack*/
	if((handle->client = jack_client_open(ao->name, jopt, &jstat)) == 0)
	{
		if(!AOQUIET)
			error1("Failed to open jack client: 0x%x", jstat);
		close_jack(ao);
		return -1;
	}

	realname = jack_get_client_name(handle->client);
	/* Display the unique client name allocated to us */
	if(AOVERBOSE(1))
		fprintf( stderr, "Registered as JACK client %s.\n"
		,	realname ? realname : "<nil>" );

	/* Just make sure. */
	ao->rate   = jack_get_sample_rate(handle->client);

	/* Check the sample rate is correct*/
	if (jack_get_sample_rate( handle->client ) != (jack_nframes_t)ao->rate)
	{
		if(!AOQUIET)
			error("JACK Sample Rate is different to sample rate of file.");
		close_jack(ao);
		return -1;
	}

	/* Register ports with Jack*/
	if(handle->channels > 0 && handle->channels < 100)
	{
		for(i=0;i<handle->channels;++i)
		{
			char numbuf[3]; /* two digits, zero byte */
			sprintf(numbuf, "%d", i+1);
			if( !(handle->ports[i] = jack_port_register( handle->client
			                         , numbuf, JACK_DEFAULT_AUDIO_TYPE
			                         , JackPortIsOutput, 0 )) )
			{
				if(!AOQUIET)
					error1("Cannot register JACK output port '%s'.", numbuf);
				close_jack(ao);
				return -1;
			}
		}
	}
	else
	{
		if(!AOQUIET)
			error1("excessive number of output channels (%d).", handle->channels);
		close_jack(ao);
		return -1;
	}

	/* Use device_buffer parameter for ring buffer, but ensure that two
	   JACK buffers fit in there. We do not support that buffer increasing
	   later on. */
	handle->rb_size = (size_t)( ao->device_buffer
	*	jack_get_sample_rate(handle->client)
	+	0.5 ); /* PCM frames */
	handle->procbuf_frames = jack_get_buffer_size(handle->client);
	if(handle->rb_size < 2*handle->procbuf_frames)
		handle->rb_size = 2*handle->procbuf_frames;
	debug1("JACK ringbuffer for %"SIZE_P" PCM frames", (size_p)handle->rb_size);
	/* Convert to bytes. */
	handle->rb_size *= handle->framesize;
	handle->rb = jack_ringbuffer_create(handle->rb_size);
	handle->procbuf = malloc(handle->procbuf_frames*handle->framesize);
	if(!handle->rb || !handle->procbuf)
	{
		if(!AOQUIET)
			error("failed to allocate buffers");
		close_jack(ao);
		return -1;
	}

	/* Set the callbacks*/
	jack_set_process_callback(handle->client, process_callback, (void*)handle);
	jack_on_shutdown(handle->client, shutdown_callback, (void*)handle);
	handle->alive = 1;
	/* Activate client*/
	if(jack_activate(handle->client))
	{
		if(!AOQUIET)
			error("Can't activate client.");
		close_jack(ao);
		return -1;
	}

	/* Connect up the portsm, return */
	if(!connect_jack_ports(ao, handle))
	{
		/* deregistering of ports will not work but should just fail, then,
		   and let the rest clean up */
		close_jack(ao);
		return -1;
	}

	debug("Jack open successful.\n");
	ao->realname = compat_strdup(realname);
	return 0;
}