コード例 #1
0
ファイル: dummy_driver.c プロジェクト: adiknoth/tschack
static jack_nframes_t 
dummy_driver_wait (dummy_driver_t *driver, int extra_fd, int *status,
		   float *delayed_usecs)
{
	jack_time_t now = jack_get_microseconds();

	if (driver->next_time < now) {
		if (driver->next_time == 0) {
			/* first time through */
			driver->next_time = now + driver->wait_time;
		}  else if (now - driver->next_time
			    > (PRETEND_BUFFER_SIZE * 1000000LL
			       / driver->sample_rate)) {
			/* xrun */
			jack_error("**** dummy: xrun of %ju usec",
				(uintmax_t)now - driver->next_time);
			driver->next_time = now + driver->wait_time;
		} else {
			/* late, but handled by our "buffer"; try to
			 * get back on track */
			driver->next_time += driver->wait_time;
		}
	} else {
		jack_time_t wait = driver->next_time - now;
		struct timespec ts = { .tv_sec = wait / 1000000,
				       .tv_nsec = (wait % 1000000) * 1000 };
		nanosleep(&ts,NULL);
		driver->next_time += driver->wait_time;
	}

	driver->last_wait_ust = jack_get_microseconds ();
	driver->engine->transport_cycle_start (driver->engine,
					       driver->last_wait_ust);

	/* this driver doesn't work so well if we report a delay */
	*delayed_usecs = 0;		/* lie about it */
	*status = 0;
	return driver->period_size;
}

static int dummy_driver_nt_start (dummy_driver_t *drv) 
{
	drv->next_time = 0;
	return 0; 
}
コード例 #2
0
ファイル: timestamps.c プロジェクト: adiknoth/tschack
void
jack_timestamp (const char *what)
{
	if (timestamp_index < timestamp_cnt) {
		timestamps[timestamp_index].when = jack_get_microseconds();
		timestamps[timestamp_index].what = what;
		++timestamp_index;
	}
}
コード例 #3
0
ファイル: oss_driver.c プロジェクト: adiknoth/tschack
static void set_period_size (oss_driver_t *driver, 
	jack_nframes_t new_period_size)
{
	driver->period_size = new_period_size;

	driver->period_usecs = 
		((double) driver->period_size /
		(double) driver->sample_rate) * 1e6;
	driver->last_wait_ust = 0;
	driver->last_periodtime = jack_get_microseconds();
	driver->next_periodtime = 0;
	driver->iodelay = 0.0F;
}
コード例 #4
0
ファイル: coreaudio_driver.c プロジェクト: briancline/jackosx
int coreaudio_runCycle(void *driver,long bufferSize,float **inBuffers,float **outBuffers) {
    coreaudio_driver_t * ca_driver = (coreaudio_driver_t*)driver;
    ca_driver->incoreaudio = inBuffers;
    ca_driver->outcoreaudio = outBuffers;
    ca_driver->last_wait_ust = jack_get_microseconds();
    int res = ca_driver->engine->run_cycle(ca_driver->engine, bufferSize, 0);

    if(ca_driver->needsChangeBufferSize) {
        coreaudio_driver_changeBufferSize(ca_driver);
        ca_driver->needsChangeBufferSize = FALSE;
    }

    return res;
}
コード例 #5
0
ファイル: oss_driver.c プロジェクト: adiknoth/tschack
static inline void update_times (oss_driver_t *driver)
{
	driver->last_periodtime = jack_get_microseconds();
	if (driver->next_periodtime > 0)
	{
		driver->iodelay = (float)
			((long double) driver->last_periodtime - 
			(long double) driver->next_periodtime);
	}
	else driver->iodelay = 0.0F;
	driver->next_periodtime = 
		driver->last_periodtime +
		driver->period_usecs;
}
コード例 #6
0
ファイル: dummy_driver.c プロジェクト: adiknoth/tschack
static jack_nframes_t 
dummy_driver_wait (dummy_driver_t *driver, int extra_fd, int *status,
		   float *delayed_usecs)
{
	jack_nframes_t nframes = driver->period_size;
	struct timespec now;

	*status = 0;
	/* this driver doesn't work so well if we report a delay */
	*delayed_usecs = 0;		/* lie about it */

	clock_gettime(CLOCK_REALTIME, &now);
	
	if (cmp_lt_ts(driver->next_wakeup, now)) {
		if (driver->next_wakeup.tv_sec == 0) {
			/* first time through */
			clock_gettime(CLOCK_REALTIME, &driver->next_wakeup);
		}  else if ((ts_to_nsec(now) - ts_to_nsec(driver->next_wakeup))/1000LL
			    > (PRETEND_BUFFER_SIZE * 1000000LL
			       / driver->sample_rate)) {
			/* xrun */
			jack_error("**** dummy: xrun of %ju usec",
				(uintmax_t)(ts_to_nsec(now) - ts_to_nsec(driver->next_wakeup))/1000LL);
			nframes = 0;
			driver->next_wakeup.tv_sec = 0;
		} else {
			/* late, but handled by our "buffer"; try to
			 * get back on track */
		}
		driver->next_wakeup = add_ts(driver->next_wakeup, driver->wait_time);
	} else {
		if(clock_nanosleep(CLOCK_REALTIME, TIMER_ABSTIME, &driver->next_wakeup, NULL)) {
			jack_error("error while sleeping");
			*status = -1;
		} else {
			clock_gettime(CLOCK_REALTIME, &now);
			// guaranteed to sleep long enough for this to be correct
			*delayed_usecs = (ts_to_nsec(now) - ts_to_nsec(driver->next_wakeup));
			*delayed_usecs /= 1000.0;
		}
		driver->next_wakeup = add_ts(driver->next_wakeup, driver->wait_time);
	}

	driver->last_wait_ust = jack_get_microseconds ();
	driver->engine->transport_cycle_start (driver->engine,
					       driver->last_wait_ust);

	return nframes;
}
コード例 #7
0
ファイル: coreaudio_driver.c プロジェクト: briancline/jackosx
static int
coreaudio_driver_read (coreaudio_driver_t *driver, jack_nframes_t nframes)
{
    jack_default_audio_sample_t *buf;
    channel_t chn;
    jack_port_t *port;
    JSList *node;

    for (chn = 0, node = driver->capture_ports; node; node = jack_slist_next (node), chn++) {

        port = (jack_port_t *)node->data;

        if (jack_port_connected (port) && (driver->incoreaudio[chn] != NULL)) {
            float *in = driver->incoreaudio[chn];
            buf = jack_port_get_buffer (port, nframes);
            memcpy(buf,in,sizeof(float)*nframes);
        }
    }

    driver->engine->transport_cycle_start (driver->engine,jack_get_microseconds ());
    return 0;
}
コード例 #8
0
ファイル: oss_driver.c プロジェクト: adiknoth/tschack
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 = jack_get_microseconds();
	driver->next_periodtime = 0;
	driver->iodelay = 0.0F;

	return 0;
}