예제 #1
0
static
int alsa_rawmidi_start(alsa_midi_t *m)
{
    alsa_rawmidi_t *midi = (alsa_rawmidi_t*)m;
    int err;
    char c = 'q';
    if (midi->keep_walking == 1)
        return -EALREADY;

    midi->keep_walking = 1;
    if ((err = jack_client_create_thread(midi->client, &midi->in.thread, MIDI_THREAD_PRIO, jack_is_realtime(midi->client), midi_thread, &midi->in))) {
        midi->keep_walking = 0;
        return err;
    }
    if ((err = jack_client_create_thread(midi->client, &midi->out.thread, MIDI_THREAD_PRIO, jack_is_realtime(midi->client), midi_thread, &midi->out))) {
        midi->keep_walking = 0;
        write(midi->in.wake_pipe[1], &c, 1);
        pthread_join(midi->in.thread, NULL);
        return err;
    }
    if ((err = jack_client_create_thread(midi->client, &midi->scan.thread, 0, 0, scan_thread, midi))) {
        midi->keep_walking = 0;
        write(midi->in.wake_pipe[1], &c, 1);
        write(midi->out.wake_pipe[1], &c, 1);
        pthread_join(midi->in.thread, NULL);
        pthread_join(midi->out.thread, NULL);
        return err;
    }
    return 0;
}
예제 #2
0
파일: oss_driver.c 프로젝트: Llefjord/jack1
static int oss_driver_start (oss_driver_t *driver)
{
	int flags = 0;
	int format;
	int channels;
	int samplerate;
	int infd = driver->infd;
	int outfd = driver->outfd;
	unsigned int period_size;
	size_t samplesize;
	size_t fragsize;
	const char *indev = driver->indev;
	const char *outdev = driver->outdev;

	switch (driver->bits)
	{
		case 24:
		case 32:
			samplesize = sizeof(int);
			break;
		case 64:
			samplesize = sizeof(double);
			break;
		case 16:
		default:
			samplesize = sizeof(short);
			break;
	}
	driver->trigger = 0;
	if (strcmp(indev, outdev) != 0)
	{
		if (driver->capture_channels > 0)
		{
			infd = open(indev, O_RDONLY|O_EXCL);
			if (infd < 0)
			{
				jack_error(
					"OSS: failed to open input device %s: %s@%i, errno=%d",
					indev, __FILE__, __LINE__, errno);
			}
#ifndef OSS_NO_COOKED_MODE
			ioctl(infd, SNDCTL_DSP_COOKEDMODE, &flags);
#endif
			fragsize = driver->period_size * 
				driver->capture_channels * samplesize;
			set_fragment(infd, fragsize, driver->nperiods);
		}
		else infd = -1;

		if (driver->playback_channels > 0)
		{
			outfd = open(outdev, O_WRONLY|O_EXCL);
			if (outfd < 0)
			{
				jack_error(
					"OSS: failed to open output device %s: %s@%i, errno=%d",
					outdev, __FILE__, __LINE__, errno);
			}
#ifndef OSS_NO_COOKED_MODE
			ioctl(outfd, SNDCTL_DSP_COOKEDMODE, &flags);
#endif
			fragsize = driver->period_size * 
				driver->playback_channels * samplesize;
			set_fragment(outfd, fragsize, driver->nperiods);
		}
		else outfd = -1;
	}
	else
	{
		if (driver->capture_channels != 0 &&
			driver->playback_channels == 0)
		{
			infd = open(indev, O_RDWR|O_EXCL);
			outfd = -1;
			if (infd < 0)
			{
				jack_error(
					"OSS: failed to open device %s: %s@%i, errno=%d",
					indev, __FILE__, __LINE__, errno);
				return -1;
			}
#ifndef OSS_NO_COOKED_MODE
			ioctl(infd, SNDCTL_DSP_COOKEDMODE, &flags);
#endif
		}
		else if (driver->capture_channels == 0 &&
			driver->playback_channels != 0)
		{
			infd = -1;
			outfd = open(outdev, O_RDWR|O_EXCL);
			if (outfd < 0)
			{
				jack_error(
					"OSS: failed to open device %s: %s@%i, errno=%d",
					outdev, __FILE__, __LINE__, errno);
				return -1;
			}
#ifndef OSS_NO_COOKED_MODE
			ioctl(outfd, SNDCTL_DSP_COOKEDMODE, &flags);
#endif
		}
		else
		{
			infd = outfd = open(indev, O_RDWR|O_EXCL);
			if (infd < 0)
			{
				jack_error(
					"OSS: failed to open device %s: %s@%i, errno=%d",
					indev, __FILE__, __LINE__, errno);
				return -1;
			}
#ifndef OSS_NO_COOKED_MODE
			ioctl(infd, SNDCTL_DSP_COOKEDMODE, &flags);
#endif
		}
		if (infd >= 0 && outfd >= 0)
		{
			ioctl(outfd, SNDCTL_DSP_SETTRIGGER, &driver->trigger);
			driver->trigger = (PCM_ENABLE_INPUT|PCM_ENABLE_OUTPUT);
			if (ioctl(infd, SNDCTL_DSP_SETDUPLEX, 0) < 0)
			{
				if (errno != EINVAL) /* Dont care */
					jack_error(
						"OSS: failed to enable full duplex for %s: %s@%i, errno=%d",
						indev, __FILE__, __LINE__,
						errno);
			}
		}
		if (infd >= 0)
		{
			fragsize = driver->period_size * 
				driver->capture_channels * samplesize;
			set_fragment(infd, fragsize, driver->nperiods);
		}
		if (outfd >= 0 && infd < 0)
		{
			fragsize = driver->period_size * 
				driver->playback_channels * samplesize;
			set_fragment(outfd, fragsize, driver->nperiods);
		}
	}
	driver->infd = infd;
	driver->outfd = outfd;
	
	if (infd >= 0)
	{
		format = driver->format;
		if (ioctl(infd, SNDCTL_DSP_SETFMT, &format) < 0)
			jack_error(
				"OSS: failed to set format for %s: %s@%i, errno=%d", 
				indev, __FILE__, __LINE__, errno);
		channels = driver->capture_channels;
		if (ioctl(infd, SNDCTL_DSP_CHANNELS, &channels) < 0)
			jack_error(
				"OSS: failed to set channels for %s: %s@%i, errno=%d", 
				indev, __FILE__, __LINE__, errno);
		samplerate = driver->sample_rate;
		if (ioctl(infd, SNDCTL_DSP_SPEED, &samplerate) < 0)
			jack_error(
				"OSS: failed to set samplerate for %s: %s@%i, errno=%d", 
				indev, __FILE__, __LINE__, errno);
		jack_info("oss_driver: %s : 0x%x/%i/%i (%i)", indev, 
			format, channels, samplerate, get_fragment(infd));
		
		period_size = get_fragment(infd) / samplesize / channels;
		if (period_size != driver->period_size && 
			!driver->ignorehwbuf)
		{
			jack_info("oss_driver: period size update: %u",
				period_size);
			driver->period_size = period_size;
			driver->period_usecs = 
				((double) driver->period_size / 
				 (double) driver->sample_rate) * 1e6;
			if (driver->engine->set_buffer_size(driver->engine, 
							    driver->period_size)) {
				jack_error ("OSS: cannot set engine buffer size to %d (check MIDI)", driver->period_size);
				return -1;
			}
		}
	}

	if (outfd >= 0 && infd != outfd)
	{
		format = driver->format;
		if (ioctl(outfd, SNDCTL_DSP_SETFMT, &format) < 0)
			jack_error(
				"OSS: failed to set format for %s: %s@%i, errno=%d", 
				outdev, __FILE__, __LINE__, errno);
		channels = driver->playback_channels;
		if (ioctl(outfd, SNDCTL_DSP_CHANNELS, &channels) < 0)
			jack_error(
				"OSS: failed to set channels for %s: %s@%i, errno=%d", 
				outdev, __FILE__, __LINE__, errno);
		samplerate = driver->sample_rate;
		if (ioctl(outfd, SNDCTL_DSP_SPEED, &samplerate) < 0)
			jack_error(
				"OSS: failed to set samplerate for %s: %s@%i, errno=%d", 
				outdev, __FILE__, __LINE__, errno);
		jack_info("oss_driver: %s : 0x%x/%i/%i (%i)", outdev, 
			format, channels, samplerate, 
			get_fragment(outfd));

		period_size = get_fragment(outfd) / samplesize / channels;
		if (period_size != driver->period_size &&
			!driver->ignorehwbuf)
		{
			jack_info("oss_driver: period size update: %u",
				period_size);
			driver->period_size = period_size;
			driver->period_usecs = 
				((double) driver->period_size / 
				 (double) driver->sample_rate) * 1e6;
			if (driver->engine->set_buffer_size(driver->engine, 
							    driver->period_size)) {
				jack_error ("OSS: cannot set engine buffer size to %d (check MIDI)", driver->period_size);
				return -1;
			}
		}
	}

	if (driver->capture_channels > 0)
	{
		driver->indevbufsize = driver->period_size * 
			driver->capture_channels * samplesize;
		driver->indevbuf = malloc(driver->indevbufsize);
		if (driver->indevbuf == NULL)
		{
			jack_error( "OSS: malloc() failed: %s@%i", 
				__FILE__, __LINE__);
			return -1;
		}
		memset(driver->indevbuf, 0x00, driver->indevbufsize);
	}
	else
	{
		driver->indevbufsize = 0;
		driver->indevbuf = NULL;
	}

	if (driver->playback_channels > 0)
	{
		driver->outdevbufsize = driver->period_size * 
			driver->playback_channels * samplesize;
		driver->outdevbuf = malloc(driver->outdevbufsize);
		if (driver->outdevbuf == NULL)
		{
			jack_error("OSS: malloc() failed: %s@%i", 
				__FILE__, __LINE__);
			return -1;
		}
		memset(driver->outdevbuf, 0x00, driver->outdevbufsize);
	}
	else
	{
		driver->outdevbufsize = 0;
		driver->outdevbuf = NULL;
	}

	jack_info("oss_driver: indevbuf %zd B, outdevbuf %zd B",
		driver->indevbufsize, driver->outdevbufsize);

	pthread_mutex_init(&driver->mutex_in, NULL);
	pthread_mutex_init(&driver->mutex_out, NULL);
#	ifdef USE_BARRIER
	puts("oss_driver: using barrier mode, (dual thread)");
	pthread_barrier_init(&driver->barrier, NULL, 2);
#	else
	puts("oss_driver: not using barrier mode, (single thread)");
#	endif
	sem_init(&driver->sem_start, 0, 0);
	driver->run = 1;
	driver->threads = 0;
	if (infd >= 0)
	{
		if (jack_client_create_thread(NULL, &driver->thread_in, 
			driver->engine->rtpriority, 
			driver->engine->control->real_time, 
			io_thread, driver) < 0)
		{
			jack_error("OSS: jack_client_create_thread() failed: %s@%i",
				__FILE__, __LINE__);
			return -1;
		}
		driver->threads |= 1;
	}
#	ifdef USE_BARRIER
	if (outfd >= 0)
	{
		if (jack_client_create_thread(NULL, &driver->thread_out, 
			driver->engine->rtpriority, 
			driver->engine->control->real_time, 
			io_thread, driver) < 0)
		{
			jack_error("OSS: jack_client_create_thread() failed: %s@%i",
				__FILE__, __LINE__);
			return -1;
		}
		driver->threads |= 2;
	}
#	endif

	if (driver->threads & 1) sem_post(&driver->sem_start);
	if (driver->threads & 2) sem_post(&driver->sem_start);

	driver->last_periodtime = driver->engine->get_microseconds();
	driver->next_periodtime = 0;
	driver->iodelay = 0.0F;

	return 0;
}