diff options
| -rw-r--r-- | doc/todo | 1 | ||||
| -rw-r--r-- | polyp/modargs.c | 23 | ||||
| -rw-r--r-- | polyp/pacat.c | 53 | ||||
| -rw-r--r-- | polyp/sample.c | 29 | ||||
| -rw-r--r-- | polyp/sample.h | 6 | 
5 files changed, 76 insertions, 36 deletions
@@ -7,7 +7,6 @@  - make mcalign merge chunks  - option to use default fragment size on alsa drivers  - improve module-oss-mmap latency measurement -- pacat sample type args  - filter capture data in client through alignment  - add radio module  - make autoload list use idxset diff --git a/polyp/modargs.c b/polyp/modargs.c index e1c2c9b8..d58b391b 100644 --- a/polyp/modargs.c +++ b/polyp/modargs.c @@ -263,28 +263,9 @@ int pa_modargs_get_sample_spec(struct pa_modargs *ma, struct pa_sample_spec *rss          return -1;      ss.channels = (uint8_t) channels; -    if ((format = pa_modargs_get_value(ma, "format", NULL))) { -        if (strcmp(format, "s16le") == 0) -            ss.format = PA_SAMPLE_S16LE; -        else if (strcmp(format, "s16be") == 0) -            ss.format = PA_SAMPLE_S16BE; -        else if (strcmp(format, "s16ne") == 0 || strcmp(format, "s16") == 0 || strcmp(format, "16") == 0) -            ss.format = PA_SAMPLE_S16NE; -        else if (strcmp(format, "u8") == 0 || strcmp(format, "8") == 0) -            ss.format = PA_SAMPLE_U8; -        else if (strcmp(format, "float32") == 0 || strcmp(format, "float32ne") == 0) -            ss.format = PA_SAMPLE_FLOAT32; -        else if (strcmp(format, "float32le") == 0) -            ss.format = PA_SAMPLE_FLOAT32LE; -        else if (strcmp(format, "float32be") == 0) -            ss.format = PA_SAMPLE_FLOAT32BE; -        else if (strcmp(format, "ulaw") == 0) -            ss.format = PA_SAMPLE_ULAW; -        else if (strcmp(format, "alaw") == 0) -            ss.format = PA_SAMPLE_ALAW; -        else +    if ((format = pa_modargs_get_value(ma, "format", NULL))) +        if ((ss.format = pa_parse_sample_format(format)) < 0)              return -1; -    }      if (!pa_sample_spec_valid(&ss))          return -1; diff --git a/polyp/pacat.c b/polyp/pacat.c index 67242b26..a2687116 100644 --- a/polyp/pacat.c +++ b/polyp/pacat.c @@ -58,6 +58,12 @@ static char *stream_name = NULL, *client_name = NULL, *device = NULL;  static int verbose = 0;  static pa_volume_t volume = PA_VOLUME_NORM; +static struct pa_sample_spec sample_spec = { +    .format = PA_SAMPLE_S16LE, +    .rate = 44100, +    .channels = 2 +}; +  /* A shortcut for terminating the application */  static void quit(int ret) {      assert(mainloop_api); @@ -141,12 +147,6 @@ static void stream_state_callback(struct pa_stream *s, void *userdata) {  /* This is called whenever the context status changes */  static void context_state_callback(struct pa_context *c, void *userdata) { -    static const struct pa_sample_spec ss = { -        .format = PA_SAMPLE_S16LE, -        .rate = 44100, -        .channels = 2 -    }; -      assert(c);      switch (pa_context_get_state(c)) { @@ -162,7 +162,7 @@ static void context_state_callback(struct pa_context *c, void *userdata) {              if (verbose)                  fprintf(stderr, "Connection established.\n"); -            stream = pa_stream_new(c, stream_name, &ss); +            stream = pa_stream_new(c, stream_name, &sample_spec);              assert(stream);              pa_stream_set_state_callback(stream, stream_state_callback, NULL); @@ -335,14 +335,22 @@ static void help(const char *argv0) {             "  -d, --device=DEVICE                   The name of the sink/source to connect to\n"             "  -n, --client-name=NAME                How to call this client on the server\n"             "      --stream-name=NAME                How to call this stream on the server\n" -           "      --volume=VOLUME                   Specify the initial (linear) volume in range 0...256\n", +           "      --volume=VOLUME                   Specify the initial (linear) volume in range 0...256\n" +           "      --rate=SAMPLERATE                 The sample rate in Hz (defaults to 44100)\n" +           "      --format=SAMPLEFORMAT             The sample type, one of s16le, s16be, u8, float32le,\n" +           "                                        float32be, ulaw, alaw (defaults to s16ne)\n" +           "      --channels=CHANNELS               The number of channels, 1 for mono, 2 for stereo\n" +           "                                        (defaults to 2)\n",             argv0);  }  enum {      ARG_VERSION = 256,      ARG_STREAM_NAME, -    ARG_VOLUME +    ARG_VOLUME, +    ARG_SAMPLERATE, +    ARG_SAMPLEFORMAT, +    ARG_CHANNELS  };  int main(int argc, char *argv[]) { @@ -361,6 +369,9 @@ int main(int argc, char *argv[]) {          {"help",        0, NULL, 'h'},          {"verbose",     0, NULL, 'v'},          {"volume",      1, NULL, ARG_VOLUME}, +        {"rate",        1, NULL, ARG_SAMPLERATE}, +        {"format",      1, NULL, ARG_SAMPLEFORMAT}, +        {"channels",    1, NULL, ARG_CHANNELS},          {NULL,          0, NULL, 0}      }; @@ -425,6 +436,18 @@ int main(int argc, char *argv[]) {                  break;              } +            case ARG_CHANNELS:  +                sample_spec.channels = atoi(optarg); +                break; + +            case ARG_SAMPLEFORMAT: +                sample_spec.format = pa_parse_sample_format(optarg); +                break; + +            case ARG_SAMPLERATE: +                sample_spec.rate = atoi(optarg); +                break; +              default:                  goto quit;          } @@ -435,9 +458,17 @@ int main(int argc, char *argv[]) {      if (!stream_name)          stream_name = strdup(client_name); + +    if (!pa_sample_spec_valid(&sample_spec)) { +        fprintf(stderr, "Invalid sample specification\n"); +        goto quit; +    } -    if (verbose) -        fprintf(stderr, "Opening a %s stream.\n", mode == RECORD ? "recording" : "playback"); +    if (verbose) { +        char t[PA_SAMPLE_SPEC_SNPRINT_MAX]; +        pa_sample_spec_snprint(t, sizeof(t), &sample_spec); +        fprintf(stderr, "Opening a %s stream with sample specification '%s'.\n", mode == RECORD ? "recording" : "playback", t); +    }      /* Set up a new main loop */      if (!(m = pa_mainloop_new())) { diff --git a/polyp/sample.c b/polyp/sample.c index 65ae8ff3..8c30386b 100644 --- a/polyp/sample.c +++ b/polyp/sample.c @@ -26,6 +26,7 @@  #include <stdio.h>  #include <assert.h>  #include <math.h> +#include <string.h>  #include "sample.h" @@ -68,10 +69,10 @@ pa_usec_t pa_bytes_to_usec(uint64_t length, const struct pa_sample_spec *spec) {  int pa_sample_spec_valid(const struct pa_sample_spec *spec) {      assert(spec); -    if (!spec->rate || !spec->channels) +    if (spec->rate <= 0 || spec->channels <= 0)          return 0; -    if (spec->format >= PA_SAMPLE_MAX) +    if (spec->format >= PA_SAMPLE_MAX || spec->format < 0)          return 0;      return 1; @@ -134,3 +135,27 @@ void pa_bytes_snprint(char *s, size_t l, unsigned v) {      else          snprintf(s, l, "%u B", (unsigned) v);  } + +enum pa_sample_format pa_parse_sample_format(const char *format) { +     +    if (strcmp(format, "s16le") == 0) +        return PA_SAMPLE_S16LE; +    else if (strcmp(format, "s16be") == 0) +        return PA_SAMPLE_S16BE; +    else if (strcmp(format, "s16ne") == 0 || strcmp(format, "s16") == 0 || strcmp(format, "16") == 0) +        return PA_SAMPLE_S16NE; +    else if (strcmp(format, "u8") == 0 || strcmp(format, "8") == 0) +        return PA_SAMPLE_U8; +    else if (strcmp(format, "float32") == 0 || strcmp(format, "float32ne") == 0) +        return PA_SAMPLE_FLOAT32; +    else if (strcmp(format, "float32le") == 0) +        return PA_SAMPLE_FLOAT32LE; +    else if (strcmp(format, "float32be") == 0) +        return PA_SAMPLE_FLOAT32BE; +    else if (strcmp(format, "ulaw") == 0) +        return PA_SAMPLE_ULAW; +    else if (strcmp(format, "alaw") == 0) +        return PA_SAMPLE_ALAW; + +    return -1; +} diff --git a/polyp/sample.h b/polyp/sample.h index 912cdaa0..7e810386 100644 --- a/polyp/sample.h +++ b/polyp/sample.h @@ -42,7 +42,8 @@ enum pa_sample_format {      PA_SAMPLE_S16BE,           /**< Signed 16 Bit PCM, big endian */      PA_SAMPLE_FLOAT32LE,       /**< 32 Bit IEEE floating point, little endian, range -1..1 */      PA_SAMPLE_FLOAT32BE,       /**< 32 Bit IEEE floating point, big endian, range -1..1 */ -    PA_SAMPLE_MAX              /**< Upper limit of valid sample types */ +    PA_SAMPLE_MAX,             /**< Upper limit of valid sample types */ +    PA_SAMPLE_INVALID = -1     /**< An invalid value */  };  #ifdef WORDS_BIGENDIAN @@ -119,6 +120,9 @@ double pa_volume_to_dB(pa_volume_t v);  /** Pretty print a byte size value. (i.e. "2.5 MB") */  void pa_bytes_snprint(char *s, size_t l, unsigned v); +/** Parse a sample format text */ +enum pa_sample_format pa_parse_sample_format(const char *format); +  PA_C_DECL_END  #endif  | 
