From 61ec86c90f1964ab9663b7a72a0885078d372683 Mon Sep 17 00:00:00 2001 From: Lennart Poettering Date: Fri, 17 Sep 2004 21:10:05 +0000 Subject: add resample_method option module-combine git-svn-id: file:///home/lennart/svn/public/pulseaudio/trunk@215 fefdeb5f-60dc-0310-8127-8f9354f1896f --- polyp/daemon-conf.c | 15 +++------------ polyp/module-combine.c | 21 +++++++++++++++------ polyp/module-sine.c | 2 +- polyp/play-memchunk.c | 2 +- polyp/protocol-esound.c | 4 ++-- polyp/protocol-native.c | 4 ++-- polyp/protocol-simple.c | 4 ++-- polyp/sink-input.c | 7 +++++-- polyp/sink-input.h | 2 +- polyp/sound-file-stream.c | 2 +- polyp/source-output.c | 7 +++++-- polyp/source-output.h | 2 +- polyp/util.c | 18 ++++++++++++++++++ polyp/util.h | 2 ++ 14 files changed, 59 insertions(+), 33 deletions(-) diff --git a/polyp/daemon-conf.c b/polyp/daemon-conf.c index 6dcd540d..befb9602 100644 --- a/polyp/daemon-conf.c +++ b/polyp/daemon-conf.c @@ -125,25 +125,16 @@ int pa_daemon_conf_set_log_target(struct pa_daemon_conf *c, const char *string) return -1; return 0; - } int pa_daemon_conf_set_resample_method(struct pa_daemon_conf *c, const char *string) { + int m; assert(c && string); - if (!strcmp(string, "sinc-best-quality")) - c->resample_method = SRC_SINC_BEST_QUALITY; - else if (!strcmp(string, "sinc-medium-quality")) - c->resample_method = SRC_SINC_MEDIUM_QUALITY; - else if (!strcmp(string, "sinc-fastest")) - c->resample_method = SRC_SINC_FASTEST; - else if (!strcmp(string, "zero-order-hold")) - c->resample_method = SRC_ZERO_ORDER_HOLD; - else if (!strcmp(string, "linear")) - c->resample_method = SRC_LINEAR; - else + if ((m = pa_parse_resample_method(string)) < 0) return -1; + c->resample_method = m; return 0; } diff --git a/polyp/module-combine.c b/polyp/module-combine.c index 177d7d18..f6d596bc 100644 --- a/polyp/module-combine.c +++ b/polyp/module-combine.c @@ -40,7 +40,7 @@ PA_MODULE_AUTHOR("Lennart Poettering") PA_MODULE_DESCRIPTION("Combine multiple sinks to one") PA_MODULE_VERSION(PACKAGE_VERSION) -PA_MODULE_USAGE("sink_name= master= slave= adjust_time=") +PA_MODULE_USAGE("sink_name= master= slave= adjust_time= resample_method=") #define DEFAULT_SINK_NAME "combined" #define MEMBLOCKQ_MAXLENGTH (1024*170) @@ -53,6 +53,7 @@ static const char* const valid_modargs[] = { "master", "slaves", "adjust_time", + "resample_method", NULL }; @@ -200,7 +201,7 @@ static pa_usec_t sink_get_latency_cb(struct pa_sink *s) { return pa_sink_input_get_latency(u->master->sink_input); } -static struct output *output_new(struct userdata *u, struct pa_sink *sink) { +static struct output *output_new(struct userdata *u, struct pa_sink *sink, int resample_method) { struct output *o = NULL; char t[256]; assert(u && sink && u->sink); @@ -212,7 +213,7 @@ static struct output *output_new(struct userdata *u, struct pa_sink *sink) { o->memblockq = pa_memblockq_new(MEMBLOCKQ_MAXLENGTH, MEMBLOCKQ_MAXLENGTH, pa_frame_size(&u->sink->sample_spec), 0, 0, sink->core->memblock_stat); snprintf(t, sizeof(t), "%s: output #%u", u->sink->name, u->n_outputs+1); - if (!(o->sink_input = pa_sink_input_new(sink, t, &u->sink->sample_spec, 1))) + if (!(o->sink_input = pa_sink_input_new(sink, t, &u->sink->sample_spec, 1, resample_method))) goto fail; o->sink_input->get_latency = sink_input_get_latency_cb; @@ -277,17 +278,25 @@ static void clear_up(struct userdata *u) { int pa__init(struct pa_core *c, struct pa_module*m) { struct userdata *u; struct pa_modargs *ma = NULL; - const char *master_name, *slaves; + const char *master_name, *slaves, *rm; struct pa_sink *master_sink; char *n = NULL; const char*split_state; struct timeval tv; + int resample_method = -1; assert(c && m); if (!(ma = pa_modargs_new(m->argument, valid_modargs))) { pa_log(__FILE__": failed to parse module arguments\n"); goto fail; } + + if ((rm = pa_modargs_get_value(ma, "resample_method", NULL))) { + if ((resample_method = pa_parse_resample_method(rm)) < 0) { + pa_log(__FILE__": invalid resample method '%s'\n", rm); + goto fail; + } + } u = pa_xmalloc(sizeof(struct userdata)); m->userdata = u; @@ -325,7 +334,7 @@ int pa__init(struct pa_core *c, struct pa_module*m) { u->sink->get_latency = sink_get_latency_cb; u->sink->userdata = u; - if (!(u->master = output_new(u, master_sink))) { + if (!(u->master = output_new(u, master_sink, resample_method))) { pa_log(__FILE__": failed to create master sink input on sink '%s'.\n", u->sink->name); goto fail; } @@ -341,7 +350,7 @@ int pa__init(struct pa_core *c, struct pa_module*m) { pa_xfree(n); - if (!output_new(u, slave_sink)) { + if (!output_new(u, slave_sink, resample_method)) { pa_log(__FILE__": failed to create slave sink input on sink '%s'.\n", slave_sink->name); goto fail; } diff --git a/polyp/module-sine.c b/polyp/module-sine.c index 2fa7759c..458b8788 100644 --- a/polyp/module-sine.c +++ b/polyp/module-sine.c @@ -139,7 +139,7 @@ int pa__init(struct pa_core *c, struct pa_module*m) { calc_sine(u->memblock->data, u->memblock->length, frequency); snprintf(t, sizeof(t), "Sine Generator at %u Hz", frequency); - if (!(u->sink_input = pa_sink_input_new(sink, t, &ss, 0))) + if (!(u->sink_input = pa_sink_input_new(sink, t, &ss, 0, -1))) goto fail; u->sink_input->peek = sink_input_peek; diff --git a/polyp/play-memchunk.c b/polyp/play-memchunk.c index 6490547e..aa6d30e9 100644 --- a/polyp/play-memchunk.c +++ b/polyp/play-memchunk.c @@ -88,7 +88,7 @@ int pa_play_memchunk(struct pa_sink *sink, const char *name, const struct pa_sam if (volume <= 0) return 0; - if (!(si = pa_sink_input_new(sink, name, ss, 0))) + if (!(si = pa_sink_input_new(sink, name, ss, 0, -1))) return -1; si->volume = volume; diff --git a/polyp/protocol-esound.c b/polyp/protocol-esound.c index aff45099..293d123a 100644 --- a/polyp/protocol-esound.c +++ b/polyp/protocol-esound.c @@ -305,7 +305,7 @@ static int esd_proto_stream_play(struct connection *c, esd_proto_t request, cons c->playback.fragment_size = l/10; assert(!c->sink_input); - c->sink_input = pa_sink_input_new(sink, name, &ss, 0); + c->sink_input = pa_sink_input_new(sink, name, &ss, 0, -1); assert(c->sink_input); c->sink_input->owner = c->protocol->module; @@ -368,7 +368,7 @@ static int esd_proto_stream_record(struct connection *c, esd_proto_t request, co pa_iochannel_socket_set_sndbuf(c->io, l/RECORD_BUFFER_FRAGMENTS*2); assert(!c->source_output); - c->source_output = pa_source_output_new(source, name, &ss); + c->source_output = pa_source_output_new(source, name, &ss, -1); assert(c->source_output); c->source_output->owner = c->protocol->module; diff --git a/polyp/protocol-native.c b/polyp/protocol-native.c index e197d1e2..021c1a60 100644 --- a/polyp/protocol-native.c +++ b/polyp/protocol-native.c @@ -251,7 +251,7 @@ static struct record_stream* record_stream_new(struct connection *c, struct pa_s size_t base; assert(c && source && ss && name && maxlength); - if (!(source_output = pa_source_output_new(source, name, ss))) + if (!(source_output = pa_source_output_new(source, name, ss, -1))) return NULL; s = pa_xmalloc(sizeof(struct record_stream)); @@ -295,7 +295,7 @@ static struct playback_stream* playback_stream_new(struct connection *c, struct struct pa_sink_input *sink_input; assert(c && sink && ss && name && maxlength); - if (!(sink_input = pa_sink_input_new(sink, name, ss, 0))) + if (!(sink_input = pa_sink_input_new(sink, name, ss, 0, -1))) return NULL; s = pa_xmalloc(sizeof(struct playback_stream)); diff --git a/polyp/protocol-simple.c b/polyp/protocol-simple.c index a7bd76fb..ee3bf9d3 100644 --- a/polyp/protocol-simple.c +++ b/polyp/protocol-simple.c @@ -314,7 +314,7 @@ static void on_connection(struct pa_socket_server*s, struct pa_iochannel *io, vo goto fail; } - if (!(c->sink_input = pa_sink_input_new(sink, c->client->name, &p->sample_spec, 0))) { + if (!(c->sink_input = pa_sink_input_new(sink, c->client->name, &p->sample_spec, 0, -1))) { pa_log(__FILE__": Failed to create sink input.\n"); goto fail; } @@ -344,7 +344,7 @@ static void on_connection(struct pa_socket_server*s, struct pa_iochannel *io, vo goto fail; } - c->source_output = pa_source_output_new(source, c->client->name, &p->sample_spec); + c->source_output = pa_source_output_new(source, c->client->name, &p->sample_spec, -1); if (!c->source_output) { pa_log(__FILE__": Failed to create source output.\n"); goto fail; diff --git a/polyp/sink-input.c b/polyp/sink-input.c index 486a2044..94930231 100644 --- a/polyp/sink-input.c +++ b/polyp/sink-input.c @@ -36,7 +36,7 @@ #define CONVERT_BUFFER_LENGTH 4096 -struct pa_sink_input* pa_sink_input_new(struct pa_sink *s, const char *name, const struct pa_sample_spec *spec, int variable_rate) { +struct pa_sink_input* pa_sink_input_new(struct pa_sink *s, const char *name, const struct pa_sample_spec *spec, int variable_rate, int resample_method) { struct pa_sink_input *i; struct pa_resampler *resampler = NULL; int r; @@ -47,9 +47,12 @@ struct pa_sink_input* pa_sink_input_new(struct pa_sink *s, const char *name, con pa_log(__FILE__": Failed to create sink input: too many inputs per sink.\n"); return NULL; } + + if (resample_method < 0) + resample_method = s->core->resample_method; if (variable_rate || !pa_sample_spec_equal(spec, &s->sample_spec)) - if (!(resampler = pa_resampler_new(spec, &s->sample_spec, s->core->memblock_stat, s->core->resample_method))) + if (!(resampler = pa_resampler_new(spec, &s->sample_spec, s->core->memblock_stat, resample_method))) return NULL; i = pa_xmalloc(sizeof(struct pa_sink_input)); diff --git a/polyp/sink-input.h b/polyp/sink-input.h index 37678300..7c648ac1 100644 --- a/polyp/sink-input.h +++ b/polyp/sink-input.h @@ -62,7 +62,7 @@ struct pa_sink_input { struct pa_resampler *resampler; }; -struct pa_sink_input* pa_sink_input_new(struct pa_sink *s, const char *name, const struct pa_sample_spec *spec, int variable_rate); +struct pa_sink_input* pa_sink_input_new(struct pa_sink *s, const char *name, const struct pa_sample_spec *spec, int variable_rate, int resample_method); void pa_sink_input_unref(struct pa_sink_input* i); struct pa_sink_input* pa_sink_input_ref(struct pa_sink_input* i); diff --git a/polyp/sound-file-stream.c b/polyp/sound-file-stream.c index 60a58f47..b77d6d61 100644 --- a/polyp/sound-file-stream.c +++ b/polyp/sound-file-stream.c @@ -145,7 +145,7 @@ int pa_play_file(struct pa_sink *sink, const char *fname, pa_volume_t volume) { goto fail; } - if (!(u->sink_input = pa_sink_input_new(sink, fname, &ss, 0))) + if (!(u->sink_input = pa_sink_input_new(sink, fname, &ss, 0, -1))) goto fail; u->sink_input->volume = volume; diff --git a/polyp/source-output.c b/polyp/source-output.c index 252c155c..13b39658 100644 --- a/polyp/source-output.c +++ b/polyp/source-output.c @@ -33,7 +33,7 @@ #include "subscribe.h" #include "log.h" -struct pa_source_output* pa_source_output_new(struct pa_source *s, const char *name, const struct pa_sample_spec *spec) { +struct pa_source_output* pa_source_output_new(struct pa_source *s, const char *name, const struct pa_sample_spec *spec, int resample_method) { struct pa_source_output *o; struct pa_resampler *resampler = NULL; int r; @@ -44,8 +44,11 @@ struct pa_source_output* pa_source_output_new(struct pa_source *s, const char *n return NULL; } + if (resample_method < 0) + resample_method = s->core->resample_method; + if (!pa_sample_spec_equal(&s->sample_spec, spec)) - if (!(resampler = pa_resampler_new(&s->sample_spec, spec, s->core->memblock_stat, s->core->resample_method))) + if (!(resampler = pa_resampler_new(&s->sample_spec, spec, s->core->memblock_stat, resample_method))) return NULL; o = pa_xmalloc(sizeof(struct pa_source_output)); diff --git a/polyp/source-output.h b/polyp/source-output.h index ed09b537..51d5936b 100644 --- a/polyp/source-output.h +++ b/polyp/source-output.h @@ -57,7 +57,7 @@ struct pa_source_output { void *userdata; }; -struct pa_source_output* pa_source_output_new(struct pa_source *s, const char *name, const struct pa_sample_spec *spec); +struct pa_source_output* pa_source_output_new(struct pa_source *s, const char *name, const struct pa_sample_spec *spec, int resample_method); void pa_source_output_unref(struct pa_source_output* o); struct pa_source_output* pa_source_output_ref(struct pa_source_output *o); diff --git a/polyp/util.c b/polyp/util.c index e4dcd1c9..b9bf9f82 100644 --- a/polyp/util.c +++ b/polyp/util.c @@ -41,6 +41,8 @@ #include #include +#include + #include "util.h" #include "xmalloc.h" #include "log.h" @@ -420,3 +422,19 @@ const char *pa_strsignal(int sig) { } } +int pa_parse_resample_method(const char *string) { + assert(string); + + if (!strcmp(string, "sinc-best-quality")) + return SRC_SINC_BEST_QUALITY; + else if (!strcmp(string, "sinc-medium-quality")) + return SRC_SINC_MEDIUM_QUALITY; + else if (!strcmp(string, "sinc-fastest")) + return SRC_SINC_FASTEST; + else if (!strcmp(string, "zero-order-hold")) + return SRC_ZERO_ORDER_HOLD; + else if (!strcmp(string, "linear")) + return SRC_LINEAR; + else + return -1; +} diff --git a/polyp/util.h b/polyp/util.h index 07072df6..c842a1c3 100644 --- a/polyp/util.h +++ b/polyp/util.h @@ -64,4 +64,6 @@ char *pa_split_spaces(const char *c, const char **state); const char *pa_strsignal(int sig); +int pa_parse_resample_method(const char *string); + #endif -- cgit