Commit 5e103b5f authored by Max Kellermann's avatar Max Kellermann

filter/route: merge the two loops, one-pass parsing

parent de5be62d
...@@ -48,10 +48,9 @@ ...@@ -48,10 +48,9 @@
#include "FilterInternal.hxx" #include "FilterInternal.hxx"
#include "FilterRegistry.hxx" #include "FilterRegistry.hxx"
#include "pcm/PcmBuffer.hxx" #include "pcm/PcmBuffer.hxx"
#include "util/StringUtil.hxx"
#include "util/Error.hxx" #include "util/Error.hxx"
#include <glib.h>
#include <algorithm> #include <algorithm>
#include <assert.h> #include <assert.h>
...@@ -135,88 +134,70 @@ RouteFilter::Configure(const config_param &param, Error &error) { ...@@ -135,88 +134,70 @@ RouteFilter::Configure(const config_param &param, Error &error) {
* dynamic realloc() instead of one count run and one malloc(). * dynamic realloc() instead of one count run and one malloc().
*/ */
gchar **tokens;
int number_of_copies;
// A cowardly default, just passthrough stereo
const char *const routes = param.GetBlockValue("routes", "0>0, 1>1");
std::fill_n(sources, MAX_CHANNELS, -1); std::fill_n(sources, MAX_CHANNELS, -1);
min_input_channels = 0; min_input_channels = 0;
min_output_channels = 0; min_output_channels = 0;
tokens = g_strsplit(routes, ",", 255); // A cowardly default, just passthrough stereo
number_of_copies = g_strv_length(tokens); const char *routes = param.GetBlockValue("routes", "0>0, 1>1");
while (true) {
// Start by figuring out a few basic things about the routing set routes = strchug_fast(routes);
for (int c=0; c<number_of_copies; ++c) {
char *endptr;
// String and int representations of the source/destination const unsigned source = strtoul(routes, &endptr, 10);
gchar **sd; endptr = strchug_fast(endptr);
if (endptr == routes || *endptr != '>') {
// Squeeze whitespace error.Set(config_domain,
g_strstrip(tokens[c]); "Malformed 'routes' specification");
return false;
}
// Split the a>b string into source and destination if (source >= MAX_CHANNELS) {
sd = g_strsplit(tokens[c], ">", 2);
if (g_strv_length(sd) != 2) {
error.Format(config_domain, error.Format(config_domain,
"Invalid copy around %d in routes spec: %s", "Invalid source channel number: %u",
param.line, tokens[c]); source);
g_strfreev(sd);
g_strfreev(tokens);
return false; return false;
} }
unsigned source = strtoul(sd[0], NULL, 10);
unsigned dest = strtoul(sd[1], NULL, 10);
// Keep track of the highest channel numbers seen
// as either in- or outputs
if (source >= min_input_channels) if (source >= min_input_channels)
min_input_channels = source + 1; min_input_channels = source + 1;
if (dest >= min_output_channels)
min_output_channels = dest + 1;
g_strfreev(sd); routes = strchug_fast(endptr + 1);
}
if (!audio_valid_channel_count(min_output_channels)) { unsigned dest = strtoul(routes, &endptr, 10);
g_strfreev(tokens); endptr = strchug_fast(endptr);
error.Format(config_domain, if (endptr == routes) {
"Invalid number of output channels requested: %d", error.Set(config_domain,
min_output_channels); "Malformed 'routes' specification");
return false; return false;
} }
// Run through the spec again, and save the
// actual mapping output <- input
for (int c=0; c<number_of_copies; ++c) {
// String and int representations of the source/destination
gchar **sd;
// Split the a>b string into source and destination if (dest >= MAX_CHANNELS) {
sd = g_strsplit(tokens[c], ">", 2);
if (g_strv_length(sd) != 2) {
error.Format(config_domain, error.Format(config_domain,
"Invalid copy around %d in routes spec: %s", "Invalid destination channel number: %u",
param.line, tokens[c]); dest);
g_strfreev(sd);
g_strfreev(tokens);
return false; return false;
} }
unsigned source = strtoul(sd[0], NULL, 10); if (dest >= min_output_channels)
unsigned dest = strtoul(sd[1], NULL, 10); min_output_channels = dest + 1;
sources[dest] = source; sources[dest] = source;
g_strfreev(sd); routes = endptr;
}
if (*routes == 0)
break;
if (*routes != ',') {
error.Set(config_domain,
"Malformed 'routes' specification");
return false;
}
g_strfreev(tokens); ++routes;
}
return true; return true;
} }
......
Markdown is supported
0% or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment