172 lines · 3.8 KB · C
RawDownload
/* Pulse Audio sound handler * * Copyright 2008 Chris Bagwell And Sundry Contributors */ #include "sox_i.h" #include <pulse/simple.h>#include <pulse/error.h> typedef struct {  pa_simple *pasp;} priv_t; static int setup(sox_format_t *ft, int is_input){  priv_t *pa = (priv_t *)ft->priv;  char *server;  pa_stream_direction_t dir;  char *app_str;  char *dev;  pa_sample_spec spec;  int error;   /* TODO: If user specified device of type "server:dev" then   * break up and override server.   */  server = NULL;   if (is_input)  {    dir = PA_STREAM_RECORD;    app_str = "record";  }  else  {    dir = PA_STREAM_PLAYBACK;    app_str = "playback";  }   if (strncmp(ft->filename, "default", (size_t)7) == 0)    dev = NULL;  else    dev = ft->filename;   /* If user doesn't specify, default to some reasonable values.   * Since this is mainly for recording case, default to typical   * 16-bit values to prevent saving larger files then average user   * wants.  Power users can override to 32-bit if they wish.   */  if (ft->signal.channels == 0)    ft->signal.channels = 2;  if (ft->signal.rate == 0)    ft->signal.rate = 44100;  if (ft->encoding.bits_per_sample == 0)  {    ft->encoding.bits_per_sample = 16;    ft->encoding.encoding = SOX_ENCODING_SIGN2;  }   spec.format = PA_SAMPLE_S32NE;  spec.rate = ft->signal.rate;  spec.channels = ft->signal.channels;   pa->pasp = pa_simple_new(server, "SoX", dir, dev, app_str, &spec,                          NULL, NULL, &error);   if (pa->pasp == NULL)  {    lsx_fail_errno(ft, SOX_EPERM, "can not open audio device: %s", pa_strerror(error));    return SOX_EOF;  }   /* TODO: Is it better to convert format/rates in SoX or in   * always let Pulse Audio do it?  Since we don't know what   * hardware prefers, assume it knows best and give it   * what user specifies.   */   return SOX_SUCCESS;} static int startread(sox_format_t *ft){    return setup(ft, 1);} static int stopread(sox_format_t * ft){  priv_t *pa = (priv_t *)ft->priv;   pa_simple_free(pa->pasp);   return SOX_SUCCESS;} static size_t read_samples(sox_format_t *ft, sox_sample_t *buf, size_t nsamp){  priv_t *pa = (priv_t *)ft->priv;  size_t len;  int rc, error;   /* Pulse Audio buffer lengths are true buffer lengths and not   * count of samples. */  len = nsamp * sizeof(sox_sample_t);   rc = pa_simple_read(pa->pasp, buf, len, &error);   if (rc < 0)  {    lsx_fail_errno(ft, SOX_EPERM, "error reading from pulse audio device: %s", pa_strerror(error));    return SOX_EOF;  }  else    return nsamp;} static int startwrite(sox_format_t * ft){    return setup(ft, 0);} static size_t write_samples(sox_format_t *ft, const sox_sample_t *buf, size_t nsamp){  priv_t *pa = (priv_t *)ft->priv;  size_t len;  int rc, error;   if (!nsamp)    return 0;   /* Pulse Audio buffer lengths are true buffer lengths and not   * count of samples. */  len = nsamp * sizeof(sox_sample_t);   rc = pa_simple_write(pa->pasp, buf, len, &error);   if (rc < 0)  {    lsx_fail_errno(ft, SOX_EPERM, "error writing to pulse audio device: %s", pa_strerror(error));    return SOX_EOF;  }   return nsamp;} static int stopwrite(sox_format_t * ft){  priv_t *pa = (priv_t *)ft->priv;  int error;   pa_simple_drain(pa->pasp, &error);  pa_simple_free(pa->pasp);   return SOX_SUCCESS;} LSX_FORMAT_HANDLER(pulseaudio){  static char const *const names[] = { "pulseaudio", NULL };  static unsigned const write_encodings[] = {    SOX_ENCODING_SIGN2, 32, 0,    0};  static sox_format_handler_t const handler = {SOX_LIB_VERSION_CODE,    "Pulse Audio client",    names, SOX_FILE_DEVICE | SOX_FILE_NOSTDIO,    startread, read_samples, stopread,    startwrite, write_samples, stopwrite,    NULL, write_encodings, NULL, sizeof(priv_t)  };  return &handler;}

Keyboard shortcuts

General

Show keyboard shortcuts
?
Focus the current search
/

Issues and pull requests

Open filters
f

Issues, pull requests and Inbox

Select next item
j↓
Select previous item
k↑
Open selected item
Enter
Dismiss filters or clear selection
Esc

Repository code

Go to file
t