Beispiel #1
0
unsigned long open_audio(unsigned long f, int s)
   {
	struct sio_par par;
	int buf_max;

	hdl = sio_open(NULL, SIO_PLAY, 0);
	if (hdl == NULL)
		end_all("Error opening audio device");

	realpos = 0;
	sio_onmove(hdl, movecb, NULL);

	sio_initpar(&par);
	if (f)
		par.rate = f;
	par.pchan = 2;
	if (!sio_setpar(hdl, &par) || !sio_getpar(hdl, &par) || !sio_start(hdl) ||
	    (par.bits != 8 && par.bits != 16) || par.pchan > 2)
		end_all("Sorry, no audio format supported by this binary is available");

	buf_max = par.appbufsz * par.bps * par.pchan;
	current_freq = par.rate;
	stereo = par.pchan == 2 ? 1 : 0;

	dsp_samplesize = par.bits;
	dsize = par.bps;
	buffer = malloc(buf_max);
	buffer16 = (short *)buffer;

	idx = 0;
	samples_max = buf_max / dsize / par.pchan;
	set_watched_scalar(FREQUENCY, current_freq);
	total = 0;
	return current_freq;
   }
Beispiel #2
0
bool CAESinkSNDIO::Initialize(AEAudioFormat &format, std::string &device)
{
  if ((m_hdl = sio_open(SIO_DEVANY, SIO_PLAY, 0)) == nullptr)
  {
    CLog::Log(LOGERROR, "CAESinkSNDIO::Initialize - Failed to open device");
    return false;
  }

  AudioFormatToPar(format);
  if (!sio_setpar(m_hdl, &m_par) ||
      !sio_getpar(m_hdl, &m_par) ||
      !ParToAudioFormat(format))
  {
    CLog::Log(LOGERROR, "CAESinkSNDIO::Initialize - could not negotiate parameters");
    return false;
  }

  m_played = m_written = 0;

  sio_onmove(m_hdl, CAESinkSNDIO::OnmoveCb, this);

  if (!sio_start(m_hdl))
  {
    CLog::Log(LOGERROR, "CAESinkSNDIO::Initialize - sio_start failed");
    return false;
  }

  return true;
}
Beispiel #3
0
/* Stops recording and switches the device back to the original mode. */
static void
sndio_rec_stop(void)
{
	if (hdl != NULL)
		sio_close(hdl);
	hdl = NULL;

	_sound_bits = sndio_save_bits;
	_sound_stereo = sndio_save_stereo;
	_sound_freq = sndio_save_freq;

	if (open_sndio_device(0) != 0)
		return;

	sndio_realpos = sndio_playpos = 0;
	sio_onmove(hdl, movecb, NULL);

	sndio_volume = 127;
	sio_onvol(hdl, volcb, NULL);

	if (!sio_start(hdl)) {
		ustrzcpy(allegro_error, ALLEGRO_ERROR_SIZE,
		    get_config_text("Can not start sndio"));
		sio_close(hdl);
		return;
	}

	_unix_bg_man->register_func(sndio_update);
}
Beispiel #4
0
static void
swfdec_playback_stream_open (SwfdecPlayback *sound, SwfdecAudio *audio)
{
  Stream *stream;
  struct sio_hdl *hdl;
  struct sio_par par;

  hdl = sio_open (NULL, SIO_PLAY, 0);
  if (hdl == NULL) {
    g_printerr ("Could not open sndio\n");
    return;
  }

  sio_initpar (&par);

  par.bits = 16;
  par.sig = 1;
  par.pchan = 2;
  par.rate = 44100;
  par.appbufsz = 8192;

  if (!sio_setpar (hdl, &par)) {
    g_printerr ("\n\nCould not set sndio hardware parameters\n");
    goto fail;
  }
  if (!sio_getpar (hdl, &par)) {
    g_printerr ("\n\nCould not get sndio hardware parameters\n");
    goto fail;
  }

  stream = g_new0 (Stream, 1);
  stream->write = try_write;
  stream->sound = sound;
  stream->audio = g_object_ref (audio);
  stream->hdl = hdl;
  stream->par = par;
  sound->streams = g_list_prepend (sound->streams, stream);

  sio_onmove (hdl, sndio_movecb, stream);
  stream->f_written = stream->f_played = 0;

  g_signal_connect (stream->audio, "changed", 
      G_CALLBACK (swfdec_playback_stream_changed), stream);
  g_signal_connect (stream->audio, "new-data", 
      G_CALLBACK (swfdec_playback_stream_new_data), stream);
  swfdec_playback_stream_start (stream);
  return;

fail:
  sio_close (hdl);
}
int
sa_stream_open(sa_stream_t *s)
{
	struct sio_hdl *handle;
	struct sio_par par;

	if (s == NULL)
		return SA_ERROR_NO_INIT;

	if (s->handle != NULL)
		return SA_ERROR_INVALID;

	handle = sio_open(NULL, SIO_PLAY, 0);
	if (handle == NULL)
		return SA_ERROR_NO_DEVICE;

	sio_initpar(&par);
	par.bits = s->format;
	par.le = SIO_LE_NATIVE;
	par.pchan = s->channels;
	par.rate = s->rate;
	par.sig = 1;

	if (!sio_setpar(handle, &par) || !sio_getpar(handle, &par)) {
		sio_close(handle);
		return SA_ERROR_NOT_SUPPORTED;
	}

	if (par.bits != s->format || par.le != SIO_LE_NATIVE ||
	    par.pchan != s->channels || par.rate != s->rate || par.sig != 1) {
		sio_close(handle);
		return SA_ERROR_NOT_SUPPORTED;
	}

	sio_onmove(handle, onmove_callback, s);

	if (!sio_start(handle)) {
		sio_close(handle);
		return SA_ERROR_NOT_SUPPORTED;
	}

	s->bpf = par.pchan * par.bps;
	s->buffer = par.bufsz * s->bpf;
	s->handle = handle;

	return SA_SUCCESS;
}
Beispiel #6
0
/*
 * Open the device.
 */
struct siofile *
siofile_new(struct fileops *ops, char *path, unsigned int *rmode,
    struct aparams *ipar, struct aparams *opar,
    unsigned int *bufsz, unsigned int *round)
{
	struct sio_par par;
	struct sio_hdl *hdl;
	struct siofile *f;
	unsigned int mode = *rmode;

	hdl = sio_open(path, mode, 1);
	if (hdl == NULL) {
		if (mode != (SIO_PLAY | SIO_REC))
			return NULL;
		hdl = sio_open(path, SIO_PLAY, 1);
		if (hdl != NULL)
			mode = SIO_PLAY;
		else {
			hdl = sio_open(path, SIO_REC, 1);
			if (hdl != NULL)
				mode = SIO_REC;
			else
				return NULL;
		}
#ifdef DEBUG
		if (debug_level >= 1) {
			dbg_puts("warning, device opened in ");
			dbg_puts(mode == SIO_PLAY ? "play-only" : "rec-only");
			dbg_puts(" mode\n");
		}
#endif
	}

	sio_initpar(&par);
	if (mode & SIO_REC) {
		par.bits = ipar->bits;
		par.bps = ipar->bps;
		par.sig = ipar->sig;
		par.le = ipar->le;
		par.msb = ipar->msb;
		par.rate = ipar->rate;
		par.rchan = ipar->cmax + 1;
	} else {
		par.bits = opar->bits;
		par.bps = opar->bps;
		par.sig = opar->sig;
		par.le = opar->le;
		par.msb = opar->msb;
		par.rate = opar->rate;
	}
	if (mode & SIO_PLAY)
		par.pchan = opar->cmax + 1;
	if (*bufsz)
		par.appbufsz = *bufsz;
	if (*round)
		par.round = *round;
	if (!sio_setpar(hdl, &par))
		goto bad_close;
	if (!sio_getpar(hdl, &par))
		goto bad_close;
	if (mode & SIO_REC) {
		ipar->bits = par.bits;
		ipar->bps = par.bps;
		ipar->sig = par.sig;
		ipar->le = par.le;
		ipar->msb = par.msb;
		ipar->rate = par.rate;
		ipar->cmin = 0;
		ipar->cmax = par.rchan - 1;
	}
	if (mode & SIO_PLAY) {
		opar->bits = par.bits;
		opar->bps = par.bps;
		opar->sig = par.sig;
		opar->le = par.le;
		opar->msb = par.msb;
		opar->rate = par.rate;
		opar->cmin = 0;
		opar->cmax = par.pchan - 1;
	}
	*rmode = mode;
	*bufsz = par.bufsz;
	*round = par.round;
	f = (struct siofile *)file_new(ops, path, sio_nfds(hdl));
	if (f == NULL)
		goto bad_close;
	f->hdl = hdl;
	f->started = 0;
	f->wtickets = 0;
	f->rtickets = 0;
	f->wbpf = par.pchan * par.bps;
	f->rbpf = par.rchan * par.bps;
	f->bufsz = par.bufsz;
	sio_onmove(f->hdl, siofile_cb, f);
	return f;
 bad_close:
	sio_close(hdl);
	return NULL;
}
Beispiel #7
0
static int
sndio_stream_init(cubeb * context,
                  cubeb_stream ** stream,
                  char const * stream_name,
                  cubeb_devid input_device,
                  cubeb_stream_params * input_stream_params,
                  cubeb_devid output_device,
                  cubeb_stream_params * output_stream_params,
                  unsigned int latency_frames,
                  cubeb_data_callback data_callback,
                  cubeb_state_callback state_callback,
                  void *user_ptr)
{
  cubeb_stream *s;
  struct sio_par wpar, rpar;
  cubeb_sample_format format;
  int rate;
  size_t bps;

  DPR("sndio_stream_init(%s)\n", stream_name);

  s = malloc(sizeof(cubeb_stream));
  if (s == NULL)
    return CUBEB_ERROR;
  memset(s, 0, sizeof(cubeb_stream));
  s->mode = 0;
  if (input_stream_params) {
    if (input_stream_params->prefs & CUBEB_STREAM_PREF_LOOPBACK) {
      DPR("sndio_stream_init(), loopback not supported\n");
      goto err;
    }
    s->mode |= SIO_REC;
    format = input_stream_params->format;
    rate = input_stream_params->rate;
  }
  if (output_stream_params) {
    if (output_stream_params->prefs & CUBEB_STREAM_PREF_LOOPBACK) {
      DPR("sndio_stream_init(), loopback not supported\n");
      goto err;
    }
    s->mode |= SIO_PLAY;
    format = output_stream_params->format;
    rate = output_stream_params->rate;
  }
  if (s->mode == 0) {
    DPR("sndio_stream_init(), neither playing nor recording\n");
    goto err;
  }
  s->context = context;
  s->hdl = sio_open(NULL, s->mode, 1);
  if (s->hdl == NULL) {
    DPR("sndio_stream_init(), sio_open() failed\n");
    goto err;
  }
  sio_initpar(&wpar);
  wpar.sig = 1;
  wpar.bits = 16;
  switch (format) {
  case CUBEB_SAMPLE_S16LE:
    wpar.le = 1;
    break;
  case CUBEB_SAMPLE_S16BE:
    wpar.le = 0;
    break;
  case CUBEB_SAMPLE_FLOAT32NE:
    wpar.le = SIO_LE_NATIVE;
    break;
  default:
    DPR("sndio_stream_init() unsupported format\n");
    goto err;
  }
  wpar.rate = rate;
  if (s->mode & SIO_REC)
    wpar.rchan = input_stream_params->channels;
  if (s->mode & SIO_PLAY)
    wpar.pchan = output_stream_params->channels;
  wpar.appbufsz = latency_frames;
  if (!sio_setpar(s->hdl, &wpar) || !sio_getpar(s->hdl, &rpar)) {
    DPR("sndio_stream_init(), sio_setpar() failed\n");
    goto err;
  }
  if (rpar.bits != wpar.bits || rpar.le != wpar.le ||
      rpar.sig != wpar.sig || rpar.rate != wpar.rate ||
      ((s->mode & SIO_REC) && rpar.rchan != wpar.rchan) ||
      ((s->mode & SIO_PLAY) && rpar.pchan != wpar.pchan)) {
    DPR("sndio_stream_init() unsupported params\n");
    goto err;
  }
  sio_onmove(s->hdl, sndio_onmove, s);
  s->active = 0;
  s->nfr = rpar.round;
  s->rbpf = rpar.bps * rpar.rchan;
  s->pbpf = rpar.bps * rpar.pchan;
  s->rchan = rpar.rchan;
  s->pchan = rpar.pchan;
  s->nblks = rpar.bufsz / rpar.round;
  s->data_cb = data_callback;
  s->state_cb = state_callback;
  s->arg = user_ptr;
  s->mtx = (pthread_mutex_t)PTHREAD_MUTEX_INITIALIZER;
  s->hwpos = s->swpos = 0;
  if (format == CUBEB_SAMPLE_FLOAT32LE) {
    s->conv = 1;
    bps = sizeof(float);
  } else {
    s->conv = 0;
    bps = rpar.bps;
  }
  if (s->mode & SIO_PLAY) {
    s->pbuf = malloc(bps * rpar.pchan * rpar.round);
    if (s->pbuf == NULL)
      goto err;
  }
  if (s->mode & SIO_REC) {
    s->rbuf = malloc(bps * rpar.rchan * rpar.round);
    if (s->rbuf == NULL)
      goto err;
  }
  *stream = s;
  DPR("sndio_stream_init() end, ok\n");
  (void)context;
  (void)stream_name;
  return CUBEB_OK;
err:
  if (s->hdl)
    sio_close(s->hdl);
  if (s->pbuf)
    free(s->pbuf);
  if (s->rbuf)
    free(s->pbuf);
  free(s);
  return CUBEB_ERROR;
}
Beispiel #8
0
static int
sndio_stream_init(cubeb * context,
                  cubeb_stream ** stream,
                  char const * stream_name,
                  cubeb_devid input_device,
                  cubeb_stream_params * input_stream_params,
                  cubeb_devid output_device,
                  cubeb_stream_params * output_stream_params,
                  unsigned int latency_frames,
                  cubeb_data_callback data_callback,
                  cubeb_state_callback state_callback,
                  void *user_ptr)
{
  cubeb_stream *s;
  struct sio_par wpar, rpar;
  DPR("sndio_stream_init(%s)\n", stream_name);
  size_t size;

  assert(!input_stream_params && "not supported.");
  if (input_device || output_device) {
    /* Device selection not yet implemented. */
    return CUBEB_ERROR_DEVICE_UNAVAILABLE;
  }

  s = malloc(sizeof(cubeb_stream));
  if (s == NULL)
    return CUBEB_ERROR;
  s->context = context;
  s->hdl = sio_open(NULL, SIO_PLAY, 1);
  if (s->hdl == NULL) {
    free(s);
    DPR("sndio_stream_init(), sio_open() failed\n");
    return CUBEB_ERROR;
  }
  sio_initpar(&wpar);
  wpar.sig = 1;
  wpar.bits = 16;
  switch (output_stream_params->format) {
  case CUBEB_SAMPLE_S16LE:
    wpar.le = 1;
    break;
  case CUBEB_SAMPLE_S16BE:
    wpar.le = 0;
    break;
  case CUBEB_SAMPLE_FLOAT32NE:
    wpar.le = SIO_LE_NATIVE;
    break;
  default:
    DPR("sndio_stream_init() unsupported format\n");
    return CUBEB_ERROR_INVALID_FORMAT;
  }
  wpar.rate = output_stream_params->rate;
  wpar.pchan = output_stream_params->channels;
  wpar.appbufsz = latency_frames;
  if (!sio_setpar(s->hdl, &wpar) || !sio_getpar(s->hdl, &rpar)) {
    sio_close(s->hdl);
    free(s);
    DPR("sndio_stream_init(), sio_setpar() failed\n");
    return CUBEB_ERROR;
  }
  if (rpar.bits != wpar.bits || rpar.le != wpar.le ||
      rpar.sig != wpar.sig || rpar.rate != wpar.rate ||
      rpar.pchan != wpar.pchan) {
    sio_close(s->hdl);
    free(s);
    DPR("sndio_stream_init() unsupported params\n");
    return CUBEB_ERROR_INVALID_FORMAT;
  }
  sio_onmove(s->hdl, sndio_onmove, s);
  s->active = 0;
  s->nfr = rpar.round;
  s->bpf = rpar.bps * rpar.pchan;
  s->pchan = rpar.pchan;
  s->data_cb = data_callback;
  s->state_cb = state_callback;
  s->arg = user_ptr;
  s->mtx = PTHREAD_MUTEX_INITIALIZER;
  s->rdpos = s->wrpos = 0;
  if (output_stream_params->format == CUBEB_SAMPLE_FLOAT32LE) {
    s->conv = 1;
    size = rpar.round * rpar.pchan * sizeof(float);
  } else {
    s->conv = 0;
    size = rpar.round * rpar.pchan * rpar.bps;
  }
  s->buf = malloc(size);
  if (s->buf == NULL) {
    sio_close(s->hdl);
    free(s);
    return CUBEB_ERROR;
  }
  *stream = s;
  DPR("sndio_stream_init() end, ok\n");
  (void)context;
  (void)stream_name;
  return CUBEB_OK;
}
Beispiel #9
0
/*
 * open device and setup parameters
 * return: 0=success -1=fail
 */
static int init(struct ao *ao)
{
    struct priv *p = ao->priv;

    struct af_to_par {
        int format, bits, sig, le;
    } static const af_to_par[] = {
        {AF_FORMAT_U8,      8, 0, 0},
        {AF_FORMAT_S8,      8, 1, 0},
        {AF_FORMAT_U16_LE, 16, 0, 1},
        {AF_FORMAT_U16_BE, 16, 0, 0},
        {AF_FORMAT_S16_LE, 16, 1, 1},
        {AF_FORMAT_S16_BE, 16, 1, 0},
        {AF_FORMAT_U24_LE, 16, 0, 1},
        {AF_FORMAT_U24_BE, 24, 0, 0},
        {AF_FORMAT_S24_LE, 24, 1, 1},
        {AF_FORMAT_S24_BE, 24, 1, 0},
        {AF_FORMAT_U32_LE, 32, 0, 1},
        {AF_FORMAT_U32_BE, 32, 0, 0},
        {AF_FORMAT_S32_LE, 32, 1, 1},
        {AF_FORMAT_S32_BE, 32, 1, 0}
    }, *ap;
    int i;

    p->hdl = sio_open(p->dev, SIO_PLAY, 0);
    if (p->hdl == NULL) {
        MP_ERR(ao, "can't open sndio %s\n", p->dev);
        goto error;
    }

    ao->format = af_fmt_from_planar(ao->format);

    sio_initpar(&p->par);
    for (i = 0, ap = af_to_par;; i++, ap++) {
        if (i == sizeof(af_to_par) / sizeof(struct af_to_par)) {
            MP_VERBOSE(ao, "unsupported format\n");
            p->par.bits = 16;
            p->par.sig = 1;
            p->par.le = SIO_LE_NATIVE;
            break;
        }
        if (ap->format == ao->format) {
            p->par.bits = ap->bits;
            p->par.sig = ap->sig;
            if (ap->bits > 8)
                p->par.le = ap->le;
            if (ap->bits != SIO_BPS(ap->bits))
                p->par.bps = ap->bits / 8;
            break;
        }
    }
    p->par.rate = ao->samplerate;

    struct mp_chmap_sel sel = {0};
    for (int n = 0; n < MP_NUM_CHANNELS+1; n++)
        mp_chmap_sel_add_map(&sel, &sndio_layouts[n]);

    if (!ao_chmap_sel_adjust(ao, &sel, &ao->channels))
        goto error;

    p->par.pchan = ao->channels.num;
    p->par.appbufsz = p->par.rate * 250 / 1000;    /* 250ms buffer */
    p->par.round = p->par.rate * 10 / 1000;    /*  10ms block size */
    if (!sio_setpar(p->hdl, &p->par)) {
        MP_ERR(ao, "couldn't set params\n");
        goto error;
    }
    if (!sio_getpar(p->hdl, &p->par)) {
        MP_ERR(ao, "couldn't get params\n");
        goto error;
    }
    if (p->par.bits == 8 && p->par.bps == 1) {
        ao->format = p->par.sig ? AF_FORMAT_S8 : AF_FORMAT_U8;
    } else if (p->par.bits == 16 && p->par.bps == 2) {
        ao->format = p->par.sig ?
            (p->par.le ? AF_FORMAT_S16_LE : AF_FORMAT_S16_BE) :
            (p->par.le ? AF_FORMAT_U16_LE : AF_FORMAT_U16_BE);
    } else if ((p->par.bits == 24 || p->par.msb) && p->par.bps == 3) {
        ao->format = p->par.sig ?
            (p->par.le ? AF_FORMAT_S24_LE : AF_FORMAT_S24_BE) :
            (p->par.le ? AF_FORMAT_U24_LE : AF_FORMAT_U24_BE);
    } else if ((p->par.bits == 32 || p->par.msb) && p->par.bps == 4) {
        ao->format = p->par.sig ?
            (p->par.le ? AF_FORMAT_S32_LE : AF_FORMAT_S32_BE) :
            (p->par.le ? AF_FORMAT_U32_LE : AF_FORMAT_U32_BE);
    } else {
        MP_ERR(ao, "couldn't set format\n");
        goto error;
    }

    ao->bps = p->par.bps * p->par.pchan * p->par.rate;
    p->havevol = sio_onvol(p->hdl, volcb, p);
    sio_onmove(p->hdl, movecb, p);
    p->delay = 0;
    if (!sio_start(p->hdl))
        MP_ERR(ao, "init: couldn't start\n");

    p->pfd = calloc (sio_nfds(p->hdl), sizeof (struct pollfd));
    if (!p->pfd)
        goto error;

    return 0;

error:
    if (p->hdl)
      sio_close(p->hdl);

    return -1;
}
Beispiel #10
0
/*
 * Open the audio device for writing to.
 */
static int ao_sndio_open(ao_driver_t *this_gen,
                         uint32_t bits, uint32_t rate, int mode)
{
  sndio_driver_t *this = (sndio_driver_t *) this_gen;
  struct sio_par par;

  xprintf (this->xine, XINE_VERBOSITY_DEBUG,
           "audio_sndio_out: ao_sndio_open bits=%d rate=%d, mode=%d\n",
           bits, rate, mode);

  if (this->hdl != NULL) {
    sio_close (this->hdl);
    this->hdl = NULL;
  }

  this->hdl = sio_open(NULL, SIO_PLAY, 0);
  if (this->hdl == NULL)
    goto bad;

  sio_initpar(&par);

  switch (mode) {
  case AO_CAP_MODE_MONO:
    par.pchan = 1;
    break;
  case AO_CAP_MODE_STEREO:
    par.pchan = 2;
    break;
#if 0
  case AO_CAP_MODE_4CHANNEL:
    par.pchan = 4;
    break;
  case AO_CAP_MODE_4_1CHANNEL:
  case AO_CAP_MODE_5CHANNEL:
  case AO_CAP_MODE_5_1CHANNEL:
    par.pchan = 6;
    break;
#endif
  default:
    xprintf (this->xine, XINE_VERBOSITY_DEBUG,
             "audio_sndio_out: ao_sndio_open does not support the requested mode: 0x%X\n",
	     mode);
    goto bad;
  }

  switch (bits) {
  case 8:
    par.bits = 8;
    par.sig = 0;
    break;
  case 16:
    par.bits = 16;
    par.sig = 1;
    break;
  default:
    xprintf (this->xine, XINE_VERBOSITY_DEBUG,
             "audio_sndio_out: ao_sndio_open bits per sample not supported: %d\n", bits);
    goto bad;
  }

  par.rate = rate;
  par.appbufsz = par.rate * 250 / 1000; /* 250ms buffer */

  if (!sio_setpar(this->hdl, &par)) {
    xprintf (this->xine, XINE_VERBOSITY_DEBUG,
             "audio_sndio_out: ao_sndio_open could not set params\n");
    goto bad;
  }

  if (!sio_getpar(this->hdl, &par)) {
    xprintf (this->xine, XINE_VERBOSITY_DEBUG,
             "audio_sndio_out: ao_sndio_open could not get params\n");
    goto bad;
  }

  xprintf (this->xine, XINE_VERBOSITY_DEBUG,
           "audio_sndio_out: ao_sndio_open %d channels output\n",
           par.pchan);

  this->num_channels           = par.pchan;
  this->bytes_per_frame        = par.bps * par.pchan;
  this->playpos                = 0;
  this->realpos                = 0;
  sio_onmove(this->hdl, ao_sndio_onmove_cb, this);

  if (!sio_start(this->hdl)) {
    xprintf (this->xine, XINE_VERBOSITY_DEBUG,
             "audio_sndio_out: ao_sndio_open could not start\n");
    goto bad;
  }

  return par.rate;

bad:
  if (this->hdl != NULL)
    sio_close(this->hdl);
  return 0;
}
Beispiel #11
0
gboolean
gst_sndio_prepare (struct gstsndio *sio, GstAudioRingBufferSpec *spec)
{
  struct sio_par par, retpar;
  unsigned nchannels;

  GST_DEBUG_OBJECT (sio, "prepare");

  if (spec->type != GST_AUDIO_RING_BUFFER_FORMAT_TYPE_RAW) {
      GST_ELEMENT_ERROR (sio, RESOURCE, OPEN_READ_WRITE,
	("Only raw buffer format supported by sndio"), (NULL));
      return FALSE;
  }
  if (!GST_AUDIO_INFO_IS_INTEGER(&spec->info)) {
      GST_ELEMENT_ERROR (sio, RESOURCE, OPEN_READ_WRITE,
	("Only integer format supported"), (NULL));
      return FALSE;
  }
  if (GST_AUDIO_INFO_DEPTH(&spec->info) % 8) {
      GST_ELEMENT_ERROR (sio, RESOURCE, OPEN_READ_WRITE,
	("Only depths multiple of 8 are supported"), (NULL));
      return FALSE;
  }

  sio_initpar (&par);
  switch (GST_AUDIO_INFO_FORMAT (&spec->info)) {
  case GST_AUDIO_FORMAT_S8:
  case GST_AUDIO_FORMAT_U8:
  case GST_AUDIO_FORMAT_S16LE:
  case GST_AUDIO_FORMAT_S16BE:
  case GST_AUDIO_FORMAT_U16LE:
  case GST_AUDIO_FORMAT_U16BE:
  case GST_AUDIO_FORMAT_S32LE:
  case GST_AUDIO_FORMAT_S32BE:
  case GST_AUDIO_FORMAT_U32LE:
  case GST_AUDIO_FORMAT_U32BE:
  case GST_AUDIO_FORMAT_S24_32LE:
  case GST_AUDIO_FORMAT_S24_32BE:
  case GST_AUDIO_FORMAT_U24_32LE:
  case GST_AUDIO_FORMAT_U24_32BE:
  case GST_AUDIO_FORMAT_S24LE:
  case GST_AUDIO_FORMAT_S24BE:
  case GST_AUDIO_FORMAT_U24LE:
  case GST_AUDIO_FORMAT_U24BE:
      break;
  default:
      GST_ELEMENT_ERROR (sio, RESOURCE, OPEN_READ_WRITE,
	  ("Unsupported audio format"),
	  ("format = %d", GST_AUDIO_INFO_FORMAT (&spec->info)));
      return FALSE;
  }
  par.sig = GST_AUDIO_INFO_IS_SIGNED(&spec->info);
  par.bits = GST_AUDIO_INFO_WIDTH(&spec->info);
  par.bps = GST_AUDIO_INFO_DEPTH(&spec->info) / 8;
  if (par.bps > 1)
      par.le = GST_AUDIO_INFO_IS_LITTLE_ENDIAN(&spec->info);
  if (par.bits < par.bps * 8)
      par.msb = 0;
  par.rate = GST_AUDIO_INFO_RATE(&spec->info);
  if (sio->mode == SIO_PLAY)
      par.pchan = GST_AUDIO_INFO_CHANNELS(&spec->info);
  else
      par.rchan = GST_AUDIO_INFO_CHANNELS(&spec->info);
  par.round = par.rate / 1000000. * spec->latency_time;
  par.appbufsz = par.rate / 1000000. * spec->buffer_time;

  if (!sio_setpar (sio->hdl, &par)) {
      GST_ELEMENT_ERROR (sio, RESOURCE, OPEN_WRITE,
	("Unsupported audio encoding"), (NULL));
      return FALSE;
  }
  if (!sio_getpar (sio->hdl, &retpar)) {
      GST_ELEMENT_ERROR (sio, RESOURCE, OPEN_WRITE,
	("Couldn't get audio device parameters"), (NULL));
      return FALSE;
  }
#if 0
  fprintf(stderr, "format = %s, "
         "requested: sig = %d, bits = %d, bps = %d, le = %d, msb = %d, "
	 "rate = %d, pchan = %d, round = %d, appbufsz = %d; "
	 "returned: sig = %d, bits = %d, bps = %d, le = %d, msb = %d, "
	 "rate = %d, pchan = %d, round = %d, appbufsz = %d, bufsz = %d\n",
	 GST_AUDIO_INFO_NAME(&spec->info),
	 par.sig, par.bits, par.bps, par.le, par.msb,
	 par.rate, par.pchan, par.round, par.appbufsz,
	 retpar.sig, retpar.bits, retpar.bps, retpar.le, retpar.msb,
	 retpar.rate, retpar.pchan, retpar.round, retpar.appbufsz, retpar.bufsz);
#endif
  if (par.bits != retpar.bits ||
      par.bps != retpar.bps ||
      par.rate != retpar.rate ||
      (sio->mode == SIO_PLAY && par.pchan != retpar.pchan) ||
      (sio->mode == SIO_REC && par.rchan != retpar.rchan) ||
      (par.bps > 1 && par.le != retpar.le) ||
      (par.bits < par.bps * 8 && par.msb != retpar.msb)) {
      GST_ELEMENT_ERROR (sio, RESOURCE, OPEN_WRITE,
	("Audio device refused requested parameters"), (NULL));
      return FALSE;
  }

  nchannels = (sio->mode == SIO_PLAY) ? retpar.pchan : retpar.rchan;
  spec->segsize = retpar.round * retpar.bps * nchannels;
  spec->segtotal = retpar.bufsz / retpar.round;
  sio->bpf = retpar.bps * nchannels;
  sio->delay = 0;
  sio_onmove (sio->hdl, gst_sndio_cb, sio);

  if (!sio_start (sio->hdl)) {
    GST_ELEMENT_ERROR (sio->obj, RESOURCE, OPEN_READ_WRITE,
      ("Could not start sndio"), (NULL));
    return FALSE;
  }
  return TRUE;
}
Beispiel #12
0
av_cold int ff_sndio_open(AVFormatContext *s1, int is_output,
                          const char *audio_device)
{
    SndioData *s = s1->priv_data;
    struct sio_hdl *hdl;
    struct sio_par par;

    hdl = sio_open(audio_device, is_output ? SIO_PLAY : SIO_REC, 0);
    if (!hdl) {
        av_log(s1, AV_LOG_ERROR, "Could not open sndio device\n");
        return AVERROR(EIO);
    }

    sio_initpar(&par);

    par.bits = 16;
    par.sig  = 1;
    par.le   = SIO_LE_NATIVE;

    if (is_output)
        par.pchan = s->channels;
    else
        par.rchan = s->channels;
    par.rate = s->sample_rate;

    if (!sio_setpar(hdl, &par) || !sio_getpar(hdl, &par)) {
        av_log(s1, AV_LOG_ERROR, "Impossible to set sndio parameters, "
               "channels: %d sample rate: %d\n", s->channels, s->sample_rate);
        goto fail;
    }

    if (par.bits != 16 || par.sig != 1 ||
        (is_output  && (par.pchan != s->channels)) ||
        (!is_output && (par.rchan != s->channels)) ||
        (par.rate != s->sample_rate)) {
        av_log(s1, AV_LOG_ERROR, "Could not set appropriate sndio parameters, "
               "channels: %d sample rate: %d\n", s->channels, s->sample_rate);
        goto fail;
    }

    s->buffer_size = par.round * par.bps *
                     (is_output ? par.pchan : par.rchan);

    if (is_output) {
        s->buffer = av_malloc(s->buffer_size);
        if (!s->buffer) {
            av_log(s1, AV_LOG_ERROR, "Could not allocate buffer\n");
            goto fail;
        }
    }

    s->codec_id    = par.le ? CODEC_ID_PCM_S16LE : CODEC_ID_PCM_S16BE;
    s->channels    = is_output ? par.pchan : par.rchan;
    s->sample_rate = par.rate;
    s->bps         = par.bps;

    sio_onmove(hdl, movecb, s);

    if (!sio_start(hdl)) {
        av_log(s1, AV_LOG_ERROR, "Could not start sndio\n");
        goto fail;
    }

    s->hdl = hdl;

    return 0;

fail:
    av_freep(&s->buffer);

    if (hdl)
        sio_close(hdl);

    return AVERROR(EIO);
}
Beispiel #13
0
int
main(int argc, char **argv) {
	int ch;
	struct sio_hdl *hdl;
	ssize_t n;
	
	/*
	 * defaults parameters
	 */
	sio_initpar(&par);
	par.sig = 1;
	par.bits = 16;
	par.rchan = 2;
	par.rate = 44100;

	while ((ch = getopt(argc, argv, "r:c:e:b:x:")) != -1) {
		switch(ch) {
		case 'r':
			if (sscanf(optarg, "%u", &par.rate) != 1) {
				fprintf(stderr, "%s: bad rate\n", optarg);
				exit(1);
			}
			break;
		case 'c':
			if (sscanf(optarg, "%u", &par.rchan) != 1) {
				fprintf(stderr, "%s: channels number\n", optarg);
				exit(1);
			}
			break;
		case 'e':
			if (!sio_strtoenc(&par, optarg)) {
				fprintf(stderr, "%s: unknown encoding\n", optarg);
				exit(1);
			}
			break;
		case 'x':
			for (par.xrun = 0;; par.xrun++) {
				if (par.xrun == sizeof(xstr) / sizeof(char *)) {
					fprintf(stderr, 
					    "%s: bad xrun mode\n", optarg);
					exit(1);
				}
				if (strcmp(xstr[par.xrun], optarg) == 0)
					break;
			}
			break;			
		default:
			usage();
			exit(1);
			break;
		}
	}

	hdl = sio_open(SIO_DEVANY, SIO_REC, 0);
	if (hdl == NULL) {
		fprintf(stderr, "sio_open() failed\n");
		exit(1);
	}
	sio_onmove(hdl, cb, NULL);
	if (!sio_setpar(hdl, &par)) {
		fprintf(stderr, "sio_setpar() failed\n");
		exit(1);
	}
	if (!sio_getpar(hdl, &par)) {
		fprintf(stderr, "sio_getpar() failed\n");
		exit(1);
	}
	if (!sio_start(hdl)) {
		fprintf(stderr, "sio_start() failed\n");
		exit(1);
	}
	for (;;) {
		n = sio_read(hdl, buf, BUFSZ);
		if (n == 0) {
			fprintf(stderr, "sio_write: failed\n");
			exit(1);
		}
		rlat -= n / (int)(par.bps * par.rchan);
		if (write(STDOUT_FILENO, buf, n) < 0) {
			perror("stdout");
			exit(1);
		}
	}
	sio_close(hdl);
	return 0;
}
Beispiel #14
0
static int
sndio_init(int input, int voices)
{
	char tmp1[128], tmp2[128];

	if (input) {
		digi_driver->rec_cap_bits = 16;
		digi_driver->rec_cap_stereo = TRUE;
		return 0;
	}

	if (open_sndio_device(0) != 0)
		return -1;

	sndio_play_bufdata = _AL_MALLOC_ATOMIC(sndio_play_bufsize);
	if (sndio_play_bufdata == 0) {
		ustrzcpy(allegro_error, ALLEGRO_ERROR_SIZE,
		    get_config_text("Can not allocate audio buffer"));
		sio_close(hdl);
		return -1;
	}

	sndio_realpos = sndio_playpos = 0;
	sio_onmove(hdl, movecb, NULL);

	sndio_volume = 127;
	sio_onvol(hdl, volcb, NULL);

	if (!sio_start(hdl)) {
		ustrzcpy(allegro_error, ALLEGRO_ERROR_SIZE,
		    get_config_text("Can not start sndio"));
		sio_close(hdl);
		return -1;
	}

	digi_sndio.voices = voices;

	/* first arg is total number of samples */
	if (_mixer_init(sndio_play_round * (_sound_stereo ? 2 : 1),
	    _sound_freq, _sound_stereo, ((_sound_bits == 16) ? 1 : 0),
	    &digi_sndio.voices) != 0) {
		ustrzcpy(allegro_error, ALLEGRO_ERROR_SIZE,
		    get_config_text("Can not init software mixer"));
		sio_close(hdl);
		return -1;
	}

	_mix_some_samples((uintptr_t) sndio_play_bufdata, 0, sndio_signed);

	/* Add audio interrupt.  */
	_unix_bg_man->register_func(sndio_update);

	uszprintf(sndio_desc, sizeof(sndio_desc),
	    get_config_text("%s: %d bits, %s, %d Hz, %s"),
	    "sndio device",
	    _sound_bits,
	    uconvert_ascii((sndio_signed ? "signed" : "unsigned"), tmp1),
	    _sound_freq,
	    uconvert_ascii((par.pchan == 2 ? "stereo" : "mono"), tmp2));

	digi_driver->desc = sndio_desc;

	return 0;
}
Beispiel #15
0
/*
 * open the device.
 */
int
dev_sio_open(struct dev *d)
{
	struct sio_par par;
	unsigned int mode = d->mode & (MODE_PLAY | MODE_REC);

	d->sio.hdl = sio_open(d->path, mode, 1);
	if (d->sio.hdl == NULL) {
		if (mode != (SIO_PLAY | SIO_REC))
			return 0;
		d->sio.hdl = sio_open(d->path, SIO_PLAY, 1);
		if (d->sio.hdl != NULL)
			mode = SIO_PLAY;
		else {
			d->sio.hdl = sio_open(d->path, SIO_REC, 1);
			if (d->sio.hdl != NULL)
				mode = SIO_REC;
			else
				return 0;
		}
		if (log_level >= 1) {
			log_puts("warning, device opened in ");
			log_puts(mode == SIO_PLAY ? "play-only" : "rec-only");
			log_puts(" mode\n");
		}
	}
	sio_initpar(&par);
	par.bits = d->par.bits;
	par.bps = d->par.bps;
	par.sig = d->par.sig;
	par.le = d->par.le;
	par.msb = d->par.msb;
	if (mode & SIO_PLAY)
		par.pchan = d->pchan;
	if (mode & SIO_REC)
		par.rchan = d->rchan;
	if (d->bufsz)
		par.appbufsz = d->bufsz;
	if (d->round)
		par.round = d->round;
	if (d->rate)
		par.rate = d->rate;
	if (!sio_setpar(d->sio.hdl, &par))
		goto bad_close;
	if (!sio_getpar(d->sio.hdl, &par))
		goto bad_close;

#ifdef DEBUG
	/*
	 * We support any parameter combination exposed by the kernel,
	 * and we have no other choice than trusting the kernel for
	 * returning correct parameters. But let's check parameters
	 * early and nicely report kernel bugs rather than crashing
	 * later in memset(), malloc() or alike.
	 */

	if (par.bits > BITS_MAX) {
		log_puts(d->path);
		log_puts(": ");
		log_putu(par.bits);
		log_puts(": unsupported number of bits\n");
		goto bad_close;
	}
	if (par.bps > SIO_BPS(BITS_MAX)) {
		log_puts(d->path);
		log_puts(": ");
		log_putu(par.bps);
		log_puts(": unsupported sample size\n");
		goto bad_close;
	}
	if ((mode & SIO_PLAY) && par.pchan > NCHAN_MAX) {
		log_puts(d->path);
		log_puts(": ");
		log_putu(par.pchan);
		log_puts(": unsupported number of play channels\n");
		goto bad_close;
	}
	if ((mode & SIO_REC) && par.rchan > NCHAN_MAX) {
		log_puts(d->path);
		log_puts(": ");
		log_putu(par.rchan);
		log_puts(": unsupported number of rec channels\n");
		goto bad_close;
	}
	if (par.bufsz == 0 || par.bufsz > RATE_MAX) {
		log_puts(d->path);
		log_puts(": ");
		log_putu(par.bufsz);
		log_puts(": unsupported buffer size\n");
		goto bad_close;
	}
	if (par.round == 0 || par.round > par.bufsz ||
	    par.bufsz % par.round != 0) {
		log_puts(d->path);
		log_puts(": ");
		log_putu(par.round);
		log_puts(": unsupported block size\n");
		goto bad_close;
	}
	if (par.rate == 0 || par.rate > RATE_MAX) {
		log_puts(d->path);
		log_puts(": ");
		log_putu(par.rate);
		log_puts(": unsupported rate\n");
		goto bad_close;
	}
#endif

	d->par.bits = par.bits;
	d->par.bps = par.bps;
	d->par.sig = par.sig;
	d->par.le = par.le;
	d->par.msb = par.msb;
	if (mode & SIO_PLAY)
		d->pchan = par.pchan;
	if (mode & SIO_REC)
		d->rchan = par.rchan;
	d->bufsz = par.bufsz;
	d->round = par.round;
	d->rate = par.rate;
	if (!(mode & MODE_PLAY))
		d->mode &= ~(MODE_PLAY | MODE_MON);
	if (!(mode & MODE_REC))
		d->mode &= ~MODE_REC;
	sio_onmove(d->sio.hdl, dev_sio_onmove, d);
	d->sio.file = file_new(&dev_sio_ops, d, d->path, sio_nfds(d->sio.hdl));
	timo_set(&d->sio.watchdog, dev_sio_timeout, d);
	return 1;
 bad_close:
	sio_close(d->sio.hdl);
	return 0;
}
Beispiel #16
0
static int
op_open (AFormat fmt, int rate, int nch)
{
	struct sio_par askpar;

	pthread_mutex_lock (&mutex);

	hdl = sio_open (strlen (audiodev) > 0 ? audiodev : NULL, SIO_PLAY, 0);
	if (hdl == NULL) {
		fprintf (stderr, "%s: failed to open audio device\n", __func__);
		goto error;
	}

	sio_initpar (&par);
	afmt = fmt;
	switch (fmt) {
	case FMT_U8:
		par.bits = 8;
		par.sig = 0;
		break;
	case FMT_S8:
		par.bits = 8;
		par.sig = 1;
		break;
	case FMT_U16_LE:
		par.bits = 16;
		par.sig = 0;
		par.le = 1;
		break;
	case FMT_U16_BE:
		par.bits = 16;
		par.sig = 0;
		par.le = 0;
		break;
	case FMT_U16_NE:
		par.bits = 16;
		par.sig = 0;
		par.le = SIO_LE_NATIVE;
		break;
	case FMT_S16_LE:
		par.bits = 16;
		par.sig = 1;
		par.le = 1;
		break;
	case FMT_S16_BE:
		par.bits = 16;
		par.sig = 1;
		par.le = 0;
	case FMT_S16_NE:
		par.bits = 16;
		par.sig = 1;
		par.le = SIO_LE_NATIVE;
		break;
	default:
		fprintf (stderr, "%s: unknown format requested\n", __func__);
		goto error;
	}
	par.pchan = nch;
	par.rate = rate;

	/* 250 ms buffer */
	par.appbufsz = par.rate / 4;

	askpar = par;
	if (!sio_setpar (hdl, &par) || !sio_getpar (hdl, &par)) {
		fprintf (stderr, "%s: failed to set parameters\n", __func__);
		goto error;
	}

	if ((par.bits == 16 && par.le != askpar.le) ||
	    par.bits != askpar.bits ||
	    par.sig != askpar.sig ||
	    par.pchan != askpar.pchan ||
            par.rate != askpar.rate) {
		fprintf (stderr, "%s: parameters not supported\n", __func__);
		xmms_show_message ("Unsupported format", "XMMS requested a "
			"format that is not supported by the audio device.\n\n"
			"Please try again with the aucat(1) server running.",
			"OK", FALSE, NULL, NULL);
		goto error;
	}

	rdpos = 0;
	wrpos = 0;
	sio_onmove (hdl, onmove_cb, NULL);

	paused = 0;
	if (!sio_start (hdl)) {
		fprintf (stderr, "%s: failed to start audio device\n",
			__func__);
		goto error;
	}

	bytes_per_sec = par.bps * par.pchan * par.rate;
	pthread_mutex_unlock (&mutex);
	op_set_volume (volume, volume);
	return TRUE;

error:
	pthread_mutex_unlock (&mutex);
	op_close ();
	return FALSE;
}