示例#1
0
文件: jack.c 项目: BG2BKK/cmus
static int op_jack_init(void)
{
#ifdef HAVE_SAMPLERATE
	for (int i = 0; i < CHANNELS; i++) {
		src_state[i] = src_new(src_quality, 1, NULL);
		if (src_state[i] == NULL) {
			d_print("src_new failed");
			for (i = i - 1; i >= 0; i--) {
				src_delete(src_state[i]);
			}
			return -OP_ERROR_INTERNAL;
		}
	}
#endif
	jack_set_error_function(op_jack_error_cb);

	jack_options_t options = JackNullOption;
	if (fail) {
		/* since jackd failed, it will not be autostarted. Either jackd
		 * was killed intentionaly or it died by heartattack.
		 * Until it is restarted, init will happily fail again
		 * and again and again..
		 */
		options |= JackNoStartServer;
	}

	jack_status_t status;
	client = jack_client_open("cmus", options, &status, server_name);
	if (client == NULL) {
		d_print("jack_client_new failed\n");
		return -OP_ERROR_INTERNAL;
	}

	if (status & JackServerStarted) {
		d_print("jackd started\n");
	}

	jack_nframes_t jack_buffer_size = jack_get_buffer_size(client);
	jack_sample_rate = jack_get_sample_rate(client);
	op_jack_buffer_init(jack_buffer_size, NULL);

	jack_set_process_callback(client, op_jack_cb, NULL);
	jack_set_sample_rate_callback(client, op_jack_sample_rate_cb, NULL);
	jack_set_buffer_size_callback(client, op_jack_buffer_init, NULL);
	jack_on_shutdown(client, op_jack_shutdown_cb, NULL);

	for (int i = 0; i < CHANNELS; i++) {
		char port_name[20];
		snprintf(port_name, sizeof(port_name)-1, "output %d", i);

		output_ports[i] = jack_port_register(
			client,
			port_name,
			JACK_DEFAULT_AUDIO_TYPE,
			JackPortIsOutput,
			0
		);
		if (output_ports[i] == NULL) {
			d_print("no jack ports available\n");
			return -OP_ERROR_INTERNAL;
		}
	}

	if (jack_activate(client)) {
		d_print("jack_client_activate failed\n");
		return -OP_ERROR_INTERNAL;
	}

	const char **ports = jack_get_ports(client, NULL, NULL, JackPortIsPhysical | JackPortIsInput);
	if (ports == NULL) {
		d_print("cannot get playback ports\n");
		return -OP_ERROR_INTERNAL;
	}

	for (int i = 0; i < CHANNELS; i++) {
		if (ports[i] == NULL) {
			d_print("could not connect output %d. too few ports.\n", i);
			break;
		}
		if (jack_connect(client, jack_port_name(output_ports[i]), ports[i])) {
			d_print("connot connect port %s\n", ports[i]);
			jack_free(ports);
			return -OP_ERROR_INTERNAL;
		}
	}

	jack_free(ports);
	fail = 0;

	return OP_ERROR_SUCCESS;
}
示例#2
0
bool SC_JackDriver::BufferSizeChanged(int numSamples)
{
	Reset(jack_get_sample_rate(mClient), numSamples);
	return true;
}
/* allocate a buffer and setup resources to process the audio samples of
 * the format as specified in @spec.
 *
 * We allocate N jack ports, one for each channel. If we are asked to
 * automatically make a connection with physical ports, we connect as many
 * ports as there are physical ports, leaving leftover ports unconnected.
 *
 * It is assumed that samplerate and number of channels are acceptable since our
 * getcaps method will always provide correct values. If unacceptable caps are
 * received for some reason, we fail here.
 */
static gboolean
gst_jack_ring_buffer_acquire (GstRingBuffer * buf, GstRingBufferSpec * spec)
{
  GstJackAudioSrc *src;
  GstJackRingBuffer *abuf;
  const char **ports;
  gint sample_rate, buffer_size;
  gint i, channels, res;
  jack_client_t *client;

  src = GST_JACK_AUDIO_SRC (GST_OBJECT_PARENT (buf));
  abuf = GST_JACK_RING_BUFFER_CAST (buf);

  GST_DEBUG_OBJECT (src, "acquire");

  client = gst_jack_audio_client_get_client (src->client);

  /* sample rate must be that of the server */
  sample_rate = jack_get_sample_rate (client);
  if (sample_rate != spec->rate)
    goto wrong_samplerate;

  channels = spec->channels;

  if (!gst_jack_audio_src_allocate_channels (src, channels))
    goto out_of_ports;

  gst_jack_set_layout_on_caps (&spec->caps, channels);

  buffer_size = jack_get_buffer_size (client);

  /* the segment size in bytes, this is large enough to hold a buffer of 32bit floats
   * for all channels  */
  spec->segsize = buffer_size * sizeof (gfloat) * channels;
  spec->latency_time = gst_util_uint64_scale (spec->segsize,
      (GST_SECOND / GST_USECOND), spec->rate * spec->bytes_per_sample);
  /* segtotal based on buffer-time latency */
  spec->segtotal = spec->buffer_time / spec->latency_time;
  if (spec->segtotal < 2) {
    spec->segtotal = 2;
    spec->buffer_time = spec->latency_time * spec->segtotal;
  }

  GST_DEBUG_OBJECT (src, "buffer time: %" G_GINT64_FORMAT " usec",
      spec->buffer_time);
  GST_DEBUG_OBJECT (src, "latency time: %" G_GINT64_FORMAT " usec",
      spec->latency_time);
  GST_DEBUG_OBJECT (src, "buffer_size %d, segsize %d, segtotal %d",
      buffer_size, spec->segsize, spec->segtotal);

  /* allocate the ringbuffer memory now */
  buf->data = gst_buffer_new_and_alloc (spec->segtotal * spec->segsize);
  memset (GST_BUFFER_DATA (buf->data), 0, GST_BUFFER_SIZE (buf->data));

  if ((res = gst_jack_audio_client_set_active (src->client, TRUE)))
    goto could_not_activate;

  /* if we need to automatically connect the ports, do so now. We must do this
   * after activating the client. */
  if (src->connect == GST_JACK_CONNECT_AUTO
      || src->connect == GST_JACK_CONNECT_AUTO_FORCED) {
    /* find all the physical output ports. A physical output port is a port
     * associated with a hardware device. Someone needs connect to a physical
     * port in order to capture something. */
    ports =
        jack_get_ports (client, NULL, NULL,
        JackPortIsPhysical | JackPortIsOutput);
    if (ports == NULL) {
      /* no ports? fine then we don't do anything except for posting a warning
       * message. */
      GST_ELEMENT_WARNING (src, RESOURCE, NOT_FOUND, (NULL),
          ("No physical output ports found, leaving ports unconnected"));
      goto done;
    }

    for (i = 0; i < channels; i++) {
      /* stop when all output ports are exhausted */
      if (ports[i] == NULL) {
        /* post a warning that we could not connect all ports */
        GST_ELEMENT_WARNING (src, RESOURCE, NOT_FOUND, (NULL),
            ("No more physical ports, leaving some ports unconnected"));
        break;
      }
      GST_DEBUG_OBJECT (src, "try connecting to %s",
          jack_port_name (src->ports[i]));

      /* connect the physical port to a port */
      res = jack_connect (client, ports[i], jack_port_name (src->ports[i]));
      if (res != 0 && res != EEXIST)
        goto cannot_connect;
    }
    free (ports);
  }
done:

  abuf->sample_rate = sample_rate;
  abuf->buffer_size = buffer_size;
  abuf->channels = spec->channels;

  return TRUE;

  /* ERRORS */
wrong_samplerate:
  {
    GST_ELEMENT_ERROR (src, RESOURCE, SETTINGS, (NULL),
        ("Wrong samplerate, server is running at %d and we received %d",
            sample_rate, spec->rate));
    return FALSE;
  }
out_of_ports:
  {
    GST_ELEMENT_ERROR (src, RESOURCE, SETTINGS, (NULL),
        ("Cannot allocate more Jack ports"));
    return FALSE;
  }
could_not_activate:
  {
    GST_ELEMENT_ERROR (src, RESOURCE, SETTINGS, (NULL),
        ("Could not activate client (%d:%s)", res, g_strerror (res)));
    return FALSE;
  }
cannot_connect:
  {
    GST_ELEMENT_ERROR (src, RESOURCE, SETTINGS, (NULL),
        ("Could not connect input ports to physical ports (%d:%s)",
            res, g_strerror (res)));
    free (ports);
    return FALSE;
  }
}
示例#4
0
/* jack_init:
 *  JACK init routine.
 */
static int jack_init(int input, int voices)
{
   const char **ports;
   char tmp[128];

   if (!jack_detect(input))
      return -1;

   jack_bufsize = get_config_int("sound", "jack_buffer_size",
      jack_bufsize);

   if (jack_bufsize == -1)
      jack_bufsize = jack_get_buffer_size (jack_client);

   /* Those are already read in from the config file by Allegro. */
   jack_16bit = (_sound_bits == 16 ? 1 : 0);
   jack_stereo = (_sound_stereo ? 1 : 0);

   /* Let Allegro mix in its native unsigned format. */
   jack_signed = 0;

   jack_set_process_callback (jack_client, jack_process, NULL);

   output_left = jack_port_register (jack_client, jack_stereo ? "left" : "mono",
      JACK_DEFAULT_AUDIO_TYPE, JackPortIsOutput, 0);

   if (jack_stereo)
      output_right = jack_port_register (jack_client, "right",
         JACK_DEFAULT_AUDIO_TYPE, JackPortIsOutput, 0);

   jack_rate = jack_get_sample_rate (jack_client);

   jack_buffer = _AL_MALLOC_ATOMIC(jack_bufsize * (1 + jack_16bit) * (1 + jack_stereo));
   if (!jack_buffer) {
      ustrzcpy(allegro_error, ALLEGRO_ERROR_SIZE, get_config_text(
         "Cannot allocate audio buffer"));
      jack_exit (input);
      return -1;
   }

   digi_jack.voices = voices;

   if (_mixer_init(jack_bufsize *  (1 + jack_stereo), jack_rate,
      jack_stereo, jack_16bit, &digi_jack.voices)) {
      ustrzcpy(allegro_error, ALLEGRO_ERROR_SIZE, get_config_text(
         "Cannot init software mixer"));
      jack_exit (input);
      return -1;
   }

   _mix_some_samples((uintptr_t) jack_buffer, 0, jack_signed);

   if (jack_activate (jack_client)) {
      ustrzcpy(allegro_error, ALLEGRO_ERROR_SIZE, get_config_text(
         "Cannot activate Jack client"));
      jack_exit (input);
      return 1;
   }

   /* Try to connect the ports. Failure to connect is not critical, since with
    * JACK, users may connect/disconnect ports anytime, without Allegro caring.
    */
   if ((ports = jack_get_ports (jack_client, NULL, NULL,
      JackPortIsPhysical|JackPortIsInput)) == NULL) {
      TRACE (PREFIX_I "Cannot find any physical playback ports");
   }

   if (ports) {
      if (ports[0]) {
	 if (jack_connect (jack_client, jack_port_name (output_left), ports[0]) == 0)
	    TRACE (PREFIX_I "Connected left playback port to %s", ports[0]);
      }
      if (jack_stereo && ports[1]) {
	 if (jack_connect (jack_client, jack_port_name (output_right), ports[1]) == 0)
	    TRACE (PREFIX_I "Connected right playback port to %s", ports[1]);
      }
      _AL_FREE (ports);
   }

   uszprintf(jack_desc, sizeof(jack_desc),
      get_config_text ("Jack, client '%s': %d bits, %s, %d bps, %s"),
      jack_client_name, jack_16bit ? 16 : 8,
      uconvert_ascii((jack_signed ? "signed" : "unsigned"), tmp),
      jack_rate, uconvert_ascii((jack_stereo ? "stereo" : "mono"), tmp));

   return 0;
}
示例#5
0
int main( int argc, char **argv ) {
	const char **ports;
	const char *client_name;
	const char *server_name = NULL;
	jack_options_t options = JackNullOption;
	jack_status_t status;
	int i;
 char projectM_data[1024];


std::string config_file;
 config_file = read_config();

 ConfigFile config(config_file);

 wvw = config.read<int>( "Window Width", 512 );
 wvh = config.read<int>( "Window Height", 512 );
 int fullscreen = 0;
 if (config.read("Fullscreen", true)) fullscreen = 1;
      else fullscreen = 0;
 

#ifdef DEBUG
	int value;
	int rgb_size[3];
#endif

  const SDL_VideoInfo* info = NULL;
  int bpp = 0;
  /* Flags we will pass into SDL_SetVideoMode. */
  int flags = 0;

  //JACK INIT
  //----------------------------------------------
	if (argc >= 2) {		/* client name specified? */
		client_name = argv[1];
		if (argc >= 3) {	/* server name specified? */
			server_name = argv[2];
			//			options |= JackServerName;
		}
	} else {			/* use basename of argv[0] */
		client_name = strrchr(argv[0], '/');
		if (client_name == 0) {
			client_name = argv[0];
		} else {
			client_name++;
		}
	}

	/* open a client connection to the JACK server */

	client = jack_client_open (client_name, options, &status, server_name);
	if (client == NULL) {
		fprintf (stderr, "jack_client_open() failed, "
			 "status = 0x%2.0x\n", status);
		if (status & JackServerFailed) {
			fprintf (stderr, "Unable to connect to JACK server\n");
		}
		exit (1);
	}
	if (status & JackServerStarted) {
		fprintf (stderr, "JACK server started\n");
	}
	if (status & JackNameNotUnique) {
		client_name = jack_get_client_name(client);
		fprintf (stderr, "unique name `%s' assigned\n", client_name);
	}

	/* tell the JACK server to call `process()' whenever
	   there is work to be done.
	*/

	jack_set_process_callback (client, process, 0);

	/* tell the JACK server to call `jack_shutdown()' if
	   it ever shuts down, either entirely, or if it
	   just decides to stop calling us.
	*/

	jack_on_shutdown (client, jack_shutdown, 0);

	/* display the current sample rate. 
	 */

	printf ("engine sample rate: %d\n",
		jack_get_sample_rate (client));

	/* create two ports */

	input_port = jack_port_register (client, "input",
					 JACK_DEFAULT_AUDIO_TYPE,
					 JackPortIsInput, 0);

	if (input_port == NULL) {
		fprintf(stderr, "no more JACK ports available\n");
		exit (1);
	}

	/* Tell the JACK server that we are ready to roll.  Our
	 * process() callback will start running now. */



	//END JACK INIT ----------------------------------
  init_display(wvw,wvh,&fvw,&fvh,fullscreen);   
    /** Setup some window stuff */
    SDL_WM_SetCaption( PROJECTM_TITLE, NULL );
  globalPM = new projectM(config_file);
    /** Initialise projectM */
 



    //JACK BEGIN-----------------------------

	if (jack_activate (client)) {
		fprintf (stderr, "cannot activate client");
		exit (1);
	}

	/* Connect the ports.  You can't do this before the client is
	 * activated, because we can't make connections to clients
	 * that aren't running.  Note the confusing (but necessary)
	 * orientation of the driver backend ports: playback ports are
	 * "input" to the backend, and capture ports are "output" from
	 * it.
	 */

	ports = jack_get_ports (client, NULL, NULL, JackPortIsOutput);
	if (ports == NULL) {
		fprintf(stderr, "no physical capture ports\n");
		exit (1);
	}
      
	
        i=0;
        while (ports[i]!=NULL) 
	 { 
            printf("Connecting to Jack port %s\n",ports[i]);
	    if (jack_connect (client, ports[i], jack_port_name (input_port))) {
	      fprintf (stderr, "cannot connect input ports\n");
	    }
	      i++;
	     }
	     
	free (ports);

	//----------------------------------END


    /** Initialise the thread */
    renderLoop();

    return 1;
}
示例#6
0
int main(int argc, char *argv[])
{
  const char*filename = "jtest.caf";
  const char*myname=argv[0];
  observe_signals ();
  struct recorder d;

  ambix_matrix_t*matrix=NULL;
  int32_t order = -1;

  d.buffer_frames = 4096;
  d.minimal_frames = 32;
  d.channels = 2;
  d.timer_seconds = -1.0;
  d.timer_counter = 0;
  d.sample_format = AMBIX_SAMPLEFORMAT_FLOAT32;
  d.file_format   = AMBIX_BASIC;
  int c;
  while((c = getopt(argc, argv, "hVx:X:O:b:fhm:n:t:")) != -1) {
    switch(c) {
    case 'x':
      d.e_channels = (int) strtol(optarg, NULL, 0);
      d.file_format   = AMBIX_EXTENDED;
      break;
    case 'X':
      matrix=matrix_read(optarg, matrix);
      if(!matrix) {
        eprintf("%s: couldn't read matrix-file '%s'\n", myname, optarg);
        FAILURE;
      }
      d.file_format   = AMBIX_EXTENDED;
      break;
    case 'O':
      order = (uint32_t) strtol(optarg, NULL, 0);
      break;

    case 'b':
      d.buffer_frames = (int) strtol(optarg, NULL, 0);
      break;
#if 0
    case 'f':
      d.file_format = (int) strtol(optarg, NULL, 0);
      break;
#endif
    case 'V':
      version (myname);
      break;
    case 'h':
      usage (myname);
      break;
    case 'm':
      d.minimal_frames = (int) strtol(optarg, NULL, 0);
      break;
    case 't':
      d.timer_seconds = (float) strtod(optarg, NULL);
      break;
    default:
      eprintf("%s: illegal option, %c\n", myname, c);
      usage (myname);
      break;
    }
  }

  if(optind == argc - 1) {
    filename=argv[optind];
  } else {
    eprintf("opening default file '%s'\n", filename);
    //usage (myname);
  }

  /* Allocate channel based data. */
  if(matrix) {
    if(order<0) {
      d.a_channels = matrix->cols;
    } else {
      if(ambix_order2channels(order) != matrix->rows) {
        eprintf("%s: ambisonics order:%d cannot use [%dx%d] adaptor matrix.\n", myname, order, matrix->rows, matrix->cols);
        FAILURE;
      }
      d.a_channels = matrix->cols;
    }
  } else {
    if(order<0)
      order=1;

    d.a_channels=ambix_order2channels(order);
  }

  switch(d.file_format) {
  case AMBIX_BASIC:
    //d.a_channels;
    d.e_channels=0;
    break;
  case AMBIX_EXTENDED:
    //d.a_channels;
    //d.e_channels;
    break;
  case AMBIX_NONE: default:
    d.a_channels=0;
    //d.e_channels;
  }
  d.channels = d.a_channels+d.e_channels;


  if(d.channels < 1) {
    eprintf("%s: illegal number of channels: %d\n", myname, d.channels);
    FAILURE;
  }
  d.in = (float**)xmalloc(d.channels * sizeof(float *));
  d.input_port = (jack_port_t**)xmalloc(d.channels * sizeof(jack_port_t *));

  /* Connect to JACK. */
  
  jack_client_t *client = jack_client_unique_("ambix-jrecord");
  jack_set_error_function(jack_client_minimal_error_handler);
  jack_on_shutdown(client, jack_client_minimal_shutdown_handler, 0);
  jack_set_process_callback(client, process, &d);
  d.sample_rate = jack_get_sample_rate(client);

  /* Setup timer. */

  if(d.timer_seconds < 0.0) {
    d.timer_frames = -1;
  } else {
    d.timer_frames = d.timer_seconds * d.sample_rate;
  }

  /* Create sound file. */

  ambix_info_t sfinfo;
  memset(&sfinfo, 0, sizeof(sfinfo));
  sfinfo.samplerate = (int) d.sample_rate;
  sfinfo.frames = 0;
  sfinfo.fileformat = d.file_format;

  sfinfo.ambichannels  = d.a_channels;
  sfinfo.extrachannels = d.e_channels;

  d.sound_file = ambix_open(filename, AMBIX_WRITE, &sfinfo);

  if(matrix) {
    ambix_err_t aerr = ambix_set_adaptormatrix(d.sound_file, matrix);
    if(AMBIX_ERR_SUCCESS != aerr) {
      eprintf("setting [%dx%d] matrix returned %d.\n", matrix->rows, matrix->cols, aerr);
      FAILURE;
    }
  }

  /* Allocate buffers. */
  
  d.buffer_samples = d.buffer_frames * d.channels;
  d.buffer_bytes = d.buffer_samples * sizeof(float);

  d.a_buffer = (float32_t*)xmalloc(d.buffer_frames * d.a_channels * sizeof(float32_t));
  d.e_buffer = (float32_t*)xmalloc(d.buffer_frames * d.e_channels * sizeof(float32_t));

  d.d_buffer = (float*)xmalloc(d.buffer_bytes);
  d.j_buffer = (float*)xmalloc(d.buffer_bytes);
  d.u_buffer = (float*)xmalloc(d.buffer_bytes);
  d.ring_buffer = jack_ringbuffer_create(d.buffer_bytes);

  /* Create communication pipe. */

  xpipe(d.pipe);

  /* Start disk thread. */

  pthread_create (&(d.disk_thread),
		  NULL, 
		  disk_thread_procedure, 
		  &d);

  /* Create input ports and activate client. */

#if 0
  jack_port_make_standard(client, d.input_port, d.channels, false);
  jack_client_activate(client);
#else
  do {
    int i=0, a, e;
    const char*format=(sfinfo.fileformat == AMBIX_BASIC)?"ACN_%d":"ambisonics_%d";
    const int a_offset=(sfinfo.fileformat == AMBIX_BASIC)?0:1;
    for(a=0; a<d.a_channels; a++) {
      d.input_port[i] = _jack_port_register(client, JackPortIsInput, format, a+a_offset);
      i++;
    }
    for(e=0; e<d.e_channels; e++) {
      d.input_port[i] = _jack_port_register(client, JackPortIsInput, "in_%d", e+1);
      i++;
    }
  } while(0);

  if(jack_activate(client)) {
    eprintf("jack_activate() failed\n");
    FAILURE;
  }
#endif

  /* Wait for disk thread to end, which it does when it reaches the
     end of the file or is interrupted. */

  pthread_join(d.disk_thread, NULL);

  /* Close sound file, free ring buffer, close JACK connection, close
     pipe, free data buffers, indicate success. */

  jack_client_close(client);
  ambix_close(d.sound_file);
  jack_ringbuffer_free(d.ring_buffer);
  close(d.pipe[0]);
  close(d.pipe[1]);

  free(d.a_buffer);
  free(d.e_buffer);

  free(d.d_buffer);
  free(d.j_buffer);
  free(d.u_buffer);
  free(d.in);
  free(d.input_port);
  if(matrix)ambix_matrix_destroy(matrix);
  return EXIT_SUCCESS;
}
示例#7
0
文件: jackio.c 项目: kfoltman/calfbox
int cbox_jackio_get_sample_rate(struct cbox_io_impl *impl)
{
    struct cbox_jack_io_impl *jii = (struct cbox_jack_io_impl *)impl;

    return jack_get_sample_rate(jii->client);
}
示例#8
0
bool DevJack::start(QString *err)
{
#ifdef JACK
  jack_options_t jackopts=JackNullOption;
  jack_status_t jackstat=JackFailure;
  int srcerr;

  //
  // Connect to JACK Instance
  //
  if(jack_server_name.isEmpty()) {
    jack_jack_client=
      jack_client_open(jack_client_name.toAscii(),jackopts,&jackstat);
  }
  else {
    jack_jack_client=
      jack_client_open(jack_client_name.toAscii(),jackopts,&jackstat,
		       (const char *)jack_server_name.toAscii());
  }
  if(jack_jack_client==NULL) {
    if((jackstat&JackInvalidOption)!=0) {
      *err=tr("invalid or unsupported JACK option");
    }
    if((jackstat&JackServerError)!=0) {
      *err=tr("communication error with the JACK server");
    }
    if((jackstat&JackNoSuchClient)!=0) {
      *err=tr("requested JACK client does not exist");
    }
    if((jackstat&JackLoadFailure)!=0) {
      *err=tr("unable to load internal JACK client");
    }
    if((jackstat&JackInitFailure)!=0) {
      *err=tr("unable to initialize JACK client");
    }
    if((jackstat&JackShmFailure)!=0) {
      *err=tr("unable to access JACK shared memory");
    }
    if((jackstat&JackVersionError)!=0) {
      *err=tr("JACK protocol version mismatch");
    }
    if((jackstat&JackServerStarted)!=0) {
      *err=tr("JACK server started");
    }
    if((jackstat&JackServerFailed)!=0) {
      fprintf (stderr, "unable to communication with JACK server\n");
      *err=tr("unable to communicate with JACK server");
    }
    if((jackstat&JackNameNotUnique)!=0) {
      *err=tr("JACK client name not unique");
    }
    if((jackstat&JackFailure)!=0) {
      *err=tr("JACK general failure");
    }
    *err=tr("no connection to JACK server");
  printf("~DevJack::start() Ends FALSE 1\n");
    return false;
  }
  jack_set_buffer_size_callback(jack_jack_client,JackBufferSizeChanged,this);
  jack_set_process_callback(jack_jack_client,JackProcess,this);

  //
  // Join the Graph
  //
  if(jack_activate(jack_jack_client)) {
    *err=tr("unable to join JACK graph");
  printf("~DevJack::start() Ends FALSE 2\n");
    return false;
  }
  jack_jack_sample_rate=jack_get_sample_rate(jack_jack_client);

  //
  // Register Ports
  //
  for(unsigned i=0;i<codec()->channels();i++) {
    QString name=QString().sprintf("output_%d",i+1);
    jack_jack_ports[i]=
      jack_port_register(jack_jack_client,name.toAscii(),JACK_DEFAULT_AUDIO_TYPE,
			 JackPortIsOutput|JackPortIsTerminal,0);
  }
  Log(LOG_INFO,QString().sprintf("connected to JACK graph at %u samples/sec.",
				 jack_jack_sample_rate));

  //  jack_meter_timer->start(AUDIO_METER_INTERVAL);

  //
  // Initialize SRC
  //
  jack_pll_setpoint_ratio=
    (double)jack_jack_sample_rate/(double)codec()->samplerate();
  memset(&jack_data,0,sizeof(jack_data));
  jack_data.src_ratio=jack_pll_setpoint_ratio;
  if((jack_src=src_new(SRC_LINEAR,codec()->channels(),&srcerr))==NULL) {
    fprintf(stderr,"SRC initialization error [%s]\n",src_strerror(srcerr));
    exit(GLASS_EXIT_SRC_ERROR);
  }
  jack_play_position=0;
  jack_pll_setpoint_frames=0;
  jack_pll_offset=0.0;

  jack_play_position_timer->start(50);
  jack_meter_timer->start(AUDIO_METER_INTERVAL);

  return true;

#endif  // JACK
  return false;
}
示例#9
0
int
main(int argc, char **argv)
{
    int jitter_plot[101];
    int latency_plot[101];
    int long_index = 0;
    struct option long_options[] = {
        {"help", 0, NULL, 'h'},
        {"message-size", 1, NULL, 'm'},
        {"samples", 1, NULL, 's'},
        {"timeout", 1, NULL, 't'}
    };
    size_t name_arg_count;
    size_t name_size;
    char *option_string = "hm:s:t:";
    int show_usage = 0;
    connections_established = 0;
    error_message = NULL;
    message_size = 3;
    program_name = argv[0];
    remote_in_port = 0;
    remote_out_port = 0;
    samples = 1024;
    timeout = 5;

    for (;;) {
        signed char c = getopt_long(argc, argv, option_string, long_options,
                             &long_index);
        switch (c) {
        case 'h':
            show_usage = 1;
            break;
        case 'm':
            message_size = parse_positive_number_arg(optarg, "message-size");
            break;
        case 's':
            samples = parse_positive_number_arg(optarg, "samples");
            break;
        case 't':
            timeout = parse_positive_number_arg(optarg, "timeout");
            break;
        default:
            {
                char *s = "'- '";
                s[2] = c;
                die(s, "invalid switch");
            }
        case -1:
            if (show_usage) {
                output_usage();
                exit(EXIT_SUCCESS);
            }
            goto parse_port_names;
        case 1:
            /* end of switch :) */
            ;
        }
    }
 parse_port_names:
    name_arg_count = argc - optind;
    switch (name_arg_count) {
    case 2:
        target_in_port_name = argv[optind + 1];
        target_out_port_name = argv[optind];
        break;
    case 0:
        target_in_port_name = 0;
        target_out_port_name = 0;
        break;
    default:
        output_usage();
        return EXIT_FAILURE;
    }
    name_size = jack_port_name_size();
    alias1 = malloc(name_size * sizeof(char));
    if (alias1 == NULL) {
        error_message = strerror(errno);
        error_source = "malloc";
        goto show_error;
    }
    alias2 = malloc(name_size * sizeof(char));
    if (alias2 == NULL) {
        error_message = strerror(errno);
        error_source = "malloc";
        goto free_alias1;
    }
    latency_values = malloc(sizeof(jack_nframes_t) * samples);
    if (latency_values == NULL) {
        error_message = strerror(errno);
        error_source = "malloc";
        goto free_alias2;
    }
    latency_time_values = malloc(sizeof(jack_time_t) * samples);
    if (latency_time_values == NULL) {
        error_message = strerror(errno);
        error_source = "malloc";
        goto free_latency_values;
    }
    message_1 = malloc(message_size * sizeof(jack_midi_data_t));
    if (message_1 == NULL) {
        error_message = strerror(errno);
        error_source = "malloc";
        goto free_latency_time_values;
    }
    message_2 = malloc(message_size * sizeof(jack_midi_data_t));
    if (message_2 == NULL) {
        error_message = strerror(errno);
        error_source = "malloc";
        goto free_message_1;
    }
    switch (message_size) {
    case 1:
        message_1[0] = 0xf6;
        message_2[0] = 0xfe;
        break;
    case 2:
        message_1[0] = 0xc0;
        message_1[1] = 0x00;
        message_2[0] = 0xd0;
        message_2[1] = 0x7f;
        break;
    case 3:
        message_1[0] = 0x80;
        message_1[1] = 0x00;
        message_1[2] = 0x00;
        message_2[0] = 0x90;
        message_2[1] = 0x7f;
        message_2[2] = 0x7f;
        break;
    default:
        message_1[0] = 0xf0;
        memset(message_1 + 1, 0,
               (message_size - 2) * sizeof(jack_midi_data_t));
        message_1[message_size - 1] = 0xf7;
        message_2[0] = 0xf0;
        memset(message_2 + 1, 0x7f,
               (message_size - 2) * sizeof(jack_midi_data_t));
        message_2[message_size - 1] = 0xf7;
    }
    client = jack_client_open(program_name, JackNullOption, NULL);
    if (client == NULL) {
        error_message = "failed to open JACK client";
        error_source = "jack_client_open";
        goto free_message_2;
    }
    in_port = jack_port_register(client, "in", JACK_DEFAULT_MIDI_TYPE,
                                 JackPortIsInput, 0);
    if (in_port == NULL) {
        error_message = "failed to register MIDI-in port";
        error_source = "jack_port_register";
        goto close_client;
    }
    out_port = jack_port_register(client, "out", JACK_DEFAULT_MIDI_TYPE,
                                  JackPortIsOutput, 0);
    if (out_port == NULL) {
        error_message = "failed to register MIDI-out port";
        error_source = "jack_port_register";
        goto unregister_in_port;
    }
    if (jack_set_process_callback(client, handle_process, NULL)) {
        error_message = "failed to set process callback";
        error_source = "jack_set_process_callback";
        goto unregister_out_port;
    }
    if (jack_set_xrun_callback(client, handle_xrun, NULL)) {
        error_message = "failed to set xrun callback";
        error_source = "jack_set_xrun_callback";
        goto unregister_out_port;
    }
    if (jack_set_port_connect_callback(client, handle_port_connection_change,
                                       NULL)) {
        error_message = "failed to set port connection callback";
        error_source = "jack_set_port_connect_callback";
        goto unregister_out_port;
    }
    jack_on_shutdown(client, handle_shutdown, NULL);
    jack_set_info_function(handle_info);
    process_state = 0;

    connect_semaphore = create_semaphore(0);
    if (connect_semaphore == NULL) {
        error_message = get_semaphore_error();
        error_source = "create_semaphore";
        goto unregister_out_port;
    }
    init_semaphore = create_semaphore(1);
    if (init_semaphore == NULL) {
        error_message = get_semaphore_error();
        error_source = "create_semaphore";
        goto destroy_connect_semaphore;;
    }
    process_semaphore = create_semaphore(2);
    if (process_semaphore == NULL) {
        error_message = get_semaphore_error();
        error_source = "create_semaphore";
        goto destroy_init_semaphore;
    }
    if (jack_activate(client)) {
        error_message = "could not activate client";
        error_source = "jack_activate";
        goto destroy_process_semaphore;
    }
    if (name_arg_count) {
        if (jack_connect(client, jack_port_name(out_port),
                         target_out_port_name)) {
            error_message = "could not connect MIDI out port";
            error_source = "jack_connect";
            goto deactivate_client;
        }
        if (jack_connect(client, target_in_port_name,
                         jack_port_name(in_port))) {
            error_message = "could not connect MIDI in port";
            error_source = "jack_connect";
            goto deactivate_client;
        }
    }
    if (! register_signal_handler(handle_signal)) {
        error_message = strerror(errno);
        error_source = "register_signal_handler";
        goto deactivate_client;
    }
    printf("Waiting for connections ...\n");
    if (wait_semaphore(connect_semaphore, 1) == -1) {
        error_message = get_semaphore_error();
        error_source = "wait_semaphore";
        goto deactivate_client;
    }
    if (connections_established) {
        printf("Waiting for test completion ...\n\n");
        if (wait_semaphore(process_semaphore, 1) == -1) {
            error_message = get_semaphore_error();
            error_source = "wait_semaphore";
            goto deactivate_client;
        }
    }
    if (! register_signal_handler(SIG_DFL)) {
        error_message = strerror(errno);
        error_source = "register_signal_handler";
        goto deactivate_client;
    }
    if (process_state == 2) {
        double average_latency = ((double) total_latency) / samples;
        double average_latency_time = total_latency_time / samples;
        size_t i;
        double latency_plot_offset =
            floor(((double) lowest_latency_time) / 100.0) / 10.0;
        double sample_rate = (double) jack_get_sample_rate(client);
        jack_nframes_t total_jitter = 0;
        jack_time_t total_jitter_time = 0;
        for (i = 0; i <= 100; i++) {
            jitter_plot[i] = 0;
            latency_plot[i] = 0;
        }
        for (i = 0; i < samples; i++) {
            double latency_time_value = (double) latency_time_values[i];
            double latency_plot_time =
                (latency_time_value / 1000.0) - latency_plot_offset;
            double jitter_time = ABS(average_latency_time -
                                     latency_time_value);
            if (latency_plot_time >= 10.0) {
                (latency_plot[100])++;
            } else {
                (latency_plot[(int) (latency_plot_time * 10.0)])++;
            }
            if (jitter_time >= 10000.0) {
                (jitter_plot[100])++;
            } else {
                (jitter_plot[(int) (jitter_time / 100.0)])++;
            }
            total_jitter += ABS(average_latency -
                                ((double) latency_values[i]));
            total_jitter_time += jitter_time;
        }
        printf("Reported out-port latency: %.2f-%.2f ms (%u-%u frames)\n"
               "Reported in-port latency: %.2f-%.2f ms (%u-%u frames)\n"
               "Average latency: %.2f ms (%.2f frames)\n"
               "Lowest latency: %.2f ms (%u frames)\n"
               "Highest latency: %.2f ms (%u frames)\n"
               "Peak MIDI jitter: %.2f ms (%u frames)\n"
               "Average MIDI jitter: %.2f ms (%.2f frames)\n",
               (out_latency_range.min / sample_rate) * 1000.0,
               (out_latency_range.max / sample_rate) * 1000.0,
               out_latency_range.min, out_latency_range.max,
               (in_latency_range.min / sample_rate) * 1000.0,
               (in_latency_range.max / sample_rate) * 1000.0,
               in_latency_range.min, in_latency_range.max,
               average_latency_time / 1000.0, average_latency,
               lowest_latency_time / 1000.0, lowest_latency,
               highest_latency_time / 1000.0, highest_latency,
               (highest_latency_time - lowest_latency_time) / 1000.0,
               highest_latency - lowest_latency,
               (total_jitter_time / 1000.0) / samples,
               ((double) total_jitter) / samples);
        printf("\nJitter Plot:\n");
        for (i = 0; i < 100; i++) {
            if (jitter_plot[i]) {
                printf("%.1f - %.1f ms: %d\n", ((float) i) / 10.0,
                       ((float) (i + 1)) / 10.0, jitter_plot[i]);
            }
        }
        if (jitter_plot[100]) {
            printf("     > 10 ms: %d\n", jitter_plot[100]);
        }
        printf("\nLatency Plot:\n");
        for (i = 0; i < 100; i++) {
            if (latency_plot[i]) {
                printf("%.1f - %.1f ms: %d\n",
                       latency_plot_offset + (((float) i) / 10.0),
                       latency_plot_offset + (((float) (i + 1)) / 10.0),
                       latency_plot[i]);
            }
        }
        if (latency_plot[100]) {
            printf("     > %.1f ms: %d\n", latency_plot_offset + 10.0,
                   latency_plot[100]);
        }
    }
 deactivate_client:
    jack_deactivate(client);
    printf("\nMessages sent: %d\nMessages received: %d\n", messages_sent,
           messages_received);
    if (unexpected_messages) {
        printf("Unexpected messages received: %d\n", unexpected_messages);
    }
    if (xrun_count) {
        printf("Xruns: %d\n", xrun_count);
    }
 destroy_process_semaphore:
    destroy_semaphore(process_semaphore, 2);
 destroy_init_semaphore:
    destroy_semaphore(init_semaphore, 1);
 destroy_connect_semaphore:
    destroy_semaphore(connect_semaphore, 0);
 unregister_out_port:
    jack_port_unregister(client, out_port);
 unregister_in_port:
    jack_port_unregister(client, in_port);
 close_client:
    jack_client_close(client);
 free_message_2:
    free(message_2);
 free_message_1:
    free(message_1);
 free_latency_time_values:
    free(latency_time_values);
 free_latency_values:
    free(latency_values);
 free_alias2:
    free(alias2);
 free_alias1:
    free(alias1);
    if (error_message != NULL) {
    show_error:
        output_error(error_source, error_message);
        exit(EXIT_FAILURE);
    }
    return EXIT_SUCCESS;
}
示例#10
0
文件: ao_jack.c 项目: Nikoli/mpv
static int init(struct ao *ao)
{
    struct priv *p = ao->priv;
    struct mp_chmap_sel sel = {0};
    jack_options_t open_options;

    ao->format = AF_FORMAT_FLOATP;

    switch (p->stdlayout) {
    case 0:
        mp_chmap_sel_add_waveext(&sel);
        break;

    case 1:
        mp_chmap_sel_add_alsa_def(&sel);
        break;

    default:
        mp_chmap_sel_add_any(&sel);
    }

    if (!ao_chmap_sel_adjust(ao, &sel, &ao->channels))
        goto err_chmap;

    open_options = JackNullOption;
    if (!p->autostart)
        open_options |= JackNoStartServer;

    p->client = jack_client_open(p->cfg_client_name, open_options, NULL);
    if (!p->client) {
        MP_FATAL(ao, "cannot open server\n");
        goto err_client_open;
    }

    if (create_ports(ao, ao->channels.num))
        goto err_create_ports;

    jack_set_process_callback(p->client, process, ao);

    if (jack_activate(p->client)) {
        MP_FATAL(ao, "activate failed\n");
        goto err_activate;
    }

    ao->samplerate = jack_get_sample_rate(p->client);

    if (p->connect)
        if (connect_to_outports(ao))
            goto err_connect;

    jack_latency_range_t jack_latency_range;
    jack_port_get_latency_range(p->ports[0], JackPlaybackLatency,
                                &jack_latency_range);
    p->jack_latency = (float)(jack_latency_range.max + jack_get_buffer_size(p->client))
                      / (float)ao->samplerate;

    if (!ao_chmap_sel_get_def(ao, &sel, &ao->channels, p->num_ports))
        goto err_chmap_sel_get_def;

    return 0;

err_chmap_sel_get_def:
err_connect:
    jack_deactivate(p->client);
err_activate:
err_create_ports:
    jack_client_close(p->client);
err_client_open:
err_chmap:
    return -1;
}
示例#11
0
bool audioStreamer_JACK::init(const char* clientName,
			      int nInputChannels,
			      int nOutputChannels,
			      SPLPROC proc)
{

    njc = NULL;
    splproc = proc;

    if (client) {
      jack_client_close(client);
      client = NULL;
    }
    if ((client = jack_client_new(clientName)) == 0) {
      fprintf (stderr, "jack server not running?\n");
      return false;
      // exit(20);
    }

    jack_set_process_callback (client, (JackProcessCallback) process_cb, this);

    jack_set_timebase_callback( client, 0, (JackTimebaseCallback) jack_timebase_cb, this );

    if (_out) {
      delete[] _out;
      _out = NULL;
    }
    _out = new jack_port_t*[nOutputChannels];
    if (_outports) {
      delete[] _outports;
      _outports = NULL;
    }
    _outports = new float*[nOutputChannels];
    for (unsigned i=0; i<nOutputChannels; i++) {
      char name[10];
      snprintf(name, sizeof(name), "out%d", i+1);
      _out[i] = jack_port_register (client, name, JACK_DEFAULT_AUDIO_TYPE, JackPortIsOutput, 0);
    }

    if (_in) {
      delete[] _in;
      _in = NULL;
    }
    _in = new jack_port_t*[nInputChannels];
    if (_inports) {
      delete[] _inports;
      _inports = NULL;
    }
    _inports = new float*[nInputChannels];
    for (unsigned i=0; i<nInputChannels; i++) {
      char name[10];
      snprintf(name, sizeof(name), "in%d", i+1);
      _in[i] = jack_port_register (client, name, JACK_DEFAULT_AUDIO_TYPE, JackPortIsInput, 0);
    }

    if (jack_activate (client)) {
      fprintf (stderr, "cannot activate client\n");
      return false;
      //exit(20);
    }

    m_innch = nInputChannels;
    m_outnch = nOutputChannels;
    m_srate = jack_get_sample_rate( client );
    m_bps = 32;
    return true;
}
示例#12
0
int
so_main (int new_latency, int number_inputs, int number_outputs)
{
	/* const char **ports; */
	const char *client_name = "soft-rt-bridge";
	const char *server_name = NULL;
	jack_options_t options = JackNullOption;
	jack_status_t status;


	latency = new_latency;
	jack_write_head = 1;
	lisp_read_head = 0;

	jack_read_head = 1;
	lisp_write_head = 0;

	n_input_ports = number_inputs;
	n_output_ports = number_outputs;

	underflow_flag = false;
	ready_flag = false;
	int j;
	for (j=0; j<n_input_ports; j++) {
	  in_buffers[j] = malloc( latency * sizeof(jack_default_audio_sample_t));
	  if (in_buffers[j] == NULL) {
	    fprintf (stderr, "no memory");
	    exit(1);
	  }
	  memset (in_buffers[j], 0, latency * sizeof(jack_default_audio_sample_t));

	}

	for (j=0; j<n_output_ports; j++) {
	  out_buffers[j] = malloc( latency * sizeof(jack_default_audio_sample_t));
	  if (out_buffers[j] == NULL) {
	    fprintf (stderr, "no memory");
	    exit(1);
	  }
	  memset (out_buffers[j], 0, latency * sizeof(jack_default_audio_sample_t));

	}


	/* open a client connection to the JACK server */

	client = jack_client_open (client_name, options, &status, server_name);
	if (client == NULL) {
		fprintf (stderr, "jack_client_open() failed, "
			 "status = 0x%2.0x\n", status);
		if (status & JackServerFailed) {
			fprintf (stderr, "Unable to connect to JACK server\n");
		}
		exit (1);
	}
	if (status & JackServerStarted) {
		fprintf (stderr, "JACK server started\n");
	}
	if (status & JackNameNotUnique) {
		client_name = jack_get_client_name(client);
		fprintf (stderr, "unique name `%s' assigned\n", client_name);
	}

	/* tell the JACK server to call `process()' whenever
	   there is work to be done.
	*/

	jack_set_process_callback (client, process, 0);


	/* tell the JACK server to call `latency()' whenever
	   the latency needs to be recalculated.
	*/
	/* if (jack_set_latency_callback) */
	/*	jack_set_latency_callback (client, latency_cb, 0); */
	// FIXME the latency callback seems to generate some weird low-level
	// digital artefact that sounds frikkin nasty!


	/* tell the JACK server to call `jack_shutdown()' if
	   it ever shuts down, either entirely, or if it
	   just decides to stop calling us.
	*/

	jack_on_shutdown (client, jack_shutdown, 0);

	/* display the current sample rate.
	 */

	printf ("engine sample rate: %" PRIu32 "\n",
		jack_get_sample_rate (client));

	/* create two ports */
	char portname[256];
	for (j=0; j<n_output_ports; j++) {
	  sprintf(portname, "output %d", j);
	  output_ports[j] = jack_port_register (client, portname,
						JACK_DEFAULT_AUDIO_TYPE,
						JackPortIsOutput, 0);
	  if (output_ports[j] == NULL) {
	    fprintf(stderr, "no more JACK ports available\n");
	    exit (1);
	  }

	}

	for (j=0; j<n_input_ports; j++) {
	  sprintf(portname, "input %d", j);
	  input_ports[j] = jack_port_register (client, portname,
					       JACK_DEFAULT_AUDIO_TYPE,
					       JackPortIsInput, 0);

	  if (input_ports[j] == NULL) {
	    fprintf(stderr, "no more JACK ports available\n");
	    exit (1);
	  }
	}

	/* Tell the JACK server that we are ready to roll.  Our
	 * process() callback will start running now. */

	if (jack_activate (client)) {
		fprintf (stderr, "cannot activate client");
		exit (1);
	}

	//maybe reconnect this plumbing when multiple ports are cooked...
	/* /\* Connect the ports.  You can't do this before the client is */
	/*  * activated, because we can't make connections to clients */
	/*  * that aren't running.  Note the confusing (but necessary) */
	/*  * orientation of the driver backend ports: playback ports are */
	/*  * "input" to the backend, and capture ports are "output" from */
	/*  * it. */
	/*  *\/ */

	/* ports = jack_get_ports (client, NULL, NULL, */
	/*			JackPortIsPhysical|JackPortIsOutput); */
	/* if (ports == NULL) { */
	/*	fprintf(stderr, "no physical capture ports\n"); */
	/*	exit (1); */
	/* } */

	/* if (jack_connect (client, ports[0], jack_port_name (input_port))) { */
	/*	fprintf (stderr, "cannot connect input ports\n"); */
	/* } */

	/* free (ports); */

	/* ports = jack_get_ports (client, NULL, NULL, */
	/*			JackPortIsPhysical|JackPortIsInput); */
	/* if (ports == NULL) { */
	/*	fprintf(stderr, "no physical playback ports\n"); */
	/*	exit (1); */
	/* } */

	/* if (jack_connect (client, jack_port_name (output_port), ports[0])) { */
	/*	fprintf (stderr, "cannot connect output ports\n"); */
	/* } */

	/* free (ports); */


	/* keep running until stopped by the user */
	while (underflow_flag == false)
	  sleep (1);

	jack_deactivate (client);
	jack_client_close (client);
	/* exit (0); */
	return 0;
}
示例#13
0
static int start_jack(struct auplay_st *st)
{
	const char **ports;
	const char *client_name = "baresip";
	const char *server_name = NULL;
	jack_options_t options = JackNullOption;
	jack_status_t status;
	unsigned ch;
	jack_nframes_t engine_srate;

	/* open a client connection to the JACK server */

	st->client = jack_client_open(client_name, options,
				      &status, server_name);
	if (st->client == NULL) {
		warning("jack: jack_client_open() failed, "
			"status = 0x%2.0x\n", status);

		if (status & JackServerFailed) {
			warning("jack: Unable to connect to JACK server\n");
		}
		return ENODEV;
	}
	if (status & JackServerStarted) {
		info("jack: JACK server started\n");
	}
	if (status & JackNameNotUnique) {
		client_name = jack_get_client_name(st->client);
		info("jack: unique name `%s' assigned\n", client_name);
	}

	jack_set_process_callback(st->client, process_handler, st);

	engine_srate = jack_get_sample_rate(st->client);
	st->nframes  = jack_get_buffer_size(st->client);

	info("jack: engine sample rate: %" PRIu32 " max_frames=%u\n",
	     engine_srate, st->nframes);

	/* currently the application must use the same sample-rate
	   as the jack server backend */
	if (engine_srate != st->prm.srate) {
		warning("jack: samplerate %uHz expected\n", engine_srate);
		return EINVAL;
	}

	/* create one port per channel */
	for (ch=0; ch<st->prm.ch; ch++) {

		char buf[32];
		re_snprintf(buf, sizeof(buf), "output_%u", ch+1);

		st->portv[ch] = jack_port_register (st->client, buf,
						    JACK_DEFAULT_AUDIO_TYPE,
						    JackPortIsOutput, 0);
		if ( st->portv[ch] == NULL) {
			warning("jack: no more JACK ports available\n");
			return ENODEV;
		}
	}

	/* Tell the JACK server that we are ready to roll.  Our
	 * process() callback will start running now. */

	if (jack_activate (st->client)) {
		warning("jack: cannot activate client");
		return ENODEV;
	}

	/* Connect the ports.  You can't do this before the client is
	 * activated, because we can't make connections to clients
	 * that aren't running.  Note the confusing (but necessary)
	 * orientation of the driver backend ports: playback ports are
	 * "input" to the backend, and capture ports are "output" from
	 * it.
	 */

	ports = jack_get_ports (st->client, NULL, NULL,
				JackPortIsInput);
	if (ports == NULL) {
		warning("jack: no physical playback ports\n");
		return ENODEV;
	}

	for (ch=0; ch<st->prm.ch; ch++) {

		if (jack_connect (st->client, jack_port_name (st->portv[ch]),
				  ports[ch])) {
			warning("jack: cannot connect output ports\n");
		}
	}

	jack_free(ports);

	return 0;
}
RString RageSoundDriver_JACK::Init()
{
	jack_status_t status;
	RString error;

	// Open JACK client and call it "StepMania" or whatever
	client = jack_client_open(PRODUCT_FAMILY, JackNoStartServer, &status);
	if (client == NULL)
		return "Couldn't connect to JACK server";

	sample_rate = jack_get_sample_rate(client);
	LOG->Trace("JACK connected at %u Hz", sample_rate);

	// Start this before callbacks
	StartDecodeThread();

	// Set callback for processing audio
	if (jack_set_process_callback(client, ProcessTrampoline, this))
	{
		error = "Couldn't set JACK process callback";
		goto out_close;
	}

	if (jack_set_sample_rate_callback(client, SampleRateTrampoline, this))
	{
		error = "Couldn't set JACK sample-rate callback";
		goto out_close;
	}

	// TODO Set a jack_on_shutdown callback as well?  Probably just stop
	// caring about sound altogether if that happens.

	// Create output ports
	port_l = jack_port_register(client, "out_l", JACK_DEFAULT_AUDIO_TYPE,
			JackPortIsOutput, 0);
	if (port_l == NULL)
	{
		error = "Couldn't create JACK port out_l";
		goto out_close;
	}

	port_r = jack_port_register(client, "out_r", JACK_DEFAULT_AUDIO_TYPE,
			JackPortIsOutput, 0);
	if (port_r == NULL)
	{
		error = "Couldn't create JACK port out_r";
		goto out_unreg_l;
	}

	// Go!
	if (jack_activate(client))
	{
		error = "Couldn't activate JACK client";
		goto out_unreg_r;
	}

	error = ConnectPorts();
	if (!error.empty())
		// Eh. Not fatal. JACK *is* running and we successfully created
		// our source ports, so it's unlkely any other driver will
		// function.
		LOG->Warn( "RageSoundDriver_JACK: Couldn't connect ports: %s", error.c_str() );

	// Success!
	LOG->Trace("JACK sound driver started successfully");
	return RString();


	// Not success!
out_unreg_r:
	jack_port_unregister(client, port_r);
out_unreg_l:
	jack_port_unregister(client, port_l);
out_close:
	jack_client_close(client);
	client = NULL;
	return error;
}
示例#15
0
static int init(int rate, int channels, int format, int flags) {
    const char **matching_ports = NULL;
    char *port_name = NULL;
    char *client_name = NULL;
    int autostart = 0;
    const opt_t subopts[] = {
        {"port", OPT_ARG_MSTRZ, &port_name, NULL},
        {"name", OPT_ARG_MSTRZ, &client_name, NULL},
        {"estimate", OPT_ARG_BOOL, &estimate, NULL},
        {"autostart", OPT_ARG_BOOL, &autostart, NULL},
        {NULL}
    };
    jack_options_t open_options = JackUseExactName;
    int port_flags = JackPortIsInput;
    int i;
    estimate = 1;
    if (subopt_parse(ao_subdevice, subopts) != 0) {
        print_help();
        return 0;
    }
    if (channels > MAX_CHANS) {
        mp_msg(MSGT_AO, MSGL_FATAL, "[JACK] Invalid number of channels: %i\n", channels);
        goto err_out;
    }
    if (!client_name) {
        client_name = malloc(40);
        sprintf(client_name, "MPlayer [%d]", getpid());
    }
    if (!autostart)
        open_options |= JackNoStartServer;
    client = jack_client_open(client_name, open_options, NULL);
    if (!client) {
        mp_msg(MSGT_AO, MSGL_FATAL, "[JACK] cannot open server\n");
        goto err_out;
    }
    buffer = av_fifo_alloc(BUFFSIZE);
    jack_set_process_callback(client, outputaudio, 0);

    // list matching ports
    if (!port_name)
        port_flags |= JackPortIsPhysical;
    matching_ports = jack_get_ports(client, port_name, NULL, port_flags);
    if (!matching_ports || !matching_ports[0]) {
        mp_msg(MSGT_AO, MSGL_FATAL, "[JACK] no physical ports available\n");
        goto err_out;
    }
    i = 1;
    while (matching_ports[i]) i++;
    if (channels > i) channels = i;
    num_ports = channels;

    // create out output ports
    for (i = 0; i < num_ports; i++) {
        char pname[30];
        snprintf(pname, 30, "out_%d", i);
        ports[i] = jack_port_register(client, pname, JACK_DEFAULT_AUDIO_TYPE, JackPortIsOutput, 0);
        if (!ports[i]) {
            mp_msg(MSGT_AO, MSGL_FATAL, "[JACK] not enough ports available\n");
            goto err_out;
        }
    }
    if (jack_activate(client)) {
        mp_msg(MSGT_AO, MSGL_FATAL, "[JACK] activate failed\n");
        goto err_out;
    }
    for (i = 0; i < num_ports; i++) {
        if (jack_connect(client, jack_port_name(ports[i]), matching_ports[i])) {
            mp_msg(MSGT_AO, MSGL_FATAL, "[JACK] connecting failed\n");
            goto err_out;
        }
    }
    rate = jack_get_sample_rate(client);
    jack_latency = (float)(jack_port_get_total_latency(client, ports[0]) +
                           jack_get_buffer_size(client)) / (float)rate;
    callback_interval = 0;

    ao_data.channels = channels;
    ao_data.samplerate = rate;
    ao_data.format = AF_FORMAT_FLOAT_NE;
    ao_data.bps = channels * rate * sizeof(float);
    ao_data.buffersize = CHUNK_SIZE * NUM_CHUNKS;
    ao_data.outburst = CHUNK_SIZE;
    free(matching_ports);
    free(port_name);
    free(client_name);
    return 1;

err_out:
    free(matching_ports);
    free(port_name);
    free(client_name);
    if (client)
        jack_client_close(client);
    av_fifo_free(buffer);
    buffer = NULL;
    return 0;
}
示例#16
0
/*------------------------------------------------------------------------------
 *  Open the audio source
 *----------------------------------------------------------------------------*/
bool
JackDspSource :: open ( void )                       throw ( Exception )
{
    char         client_name[255];
    size_t       rb_size;
    unsigned int c;
    
    if ( isOpen() ) {
        return false;
    }

    // Register client with Jack
    if ( jack_client_name != NULL ) {
      snprintf(client_name, 255, "%s", jack_client_name);
    } else {
      snprintf(client_name, 255, "darkice-%d", getpid());
    }

    if ((client = jack_client_new(client_name)) == NULL) {
        throw Exception( __FILE__, __LINE__, "JACK server not running?");
    }
    Reporter::reportEvent( 1, "Registering as JACK client", client_name);


    // Check the sample rate is correct
    if (jack_get_sample_rate( client ) != (jack_nframes_t)getSampleRate()) {
        throw Exception( __FILE__, __LINE__,
                        "JACK server sample rate is different than "
                        "sample rate in darkice config file");
    }


    // Register ports with Jack
    if (getChannel() == 1) {
        if (!(ports[0] = jack_port_register(client,
                                            "mono",
                                            JACK_DEFAULT_AUDIO_TYPE,
                                            JackPortIsInput,
                                            0))) {
            throw Exception( __FILE__, __LINE__,
                            "Cannot register input port", "mono");
        }
    } else if (getChannel() == 2) {
        if (!(ports[0] = jack_port_register(client,
                                            "left",
                                            JACK_DEFAULT_AUDIO_TYPE,
                                            JackPortIsInput,
                                            0))) {
            throw Exception( __FILE__, __LINE__,
                            "Cannot register input port", "left");
        }
        if (!(ports[1] = jack_port_register(client,
                                            "right",
                                            JACK_DEFAULT_AUDIO_TYPE,
                                            JackPortIsInput, 0))) {
            throw Exception( __FILE__, __LINE__,
                            "Cannot register input port", "right");
        }
    } else {
        throw Exception( __FILE__, __LINE__,
                        "Invalid number of channels", getChannel());
    }


    // Create a ring buffer for each channel
    rb_size = 2
            * jack_get_sample_rate(client)
            * sizeof (jack_default_audio_sample_t);
    for (c=0; c<getChannel(); c++) {
        rb[c] = jack_ringbuffer_create(rb_size);
        if (!rb[c]) {
            throw Exception( __FILE__, __LINE__,
                            "Failed to create ringbuffer for", "channel", c);
        }
    }


    // Set the callbacks
    jack_on_shutdown(client, JackDspSource::shutdown_callback, (void*)this);
    if (jack_set_process_callback(client,
                                  JackDspSource::process_callback,
                                  (void*)this)) {
        throw Exception( __FILE__, __LINE__, "Failed to set process callback");
    }    

    // Activate client
    if (jack_activate(client)) {
        throw Exception( __FILE__, __LINE__, "Can't activate client");
    }
    
    // Attempt to automatically connect up our input ports to something ?
    if (auto_connect) {
        do_auto_connect();
    }
    
    return true;
}
示例#17
0
    /*
        JackProxyDriver is wrapped in a JackWaitCallbackDriver decorator that behaves
        as a "dummy driver, until Initialize method returns.
    */
    bool JackProxyDriver::Initialize()
    {
        jack_log("JackProxyDriver::Initialize");

        // save existing local connections if needed
        if (fAutoSave) {
            SaveConnections(0);
        }

        // new loading, but existing client, restart the driver
        if (fClient) {
            jack_info("JackProxyDriver restarting...");
            jack_client_close(fClient);
        }
        FreePorts();

        // display some additional infos
        jack_info("JackProxyDriver started in %s mode.",
                    (fEngineControl->fSyncMode) ? "sync" : "async");

        do {
            jack_status_t status;
            char *old = NULL;

            if (fPromiscuous) {
                // as we are fiddling with the environment variable content, save it
                const char* tmp = getenv("JACK_PROMISCUOUS_SERVER");
                if (tmp) {
                    old = strdup(tmp);
                }
                // temporary enable promiscuous mode
                if (setenv("JACK_PROMISCUOUS_SERVER", fPromiscuous, 1) < 0) {
                    free(old);
                    jack_error("Error allocating memory.");
                    return false;
                }
            }

            jack_info("JackProxyDriver connecting to %s", fUpstream);
            fClient = jack_client_open(fClientName, static_cast<jack_options_t>(JackNoStartServer|JackServerName), &status, fUpstream);

            if (fPromiscuous) {
                // restore previous environment variable content
                if (old) {
                    if (setenv("JACK_PROMISCUOUS_SERVER", old, 1) < 0) {
                        free(old);
                        jack_error("Error allocating memory.");
                        return false;
                    }
                    free(old);
                } else {
                    unsetenv("JACK_PROMISCUOUS_SERVER");
                }
            }

            // the connection failed, try again later
            if (!fClient) {
                JackSleep(1000000);
            }

        } while (!fClient);
        jack_info("JackProxyDriver connected to %s", fUpstream);

        // we are connected, let's register some callbacks

        jack_on_shutdown(fClient, shutdown_callback, this);

        if (jack_set_process_callback(fClient, process_callback, this) != 0) {
            jack_error("Cannot set process callback.");
            return false;
        }

        if (jack_set_buffer_size_callback(fClient, bufsize_callback, this) != 0) {
            jack_error("Cannot set buffer size callback.");
            return false;
        }

        if (jack_set_sample_rate_callback(fClient, srate_callback, this) != 0) {
            jack_error("Cannot set sample rate callback.");
            return false;
        }

        if (jack_set_port_connect_callback(fClient, connect_callback, this) != 0) {
            jack_error("Cannot set port connect callback.");
            return false;
        }

        // detect upstream physical playback ports if needed
        if (fDetectPlaybackChannels) {
            fPlaybackChannels = CountIO(JACK_DEFAULT_AUDIO_TYPE, JackPortIsPhysical | JackPortIsOutput);
        }

        // detect upstream physical capture ports if needed
        if (fDetectCaptureChannels) {
            fCaptureChannels = CountIO(JACK_DEFAULT_AUDIO_TYPE, JackPortIsPhysical | JackPortIsInput);
        }

        if (AllocPorts() != 0) {
            jack_error("Can't allocate ports.");
            return false;
        }

        bufsize_callback(jack_get_buffer_size(fClient));
        srate_callback(jack_get_sample_rate(fClient));

        // restore local connections if needed
        if (fAutoSave) {
            LoadConnections(0);
        }

        // everything is ready, start upstream processing
        if (jack_activate(fClient) != 0) {
            jack_error("Cannot activate jack client.");
            return false;
        }

        // connect upstream ports if needed
        if (fAutoConnect) {
            ConnectPorts();
        }

        return true;
    }
示例#18
0
ExternalMetro::ExternalMetro(int freq, double max_amp, int dur_arg, int bpm, const char* client_name)
{
    sample_t scale;
    int i, attack_length, decay_length;
    int attack_percent = 1, decay_percent = 10;
    const char *bpm_string = "bpm";
    jack_options_t options = JackNullOption;
    jack_status_t status;
    offset = 0;

    /* Initial Jack setup, get sample rate */
    if ((client = jack_client_open (client_name, options, &status)) == 0) {
        fprintf (stderr, "jack server not running?\n");
        throw -1;
    }

    jack_set_process_callback (client, process_audio, this);
    jack_on_shutdown (client, shutdown, this);
    output_port = jack_port_register (client, bpm_string, JACK_DEFAULT_AUDIO_TYPE, JackPortIsOutput, 0);
    input_port = jack_port_register (client, "metro_in", JACK_DEFAULT_AUDIO_TYPE, JackPortIsInput, 0);

    sr = jack_get_sample_rate (client);

    /* setup wave table parameters */
    wave_length = 60 * sr / bpm;
    tone_length = sr * dur_arg / 1000;
    attack_length = tone_length * attack_percent / 100;
    decay_length = tone_length * decay_percent / 100;
    scale = 2 * PI * freq / sr;

    if (tone_length >= wave_length) {
        /*
        fprintf (stderr, "invalid duration (tone length = %" PRIu32
        	 ", wave length = %" PRIu32 "\n", tone_length,
        	 wave_length);
        */
        return ;
    }
    if (attack_length + decay_length > (int)tone_length) {
        fprintf (stderr, "invalid attack/decay\n");
        return ;
    }

    /* Build the wave table */
    wave = (sample_t *) malloc (wave_length * sizeof(sample_t));
    amp = (double *) malloc (tone_length * sizeof(double));

    for (i = 0; i < attack_length; i++) {
        amp[i] = max_amp * i / ((double) attack_length);
    }
    for (i = attack_length; i < (int) tone_length - decay_length; i++) {
        amp[i] = max_amp;
    }
    for (i = (int)tone_length - decay_length; i < (int)tone_length; i++) {
        amp[i] = - max_amp * (i - (double) tone_length) / ((double) decay_length);
    }
    for (i = 0; i < (int) tone_length; i++) {
        wave[i] = amp[i] * sin (scale * i);
    }
    for (i = tone_length; i < (int) wave_length; i++) {
        wave[i] = 0;
    }

    if (jack_activate (client)) {
        fprintf (stderr, "cannot activate client");
    }
}
示例#19
0
文件: jackio.c 项目: kfoltman/calfbox
gboolean cbox_io_init_jack(struct cbox_io *io, struct cbox_open_params *const params, struct cbox_command_target *fb, GError **error)
{
    const char *client_name = cbox_config_get_string_with_default("io", "client_name", "cbox");

    jack_client_t *client = NULL;
    jack_status_t status = 0;
    client = jack_client_open(client_name, JackNoStartServer, &status);
    if (client == NULL)
    {
        if (!cbox_hwcfg_setup_jack())
        {
            g_set_error(error, CBOX_MODULE_ERROR, CBOX_MODULE_ERROR_FAILED, "Cannot set up JACK server configuration based on current hardware");
            return FALSE;
        }

        status = 0;
        client = jack_client_open(client_name, 0, &status);
    }
    if (client == NULL)
    {
        g_set_error(error, CBOX_MODULE_ERROR, CBOX_MODULE_ERROR_FAILED, "Cannot create JACK instance");
        return FALSE;
    }

    // XXXKF would use a callback instead
    io->io_env.buffer_size = jack_get_buffer_size(client);
    io->cb = NULL;
    io->io_env.input_count = cbox_config_get_int("io", "inputs", 0);
    io->input_buffers = malloc(sizeof(float *) * io->io_env.input_count);
    io->io_env.output_count = cbox_config_get_int("io", "outputs", 2);
    io->output_buffers = malloc(sizeof(float *) * io->io_env.output_count);

    struct cbox_jack_io_impl *jii = malloc(sizeof(struct cbox_jack_io_impl));
    io->impl = &jii->ioi;
    jii->enable_common_midi_input = cbox_config_get_int("io", "enable_common_midi_input", 1);
    jii->debug_transport = cbox_config_get_int("debug", "jack_transport", 0);
    jii->last_transport_state = JackTransportStopped;
    jii->external_tempo = FALSE;

    cbox_command_target_init(&io->cmd_target, cbox_jack_io_process_cmd, jii);
    jii->ioi.pio = io;
    jii->ioi.getsampleratefunc = cbox_jackio_get_sample_rate;
    jii->ioi.startfunc = cbox_jackio_start;
    jii->ioi.stopfunc = cbox_jackio_stop;
    jii->ioi.getstatusfunc = cbox_jackio_get_status;
    jii->ioi.pollfunc = cbox_jackio_poll_ports;
    jii->ioi.cyclefunc = cbox_jackio_cycle;
    jii->ioi.getmidifunc = cbox_jackio_get_midi_data;
    jii->ioi.createmidiinfunc = cbox_jackio_create_midi_in;
    jii->ioi.destroymidiinfunc = cbox_jackio_destroy_midi_in;
    jii->ioi.createmidioutfunc = cbox_jackio_create_midi_out;
    jii->ioi.destroymidioutfunc = cbox_jackio_destroy_midi_out;
    jii->ioi.updatemidiinroutingfunc = cbox_jackio_update_midi_in_routing;
    jii->ioi.createaudiooutfunc = cbox_jackio_create_audio_out;
    jii->ioi.destroyaudiooutfunc = cbox_jackio_destroy_audio_out;
    jii->ioi.controltransportfunc = cbox_jackio_control_transport;
    jii->ioi.getsynccompletedfunc = cbox_jackio_get_sync_completed;
    jii->ioi.destroyfunc = cbox_jackio_destroy;

    jii->client_name = g_strdup(jack_get_client_name(client));
    jii->client = client;
    jii->rb_autoconnect = jack_ringbuffer_create(sizeof(jack_port_t *) * 128);
    jii->error_str = NULL;
    io->io_env.srate = jack_get_sample_rate(client);

    jii->inputs = malloc(sizeof(jack_port_t *) * io->io_env.input_count);
    jii->outputs = malloc(sizeof(jack_port_t *) * io->io_env.output_count);
    for (uint32_t i = 0; i < io->io_env.input_count; i++)
        jii->inputs[i] = NULL;
    for (uint32_t i = 0; i < io->io_env.output_count; i++)
        jii->outputs[i] = NULL;
    for (uint32_t i = 0; i < io->io_env.input_count; i++)
    {
        gchar *name = g_strdup_printf("in_%d", 1 + i);
        jii->inputs[i] = jack_port_register(jii->client, name, JACK_DEFAULT_AUDIO_TYPE, JackPortIsInput, 0);
        if (!jii->inputs[i])
        {
            g_set_error(error, CBOX_MODULE_ERROR, CBOX_MODULE_ERROR_FAILED, "Cannot create input port %d (%s)", i, name);
            g_free(name);
            goto cleanup;
        }
        g_free(name);
    }
    for (uint32_t i = 0; i < io->io_env.output_count; i++)
    {
        gchar *name = g_strdup_printf("out_%d", 1 + i);
        jii->outputs[i] = jack_port_register(jii->client, name, JACK_DEFAULT_AUDIO_TYPE, JackPortIsOutput, 0);
        if (!jii->outputs[i])
        {
            g_set_error(error, CBOX_MODULE_ERROR, CBOX_MODULE_ERROR_FAILED, "Cannot create output port %d (%s)", i, name);
            g_free(name);
            goto cleanup;
        }
        g_free(name);
    }
    if (jii->enable_common_midi_input)
    {
        jii->midi = jack_port_register(jii->client, "midi", JACK_DEFAULT_MIDI_TYPE, JackPortIsInput, 0);
        if (!jii->midi)
        {
            g_set_error(error, CBOX_MODULE_ERROR, CBOX_MODULE_ERROR_FAILED, "Cannot create MIDI port");
            return FALSE;
        }
    }
    else
        jii->midi = NULL;

    if (fb)
        cbox_execute_on(fb, NULL, "/io/jack_client_name", "s", NULL, jii->client_name);

    cbox_io_poll_ports(io, fb);

    return TRUE;

cleanup:
    if (jii->inputs)
    {
        for (uint32_t i = 0; i < io->io_env.input_count; i++)
            free(jii->inputs[i]);
        free(jii->inputs);
    }
    if (jii->outputs)
    {
        for (uint32_t i = 0; i < io->io_env.output_count; i++)
            free(jii->outputs[i]);
        free(jii->outputs);
    }
    cbox_io_destroy_all_midi_ports(io);
    if (jii->client_name)
        free(jii->client_name);
    jack_client_close(jii->client);
    free(jii);
    io->impl = NULL;
    return FALSE;
};
示例#20
0
int pa__init(pa_module*m) {
    struct userdata *u = NULL;
    pa_sample_spec ss;
    pa_channel_map map;
    pa_modargs *ma = NULL;
    jack_status_t status;
    const char *server_name, *client_name;
    uint32_t channels = 0;
    bool do_connect = true;
    unsigned i;
    const char **ports = NULL, **p;
    pa_sink_new_data data;
    jack_latency_range_t r;
    size_t n;

    pa_assert(m);

    jack_set_error_function(jack_error_func);

    if (!(ma = pa_modargs_new(m->argument, valid_modargs))) {
        pa_log("Failed to parse module arguments.");
        goto fail;
    }

    if (pa_modargs_get_value_boolean(ma, "connect", &do_connect) < 0) {
        pa_log("Failed to parse connect= argument.");
        goto fail;
    }

    server_name = pa_modargs_get_value(ma, "server_name", NULL);
    client_name = pa_modargs_get_value(ma, "client_name", "PulseAudio JACK Sink");

    m->userdata = u = pa_xnew0(struct userdata, 1);
    u->core = m->core;
    u->module = m;
    u->saved_frame_time_valid = false;
    u->rtpoll = pa_rtpoll_new();
    pa_thread_mq_init(&u->thread_mq, m->core->mainloop, u->rtpoll);

    /* The queue linking the JACK thread and our RT thread */
    u->jack_msgq = pa_asyncmsgq_new(0);

    /* The msgq from the JACK RT thread should have an even higher
     * priority than the normal message queues, to match the guarantee
     * all other drivers make: supplying the audio device with data is
     * the top priority -- and as long as that is possible we don't do
     * anything else */
    u->rtpoll_item = pa_rtpoll_item_new_asyncmsgq_read(u->rtpoll, PA_RTPOLL_EARLY-1, u->jack_msgq);

    if (!(u->client = jack_client_open(client_name, server_name ? JackServerName : JackNullOption, &status, server_name))) {
        pa_log("jack_client_open() failed.");
        goto fail;
    }

    ports = jack_get_ports(u->client, NULL, JACK_DEFAULT_AUDIO_TYPE, JackPortIsPhysical|JackPortIsInput);

    channels = 0;
    if (ports)
        for (p = ports; *p; p++)
            channels++;

    if (!channels)
        channels = m->core->default_sample_spec.channels;

    if (pa_modargs_get_value_u32(ma, "channels", &channels) < 0 ||
        !pa_channels_valid(channels)) {
        pa_log("Failed to parse channels= argument.");
        goto fail;
    }

    if (channels == m->core->default_channel_map.channels)
        map = m->core->default_channel_map;
    else
        pa_channel_map_init_extend(&map, channels, PA_CHANNEL_MAP_ALSA);

    if (pa_modargs_get_channel_map(ma, NULL, &map) < 0 || map.channels != channels) {
        pa_log("Failed to parse channel_map= argument.");
        goto fail;
    }

    pa_log_info("Successfully connected as '%s'", jack_get_client_name(u->client));

    u->channels = ss.channels = (uint8_t) channels;
    ss.rate = jack_get_sample_rate(u->client);
    ss.format = PA_SAMPLE_FLOAT32NE;

    pa_assert(pa_sample_spec_valid(&ss));

    for (i = 0; i < ss.channels; i++) {
        if (!(u->port[i] = jack_port_register(u->client, pa_channel_position_to_string(map.map[i]), JACK_DEFAULT_AUDIO_TYPE, JackPortIsOutput|JackPortIsTerminal, 0))) {
            pa_log("jack_port_register() failed.");
            goto fail;
        }
    }

    pa_sink_new_data_init(&data);
    data.driver = __FILE__;
    data.module = m;
    pa_sink_new_data_set_name(&data, pa_modargs_get_value(ma, "sink_name", DEFAULT_SINK_NAME));
    pa_sink_new_data_set_sample_spec(&data, &ss);
    pa_sink_new_data_set_channel_map(&data, &map);
    pa_proplist_sets(data.proplist, PA_PROP_DEVICE_API, "jack");
    if (server_name)
        pa_proplist_sets(data.proplist, PA_PROP_DEVICE_STRING, server_name);
    pa_proplist_setf(data.proplist, PA_PROP_DEVICE_DESCRIPTION, "Jack sink (%s)", jack_get_client_name(u->client));
    pa_proplist_sets(data.proplist, "jack.client_name", jack_get_client_name(u->client));

    if (pa_modargs_get_proplist(ma, "sink_properties", data.proplist, PA_UPDATE_REPLACE) < 0) {
        pa_log("Invalid properties");
        pa_sink_new_data_done(&data);
        goto fail;
    }

    u->sink = pa_sink_new(m->core, &data, PA_SINK_LATENCY);
    pa_sink_new_data_done(&data);

    if (!u->sink) {
        pa_log("Failed to create sink.");
        goto fail;
    }

    u->sink->parent.process_msg = sink_process_msg;
    u->sink->userdata = u;

    pa_sink_set_asyncmsgq(u->sink, u->thread_mq.inq);
    pa_sink_set_rtpoll(u->sink, u->rtpoll);
    pa_sink_set_max_request(u->sink, jack_get_buffer_size(u->client) * pa_frame_size(&u->sink->sample_spec));

    jack_set_process_callback(u->client, jack_process, u);
    jack_on_shutdown(u->client, jack_shutdown, u);
    jack_set_thread_init_callback(u->client, jack_init, u);
    jack_set_buffer_size_callback(u->client, jack_buffer_size, u);

    if (!(u->thread = pa_thread_new("jack-sink", thread_func, u))) {
        pa_log("Failed to create thread.");
        goto fail;
    }

    if (jack_activate(u->client)) {
        pa_log("jack_activate() failed");
        goto fail;
    }

    if (do_connect) {
        for (i = 0, p = ports; i < ss.channels; i++, p++) {

            if (!p || !*p) {
                pa_log("Not enough physical output ports, leaving unconnected.");
                break;
            }

            pa_log_info("Connecting %s to %s", jack_port_name(u->port[i]), *p);

            if (jack_connect(u->client, jack_port_name(u->port[i]), *p)) {
                pa_log("Failed to connect %s to %s, leaving unconnected.", jack_port_name(u->port[i]), *p);
                break;
            }
        }
    }

    jack_port_get_latency_range(u->port[0], JackPlaybackLatency, &r);
    n = r.max * pa_frame_size(&u->sink->sample_spec);
    pa_sink_set_fixed_latency(u->sink, pa_bytes_to_usec(n, &u->sink->sample_spec));
    pa_sink_put(u->sink);

    if (ports)
        jack_free(ports);
    pa_modargs_free(ma);

    return 0;

fail:
    if (ma)
        pa_modargs_free(ma);

    if (ports)
        jack_free(ports);

    pa__done(m);

    return -1;
}
示例#21
0
void *
start_jack_client(void *ptr)
{
    const char *client_name = "filter";
    const char *server_name = NULL;
    jack_options_t options = (JackNoStartServer|JackUseExactName|JackSessionID);
    jack_status_t status;

    /* open a client connection to the JACK server */
    client = jack_client_open (client_name, options, &status, server_name);
    if (client == NULL) {
	fprintf (stderr, "jack_client_open() failed, "
		"status = 0x%2.0x\n", status);
	if (status & JackServerFailed) {
	    fprintf (stderr, "Unable to connect to JACK server\n");
	}
	exit (1);
    }
    if (status & JackServerStarted) {
	fprintf (stderr, "JACK server started\n");
    }
    if (status & JackNameNotUnique) {
	client_name = jack_get_client_name(client);
	fprintf (stderr, "unique name `%s' assigned\n", client_name);
    }

    /* tell the JACK server to call `process()' whenever
       there is work to be done.  */
    jack_set_process_callback (client, process, 0);


    /* tell the JACK server to call `jack_shutdown()' if
       it ever shuts down, either entirely, or if it
       just decides to stop calling us.  */
    jack_on_shutdown (client, jack_shutdown, 0);


    /* display the current sample rate.  */
    printf ("engine sample rate: %" PRIu32 "\n",
	    jack_get_sample_rate (client));


    /* create two ports */

    input_port = jack_port_register (client, "input",
	    JACK_DEFAULT_AUDIO_TYPE, JackPortIsInput, 0);

    output_port = jack_port_register (client, "output",
	    JACK_DEFAULT_AUDIO_TYPE, JackPortIsOutput, 0);

    if ((input_port == NULL) || (output_port == NULL)) {
	fprintf(stderr, "no more JACK ports available\n");
	exit (1);
    }

    /* create and initialize the control list */
    ctrls = malloc(sizeof(control_list));

    /* set with default values */
    ctrls->ftype = LPF;
    ctrls->dBgain = 0;	// dB value
    ctrls->fc = 100;	//Hz value
    ctrls->fs = (smp_type)jack_get_sample_rate(client);
    ctrls->bw = 0.25;	//bandwidth (ocataves)

    /* Compute default biquad lpf */
    filter = compute_biquad(ctrls->ftype, 
			    ctrls->dBgain, 
			    ctrls->fc, 
			    ctrls->fs, 
			    ctrls->bw); 

    printf("initial coefficients:\n");
    printf("b0=%f, b1=%f, b2=%f, a1=%f, a2=%f \n", filter->b0, filter->b1, filter->b2, filter->a1, filter->a2);


    /* Tell the JACK server that we are ready to roll.  Our
     * process() callback will start running now. */

    if (jack_activate (client)) {
	fprintf (stderr, "cannot activate client");
	exit (1);
    }


    /* Connect the ports.  You can't do this before the client is
     * activated, because we can't make connections to clients
     * that aren't running.  Note the confusing (but necessary)
     * orientation of the driver backend ports: playback ports are
     * "input" to the backend, and capture ports are "output" from
     * it.  */

    /**********************************************************
     Automatic Port Connections! -> Not usually recommended!
    ***********************************************************
    const char **ports;

    ports = jack_get_ports (client, NULL, NULL, JackPortIsPhysical|JackPortIsOutput);
    if (ports == NULL) {
	fprintf(stderr, "no physical capture ports\n");
	exit (1);
    }

    if (jack_connect (client, ports[0], jack_port_name (input_port))) {
	fprintf (stderr, "cannot connect input ports\n");
    }

    free (ports);

    ports = jack_get_ports (client, NULL, NULL, 
			    JackPortIsPhysical|JackPortIsInput);

    if (ports == NULL) {
	fprintf(stderr, "no physical playback ports\n");
	exit (1);
    }

    if (jack_connect (client, jack_port_name (output_port), ports[0])) {
	fprintf (stderr, "cannot connect output ports\n");
    }

    free (ports);
*/
    /* keep running until stopped by the user */

    sleep (-1);

    /* this is never reached, but if the program
       had some other way to exit besides being killed,
       they would be important to call.  */

    jack_client_close (client);
    exit (0);
}
int
main (int argc, char *argv[])
{
	const char **ports;
	const char *client_name = "simple";
	const char *server_name = NULL;
	jack_options_t options = JackNullOption;
	jack_status_t status;
	
	/* open a client connection to the JACK server */

	client = jack_client_open (client_name, options, &status, server_name);
	if (client == NULL) {
		fprintf (stderr, "jack_client_open() failed, "
			 "status = 0x%2.0x\n", status);
		if (status & JackServerFailed) {
			fprintf (stderr, "Unable to connect to JACK server\n");
		}
		exit (1);
	}
	if (status & JackServerStarted) {
		fprintf (stderr, "JACK server started\n");
	}
	if (status & JackNameNotUnique) {
		client_name = jack_get_client_name(client);
		fprintf (stderr, "unique name `%s' assigned\n", client_name);
	}

	/* tell the JACK server to call `process()' whenever
	   there is work to be done.
	*/

	jack_set_process_callback (client, process, 0);

	/* tell the JACK server to call `jack_shutdown()' if
	   it ever shuts down, either entirely, or if it
	   just decides to stop calling us.
	*/

	jack_on_shutdown (client, jack_shutdown, 0);

	/* display the current sample rate. 
	 */

	printf ("engine sample rate: %" PRIu32 "\n",
		jack_get_sample_rate (client));

	/* create two ports */

	input_port = jack_port_register (client, "input",
					 JACK_DEFAULT_AUDIO_TYPE,
					 JackPortIsInput, 0);
	output_port = jack_port_register (client, "output",
					  JACK_DEFAULT_AUDIO_TYPE,
					  JackPortIsOutput, 0);

	if ((input_port == NULL) || (output_port == NULL)) {
		fprintf(stderr, "no more JACK ports available\n");
		exit (1);
	}

	/* Tell the JACK server that we are ready to roll.  Our
	 * process() callback will start running now. */

	if (jack_activate (client)) {
		fprintf (stderr, "cannot activate client");
		exit (1);
	}

	/* Connect the ports.  You can't do this before the client is
	 * activated, because we can't make connections to clients
	 * that aren't running.  Note the confusing (but necessary)
	 * orientation of the driver backend ports: playback ports are
	 * "input" to the backend, and capture ports are "output" from
	 * it.
	 */

	ports = jack_get_ports (client, NULL, NULL,
				JackPortIsPhysical|JackPortIsOutput);
	if (ports == NULL) {
		fprintf(stderr, "no physical capture ports\n");
		exit (1);
	}

	if (jack_connect (client, ports[0], jack_port_name (input_port))) {
		fprintf (stderr, "cannot connect input ports\n");
	}

	free (ports);
	
	ports = jack_get_ports (client, NULL, NULL,
				JackPortIsPhysical|JackPortIsInput);
	if (ports == NULL) {
		fprintf(stderr, "no physical playback ports\n");
		exit (1);
	}

	if (jack_connect (client, jack_port_name (output_port), ports[0])) {
		fprintf (stderr, "cannot connect output ports\n");
	}

	free (ports);

	/* keep running until stopped by the user */

	sleep (-1);

	/* this is never reached but if the program
	   had some other way to exit besides being killed,
	   they would be important to call.
	*/

	jack_client_close (client);
	exit (0);
}
示例#23
0
文件: tmrd.c 项目: ianxm/tmrd
int main (int argc, char *argv[])
{
  fprintf(stderr, "tmrd v%s\n", VERSION);
  parseArgs(argc, argv);

  attach_sig_handler();

  jack_client_t *client;
  const char **ports;
 
  /* init jack */
  if ((client = jack_client_new ("smp")) == 0) {
    fprintf (stderr, "jack server not running?\n");
    return 1;
  }
  jack_set_process_callback (client, process, 0);
  jack_on_shutdown (client, jack_shutdown, 0);
  sample_rate = jack_get_sample_rate (client);
  printf ("engine sample rate: %u\n", sample_rate);
 
  /* create a delay buffer for each channel */
  buffer = (jack_default_audio_sample_t**)malloc(2*sizeof(jack_default_audio_sample_t**));

  /* div by 10 since time is in tenths of secs */
  buf_frames = max_delay_time*sample_rate/10;
  buffer[0] = (jack_default_audio_sample_t*)malloc(buf_frames*sizeof(jack_default_audio_sample_t));
  buffer[1] = (jack_default_audio_sample_t*)malloc(buf_frames*sizeof(jack_default_audio_sample_t));
  memset(buffer[0], 0, buf_frames*sizeof(jack_default_audio_sample_t));
  memset(buffer[1], 0, buf_frames*sizeof(jack_default_audio_sample_t));
  printf("buffer frames: %d\n", buf_frames);
  
  /* create two input ports and two output ports */
  input_port = (jack_port_t**)malloc(2*sizeof(jack_port_t**));
  output_port = (jack_port_t**)malloc(2*sizeof(jack_port_t**));
  input_port[0] = jack_port_register (client, "input0", JACK_DEFAULT_AUDIO_TYPE, JackPortIsInput, 0);
  input_port[1] = jack_port_register (client, "input1", JACK_DEFAULT_AUDIO_TYPE, JackPortIsInput, 0);
  output_port[0] = jack_port_register (client, "output0", JACK_DEFAULT_AUDIO_TYPE, JackPortIsOutput, 0);
  output_port[1] = jack_port_register (client, "output1", JACK_DEFAULT_AUDIO_TYPE, JackPortIsOutput, 0);
 
  /* start jack */
  if (jack_activate (client)) {
    fprintf (stderr, "cannot activate client");
    return 1;
  }
  if ((ports = jack_get_ports (client, NULL, NULL, JackPortIsPhysical|JackPortIsOutput)) == NULL) {
    fprintf(stderr, "Cannot find any physical capture ports\n");
    exit(1);
  }
 
  if (jack_connect (client, ports[0], jack_port_name (input_port[0])))
    fprintf (stderr, "cannot connect input ports\n");

  if (jack_connect (client, ports[1], jack_port_name (input_port[1])))
    fprintf (stderr, "cannot connect input ports\n");
 
  free (ports);
         
  if ((ports = jack_get_ports (client, NULL, NULL, JackPortIsPhysical|JackPortIsInput)) == NULL) {
    fprintf(stderr, "Cannot find any physical playback ports\n");
    exit(1);
  }

  if (jack_connect (client, jack_port_name (output_port[0]), ports[0]))
    fprintf (stderr, "cannot connect output ports\n");

  if (jack_connect (client, jack_port_name (output_port[1]), ports[1]))
    fprintf (stderr, "cannot connect output ports\n");
 
  free (ports);
 
  run_ui(); /* start the ui, listen for keyboard input */

  jack_client_close (client);
  exit (0);
}
示例#24
0
int main (int argc, char *argv[]) {
    char jack_name[30] = "alsa_out";
    char alsa_device[30] = "hw:0";

    extern char *optarg;
    extern int optind, optopt;
    int errflg=0;
    int c;

    while ((c = getopt(argc, argv, "ivj:r:c:p:n:d:q:m:t:f:F:C:Q:s:")) != -1) {
	switch(c) {
	    case 'j':
		strcpy(jack_name,optarg);
		break;
	    case 'r':
		sample_rate = atoi(optarg);
		break;
	    case 'c':
		num_channels = atoi(optarg);
		break;
	    case 'p':
		period_size = atoi(optarg);
		break;
	    case 'n':
		num_periods = atoi(optarg);
		break;
	    case 'd':
		strcpy(alsa_device,optarg);
		break;
	    case 't':
		target_delay = atoi(optarg);
		break;
	    case 'q':
		samplerate_quality = atoi(optarg);
		break;
	    case 'm':
		max_diff = atoi(optarg);
		break;
	    case 'f':
		catch_factor = atoi(optarg);
		break;
	    case 'F':
		catch_factor2 = atoi(optarg);
		break;
	    case 'C':
		pclamp = (double) atoi(optarg);
		break;
	    case 'Q':
		controlquant = (double) atoi(optarg);
		break;
	    case 'v':
		verbose = 1;
		break;
	    case 'i':
		instrument = 1;
		break;
	    case 's':
		smooth_size = atoi(optarg);
		break;
	    case ':':
		fprintf(stderr,
			"Option -%c requires an operand\n", optopt);
		errflg++;
		break;
	    case '?':
		fprintf(stderr,
			"Unrecognized option: -%c\n", optopt);
		errflg++;
	}
    }
    if (errflg) {
	printUsage();
	exit(2);
    }

    if( (samplerate_quality < 0) || (samplerate_quality > 4) ) {
	fprintf (stderr, "invalid samplerate quality\n");
	return 1;
    }
    if ((client = jack_client_open (jack_name, 0, NULL)) == 0) {
	fprintf (stderr, "jack server not running?\n");
	return 1;
    }

    /* tell the JACK server to call `process()' whenever
       there is work to be done.
       */

    jack_set_process_callback (client, process, 0);

    /* tell the JACK server to call `freewheel()' whenever
       freewheel mode changes.
       */

    jack_set_freewheel_callback (client, freewheel, 0);

    /* tell the JACK server to call `jack_shutdown()' if
       it ever shuts down, either entirely, or if it
       just decides to stop calling us.
       */

    jack_on_shutdown (client, jack_shutdown, 0);

    if (jack_set_latency_callback)
	    jack_set_latency_callback (client, latency_cb, 0);

    // get jack sample_rate
    
    jack_sample_rate = jack_get_sample_rate( client );

    if( !sample_rate )
	sample_rate = jack_sample_rate;

    static_resample_factor =  (double) sample_rate / (double) jack_sample_rate;
    resample_lower_limit = static_resample_factor * 0.25;
    resample_upper_limit = static_resample_factor * 4.0;
    resample_mean = static_resample_factor;

    offset_array = malloc( sizeof(double) * smooth_size );
    if( offset_array == NULL ) {
	    fprintf( stderr, "no memory for offset_array !!!\n" );
	    exit(20);
    }
    window_array = malloc( sizeof(double) * smooth_size );
    if( window_array == NULL ) {
	    fprintf( stderr, "no memory for window_array !!!\n" );
	    exit(20);
    }
    int i;
    for( i=0; i<smooth_size; i++ ) {
	    offset_array[i] = 0.0;
	    window_array[i] = hann( (double) i / ((double) smooth_size - 1.0) );
    }

    jack_buffer_size = jack_get_buffer_size( client );
    // Setup target delay and max_diff for the normal user, who does not play with them...
    if( !target_delay ) 
	target_delay = (num_periods*period_size / 2) - jack_buffer_size/2;

    if( !max_diff )
	max_diff = target_delay;	

    if( max_diff > target_delay ) {
	    fprintf( stderr, "target_delay (%d) cant be smaller than max_diff(%d)\n", target_delay, max_diff );
	    exit(20);
    }
    if( (target_delay+max_diff) > (num_periods*period_size) ) {
	    fprintf( stderr, "target_delay+max_diff (%d) cant be bigger than buffersize(%d)\n", target_delay+max_diff, num_periods*period_size );
	    exit(20);
    }
    // now open the alsa fd...
    alsa_handle = open_audiofd( alsa_device, 0, sample_rate, num_channels, period_size, num_periods);
    if( alsa_handle == 0 )
	exit(20);

    printf( "selected sample format: %s\n", formats[format].name );

    // alloc input ports, which are blasted out to alsa...
    alloc_ports( 0, num_channels );

    outbuf = malloc( num_periods * period_size * formats[format].sample_size * num_channels );
    resampbuf = malloc( num_periods * period_size * sizeof( float ) );
    tmpbuf = malloc( 512 * formats[format].sample_size * num_channels );

    if ((outbuf == NULL) || (resampbuf == NULL) || (tmpbuf == NULL))
    {
	    fprintf( stderr, "no memory for buffers.\n" );
	    exit(20);
    }


    /* tell the JACK server that we are ready to roll */

    if (jack_activate (client)) {
	fprintf (stderr, "cannot activate client");
	return 1;
    }

    signal( SIGTERM, sigterm_handler );
    signal( SIGINT, sigterm_handler );

    if( verbose ) {
	    while(!quit) {
		    usleep(500000);
		    if( output_new_delay ) {
			    printf( "delay = %d\n", output_new_delay );
			    output_new_delay = 0;
		    }
		    printf( "res: %f, \tdiff = %f, \toffset = %f \n", output_resampling_factor, output_diff, output_offset );
	    }
    } else if( instrument ) {
	    printf( "# n\tresamp\tdiff\toffseti\tintegral\n");
	    int n=0;
	    while(!quit) {
		    usleep(1000);
		    printf( "%d\t%f\t%f\t%f\t%f\n", n++, output_resampling_factor, output_diff, output_offset, output_integral );
	    }
    } else {
	    while(!quit)
	    {
		    usleep(500000);
		    if( output_new_delay ) {
			    printf( "delay = %d\n", output_new_delay );
			    output_new_delay = 0;
		    }
	    }
    }

    jack_deactivate( client );
    jack_client_close (client);
    exit (0);
}
示例#25
0
bool SC_JackDriver::DriverSetup(int* outNumSamples, double* outSampleRate)
{
	char* clientName = 0;
	char* serverName = 0;

	if (mWorld->hw->mInDeviceName && (strlen(mWorld->hw->mInDeviceName) > 0)) {
		// parse string <serverName>:<clientName>
		SC_StringParser sp(mWorld->hw->mInDeviceName, ':');
		if (!sp.AtEnd()) serverName = strdup(sp.NextToken());
		if (!sp.AtEnd()) clientName = strdup(sp.NextToken());
		if (clientName == 0) {
			// no semicolon found
			clientName = serverName;
			serverName = 0;
		} else if (strlen(clientName) == 0) {
			free(clientName);
			clientName = 0;
		}
	}

#ifdef SC_USE_JACK_CLIENT_NEW
	// old style client startup for Jack <0.100 -- AG
	if (clientName) {
		mClient = jack_client_new(clientName);
	} else {
		clientName = strdup("SuperCollider");
		mClient = jack_client_new(clientName);
		if (mClient == 0) {
			char uniqueName[64];
			sprintf(uniqueName, "SuperCollider-%d", getpid());
			clientName = strdup(uniqueName);
			mClient = jack_client_new(uniqueName);
		}
	}
	if (mClient) scprintf("%s: client name is '%s'\n", kJackDriverIdent, clientName);
	if (serverName) free(serverName); if (clientName) free(clientName);
	if (mClient == 0) return false;
#else
	mClient = jack_client_open(
		clientName ? clientName : kJackDefaultClientName,
		serverName ? JackServerName : JackNullOption,
		NULL, serverName);
	if (serverName) free(serverName); if (clientName) free(clientName);
	if (mClient == 0) return false;

	scprintf("%s: client name is '%s'\n", kJackDriverIdent, jack_get_client_name(mClient));
#endif

	// create jack I/O ports
	mInputList = new SC_JackPortList(mClient, mWorld->mNumInputs, JackPortIsInput);
	mOutputList = new SC_JackPortList(mClient, mWorld->mNumOutputs, JackPortIsOutput);

	// register callbacks
	jack_set_process_callback(mClient, sc_jack_process_cb, this);
	jack_set_buffer_size_callback(mClient, sc_jack_bufsize_cb, this);
	jack_set_sample_rate_callback(mClient, sc_jack_srate_cb, this);
	jack_set_graph_order_callback(mClient, sc_jack_graph_order_cb, this);
	jack_set_xrun_callback(mClient, sc_jack_xrun_cb, this);
	jack_on_shutdown(mClient, sc_jack_shutdown_cb, mWorld);

	*outNumSamples = (int)jack_get_buffer_size(mClient);
	*outSampleRate = (double)jack_get_sample_rate(mClient);

	return true;
}
示例#26
0
static int init(int rate, const struct mp_chmap *channels, int format, int flags)
{
  const char **matching_ports = NULL;
  char *port_name = NULL;
  char *client_name = NULL;
  int autostart = 0;
  int connect = 1;
  const opt_t subopts[] = {
    {"port", OPT_ARG_MSTRZ, &port_name, NULL},
    {"name", OPT_ARG_MSTRZ, &client_name, NULL},
    {"estimate", OPT_ARG_BOOL, &estimate, NULL},
    {"autostart", OPT_ARG_BOOL, &autostart, NULL},
    {"connect", OPT_ARG_BOOL, &connect, NULL},
    {NULL}
  };
  jack_options_t open_options = JackUseExactName;
  int port_flags = JackPortIsInput;
  int i;
  estimate = 1;
  if (subopt_parse(ao_subdevice, subopts) != 0) {
    print_help();
    return 0;
  }

  struct mp_chmap_sel sel = {0};
  mp_chmap_sel_add_waveext(&sel);
  if (!ao_chmap_sel_adjust(&ao_data, &sel, &ao_data.channels))
    goto err_out;

  if (!client_name) {
    client_name = malloc(40);
    sprintf(client_name, "mpv [%d]", getpid());
  }
  if (!autostart)
    open_options |= JackNoStartServer;
  client = jack_client_open(client_name, open_options, NULL);
  if (!client) {
    mp_msg(MSGT_AO, MSGL_FATAL, "[JACK] cannot open server\n");
    goto err_out;
  }
  buffer = av_fifo_alloc(BUFFSIZE);
  jack_set_process_callback(client, outputaudio, 0);

  // list matching ports if connections should be made
  if (connect) {
    if (!port_name)
      port_flags |= JackPortIsPhysical;
    matching_ports = jack_get_ports(client, port_name, NULL, port_flags);
    if (!matching_ports || !matching_ports[0]) {
      mp_msg(MSGT_AO, MSGL_FATAL, "[JACK] no physical ports available\n");
      goto err_out;
    }
    i = 1;
    num_ports = ao_data.channels.num;
    while (matching_ports[i]) i++;
    if (num_ports > i) num_ports = i;
  }

  // create out output ports
  for (i = 0; i < num_ports; i++) {
    char pname[30];
    snprintf(pname, 30, "out_%d", i);
    ports[i] = jack_port_register(client, pname, JACK_DEFAULT_AUDIO_TYPE, JackPortIsOutput, 0);
    if (!ports[i]) {
      mp_msg(MSGT_AO, MSGL_FATAL, "[JACK] not enough ports available\n");
      goto err_out;
    }
  }
  if (jack_activate(client)) {
    mp_msg(MSGT_AO, MSGL_FATAL, "[JACK] activate failed\n");
    goto err_out;
  }
  for (i = 0; i < num_ports; i++) {
    if (jack_connect(client, jack_port_name(ports[i]), matching_ports[i])) {
      mp_msg(MSGT_AO, MSGL_FATAL, "[JACK] connecting failed\n");
      goto err_out;
    }
  }
  rate = jack_get_sample_rate(client);
  jack_latency_range_t jack_latency_range;
  jack_port_get_latency_range(ports[0], JackPlaybackLatency,
                              &jack_latency_range);
  jack_latency = (float)(jack_latency_range.max + jack_get_buffer_size(client))
                 / (float)rate;
  callback_interval = 0;

  if (!ao_chmap_sel_get_def(&ao_data, &sel, &ao_data.channels, num_ports))
    goto err_out;

  ao_data.samplerate = rate;
  ao_data.format = AF_FORMAT_FLOAT_NE;
  ao_data.bps = ao_data.channels.num * rate * sizeof(float);
  ao_data.buffersize = CHUNK_SIZE * NUM_CHUNKS;
  ao_data.outburst = CHUNK_SIZE;
  free(matching_ports);
  free(port_name);
  free(client_name);
  return 1;

err_out:
  free(matching_ports);
  free(port_name);
  free(client_name);
  if (client)
    jack_client_close(client);
  av_fifo_free(buffer);
  buffer = NULL;
  return 0;
}
    uint32_t JackAudioSystem::sample_rate()
    {
	if( !_client ) return 0;
	return jack_get_sample_rate(_client);
    }
示例#28
0
void synthv1_jack::open ( const char *client_id )
{
	// init param ports
	for (uint32_t i = 0; i < synthv1::NUM_PARAMS; ++i) {
		const synthv1::ParamIndex index = synthv1::ParamIndex(i);
		m_params[i] = synthv1_param::paramDefaultValue(index);
		synthv1::setParamPort(index, &m_params[i]);
	}

	// open client
	m_client = ::jack_client_open(client_id, JackNullOption, NULL);
	if (m_client == NULL)
		return;

	// set sample rate
	synthv1::setSampleRate(float(jack_get_sample_rate(m_client)));
//	synthv1::reset();

	// register audio ports & buffers
	uint16_t nchannels = synthv1::channels();

	m_audio_ins  = new jack_port_t * [nchannels];
	m_audio_outs = new jack_port_t * [nchannels];

	m_ins  = new float * [nchannels];
	m_outs = new float * [nchannels];

	char port_name[32];
	for (uint16_t k = 0; k < nchannels; ++k) {
		::snprintf(port_name, sizeof(port_name), "in_%d", k + 1);
		m_audio_ins[k] = ::jack_port_register(m_client,
			port_name, JACK_DEFAULT_AUDIO_TYPE, JackPortIsInput, 0);
		m_ins[k] = NULL;
		::snprintf(port_name, sizeof(port_name), "out_%d", k + 1);
		m_audio_outs[k] = ::jack_port_register(m_client,
			port_name, JACK_DEFAULT_AUDIO_TYPE, JackPortIsOutput, 0);
		m_outs[k] = NULL;
	}

	// register midi port
#ifdef CONFIG_JACK_MIDI
	m_midi_in = ::jack_port_register(m_client,
		"in", JACK_DEFAULT_MIDI_TYPE, JackPortIsInput, 0);
#endif
#ifdef CONFIG_ALSA_MIDI
	m_alsa_seq     = NULL;
//	m_alsa_client  = -1;
	m_alsa_port    = -1;
	m_alsa_decoder = NULL;
	m_alsa_buffer  = NULL;
	m_alsa_thread  = NULL;
	// open alsa sequencer client...
	if (snd_seq_open(&m_alsa_seq, "hw", SND_SEQ_OPEN_INPUT, 0) >= 0) {
		snd_seq_set_client_name(m_alsa_seq, client_id);
	//	m_alsa_client = snd_seq_client_id(m_alsa_seq);
		m_alsa_port = snd_seq_create_simple_port(m_alsa_seq, "in",
			SND_SEQ_PORT_CAP_WRITE | SND_SEQ_PORT_CAP_SUBS_WRITE,
			SND_SEQ_PORT_TYPE_MIDI_GENERIC | SND_SEQ_PORT_TYPE_APPLICATION);
		snd_midi_event_new(1024, &m_alsa_decoder);
		m_alsa_buffer = ::jack_ringbuffer_create(
			1024 * (sizeof(jack_midi_event_t) + 4));
		m_alsa_thread = new synthv1_alsa_thread(this);
		m_alsa_thread->start(QThread::TimeCriticalPriority);
	}
#endif	// CONFIG_ALSA_MIDI

	// setup any local buffers
	synthv1::setBufferSize(::jack_get_buffer_size(m_client));

	// set process callbacks...
	::jack_set_process_callback(m_client,
		synthv1_jack_process, this);

#ifdef CONFIG_JACK_SESSION
	// JACK session event callback...
	if (::jack_set_session_callback) {
		::jack_set_session_callback(m_client,
			synthv1_jack_session_event, this);
	}
#endif
}
示例#29
0
/*static*/ int
jack_init (cubeb ** context, char const * context_name)
{
  int r;

  if(context == NULL) {
    return CUBEB_ERROR;
  }

  *context = NULL;

  cubeb *ctx = (cubeb*)calloc(1, sizeof(*ctx));
  if(ctx == NULL) {
    return CUBEB_ERROR;
  }

  r = pthread_mutex_init(&ctx->mutex, NULL);
  if(r != 0) {
    cbjack_destroy(ctx);
    return CUBEB_ERROR;
  }

  ctx->ops = &cbjack_ops;

  const char* jack_client_name = "cubeb";
  if(context_name)
    jack_client_name = context_name;

  ctx->jack_client = jack_client_open (jack_client_name,
                                       JackNoStartServer,
                                       NULL);

  if (ctx->jack_client == NULL) {
    cbjack_destroy(ctx);
    return CUBEB_ERROR;
  }

  ctx->jack_sample_rate = jack_get_sample_rate(ctx->jack_client);

  jack_set_process_callback (ctx->jack_client, cbjack_process, ctx);

  if (jack_activate (ctx->jack_client)) {
    cbjack_destroy(ctx);
    return CUBEB_ERROR;
  }

  for(int s = 0; s < MAX_STREAMS; s++) {
    for (int c = 0; c < MAX_CHANNELS; c++) {
      ctx->streams[s].ringbuffer[c] = jack_ringbuffer_create(FIFO_SIZE);
      if(!ctx->streams[s].ringbuffer[c]) {
        cbjack_destroy(ctx);
        return CUBEB_ERROR;
      }
    }
  }

  ctx->active = true;
  int ret = pthread_create (&ctx->stream_refill_thread, NULL, stream_refill_thread, (void *)ctx);
  if(ret != 0) {
    ctx->stream_refill_thread = 0;
    cbjack_destroy(ctx);
    return CUBEB_ERROR;
  }

  *context = ctx;

  return CUBEB_OK;
}
示例#30
0
文件: main.c 项目: jerash/jpmidi
int main(int argc, char **argv)
{
    char opts[NELEM(long_opts) * 3 + 1];
    char *cp;
    int  c;
    struct option *op;

    /* Build up the short option string */
    cp = opts;
    for (op = long_opts; op < &long_opts[NELEM(long_opts)]; op++) {
        *cp++ = op->val;
        if (op->has_arg)
            *cp++ = ':';
    }


    /* Deal with the options */
    for (;;) {
        c = getopt_long(argc, argv, opts, long_opts, NULL);
        if (c == -1)
            break;

        switch(c) {
        case 'v':
            main_showversion();
            exit(0);
        case 'd':
            be_jack_client = 0;
            break;
	case 's':
	    be_server = 1;
	    break;
        default:
            main_showusage();
            exit(1);
        }
    }

    if (optind >= argc) {
        printf("No input files!\n");
        main_showusage();
        exit( 1);
    }

    if (optind < argc-1) {
        printf("Too many input files!\n");
        main_showusage();
        exit( 1);
    }

    if (!jpmidi_init()) {
        fprintf( stderr, "Failed to initialize jpmidi, errno = %d\n", errno);
        exit( errno);
    }

    dump_init();

    jack_nframes_t jack_sample_rate = 44100;
    
    if (be_jack_client)
    {
        if (jackclient_new( "jpmidi")) return 1;
        
        jack_sample_rate = jack_get_sample_rate(jackclient_get_client());
    }
    else printf("Not connecting to jack, assuming sample rate of %d\n", jack_sample_rate);


    root = jpmidi_loadfile(argv[optind], jack_sample_rate);
    printf("loaded %s\n", root->filename);

    if (be_jack_client && jackclient_activate()) return 1;
    
    /* launch either command line or server mode */
    if (be_server)
    {
	tcpserver(TCPPORT);
    }
    else
    {
	cmdline();
    }

    if (be_jack_client && jackclient_deactivate()) return 1;
    if (be_jack_client && jackclient_close()) return 1;
    
    return 0;
}