Add a simple utility that parses topology bin files and creates a graph using the linux dot tool.
Signed-off-by: Ranjani Sridharan ranjani.sridharan@linux.intel.com --- topology/Makefile.am | 5 ++ topology/parse_topology.c | 130 ++++++++++++++++++++++++++++++++++++++++++++++ 2 files changed, 135 insertions(+) create mode 100644 topology/parse_topology.c
diff --git a/topology/Makefile.am b/topology/Makefile.am index 73e10e9..b69dfb4 100644 --- a/topology/Makefile.am +++ b/topology/Makefile.am @@ -59,3 +59,8 @@ EXTRA_DIST = \ sof-cnl-rt274.m4 \ sof-hsw-rt5640.m4 \ sof-apl-tdf8532.m4 + +bin_PROGRAMS = tplg_graph + +tplg_graph_SOURCES = \ + parse_topology.c diff --git a/topology/parse_topology.c b/topology/parse_topology.c new file mode 100644 index 0000000..b54ca77 --- /dev/null +++ b/topology/parse_topology.c @@ -0,0 +1,130 @@ +/* + * Utility for visualizing topology files. + * + * Copyright (c) 2015, Intel Corporation. + * + * This program is free software; you can redistribute it and/or modify it + * under the terms and conditions of the GNU General Public License, + * version 2, as published by the Free Software Foundation. + * + * This program is distributed in the hope it will be useful, but WITHOUT + * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or + * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for + * more details. + */ + +#include <stdio.h> +#include <sound/asoc.h> +#include <string.h> +#include <stdlib.h> + +/* + * The output graph is saved as "tplg.png" + * Usage: ./tplg_graph <tplg file> + */ + +int main(int argc, char **argv) +{ + struct snd_soc_tplg_hdr *hdr; + struct snd_soc_tplg_dapm_graph_elem *graph_elem; + char *filename; + char *dotfilename = "tplg.dot"; + FILE *file, *dotfile; + char *start = "digraph topology {\n"; + char *node_color = "node [color=Red,fontname=Courier]\n"; + char *edge_color = "edge [color=Blue, style=dashed]\n"; + char *end = "}\n"; + char edge[256]; + int i, status, ret; + size_t size, file_size; + + /* command line arguments */ + if (argc < 2) { + printf("usage: tplg_graph <tplg file>\n"); + exit(EXIT_FAILURE); + } + + filename = malloc(strlen(argv[1])); + strcpy(filename, argv[1]); + + /* open files */ + file = fopen(filename, "rb"); + if (!file) { + fprintf(stderr, "Unable to open file %s", filename); + return -1; + } + + dotfile = fopen(dotfilename, "w"); + if (!dotfile) { + fprintf(stderr, "Unable to open file %s", dotfilename); + return -1; + } + + fwrite(start, strlen(start), 1, dotfile); + fwrite(node_color, strlen(node_color), 1, dotfile); + fwrite(edge_color, strlen(edge_color), 1, dotfile); + + + /* file size */ + fseek(file, 0, SEEK_END); + file_size = ftell(file); + fseek(file, 0, SEEK_SET); + + /* Allocate memory */ + size = sizeof(struct snd_soc_tplg_hdr); + hdr = (struct snd_soc_tplg_hdr *)malloc(size); + if (!hdr) { + printf("error: mem alloc\n"); + return -1; + } + + size = sizeof(struct snd_soc_tplg_dapm_graph_elem); + graph_elem = (struct snd_soc_tplg_dapm_graph_elem *)malloc(size); + if (!graph_elem) { + printf("error: mem alloc\n"); + return -1; + } + + while (1) { + ret = fread(hdr, sizeof(struct snd_soc_tplg_hdr), 1, file); + if (ret != 1) + printf("error: reading header\n"); + + switch (hdr->type) { + case SND_SOC_TPLG_TYPE_DAPM_GRAPH: + size = sizeof(struct snd_soc_tplg_dapm_graph_elem); + /* parse pipeline graph */ + for (i = 0; i < hdr->count; i++) { + ret = fread(graph_elem, size, 1, file); + if (ret != 1) + printf("error: reading graph elem\n"); + + /* write route to output dot file */ + sprintf(edge, ""%s"->"%s"\n", + graph_elem->source, graph_elem->sink); + fwrite(edge, strlen(edge), 1, dotfile); + fwrite("\n", 1, 1, dotfile); + } + + if (ftell(file) == file_size) + goto finish; + break; + + default: + fseek(file, hdr->payload_size, SEEK_CUR); + if (ftell(file) == file_size) + goto finish; + break; + } + } + +finish: + fwrite(end, strlen(end), 1, dotfile); + fclose(dotfile); + fclose(file); + free(hdr); + free(graph_elem); + + /* create topology graph */ + status = system("dot tplg.dot -Tpng -o tplg.png"); +}