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