Exemplo n.º 1
0
int jack_card_read(JackCard *obj,char *buf,int size)
{
  size_t bytes, can_read, i;
  int error;
  float norm, value;

  g_return_val_if_fail((obj->read.buffer!=NULL)&&(obj->read.src_state!=NULL),-1);
  if (jack_init(obj) != 0) return -1;
  size /= 2;
  can_read = MIN(size, obj->read.frames);
  //  can_read = MIN(((long)((double)can_read / obj->read.data.src_ratio))*sizeof(sample_t), jack_ringbuffer_read_space(obj->read.buffer));
  can_read = ((long)((double)can_read / obj->read.data.src_ratio))*sizeof(sample_t);
  obj->read.can_process = FALSE;
  bytes = jack_ringbuffer_read (obj->read.buffer, (void *)obj->read.data.data_in, can_read);
  obj->read.can_process = TRUE;
  obj->read.data.input_frames = bytes / sizeof(sample_t);
  can_read = MIN(size, obj->read.frames);
  obj->read.data.output_frames = can_read;
  if ((error = src_process(obj->read.src_state, &(obj->read.data))) != 0)
    g_warning("error while samplerate conversion. error: %s", src_strerror(error));
  norm = obj->read.level*obj->level*(float)0x8000;
  for (i=0; i < obj->read.data.output_frames_gen; i++) {
    value = obj->read.data.data_out[i]*norm;
    if (value >= 32767.0) 
      ((short*)buf)[i] = 32767;
    else if (value <= -32768.0)
      ((short*)buf)[i] = -32768;
    else
      ((short*)buf)[i] = (short)value;
  }
  bytes = obj->read.data.output_frames_gen * 2;
  return bytes;
}
Exemplo n.º 2
0
int jack_card_open_w(JackCard *obj,int bits,int stereo,int rate)
{
  int channels = stereo + 1, bsize, err;
  obj->write.init = TRUE;
  if (jack_init(obj) != 0) return -1;

  obj->write.rate = rate;
  obj->sample_size = bits / 8;
  obj->frame_size = channels * obj->sample_size;
  bsize = BSIZE;
  obj->write.frames = bsize / 2;
  SND_CARD(obj)->bsize = bsize;
  SND_CARD(obj)->flags |= SND_CARD_FLAGS_OPENED;
  obj->write.channels = channels;
  if ((obj->write.src_state = src_new (SRC_SINC_FASTEST, channels, &err)) == NULL)
    g_warning("Error while initializing the samplerate converter: %s", src_strerror(err));
  obj->write.data.src_ratio = (double)obj->rate / (double)rate;
  obj->write.data.data_in = malloc(obj->write.frames*sizeof(float));
  obj->write.data.end_of_input = 0;
  obj->write.data.output_frames = (long)((double)obj->write.frames*obj->write.data.src_ratio);
  obj->write.data.data_out = malloc(obj->write.data.output_frames*sizeof(float));
  if (!obj->write.buffer)
    obj->write.buffer = jack_ringbuffer_create(WRITEBUFFERSIZE);
  obj->write.can_process = TRUE;
  obj->can_process = TRUE;
  obj->write.open = TRUE;
  obj->write.init = FALSE;
  return 0;
}
Exemplo n.º 3
0
int jack_card_write(JackCard *obj,char *buf,int size)
{
  size_t bytes, can_write, i;
  int error;
  float norm;

  g_return_val_if_fail((obj->write.buffer!=NULL)&&(obj->write.src_state!=NULL),-1);
  if (jack_init(obj) != 0) return -1;
  size /= 2;
  can_write = MIN(size, obj->write.frames);
  norm = obj->write.level*obj->level/(float)0x8000;
  for (i=0; i<can_write; i++) {
    obj->write.data.data_in[i] = (float)((short*)buf)[i]*norm;
  }
  obj->write.data.input_frames = can_write;
  if ((error = src_process(obj->write.src_state, &(obj->write.data))) != 0)
    g_warning("error while samplerate conversion. error: %s", src_strerror(error));
  obj->write.can_process = FALSE;
  bytes = jack_ringbuffer_write (obj->write.buffer, (void *) obj->write.data.data_out, sizeof(sample_t)*obj->write.data.output_frames_gen);
  obj->write.can_process = TRUE;
  return bytes;
}
Exemplo n.º 4
0
int
jack_watchdog(void) {
    int		watchdog_state = WATCHDOG_STATE_CLIENT_ACTIVE;

    while (!shutdown) {
#ifdef EXTRA_DEBUG
	if (debug) {
	    fprintf (stderr, "JACK Watchdog loop...\n");
	}
#endif

	if (gtkui_restarting) {
	    pthread_join (gtkui_thread_p, NULL);
	    start_gtkui_thread ();
	}

    /* poll lash for events */
    #ifndef WITHOUT_LASH
    lash_pollevent();
    #endif

	/* everybody sleeps */
	usleep (250000);

	switch (watchdog_state) {
	case WATCHDOG_STATE_CLIENT_ACTIVE:
	    /* make sure the thread didn't go away */
	    if (client == NULL) {
		if (debug && !shutdown) {
		    fprintf (stderr, "JACK Watchdog: JACK client went away!  Attempting to recover.\n");
		}
		watchdog_state = WATCHDOG_STATE_NO_CLIENT;
		usleep (250000);
	    }
	    else {
#ifdef JOIN_JACK_CLIENT_THREAD
		/* if there's a jack client thread, wait for it to die */
		if (debug) {
		    fprintf (stderr, "JACK Watchdog: Waiting for JACK client thread 0x%lx to exit.\n", jack_thread_p);
		}
		if (pthread_join (jack_thread_p, NULL) == 0) {
		    if (debug) {
			fprintf (stderr, "JACK Watchdog: pthread_join() successful!\n");
		    }
		    /* client is invalid at this point, so don't call jack_client_close() */
		    client = NULL;
		    jack_thread_p = 0;
		    jack_running = 0;
		    watchdog_state = WATCHDOG_STATE_NO_CLIENT;
		    usleep (250000);
		}
		else {
		    if (debug) {
			fprintf (stderr, "JACK Watchdog: pthread_join() on JACK client thread 0x%lx failed!\n", jack_thread_p);
		    }
		}
#else
		if (jack_thread_p == 0) {
		    if (debug) {
			fprintf (stderr, "JACK Watchdog: JACK thread went away!  Attempting to recover.\n");
		    }
		    client       = NULL;
		    jack_running = 0;
		    watchdog_state = WATCHDOG_STATE_NO_CLIENT;
		    usleep (250000);
		}
#endif
	    }
	    usleep (250000);
	    break;

	case WATCHDOG_STATE_NO_CLIENT:
	    /* open a new client */
	    if (jack_init () == 0) {
		if (debug) {
		    fprintf (stderr, "JACK Watchdog: Initialized JACK client.\n");
		}
		jack_thread_p = 0;
		jack_running = 0;
		watchdog_state = WATCHDOG_STATE_CLIENT_INIT;
	    }
	    else {
		if (debug) {
		    fprintf (stderr, "JACK Watchdog: Waiting for JACK server...\n");
		}
	    }
	    usleep (250000);
	    break;

	case WATCHDOG_STATE_CLIENT_INIT:
	    /* start client */
	    if (jack_start () == 0) {
		if (debug) {
		    fprintf (stderr, "JACK Watchdog: Started JACK with client thread 0x%lx\n", jack_thread_p);
		}
		jack_running = 1;
		watchdog_state = WATCHDOG_STATE_CLIENT_ACTIVE;
	    }
	    else {
		if (debug) {
		    fprintf (stderr, "JACK Watchdog: Unable to start JACK client.\n");
		}
		jack_thread_p = 0;
		if (client != NULL) {
		    /* no thread to wait for unless jack client actually starts */
		    jack_client_close (client);
		    client = NULL;
		}
		watchdog_state = WATCHDOG_STATE_NO_CLIENT;
	    }
	    usleep (250000);
	    break;
	}
    }

    usleep (250000);

    if ((client != NULL) && (jack_thread_p != 0)) {
	jack_client_close (client);
	client = NULL;
	jack_thread_p = 0;
    }

    /* not reached */
    return 0;
}
Exemplo n.º 5
0
int main(int argc, char *argv[])
{
    int rc = -1, n, priority;
    const char *importer, *scanner, *geo;
    char *endptr;
    size_t nctl;
    double speed;
    struct timecode_def *timecode;
    bool protect, use_mlock, phono;

    struct controller ctl[2];
    struct rt rt;
    struct library library;

#if defined WITH_OSS || WITH_ALSA
    int rate;
#endif

#ifdef WITH_OSS
    int oss_buffers, oss_fragment;
#endif

#ifdef WITH_ALSA
    int alsa_buffer;
#endif

    fprintf(stderr, "%s\n\n" NOTICE "\n\n", banner);

    if (thread_global_init() == -1)
        return -1;

    if (rig_init() == -1)
        return -1;
    rt_init(&rt);
    library_init(&library);

    ndeck = 0;
    geo = "";
    nctl = 0;
    priority = DEFAULT_PRIORITY;
    importer = DEFAULT_IMPORTER;
    scanner = DEFAULT_SCANNER;
    timecode = NULL;
    speed = 1.0;
    protect = false;
    phono = false;
    use_mlock = false;

#if defined WITH_OSS || WITH_ALSA
    rate = DEFAULT_RATE;
#endif

#ifdef WITH_ALSA
    alsa_buffer = DEFAULT_ALSA_BUFFER;
#endif

#ifdef WITH_OSS
    oss_fragment = DEFAULT_OSS_FRAGMENT;
    oss_buffers = DEFAULT_OSS_BUFFERS;
#endif

    /* Skip over command name */

    argv++;
    argc--;

    while (argc > 0) {

        if (!strcmp(argv[0], "-h")) {
            usage(stdout);
            return 0;

#ifdef WITH_OSS
        } else if (!strcmp(argv[0], "-f")) {

            /* Set fragment size for subsequent devices */

            if (argc < 2) {
                fprintf(stderr, "-f requires an integer argument.\n");
                return -1;
            }

            oss_fragment = strtol(argv[1], &endptr, 10);
            if (*endptr != '\0') {
                fprintf(stderr, "-f requires an integer argument.\n");
                return -1;
            }

            /* Fragment sizes greater than the default aren't useful
             * as they are dependent on DEVICE_FRAME */

            if (oss_fragment < DEFAULT_OSS_FRAGMENT) {
                fprintf(stderr, "Fragment size must be %d or more; aborting.\n",
                        DEFAULT_OSS_FRAGMENT);
                return -1;
            }

            argv += 2;
            argc -= 2;

        } else if (!strcmp(argv[0], "-b")) {

            /* Set number of buffers for subsequent devices */

            if (argc < 2) {
                fprintf(stderr, "-b requires an integer argument.\n");
                return -1;
            }

            oss_buffers = strtol(argv[1], &endptr, 10);
            if (*endptr != '\0') {
                fprintf(stderr, "-b requires an integer argument.\n");
                return -1;
            }

            argv += 2;
            argc -= 2;
#endif

#if defined WITH_OSS || WITH_ALSA
        } else if (!strcmp(argv[0], "-r")) {

            /* Set sample rate for subsequence devices */

            if (argc < 2) {
                fprintf(stderr, "-r requires an integer argument.\n");
                return -1;
            }

            rate = strtol(argv[1], &endptr, 10);
            if (*endptr != '\0') {
                fprintf(stderr, "-r requires an integer argument.\n");
                return -1;
            }

            argv += 2;
            argc -= 2;
#endif

#ifdef WITH_ALSA
        } else if (!strcmp(argv[0], "-m")) {

            /* Set size of ALSA buffer for subsequence devices */

            if (argc < 2) {
                fprintf(stderr, "-m requires an integer argument.\n");
                return -1;
            }

            alsa_buffer = strtol(argv[1], &endptr, 10);
            if (*endptr != '\0') {
                fprintf(stderr, "-m requires an integer argument.\n");
                return -1;
            }

            argv += 2;
            argc -= 2;
#endif

        } else if (!strcmp(argv[0], "-d") || !strcmp(argv[0], "-a") ||
                   !strcmp(argv[0], "-j"))
        {
            int r;
            unsigned int sample_rate;
            struct deck *ld;
            struct device *device;
            struct timecoder *timecoder;

            /* Create a deck */

            if (argc < 2) {
                fprintf(stderr, "-%c requires a device name as an argument.\n",
                        argv[0][1]);
                return -1;
            }

            if (ndeck == ARRAY_SIZE(deck)) {
                fprintf(stderr, "Too many decks; aborting.\n");
                return -1;
            }

            fprintf(stderr, "Initialising deck %zd (%s)...\n", ndeck, argv[1]);

            ld = &deck[ndeck];
            device = &ld->device;
            timecoder = &ld->timecoder;
            ld->importer = importer;
            ld->protect = protect;

            /* Work out which device type we are using, and initialise
             * an appropriate device. */

            switch(argv[0][1]) {

#ifdef WITH_OSS
            case 'd':
                r = oss_init(device, argv[1], rate, oss_buffers, oss_fragment);
                break;
#endif
#ifdef WITH_ALSA
            case 'a':
                r = alsa_init(device, argv[1], rate, alsa_buffer);
                break;
#endif
#ifdef WITH_JACK
            case 'j':
                r = jack_init(device, argv[1]);
                break;
#endif
            default:
                fprintf(stderr, "Device type is not supported by this "
                        "distribution of xwax.\n");
                return -1;
            }

            if (r == -1)
                return -1;

            sample_rate = device_sample_rate(device);

            /* Default timecode decoder where none is specified */

            if (timecode == NULL) {
                timecode = timecoder_find_definition(DEFAULT_TIMECODE);
                assert(timecode != NULL);
            }

            timecoder_init(timecoder, timecode, speed, sample_rate, phono);

            /* Connect up the elements to make an operational deck */

            r = deck_init(ld, &rt, ndeck);
            if (r == -1)
                return -1;

            /* Connect this deck to available controllers */

            for (n = 0; n < nctl; n++)
                controller_add_deck(&ctl[n], &deck[ndeck]);

            /* Connect this deck to OSC server */

            osc_add_deck();

            ndeck++;

            argv += 2;
            argc -= 2;

        } else if (!strcmp(argv[0], "-t")) {

            /* Set the timecode definition to use */

            if (argc < 2) {
                fprintf(stderr, "-t requires a name as an argument.\n");
                return -1;
            }

            timecode = timecoder_find_definition(argv[1]);
            if (timecode == NULL) {
                fprintf(stderr, "Timecode '%s' is not known.\n", argv[1]);
                return -1;
            }

            argv += 2;
            argc -= 2;

        } else if (!strcmp(argv[0], "-33")) {

            speed = 1.0;

            argv++;
            argc--;

        } else if (!strcmp(argv[0], "-45")) {

            speed = 1.35;

            argv++;
            argc--;

        } else if (!strcmp(argv[0], "-c")) {

            protect = true;

            argv++;
            argc--;

        } else if (!strcmp(argv[0], "-u")) {

            protect = false;

            argv++;
            argc--;

        } else if (!strcmp(argv[0], "--line")) {

            phono = false;

            argv++;
            argc--;

        } else if (!strcmp(argv[0], "--phono")) {

            phono = true;

            argv++;
            argc--;

        } else if (!strcmp(argv[0], "-k")) {

            use_mlock = true;
            track_use_mlock();

            argv++;
            argc--;

        } else if (!strcmp(argv[0], "-q")) {

            if (argc < 2) {
                fprintf(stderr, "-q requires an integer argument.\n");
                return -1;
            }

            priority = strtol(argv[1], &endptr, 10);
            if (*endptr != '\0') {
                fprintf(stderr, "-q requires an integer argument.\n");
                return -1;
            }

            if (priority < 0) {
                fprintf(stderr, "Priority (%d) must be zero or positive.\n",
                        priority);
                return -1;
            }

            argv += 2;
            argc -= 2;

        } else if (!strcmp(argv[0], "-g")) {

            if (argc < 2) {
                fprintf(stderr, "-g requires an argument.\n");
                return -1;
            }

            geo = argv[1];

            argv += 2;
            argc -= 2;

        } else if (!strcmp(argv[0], "-i")) {

            /* Importer script for subsequent decks */

            if (argc < 2) {
                fprintf(stderr, "-i requires an executable path "
                        "as an argument.\n");
                return -1;
            }

            importer = argv[1];

            argv += 2;
            argc -= 2;

        } else if (!strcmp(argv[0], "-s")) {

            /* Scan script for subsequent libraries */

            if (argc < 2) {
                fprintf(stderr, "-s requires an executable path "
                        "as an argument.\n");
                return -1;
            }

            scanner = argv[1];

            argv += 2;
            argc -= 2;

        } else if (!strcmp(argv[0], "-l")) {

            /* Load in a music library */

            if (argc < 2) {
                fprintf(stderr, "-%c requires a pathname as an argument.\n",
                        argv[0][1]);
                return -1;
            }

            if (library_import(&library, scanner, argv[1]) == -1)
                return -1;

            argv += 2;
            argc -= 2;

#ifdef WITH_ALSA
        } else if (!strcmp(argv[0], "--dicer")) {

            struct controller *c;

            if (nctl == sizeof ctl) {
                fprintf(stderr, "Too many controllers; aborting.\n");
                return -1;
            }

            c = &ctl[nctl];

            if (argc < 2) {
                fprintf(stderr, "Dicer requires an ALSA device name.\n");
                return -1;
            }

            if (dicer_init(c, &rt, argv[1]) == -1)
                return -1;

            nctl++;

            argv += 2;
            argc -= 2;
#endif

        } else {
            fprintf(stderr, "'%s' argument is unknown; try -h.\n", argv[0]);
            return -1;
        }
    }

#ifdef WITH_ALSA
    alsa_clear_config_cache();
#endif

    if (ndeck == 0) {
        fprintf(stderr, "You need to give at least one audio device to use "
                "as a deck; try -h.\n");
        return -1;
    }

    rc = EXIT_FAILURE; /* until clean exit */

    if (osc_start((struct deck *)&deck, &library) == -1)
        return -1;
    osc_start_updater_thread();

    /* Order is important: launch realtime thread first, then mlock.
     * Don't mlock the interface, use sparingly for audio threads */

    if (rt_start(&rt, priority) == -1)
        return -1;

    if (use_mlock && mlockall(MCL_CURRENT) == -1) {
        perror("mlockall");
        goto out_rt;
    }

    if (interface_start(&library, geo) == -1)
        goto out_rt;

    if (rig_main() == -1)
        goto out_interface;

    rc = EXIT_SUCCESS;
    fprintf(stderr, "Exiting cleanly...\n");

out_interface:
    interface_stop();
out_rt:
    rt_stop(&rt);

    for (n = 0; n < ndeck; n++)
        deck_clear(&deck[n]);

    for (n = 0; n < nctl; n++)
        controller_clear(&ctl[n]);

    timecoder_free_lookup();
    library_clear(&library);
    rt_clear(&rt);
    rig_clear();
    osc_stop();
    thread_global_clear();

    if (rc == EXIT_SUCCESS)
        fprintf(stderr, "Done.\n");

    return rc;
}
Exemplo n.º 6
0
SndCard * jack_card_new(jack_client_t *client)
{
	JackCard * obj;
	SndCard *base;

	obj= g_new0(JackCard,1);

	if (!client) return NULL;
	obj->client = client;
	obj->jack_running = TRUE;
	obj->jack_active = FALSE;
	obj->can_process = FALSE;
	obj->clear = TRUE;
	obj->write.can_process = FALSE;
	obj->write.open = FALSE;
	obj->write.init = TRUE;
	obj->write.port = NULL;
	obj->write.phys_ports = NULL;
	obj->write.buffer = NULL;
	obj->read.can_process = FALSE;
	obj->read.open = FALSE;
	obj->read.init = TRUE;
	obj->read.port = NULL;
	obj->read.phys_ports = NULL;
	obj->read.buffer = NULL;

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

        /* 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, obj);

	jack_set_sample_rate_callback (client, samplerate, obj);

	obj->rate = jack_get_sample_rate (client);
	obj->buffer_size = jack_get_buffer_size(obj->client);

	jack_init(obj);
	
	base= SND_CARD(obj);
	snd_card_init(base);
	
#ifdef HAVE_GLIB
	base->card_name=g_strdup_printf("JACK client");
#else
	base->card_name=malloc(100);
	snprintf(base->card_name, 100, "JACK client");
#endif

	base->_probe=(SndCardOpenFunc)jack_card_probe;
	base->_open_r=(SndCardOpenFunc)jack_card_open_r;
	base->_open_w=(SndCardOpenFunc)jack_card_open_w;
	base->_can_read=(SndCardPollFunc)jack_card_can_read;
	base->_set_blocking_mode=(SndCardSetBlockingModeFunc)jack_card_set_blocking_mode;
	base->_read=(SndCardIOFunc)jack_card_read;
	base->_write=(SndCardIOFunc)jack_card_write;
	base->_close_r=(SndCardCloseFunc)jack_card_close_r;
	base->_close_w=(SndCardCloseFunc)jack_card_close_w;
	base->_set_rec_source=(SndCardMixerSetRecSourceFunc)jack_card_set_source;
	base->_set_level=(SndCardMixerSetLevelFunc)jack_card_set_level;
	base->_get_level=(SndCardMixerGetLevelFunc)jack_card_get_level;
	base->_destroy=(SndCardDestroyFunc)jack_card_destroy;
	base->_create_read_filter=(SndCardCreateFilterFunc)jack_card_create_read_filter;
	base->_create_write_filter=(SndCardCreateFilterFunc)jack_card_create_write_filter;
	
	obj->read.buffer=NULL;
	obj->write.buffer=NULL;
	obj->buffer_size = 0;
	obj->level = 1.0;
	obj->write.level = 1.0;
	obj->read.level = 1.0;

	return base;
}
Exemplo n.º 7
0
int jack_card_probe(JackCard *obj,int bits,int stereo,int rate)
{
  if (obj->jack_running) return BSIZE;
  else if (jack_init(obj) == 0) return BSIZE;
  else return -1;
}