예제 #1
0
static int oss_reset(int fd, uint32_t srate, uint8_t ch, int frame_size,
		     int nonblock)
{
	int format    = AFMT_S16_LE;
	int speed     = srate;
	int channels  = ch;
	int blocksize = 0;
	int err;

	err = set_fragment(fd, frame_size);
	if (err)
		return err;

	if (0 != ioctl(fd, FIONBIO, &nonblock))
		return errno;
	if (0 != ioctl(fd, SNDCTL_DSP_SETFMT, &format))
		return errno;
	if (0 != ioctl(fd, SNDCTL_DSP_CHANNELS, &channels))
		return errno;
	if (2 == channels) {
		int stereo = 1;
		if (0 != ioctl(fd, SNDCTL_DSP_STEREO, &stereo))
			return errno;
	}
	if (0 != ioctl(fd, SNDCTL_DSP_SPEED, &speed))
		return errno;

	(void)ioctl(fd, SNDCTL_DSP_GETBLKSIZE, &blocksize);

	re_printf("oss init: %u bit %d Hz %d ch, blocksize=%d\n",
		  format, speed, channels, blocksize);

	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;
}
예제 #3
0
 uri_builder &fragment(const Source &fragment) {
   set_fragment(detail::translate(fragment));
   return *this;
 }
예제 #4
0
 builder &fragment(const string_type &fragment) {
   return set_fragment(fragment);
 }