Пример #1
0
/* Return the amount of data that can be written to the device */
static int audacious_jack_free(void)
{
  unsigned long return_val = JACK_GetBytesFreeSpace(driver);
  unsigned long tmp;

  /* adjust for frequency differences, otherwise xmms could send us */
  /* as much data as we have free, then we go to convert this to */
  /* the output frequency and won't have enough space, so adjust */
  /* by the ratio of the two */
  if(effect.frequency != output.frequency)
  {
    tmp = return_val;
    return_val = (return_val * effect.frequency) / output.frequency;
    TRACE("adjusting from %ld to %ld free bytes to compensate for frequency differences\n", tmp, return_val);
  }

  if(return_val > INT_MAX)
  {
      TRACE("Warning: return_val > INT_MAX\n");
      return_val = INT_MAX;
  }

  TRACE("free space of %ld bytes\n", return_val);

  return return_val;
}
Пример #2
0
int audev_loop(mix_func_t mixfunc, generate_func_t genfunc, void *rock)
{
  char *ptr;
  int ix, res;
  long pos;

  while (1) {
    res = mixfunc(valbuffer, genfunc, rock);
    if (res)
      return TRUE;

    if (sound_format) {
      for (ix=0, ptr=rawbuffer; ix<samplesperbuf; ix++) {
        long samp = valbuffer[ix];
        if (samp > 0x7FFF)
          samp = 0x7FFF;
        else if (samp < -0x7FFF)
          samp = -0x7FFF;
        *ptr++ = ((samp >> 8) & 0xFF);
        *ptr++ = ((samp) & 0xFF);
      }
    }
    else {
      for (ix=0, ptr=rawbuffer; ix<samplesperbuf; ix++) {
        long samp = valbuffer[ix];
        if (samp > 0x7FFF)
          samp = 0x7FFF;
        else if (samp < -0x7FFF)
          samp = -0x7FFF;
        *ptr++ = ((samp) & 0xFF);
        *ptr++ = ((samp >> 8) & 0xFF);
      }
    }

    pos = 0;

    while (pos < sound_buffersize) {
      long written;
      long towrite = JACK_GetBytesFreeSpace(deviceid);

      if (towrite <= 0) {
        struct timeval tv = sleeptime;
        select(0, 0, 0, 0, &tv);
        continue;
      }

      if (towrite > sound_buffersize-pos)
        towrite = sound_buffersize-pos;

      written = JACK_Write(deviceid, (unsigned char *)rawbuffer + pos, towrite);
      if (written != towrite) {
        fprintf(stderr, "Device write incomplete: %ld of %ld\n", written, towrite);
        return FALSE;
      }

      pos += written;
    }

  }
Пример #3
0
CAMLprim value caml_bjack_get_bytes_free_space(value d)
{
    CAMLparam1(d);
    CAMLreturn(Val_long(JACK_GetBytesFreeSpace(Bjack_drv_val(d))));
}
Пример #4
0
int audev_init_device(char *devname, long ratewanted, int verbose, extraopt_t *extra)
{
  extraopt_t *opt;
  int channels;
  unsigned long rate;
  int fragsize, format;
  long jbufframes, jbufsize;
  int res;

  if (verbose) {
    printf("Boodler: JackBIO sound driver.\n");
  }

  if (deviceid) {
    fprintf(stderr, "Sound device is already open.\n");
    return FALSE;
  }

  if (!ratewanted)
    ratewanted = DEFAULT_SOUNDRATE;
  if (!devname) 
    devname = DEFAULT_CLIENTNAME;

  rate = ratewanted;
  channels = 2;
  fragsize = 32768;
  format = 0; /* default to little-endian */

  for (opt=extra; opt->key; opt++) {
    if (!strcmp(opt->key, "end") && opt->val) {
      if (!strcmp(opt->val, "big"))
        format = 1;
      else if (!strcmp(opt->val, "little"))
        format = 0;
    }
    else if (!strcmp(opt->key, "connect") && opt->val) {
      if (!strcmp(opt->val, "none"))
        connect_mode = CONNECT_NONE;
      else if (!strcmp(opt->val, "output"))
        connect_mode = CONNECT_OUTPUT;
      else if (!strcmp(opt->val, "all"))
        connect_mode = CONNECT_ALL;
      else
        printf("JackB connect parameter must be none, output, or all.\n");
    }
    else if (!strcmp(opt->key, "buffersize") && opt->val) {
      fragsize = atol(opt->val);
    }
    else if (!strcmp(opt->key, "listdevices")) {
      printf("JackB driver is unable to list devices.\n");
    }
  }

  JACK_Init();
  JACK_SetPortConnectionMode(connect_mode);
  JACK_SetClientName(devname);

  res = JACK_Open(&deviceid, 16, &rate, 2);
  if (res) {
    fprintf(stderr, "Unable to open JACK connection: error %d\n", res);
    return FALSE;
  }

  jbufsize = JACK_GetBytesFreeSpace(deviceid);
  jbufframes = jbufsize / JACK_GetBytesPerOutputFrame(deviceid);
  if (jbufframes/2 >= rate) {
    sleeptime.tv_sec = 1;
    sleeptime.tv_usec = 0;
  }
  else {
    sleeptime.tv_sec = 0;
    sleeptime.tv_usec = (jbufframes/2) * 1000000 / rate;
  }

  if (verbose) {
    printf("Jack client name is \"%s_...\"\n", devname);
    printf("Sample format is %s-endian.\n", (format ? "big" : "little"));
    printf("Sample rate is %ld fps.\n", rate);
    printf("Boodler buffer size is %d.\n", fragsize);
    printf("Bio2Jack buffer size is %ld (%ld frames).\n", jbufsize, jbufframes);
    switch (connect_mode) {
    case CONNECT_NONE:
      printf("Bio2Jack connect_mode=CONNECT_NONE.\n");
      break;
    case CONNECT_OUTPUT:
      printf("Bio2Jack connect_mode=CONNECT_OUTPUT.\n");
      break;
    case CONNECT_ALL:
      printf("Bio2Jack connect_mode=CONNECT_ALL.\n");
      break;
    default:
      printf("Bio2Jack connect_mode=???.\n");
      break;
    }
  }

  sound_rate = rate;
  sound_channels = channels;
  sound_format = format;
  sound_buffersize = fragsize;

  samplesperbuf = sound_buffersize / 2;
  framesperbuf = sound_buffersize / (2 * sound_channels);

  valbuffer = (long *)malloc(sizeof(long) * samplesperbuf);
  if (!valbuffer) {
    fprintf(stderr, "Unable to allocate sound buffer.\n");
    JACK_Close(deviceid);
    deviceid = 0;
    return FALSE;     
  }
  rawbuffer = (char *)malloc(sound_buffersize);
  if (!rawbuffer) {
    fprintf(stderr, "Unable to allocate sound buffer.\n");
    free(valbuffer);
    JACK_Close(deviceid);
    deviceid = 0;
    return FALSE;    
  }

  return TRUE;
}