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; }
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; } }
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; }
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; }
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; }
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; }
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; }
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; }