+static int parse_sample_format(const struct config_state *cs,
+ struct stream_header *format,
+ int nvec, char **vec) {
+ char *p = vec[0];
+ long t;
+
+ if(nvec != 1) {
+ error(0, "%s:%d: wrong number of arguments", cs->path, cs->line);
+ return -1;
+ }
+ if(xstrtol(&t, p, &p, 0)) {
+ error(errno, "%s:%d: converting bits-per-sample", cs->path, cs->line);
+ return -1;
+ }
+ if(t != 8 && t != 16) {
+ error(0, "%s:%d: bad bite-per-sample (%ld)", cs->path, cs->line, t);
+ return -1;
+ }
+ if(format) format->bits = t;
+ switch (*p) {
+ case 'l': case 'L': t = ENDIAN_LITTLE; p++; break;
+ case 'b': case 'B': t = ENDIAN_BIG; p++; break;
+ default: t = ENDIAN_NATIVE; break;
+ }
+ if(format) format->endian = t;
+ if(*p != '/') {
+ error(errno, "%s:%d: expected `/' after bits-per-sample",
+ cs->path, cs->line);
+ return -1;
+ }
+ p++;
+ if(xstrtol(&t, p, &p, 0)) {
+ error(errno, "%s:%d: converting sample-rate", cs->path, cs->line);
+ return -1;
+ }
+ if(t < 1 || t > INT_MAX) {
+ error(0, "%s:%d: silly sample-rate (%ld)", cs->path, cs->line, t);
+ return -1;
+ }
+ if(format) format->rate = t;
+ if(*p != '/') {
+ error(0, "%s:%d: expected `/' after sample-rate",
+ cs->path, cs->line);
+ return -1;
+ }
+ p++;
+ if(xstrtol(&t, p, &p, 0)) {
+ error(errno, "%s:%d: converting channels", cs->path, cs->line);
+ return -1;
+ }
+ if(t < 1 || t > 8) {
+ error(0, "%s:%d: silly number (%ld) of channels", cs->path, cs->line, t);
+ return -1;
+ }
+ if(format) format->channels = t;
+ if(*p) {
+ error(0, "%s:%d: junk after channels", cs->path, cs->line);
+ return -1;
+ }
+ return 0;
+}
+
+static int set_sample_format(const struct config_state *cs,
+ const struct conf *whoami,
+ int nvec, char **vec) {
+ return parse_sample_format(cs, ADDRESS(cs->config, struct stream_header),
+ nvec, vec);
+}
+