int sio_start(struct sio_hdl *hdl) { #ifdef DEBUG struct timespec ts; #endif if (hdl->eof) { DPRINTF("sio_start: eof\n"); return 0; } if (hdl->started) { DPRINTF("sio_start: already started\n"); hdl->eof = 1; return 0; } hdl->cpos = 0; hdl->rused = hdl->wused = 0; if (!sio_getpar(hdl, &hdl->par)) return 0; #ifdef DEBUG hdl->pollcnt = 0; clock_gettime(CLOCK_MONOTONIC, &ts); hdl->start_nsec = 1000000000LL * ts.tv_sec + ts.tv_nsec; #endif hdl->rdrop = hdl->wsil = 0; if (!hdl->ops->start(hdl)) return 0; hdl->started = 1; return 1; }
int ai_sndio_setup(audio_in_t *ai) { struct sio_par par; sio_initpar(&par); par.bits = 16; par.sig = 1; par.le = 1; par.rchan = ai->req_channels; par.rate = ai->req_samplerate; par.appbufsz = ai->req_samplerate; /* 1 sec */ if (!sio_setpar(ai->sndio.hdl, &par) || !sio_getpar(ai->sndio.hdl, &par)) { mp_msg(MSGT_TV, MSGL_ERR, "could not configure sndio audio"); return -1; } ai->channels = par.rchan; ai->samplerate = par.rate; ai->samplesize = par.bits; ai->bytes_per_sample = par.bps; ai->blocksize = par.round * par.bps; return 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; }
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; }
static int sndio_set_sf(sample_format_t sf) { struct sio_par apar; sndio_sf = sf; sio_initpar(&par); par.pchan = sf_get_channels(sndio_sf); par.rate = sf_get_rate(sndio_sf); sndio_paused = 0; if (sf_get_signed(sndio_sf)) par.sig = 1; else par.sig = 0; if (sf_get_bigendian(sndio_sf)) par.le = 0; else par.le = 1; switch (sf_get_bits(sndio_sf)) { case 16: par.bits = 16; break; case 8: par.bits = 8; break; default: return -OP_ERROR_SAMPLE_FORMAT; } par.appbufsz = par.rate * 300 / 1000; apar = par; if (!sio_setpar(hdl, &par)) return -OP_ERROR_INTERNAL; if (!sio_getpar(hdl, &par)) return -OP_ERROR_INTERNAL; if (apar.rate != par.rate || apar.pchan != par.pchan || apar.bits != par.bits || (par.bits > 8 && apar.le != par.le) || apar.sig != par.sig) return -OP_ERROR_INTERNAL; sndio_mixer_set_volume(sndio_volume, sndio_volume); if (!sio_start(hdl)) return -OP_ERROR_INTERNAL; return OP_ERROR_SUCCESS; }
/* used to probe and to configure the device. don't use sio_start() here. */ static int open_sndio_device(int input) { hdl = sio_open(NULL, (input ? SIO_REC : SIO_PLAY), 0); if (hdl == NULL) { uszprintf(allegro_error, ALLEGRO_ERROR_SIZE, get_config_text("sio_opn failed")); return -1; } sio_initpar(&par); par.bits = (_sound_bits == 8) ? 8 : 16; par.sig = (_sound_bits == 8) ? 0 : 1; if (input) par.rchan = (_sound_stereo) ? 2 : 1; else par.pchan = (_sound_stereo) ? 2 : 1; par.rate = (_sound_freq > 0) ? _sound_freq : 48000; par.le = SIO_LE_NATIVE; /* allegro wants small blocks */ par.round = 512; par.appbufsz = par.rate / 10; if (!sio_setpar(hdl, &par) || !sio_getpar(hdl, &par) || (par.bits != 8 && par.bits != 16) || (par.bits == 8 && par.sig) || (par.bits == 16 && !par.sig) || (par.bits == 16 && par.le != SIO_LE_NATIVE) || (input && (par.rchan != 1 && par.rchan != 2)) || (!input && (par.pchan != 1 && par.pchan != 2))) { ustrzcpy(allegro_error, ALLEGRO_ERROR_SIZE, get_config_text("could not set sndio parameters")); sio_close(hdl); return -1; } _sound_bits = par.bits; _sound_stereo = input ? par.rchan == 2 : par.pchan == 2; _sound_freq = par.rate; if (input) { sndio_rec_round = par.round; sndio_rec_appbufsz = par.appbufsz; sndio_rec_bufsize = par.round * par.bps * par.rchan; } else { sndio_play_round = par.round; sndio_play_appbufsz = par.appbufsz; sndio_play_bufsize = sndio_play_round * par.bps * par.pchan; } sndio_signed = par.sig ? 1 : 0; return 0; }
static int open_output(void) { static struct sio_par par, newpar; sndio_ctx = sio_open(NULL, SIO_PLAY, 0); if (sndio_ctx == NULL) { ctl->cmsg(CMSG_ERROR, VERB_NORMAL, "sio_open() failed"); return -1; } sio_initpar(&par); par.sig = 1; par.pchan = (dpm.encoding & PE_MONO) ? 1 : 2; par.le = SIO_LE_NATIVE; par.rate = dpm.rate; if (dpm.encoding & PE_24BIT) { par.bits = 24; par.bps = 3; } else if (dpm.encoding & PE_16BIT) { par.bits = 16; par.bps = 2; } else { par.bits = 8; par.bps = 1; } if (!sio_setpar(sndio_ctx, &par)) { ctl->cmsg(CMSG_ERROR, VERB_NORMAL, "sio_setpar() failed"); return -1; } if (sio_getpar(sndio_ctx, &newpar) == 0) { ctl->cmsg(CMSG_ERROR, VERB_NORMAL, "sio_getpar() failed"); return -1; } if (newpar.sig != par.sig || newpar.le != par.le || newpar.pchan != par.pchan || newpar.bits != par.bits || newpar.bps != par.bps || newpar.rate * 1000 > par.rate * 1005 || newpar.rate * 1000 < par.rate * 995) { ctl->cmsg(CMSG_ERROR, VERB_NORMAL, "couldn't set output play parameters"); return -1; } if (!sio_start(sndio_ctx)) { ctl->cmsg(CMSG_ERROR, VERB_NORMAL, "sio_start() failed"); return -1; } return 0; }
int audio_init(int argc, char *argv[]) { int rate_set = 0; int use_audio = 1; prog = argv[0]; argc = getargs("OpenBSD Audio",argc, argv, "r", "%d", &rate_set, "Sample rate", "a", NULL, &use_audio, "Audio enable", NULL); if (help_only) return argc; if (rate_set) samp_rate = rate_set; if (!use_audio) return argc; audio_open(); sio_initpar(&par); par.bits = 16; par.sig = 1; par.rate = samp_rate; par.pchan = 1; if (!sio_setpar(hdl, &par) || !sio_getpar(hdl, &par)) { fprintf(stderr, "error setting sndio parameters\n"); hdl = NULL; } else { if (par.bits != 16 || par.sig != 1 || par.pchan != 1 || par.rate != samp_rate) { fprintf(stderr, "returned incorrect sndio parameters\n"); hdl = NULL; } } if (hdl && !sio_start(hdl)) { fprintf(stderr, "error starting sndio\n"); hdl = NULL; } return argc; }
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); }
static void sndio_play (int argc, char *argv []) { struct sio_hdl *hdl ; struct sio_par par ; short buffer [BUFFER_LEN] ; SNDFILE *sndfile ; SF_INFO sfinfo ; int k, readcount ; for (k = 1 ; k < argc ; k++) { printf ("Playing %s\n", argv [k]) ; if (! (sndfile = sf_open (argv [k], SFM_READ, &sfinfo))) { puts (sf_strerror (NULL)) ; continue ; } ; if (sfinfo.channels < 1 || sfinfo.channels > 2) { printf ("Error : channels = %d.\n", sfinfo.channels) ; continue ; } ; if ((hdl = sio_open (NULL, SIO_PLAY, 0)) == NULL) { fprintf (stderr, "open sndio device failed") ; return ; } ; sio_initpar (&par) ; par.rate = sfinfo.samplerate ; par.pchan = sfinfo.channels ; par.bits = 16 ; par.sig = 1 ; par.le = SIO_LE_NATIVE ; if (! sio_setpar (hdl, &par) || ! sio_getpar (hdl, &par)) { fprintf (stderr, "set sndio params failed") ; return ; } ; if (! sio_start (hdl)) { fprintf (stderr, "sndio start failed") ; return ; } ; while ((readcount = sf_read_short (sndfile, buffer, BUFFER_LEN))) sio_write (hdl, buffer, readcount * sizeof (short)) ; sio_close (hdl) ; } ; return ; } /* sndio_play */
int SndioSink::setAudioConfiguration(const AudioConfiguration* config) { d->config = *config; if (d->valid) sio_stop(d->hdl); sio_initpar(&d->par); if (config->sample_width < 0) { d->par.bits = 16; d->par.sig = 1; } else { d->par.bits = config->sample_width; if (d->par.bits == 8) d->par.sig = 0; else d->par.sig = 1; } d->par.pchan = config->channels; d->par.rate = config->sample_rate; if (!sio_setpar(d->hdl, &d->par)) { d->valid = false; return -1; } if (!sio_getpar(d->hdl, &d->par)) { d->valid = false; return -1; } d->config.sample_width = d->par.bits; d->config.sample_rate = d->par.rate; d->config.channels = d->par.pchan; if (d->config.channels <= 2) d->config.channel_config = MonoStereo; if (!sio_start(d->hdl)) { std::cerr << "akode: could not restart sndio device\n"; d->valid = false; return -1; } if (d->config == *config) return 0; else return 1; }
static int init (struct xmp_context *ctx) { struct sio_par par, askpar; struct xmp_options *opt = &ctx->o; hdl = sio_open (NULL, SIO_PLAY, 0); if (hdl == NULL) { fprintf (stderr, "%s: failed to open audio device\n", __func__); return XMP_ERR_DINIT; } sio_initpar (&par); par.pchan = opt->outfmt & XMP_FMT_MONO ? 1 : 2; par.rate = opt->freq; par.bits = opt->resol; par.sig = opt->resol > 8 ? 1 : 0; par.le = SIO_LE_NATIVE; 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 * 1000 < askpar.rate * 995) || (par.rate * 1000 > askpar.rate * 1005))) { fprintf (stderr, "%s: parameters not supported\n", __func__); goto error; } if (!sio_start (hdl)) { fprintf (stderr, "%s: failed to start audio device\n", __func__); goto error; } return xmp_smix_on (ctx); error: sio_close (hdl); return XMP_ERR_DINIT; }
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; }
static int init(int argc, char **argv) { sio = sio_open(SIO_DEVANY, SIO_PLAY, 0); if (!sio) die("sndio: cannot connect to sound server"); sio_initpar(&par); par.bits = 16; par.rate = 44100; par.pchan = 2; par.le = SIO_LE_NATIVE; par.sig = 1; if (!sio_setpar(sio, &par)) die("sndio: failed to set audio parameters"); if (!sio_getpar(sio, &par)) die("sndio: failed to get audio parameters"); return 0; }
void audioInit(int sampleSize, int frequency, int stereo, int sign, int big) { sio_initpar(&par); par.bits = sampleSize; par.sig = sign ? 1 : 0; par.le = big ? 0 : 1; par.rate = frequency; par.pchan = stereo ? 2 : 1; if (!sio_setpar(hdl, &par) || !sio_getpar(hdl, &par)) fprintf(stderr, "error setting sndio parameters\n"); if (par.bits != sampleSize || par.sig != sign ? 1 : 0 || par.le != big ? 0 : 1 || par.rate != frequency || par.pchan != stereo ? 2 : 1) fprintf(stderr, "could not set requested audio parameters"); if (!sio_start(hdl)) fprintf(stderr, "could not start audio"); }
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 play_alloc(struct auplay_st **stp, const struct auplay *ap, struct auplay_prm *prm, const char *device, auplay_write_h *wh, void *arg) { struct auplay_st *st; struct sio_par *par = NULL; int err; const char *name; if (!stp || !ap || !prm) return EINVAL; name = (str_isset(device)) ? device : SIO_DEVANY; if ((st = mem_zalloc(sizeof(*st), auplay_destructor)) == NULL) return ENOMEM; st->ap = ap; st->wh = wh; st->arg = arg; st->hdl = sio_open(name, SIO_PLAY, 0); if (!st->hdl) { warning("sndio: could not open auplay device '%s'\n", name); err = EINVAL; goto out; } par = sndio_initpar(prm->srate, prm->ch); if (!par) { err = ENOMEM; goto out; } if (!sio_setpar(st->hdl, par)) { err = EINVAL; goto out; } if (!sio_getpar(st->hdl, par)) { err = EINVAL; goto out; } st->sampc = prm->srate * prm->ch * prm->ptime / 1000; st->sampv = mem_alloc(2 * st->sampc, NULL); if (!st->sampv) { err = ENOMEM; goto out; } st->run = true; err = pthread_create(&st->thread, NULL, write_thread, st); if (err) st->run = false; out: mem_deref(par); if (err) mem_deref(st); else *stp = st; return err; }
static int src_alloc(struct ausrc_st **stp, const struct ausrc *as, struct media_ctx **ctx, struct ausrc_prm *prm, const char *device, ausrc_read_h *rh, ausrc_error_h *errh, void *arg) { struct ausrc_st *st; struct sio_par *par = NULL; int err; const char *name; (void)ctx; (void)errh; if (!stp || !as || !prm) return EINVAL; name = (str_isset(device)) ? device : SIO_DEVANY; if ((st = mem_zalloc(sizeof(*st), ausrc_destructor)) == NULL) return ENOMEM; st->as = as; st->rh = rh; st->arg = arg; st->hdl = sio_open(name, SIO_REC, 0); if (!st->hdl) { warning("sndio: could not open ausrc device '%s'\n", name); err = EINVAL; goto out; } par = sndio_initpar(prm->srate, prm->ch); if (!par) { err = ENOMEM; goto out; } if (!sio_setpar(st->hdl, par)) { err = EINVAL; goto out; } if (!sio_getpar(st->hdl, par)) { err = EINVAL; goto out; } st->sampc = par->bufsz / 2; st->sampv = mem_alloc(2 * st->sampc, NULL); if (!st->sampv) { err = ENOMEM; goto out; } st->run = true; err = pthread_create(&st->thread, NULL, read_thread, st); if (err) st->run = false; out: mem_deref(par); if (err) mem_deref(st); else *stp = st; return err; }
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; }
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); }
AudioSndio::AudioSndio(bool & _success_ful, Mixer * _mixer) : AudioDevice( tLimit<ch_cnt_t>( ConfigManager::inst()->value( "audiosndio", "channels" ).toInt(), DEFAULT_CHANNELS, SURROUND_CHANNELS ), _mixer ) { _success_ful = FALSE; QString dev = ConfigManager::inst()->value( "audiosndio", "device" ); if (dev == "") { m_hdl = sio_open( NULL, SIO_PLAY, 0 ); } else { m_hdl = sio_open( dev.toAscii().data(), SIO_PLAY, 0 ); } if( m_hdl == NULL ) { printf( "sndio: failed opening audio-device\n" ); return; } sio_initpar(&m_par); m_par.pchan = channels(); m_par.bits = 16; m_par.le = SIO_LE_NATIVE; m_par.rate = sampleRate(); m_par.round = mixer()->framesPerPeriod(); m_par.appbufsz = m_par.round * 2; struct sio_par reqpar = m_par; if (!sio_setpar(m_hdl, &m_par)) { printf( "sndio: sio_setpar failed\n" ); return; } if (!sio_getpar(m_hdl, &m_par)) { printf( "sndio: sio_getpar failed\n" ); return; } if (reqpar.pchan != m_par.pchan || reqpar.bits != m_par.bits || reqpar.le != m_par.le || (abs(reqpar.rate - m_par.rate) * 100)/reqpar.rate > 2) { printf( "sndio: returned params not as requested\n" ); return; } if (!sio_start(m_hdl)) { printf( "sndio: sio_start failed\n" ); return; } _success_ful = TRUE; }
input_module_t *sndio_open_module(module_param_t *params) { input_module_t *mod = calloc(1, sizeof(input_module_t)); im_sndio_state *s; module_param_t *current; char *device = NULL; /* default device */ int sample_rate = 44100; int channels = 2; int use_metadata = 1; /* Default to on */ mod->type = ICES_INPUT_PCM; #ifdef WORDS_BIGENDIAN mod->subtype = INPUT_PCM_BE_16; #else mod->subtype = INPUT_PCM_LE_16; #endif mod->getdata = sndio_read; mod->handle_event = event_handler; mod->metadata_update = metadata_update; mod->internal = calloc(1, sizeof(im_sndio_state)); s = mod->internal; thread_mutex_create(&s->metadatalock); current = params; while (current) { if (!strcmp(current->name, "rate")) sample_rate = atoi(current->value); else if (!strcmp(current->name, "channels")) channels = atoi(current->value); else if (!strcmp(current->name, "device")) device = current->value; else if (!strcmp(current->name, "metadata")) use_metadata = atoi(current->value); else if(!strcmp(current->name, "metadatafilename")) ices_config->metadata_filename = current->value; else LOG_WARN1("Unknown parameter %s for sndio module", current->name); current = current->next; } /* First up, lets open the audio device */ if((s->hdl = sio_open(device, SIO_REC, 0)) == NULL) { LOG_ERROR0("Failed to open sndio device"); goto fail; } /* Try and set up what we want */ sio_initpar(&s->par); s->par.rate = sample_rate; s->par.rchan = channels; s->par.bits = 16; s->par.sig = 1; s->par.le = SIO_LE_NATIVE; s->par.round = BUFSIZE; s->par.appbufsz = BUFSIZE * 4; if (!sio_setpar(s->hdl, &s->par) || !sio_getpar(s->hdl, &s->par)) { LOG_ERROR0("Failed to configure sndio device"); goto fail; } /* Check all went according to plan */ if (s->par.rate != sample_rate) { LOG_ERROR0("Couldn't set sampling rate"); goto fail; } if (s->par.rchan != channels) { LOG_ERROR0("Couldn't set number of channels"); goto fail; } if (s->par.bits != 16) { LOG_ERROR0("Couldn't set 16 bit precision"); goto fail; } if (s->par.sig != 1) { LOG_ERROR0("Couldn't set signed linear encoding"); goto fail; } if (s->par.le != SIO_LE_NATIVE) { LOG_ERROR0("Couldn't set proper endianness"); goto fail; } if (!sio_start(s->hdl)) { LOG_ERROR0("Couldn't start sndio"); goto fail; } /* We're done, and we didn't fail! */ LOG_INFO2("Opened audio device for %d channel(s), %d Hz", channels, sample_rate); if(use_metadata) { LOG_INFO0("Starting metadata update thread"); if(ices_config->metadata_filename) thread_create("im_sndio-metadata", metadata_thread_signal, mod, 1); else thread_create("im_sndio-metadata", metadata_thread_stdin, mod, 1); } return mod; fail: close_module(mod); /* safe, this checks for valid contents */ return NULL; }
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 gboolean sndio_open(void *dp) { sndio_in_driver *d = dp; char buf[256]; sio_initpar(&d->par); d->hdl = sio_open(NULL, SIO_REC, 0); if (d->hdl == NULL) { snprintf(buf, sizeof(buf), "can't open sndio rec device"); goto out; } d->par.rate = 44100; d->par.bits = 16; d->par.rchan = 1; d->par.appbufsz = 2048; if (!sio_setpar(d->hdl, &d->par) || !sio_getpar(d->hdl, &d->par)) { snprintf(buf, sizeof(buf), "can't configure sndio device"); goto out; } if (d->par.bits == 16) { if (d->par.sig) { if (d->par.le) d->mf = ST_MIXER_FORMAT_S16_LE; else d->mf = ST_MIXER_FORMAT_S16_BE; } else { if (d->par.le) d->mf = ST_MIXER_FORMAT_U16_LE; else d->mf = ST_MIXER_FORMAT_U16_BE; } } else if (d->par.bits == 8) { if (d->par.sig) d->mf = ST_MIXER_FORMAT_S8; else d->mf = ST_MIXER_FORMAT_U8; } else { snprintf(buf, sizeof(buf), "invalid sndio bit-depth"); goto out; } if (d->par.rchan == 2) { d->mf |= ST_MIXER_FORMAT_STEREO; } else if (d->par.rchan != 1) { snprintf(buf, sizeof(buf), "invalid sndio channel count"); goto out; } d->bufsize = d->par.round; d->sndbuf = calloc(1, d->bufsize * d->par.bps * d->par.rchan); d->read_trun = 1; if (pthread_create(&d->read_tid, NULL, read_thread, d)) { snprintf(buf, sizeof(buf), "couldn't spawn reading thread"); goto out; } return TRUE; out: error_error(buf); sndio_release(dp); return FALSE; }
static ALCboolean sndio_reset_playback(ALCdevice *device) { sndio_data *data = device->ExtraData; struct sio_par par; sio_initpar(&par); par.rate = device->Frequency; par.pchan = ((device->FmtChans != DevFmtMono) ? 2 : 1); switch(device->FmtType) { case DevFmtByte: par.bits = 8; par.sig = 1; break; case DevFmtUByte: par.bits = 8; par.sig = 0; break; case DevFmtFloat: case DevFmtShort: par.bits = 16; par.sig = 1; break; case DevFmtUShort: par.bits = 16; par.sig = 0; break; case DevFmtInt: par.bits = 32; par.sig = 1; break; case DevFmtUInt: par.bits = 32; par.sig = 0; break; } par.le = SIO_LE_NATIVE; par.round = device->UpdateSize; par.appbufsz = device->UpdateSize * (device->NumUpdates-1); if(!par.appbufsz) par.appbufsz = device->UpdateSize; if(!sio_setpar(data->sndHandle, &par) || !sio_getpar(data->sndHandle, &par)) { ERR("Failed to set device parameters\n"); return ALC_FALSE; } if(par.bits != par.bps*8) { ERR("Padded samples not supported (%u of %u bits)\n", par.bits, par.bps*8); return ALC_FALSE; } device->Frequency = par.rate; device->FmtChans = ((par.pchan==1) ? DevFmtMono : DevFmtStereo); if(par.bits == 8 && par.sig == 1) device->FmtType = DevFmtByte; else if(par.bits == 8 && par.sig == 0) device->FmtType = DevFmtUByte; else if(par.bits == 16 && par.sig == 1) device->FmtType = DevFmtShort; else if(par.bits == 16 && par.sig == 0) device->FmtType = DevFmtUShort; else if(par.bits == 32 && par.sig == 1) device->FmtType = DevFmtInt; else if(par.bits == 32 && par.sig == 0) device->FmtType = DevFmtUInt; else { ERR("Unhandled sample format: %s %u-bit\n", (par.sig?"signed":"unsigned"), par.bits); return ALC_FALSE; } device->UpdateSize = par.round; device->NumUpdates = (par.bufsz/par.round) + 1; SetDefaultChannelOrder(device); return ALC_TRUE; }
/* * 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; }
/* * 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; }
/* * 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; }
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; }
FILE *out_file_open(char *outFile, int *wav_format, int rate, int mapping_family, int *channels) { FILE *fout=NULL; /*Open output file*/ if (strlen(outFile)==0) { #if defined HAVE_SYS_SOUNDCARD_H int audio_fd, format, stereo; audio_fd=open("/dev/dsp", O_WRONLY); if (audio_fd<0) { perror("Cannot open /dev/dsp"); quit(1); } format=AFMT_S16_NE; if (ioctl(audio_fd, SNDCTL_DSP_SETFMT, &format)==-1) { perror("SNDCTL_DSP_SETFMT"); close(audio_fd); quit(1); } stereo=0; if (*channels==2) stereo=1; if (ioctl(audio_fd, SNDCTL_DSP_STEREO, &stereo)==-1) { perror("SNDCTL_DSP_STEREO"); close(audio_fd); quit(1); } if (stereo!=0) { if (*channels==1) fprintf (stderr, "Cannot set mono mode, will decode in stereo\n"); *channels=2; } if (ioctl(audio_fd, SNDCTL_DSP_SPEED, &rate)==-1) { perror("SNDCTL_DSP_SPEED"); close(audio_fd); quit(1); } fout = fdopen(audio_fd, "w"); if(!fout) { perror("Cannot open output"); quit(1); } #elif defined HAVE_LIBSNDIO struct sio_par par; hdl = sio_open(NULL, SIO_PLAY, 0); if (!hdl) { fprintf(stderr, "Cannot open sndio device\n"); quit(1); } sio_initpar(&par); par.sig = 1; par.bits = 16; par.rate = rate; par.pchan = *channels; if (!sio_setpar(hdl, &par) || !sio_getpar(hdl, &par) || par.sig != 1 || par.bits != 16 || par.rate != rate) { fprintf(stderr, "could not set sndio parameters\n"); quit(1); } *channels = par.pchan; if (!sio_start(hdl)) { fprintf(stderr, "could not start sndio\n"); quit(1); } #elif defined HAVE_SYS_AUDIOIO_H audio_info_t info; int audio_fd; audio_fd = open("/dev/audio", O_WRONLY); if (audio_fd<0) { perror("Cannot open /dev/audio"); quit(1); } AUDIO_INITINFO(&info); #ifdef AUMODE_PLAY /* NetBSD/OpenBSD */ info.mode = AUMODE_PLAY; #endif info.play.encoding = AUDIO_ENCODING_SLINEAR; info.play.precision = 16; info.play.input_sample_rate = rate; info.play.channels = *channels; if (ioctl(audio_fd, AUDIO_SETINFO, &info) < 0) { perror ("AUDIO_SETINFO"); quit(1); } fout = fdopen(audio_fd, "w"); if(!fout) { perror("Cannot open output"); quit(1); } #elif defined WIN32 || defined _WIN32 { unsigned int opus_channels = *channels; if (Set_WIN_Params (INVALID_FILEDESC, rate, SAMPLE_SIZE, opus_channels)) { fprintf (stderr, "Can't access %s\n", "WAVE OUT"); quit(1); } } #else fprintf (stderr, "No soundcard support\n"); quit(1); #endif } else { if (strcmp(outFile,"-")==0) { #if defined WIN32 || defined _WIN32 _setmode(_fileno(stdout), _O_BINARY); #endif fout=stdout; } else { fout = fopen_utf8(outFile, "wb"); if (!fout) { perror(outFile); quit(1); } if (*wav_format) { *wav_format = write_wav_header(fout, rate, mapping_family, *channels); if (*wav_format < 0) { fprintf (stderr, "Error writing WAV header.\n"); quit(1); } } } } return fout; }