summaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
-rw-r--r--polyp/daemon-conf.c15
-rw-r--r--polyp/module-combine.c21
-rw-r--r--polyp/module-sine.c2
-rw-r--r--polyp/play-memchunk.c2
-rw-r--r--polyp/protocol-esound.c4
-rw-r--r--polyp/protocol-native.c4
-rw-r--r--polyp/protocol-simple.c4
-rw-r--r--polyp/sink-input.c7
-rw-r--r--polyp/sink-input.h2
-rw-r--r--polyp/sound-file-stream.c2
-rw-r--r--polyp/source-output.c7
-rw-r--r--polyp/source-output.h2
-rw-r--r--polyp/util.c18
-rw-r--r--polyp/util.h2
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=<name for the sink> master=<master sink> slave=<slave sinks> adjust_time=<seconds>")
+PA_MODULE_USAGE("sink_name=<name for the sink> master=<master sink> slave=<slave sinks> adjust_time=<seconds> resample_method=<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 <sys/resource.h>
#include <limits.h>
+#include <samplerate.h>
+
#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