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; }
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; }
/* 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); }
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; }
/* * 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; }
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; }
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; }
/* * 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; }
/* * 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; }
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; }
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); }
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; }
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; }
/* * 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; }
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; }