OSDN Git Service

topology: Add parsing for rates from conf
authorGuneshwor Singh <guneshwor.o.singh@intel.com>
Tue, 20 Jun 2017 04:15:45 +0000 (09:45 +0530)
committerTakashi Iwai <tiwai@suse.de>
Tue, 20 Jun 2017 06:10:36 +0000 (08:10 +0200)
In alsa-lib topology parser, rate_min and rate_max are parsed currently.
Add support to parse rates also.

Signed-off-by: Guneshwor Singh <guneshwor.o.singh@intel.com>
Signed-off-by: Takashi Iwai <tiwai@suse.de>
include/topology.h
src/topology/pcm.c
src/topology/tplg_local.h

index ccb3a00..42d2376 100644 (file)
@@ -534,6 +534,7 @@ extern "C" {
  * SectionPCMCapabilities."name" {
  *
  *     formats "S24_LE,S16_LE"         # Supported formats
+ *     rates "48000"                   # Supported rates
  *     rate_min "48000"                # Max supported sample rate
  *     rate_max "48000"                # Min supported sample rate
  *     channels_min "2"                # Min number of channels
index 0f4deb4..bb63142 100644 (file)
 #include "list.h"
 #include "tplg_local.h"
 
+#define RATE(v) [SND_PCM_RATE_##v] = #v
+
+static const char *const snd_pcm_rate_names[] = {
+       RATE(5512),
+       RATE(8000),
+       RATE(11025),
+       RATE(16000),
+       RATE(22050),
+       RATE(32000),
+       RATE(44100),
+       RATE(48000),
+       RATE(64000),
+       RATE(88200),
+       RATE(96000),
+       RATE(176400),
+       RATE(192000),
+       RATE(CONTINUOUS),
+       RATE(KNOT),
+};
+
 struct tplg_elem *lookup_pcm_dai_stream(struct list_head *base, const char* id)
 {
        struct list_head *pos;
@@ -309,6 +329,42 @@ static int split_format(struct snd_soc_tplg_stream_caps *caps, char *str)
        return 0;
 }
 
+static int get_rate_value(const char* name)
+{
+       int rate;
+       for (rate = 0; rate <= SND_PCM_RATE_LAST; rate++) {
+               if (snd_pcm_rate_names[rate] &&
+                   strcasecmp(name, snd_pcm_rate_names[rate]) == 0) {
+                       return rate;
+               }
+       }
+
+       return SND_PCM_RATE_UNKNOWN;
+}
+
+static int split_rate(struct snd_soc_tplg_stream_caps *caps, char *str)
+{
+       char *s = NULL;
+       snd_pcm_rates_t rate;
+       int i = 0;
+
+       s = strtok(str, ",");
+       while (s) {
+               rate = get_rate_value(s);
+
+               if (rate == SND_PCM_RATE_UNKNOWN) {
+                       SNDERR("error: unsupported stream rate %s\n", s);
+                       return -EINVAL;
+               }
+
+               caps->rates |= 1 << rate;
+               s = strtok(NULL, ", ");
+               i++;
+       }
+
+       return 0;
+}
+
 /* Parse pcm stream capabilities */
 int tplg_parse_stream_caps(snd_tplg_t *tplg,
        snd_config_t *cfg, void *private ATTRIBUTE_UNUSED)
@@ -360,6 +416,21 @@ int tplg_parse_stream_caps(snd_tplg_t *tplg,
                        continue;
                }
 
+               if (strcmp(id, "rates") == 0) {
+                       s = strdup(val);
+                       if (!s)
+                               return -ENOMEM;
+
+                       err = split_rate(sc, s);
+                       free(s);
+
+                       if (err < 0)
+                               return err;
+
+                       tplg_dbg("\t\t%s: %s\n", id, val);
+                       continue;
+               }
+
                if (strcmp(id, "rate_min") == 0) {
                        sc->rate_min = atoi(val);
                        tplg_dbg("\t\t%s: %d\n", id, sc->rate_min);
index 60af017..af59914 100644 (file)
 struct tplg_ref;
 struct tplg_elem;
 
+typedef enum _snd_pcm_rates {
+       SND_PCM_RATE_UNKNOWN = -1,
+       SND_PCM_RATE_5512 = 0,
+       SND_PCM_RATE_8000,
+       SND_PCM_RATE_11025,
+       SND_PCM_RATE_16000,
+       SND_PCM_RATE_22050,
+       SND_PCM_RATE_32000,
+       SND_PCM_RATE_44100,
+       SND_PCM_RATE_48000,
+       SND_PCM_RATE_64000,
+       SND_PCM_RATE_88200,
+       SND_PCM_RATE_96000,
+       SND_PCM_RATE_176400,
+       SND_PCM_RATE_192000,
+       SND_PCM_RATE_CONTINUOUS = 30,
+       SND_PCM_RATE_KNOT = 31,
+       SND_PCM_RATE_LAST = SND_PCM_RATE_KNOT,
+} snd_pcm_rates_t;
+
 struct snd_tplg {
 
        /* opaque vendor data */