summaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
-rw-r--r--src/modules/alsa-util.c44
-rw-r--r--src/modules/alsa-util.h2
-rw-r--r--src/modules/module-alsa-sink.c15
-rw-r--r--src/modules/module-alsa-source.c13
-rw-r--r--src/modules/module-combine.c2
-rw-r--r--src/modules/module-jack-sink.c2
-rw-r--r--src/modules/module-jack-source.c2
-rw-r--r--src/modules/module-null-sink.c2
-rw-r--r--src/modules/module-oss-mmap.c2
-rw-r--r--src/modules/module-oss.c2
-rw-r--r--src/modules/module-pipe-sink.c2
-rw-r--r--src/modules/module-pipe-source.c2
-rw-r--r--src/modules/module-tunnel.c2
-rw-r--r--src/modules/rtp/module-rtp-send.c2
-rw-r--r--src/polyp/channelmap.c125
-rw-r--r--src/polyp/channelmap.h14
-rw-r--r--src/polyp/stream.c2
-rw-r--r--src/polypcore/core-scache.c2
-rw-r--r--src/polypcore/modargs.c5
-rw-r--r--src/polypcore/modargs.h2
-rw-r--r--src/polypcore/resampler.c4
-rw-r--r--src/polypcore/sink-input.c58
-rw-r--r--src/polypcore/sink.c37
-rw-r--r--src/polypcore/sound-file.c2
-rw-r--r--src/polypcore/source-output.c37
-rw-r--r--src/polypcore/source.c36
-rw-r--r--src/tests/channelmap-test.c10
27 files changed, 237 insertions, 191 deletions
diff --git a/src/modules/alsa-util.c b/src/modules/alsa-util.c
index a8192165..503b8efb 100644
--- a/src/modules/alsa-util.c
+++ b/src/modules/alsa-util.c
@@ -340,47 +340,3 @@ snd_mixer_elem_t *pa_alsa_find_elem(snd_mixer_t *mixer, const char *name) {
return elem;
}
-
-pa_channel_map* pa_alsa_channel_map_init_auto(pa_channel_map *m, unsigned channels) {
- assert(m);
- assert(channels > 0);
- assert(channels <= PA_CHANNELS_MAX);
-
- pa_channel_map_init(m);
-
- m->channels = channels;
-
- /* The standard ALSA channel order */
-
- switch (channels) {
- case 1:
- m->map[0] = PA_CHANNEL_POSITION_MONO;
- return m;
-
- case 8:
- m->map[6] = PA_CHANNEL_POSITION_SIDE_LEFT;
- m->map[7] = PA_CHANNEL_POSITION_SIDE_RIGHT;
- /* Fall through */
-
- case 6:
- m->map[5] = PA_CHANNEL_POSITION_LFE;
- /* Fall through */
-
- case 5:
- m->map[4] = PA_CHANNEL_POSITION_FRONT_CENTER;
- /* Fall through */
-
- case 4:
- m->map[2] = PA_CHANNEL_POSITION_REAR_LEFT;
- m->map[3] = PA_CHANNEL_POSITION_REAR_RIGHT;
- /* Fall through */
-
- case 2:
- m->map[0] = PA_CHANNEL_POSITION_FRONT_LEFT;
- m->map[1] = PA_CHANNEL_POSITION_FRONT_RIGHT;
- return m;
-
- default:
- return NULL;
- }
-}
diff --git a/src/modules/alsa-util.h b/src/modules/alsa-util.h
index bad6e9bf..69d4eddc 100644
--- a/src/modules/alsa-util.h
+++ b/src/modules/alsa-util.h
@@ -42,6 +42,4 @@ int pa_alsa_set_hw_params(snd_pcm_t *pcm_handle, const pa_sample_spec *ss, uint3
int pa_alsa_prepare_mixer(snd_mixer_t *mixer, const char *dev);
snd_mixer_elem_t *pa_alsa_find_elem(snd_mixer_t *mixer, const char *name);
-pa_channel_map* pa_alsa_channel_map_init_auto(pa_channel_map *m, unsigned channels);
-
#endif
diff --git a/src/modules/module-alsa-sink.c b/src/modules/module-alsa-sink.c
index 99e74bfc..47065659 100644
--- a/src/modules/module-alsa-sink.c
+++ b/src/modules/module-alsa-sink.c
@@ -324,19 +324,8 @@ int pa__init(pa_core *c, pa_module*m) {
}
ss = c->default_sample_spec;
- if (pa_modargs_get_sample_spec(ma, &ss) < 0) {
- pa_log(__FILE__": failed to parse sample specification");
- goto fail;
- }
-
- pa_alsa_channel_map_init_auto(&map, ss.channels);
- if ((pa_modargs_get_channel_map(ma, &map) < 0)) {
- pa_log(__FILE__": invalid channel map.");
- goto fail;
- }
-
- if (ss.channels != map.channels) {
- pa_log(__FILE__": channel map and sample specification don't match.");
+ if (pa_modargs_get_sample_spec_and_channel_map(ma, &ss, &map, PA_CHANNEL_MAP_ALSA) < 0) {
+ pa_log(__FILE__": failed to parse sample specification and channel map");
goto fail;
}
diff --git a/src/modules/module-alsa-source.c b/src/modules/module-alsa-source.c
index 660bc83b..d46f8e42 100644
--- a/src/modules/module-alsa-source.c
+++ b/src/modules/module-alsa-source.c
@@ -316,22 +316,11 @@ int pa__init(pa_core *c, pa_module*m) {
}
ss = c->default_sample_spec;
- if (pa_modargs_get_sample_spec(ma, &ss) < 0) {
+ if (pa_modargs_get_sample_spec_and_channel_map(ma, &ss, &map, PA_CHANNEL_MAP_ALSA) < 0) {
pa_log(__FILE__": failed to parse sample specification");
goto fail;
}
- pa_alsa_channel_map_init_auto(&map, ss.channels);
- if ((pa_modargs_get_channel_map(ma, &map) < 0)) {
- pa_log(__FILE__": invalid channel map.");
- goto fail;
- }
-
- if (ss.channels != map.channels) {
- pa_log(__FILE__": channel map and sample specification don't match.");
- goto fail;
- }
-
frame_size = pa_frame_size(&ss);
/* Fix latency to 100ms */
diff --git a/src/modules/module-combine.c b/src/modules/module-combine.c
index 3b927d13..369778a6 100644
--- a/src/modules/module-combine.c
+++ b/src/modules/module-combine.c
@@ -361,7 +361,7 @@ int pa__init(pa_core *c, pa_module*m) {
if (ss.channels == master_sink->sample_spec.channels)
map = master_sink->channel_map;
else
- pa_channel_map_init_auto(&map, ss.channels);
+ pa_channel_map_init_auto(&map, ss.channels, PA_CHANNEL_MAP_DEFAULT);
if ((pa_modargs_get_channel_map(ma, &map) < 0)) {
pa_log(__FILE__": invalid channel map.");
diff --git a/src/modules/module-jack-sink.c b/src/modules/module-jack-sink.c
index 09030530..324a2cb3 100644
--- a/src/modules/module-jack-sink.c
+++ b/src/modules/module-jack-sink.c
@@ -296,7 +296,7 @@ int pa__init(pa_core *c, pa_module*m) {
goto fail;
}
- pa_channel_map_init_auto(&map, channels);
+ pa_channel_map_init_auto(&map, channels, PA_CHANNEL_MAP_ALSA);
if (pa_modargs_get_channel_map(ma, &map) < 0 || map.channels != channels) {
pa_log(__FILE__": failed to parse channel_map= argument.");
goto fail;
diff --git a/src/modules/module-jack-source.c b/src/modules/module-jack-source.c
index ad39b9dd..94cabbea 100644
--- a/src/modules/module-jack-source.c
+++ b/src/modules/module-jack-source.c
@@ -294,7 +294,7 @@ int pa__init(pa_core *c, pa_module*m) {
goto fail;
}
- pa_channel_map_init_auto(&map, channels);
+ pa_channel_map_init_auto(&map, channels, PA_CHANNEL_MAP_ALSA);
if (pa_modargs_get_channel_map(ma, &map) < 0 || map.channels != channels) {
pa_log(__FILE__": failed to parse channel_map= argument.");
goto fail;
diff --git a/src/modules/module-null-sink.c b/src/modules/module-null-sink.c
index 9c564429..5cdfeab8 100644
--- a/src/modules/module-null-sink.c
+++ b/src/modules/module-null-sink.c
@@ -104,7 +104,7 @@ int pa__init(pa_core *c, pa_module*m) {
}
ss = c->default_sample_spec;
- if (pa_modargs_get_sample_spec_and_channel_map(ma, &ss, &map) < 0) {
+ if (pa_modargs_get_sample_spec_and_channel_map(ma, &ss, &map, PA_CHANNEL_MAP_DEFAULT) < 0) {
pa_log(__FILE__": invalid sample format specification or channel map.");
goto fail;
}
diff --git a/src/modules/module-oss-mmap.c b/src/modules/module-oss-mmap.c
index e032ce46..b8012214 100644
--- a/src/modules/module-oss-mmap.c
+++ b/src/modules/module-oss-mmap.c
@@ -383,7 +383,7 @@ int pa__init(pa_core *c, pa_module*m) {
}
u->sample_spec = c->default_sample_spec;
- if (pa_modargs_get_sample_spec_and_channel_map(ma, &u->sample_spec, &map) < 0) {
+ if (pa_modargs_get_sample_spec_and_channel_map(ma, &u->sample_spec, &map, PA_CHANNEL_MAP_ALSA) < 0) {
pa_log(__FILE__": failed to parse sample specification or channel map");
goto fail;
}
diff --git a/src/modules/module-oss.c b/src/modules/module-oss.c
index 4d811a76..eab9a60a 100644
--- a/src/modules/module-oss.c
+++ b/src/modules/module-oss.c
@@ -347,7 +347,7 @@ int pa__init(pa_core *c, pa_module*m) {
mode = (playback&&record) ? O_RDWR : (playback ? O_WRONLY : (record ? O_RDONLY : 0));
ss = c->default_sample_spec;
- if (pa_modargs_get_sample_spec_and_channel_map(ma, &ss, &map) < 0) {
+ if (pa_modargs_get_sample_spec_and_channel_map(ma, &ss, &map, PA_CHANNEL_MAP_ALSA) < 0) {
pa_log(__FILE__": failed to parse sample specification or channel map");
goto fail;
}
diff --git a/src/modules/module-pipe-sink.c b/src/modules/module-pipe-sink.c
index 2be1b297..0fb73cd8 100644
--- a/src/modules/module-pipe-sink.c
+++ b/src/modules/module-pipe-sink.c
@@ -154,7 +154,7 @@ int pa__init(pa_core *c, pa_module*m) {
}
ss = c->default_sample_spec;
- if (pa_modargs_get_sample_spec_and_channel_map(ma, &ss, &map) < 0) {
+ if (pa_modargs_get_sample_spec_and_channel_map(ma, &ss, &map, PA_CHANNEL_MAP_DEFAULT) < 0) {
pa_log(__FILE__": invalid sample format specification");
goto fail;
}
diff --git a/src/modules/module-pipe-source.c b/src/modules/module-pipe-source.c
index c80bfd09..d999754a 100644
--- a/src/modules/module-pipe-source.c
+++ b/src/modules/module-pipe-source.c
@@ -132,7 +132,7 @@ int pa__init(pa_core *c, pa_module*m) {
}
ss = c->default_sample_spec;
- if (pa_modargs_get_sample_spec_and_channel_map(ma, &ss, &map) < 0) {
+ if (pa_modargs_get_sample_spec_and_channel_map(ma, &ss, &map, PA_CHANNEL_MAP_DEFAULT) < 0) {
pa_log(__FILE__": invalid sample format specification or channel map");
goto fail;
}
diff --git a/src/modules/module-tunnel.c b/src/modules/module-tunnel.c
index bffcc7c0..2e04b120 100644
--- a/src/modules/module-tunnel.c
+++ b/src/modules/module-tunnel.c
@@ -895,7 +895,7 @@ int pa__init(pa_core *c, pa_module*m) {
}
ss = c->default_sample_spec;
- if (pa_modargs_get_sample_spec_and_channel_map(ma, &ss, &map) < 0) {
+ if (pa_modargs_get_sample_spec_and_channel_map(ma, &ss, &map, PA_CHANNEL_MAP_DEFAULT) < 0) {
pa_log(__FILE__": invalid sample format specification");
goto fail;
}
diff --git a/src/modules/rtp/module-rtp-send.c b/src/modules/rtp/module-rtp-send.c
index 0bb20979..d0def859 100644
--- a/src/modules/rtp/module-rtp-send.c
+++ b/src/modules/rtp/module-rtp-send.c
@@ -197,7 +197,7 @@ int pa__init(pa_core *c, pa_module*m) {
}
if (ss.channels != cm.channels)
- pa_channel_map_init_auto(&cm, ss.channels);
+ pa_channel_map_init_auto(&cm, ss.channels, PA_CHANNEL_MAP_AIFF);
payload = pa_rtp_payload_from_sample_spec(&ss);
diff --git a/src/polyp/channelmap.c b/src/polyp/channelmap.c
index 794711ae..8d16f7b3 100644
--- a/src/polyp/channelmap.c
+++ b/src/polyp/channelmap.c
@@ -112,7 +112,7 @@ pa_channel_map* pa_channel_map_init_stereo(pa_channel_map *m) {
return m;
}
-pa_channel_map* pa_channel_map_init_auto(pa_channel_map *m, unsigned channels) {
+pa_channel_map* pa_channel_map_init_auto(pa_channel_map *m, unsigned channels, pa_channel_map_def_t def) {
assert(m);
assert(channels > 0);
assert(channels <= PA_CHANNELS_MAX);
@@ -121,46 +121,99 @@ pa_channel_map* pa_channel_map_init_auto(pa_channel_map *m, unsigned channels) {
m->channels = channels;
- /* This is somewhat compatible with RFC3551 */
-
- switch (channels) {
- case 1:
- m->map[0] = PA_CHANNEL_POSITION_MONO;
- return m;
-
- case 6:
- m->map[0] = PA_CHANNEL_POSITION_FRONT_LEFT;
- m->map[1] = PA_CHANNEL_POSITION_SIDE_LEFT;
- m->map[2] = PA_CHANNEL_POSITION_FRONT_CENTER;
- m->map[3] = PA_CHANNEL_POSITION_FRONT_RIGHT;
- m->map[4] = PA_CHANNEL_POSITION_SIDE_RIGHT;
- m->map[5] = PA_CHANNEL_POSITION_LFE;
- return m;
+ switch (def) {
+ case PA_CHANNEL_MAP_AIFF:
- case 5:
- m->map[2] = PA_CHANNEL_POSITION_FRONT_CENTER;
- m->map[3] = PA_CHANNEL_POSITION_REAR_LEFT;
- m->map[4] = PA_CHANNEL_POSITION_REAR_RIGHT;
- /* Fall through */
+ /* This is somewhat compatible with RFC3551 */
- case 2:
- m->map[0] = PA_CHANNEL_POSITION_FRONT_LEFT;
- m->map[1] = PA_CHANNEL_POSITION_FRONT_RIGHT;
- return m;
+ switch (channels) {
+ case 1:
+ m->map[0] = PA_CHANNEL_POSITION_MONO;
+ return m;
+
+ case 6:
+ m->map[0] = PA_CHANNEL_POSITION_FRONT_LEFT;
+ m->map[1] = PA_CHANNEL_POSITION_SIDE_LEFT;
+ m->map[2] = PA_CHANNEL_POSITION_FRONT_CENTER;
+ m->map[3] = PA_CHANNEL_POSITION_FRONT_RIGHT;
+ m->map[4] = PA_CHANNEL_POSITION_SIDE_RIGHT;
+ m->map[5] = PA_CHANNEL_POSITION_LFE;
+ return m;
+
+ case 5:
+ m->map[2] = PA_CHANNEL_POSITION_FRONT_CENTER;
+ m->map[3] = PA_CHANNEL_POSITION_REAR_LEFT;
+ m->map[4] = PA_CHANNEL_POSITION_REAR_RIGHT;
+ /* Fall through */
+
+ case 2:
+ m->map[0] = PA_CHANNEL_POSITION_FRONT_LEFT;
+ m->map[1] = PA_CHANNEL_POSITION_FRONT_RIGHT;
+ return m;
+
+ case 3:
+ m->map[0] = PA_CHANNEL_POSITION_LEFT;
+ m->map[1] = PA_CHANNEL_POSITION_RIGHT;
+ m->map[2] = PA_CHANNEL_POSITION_CENTER;
+ return m;
+
+ case 4:
+ m->map[0] = PA_CHANNEL_POSITION_LEFT;
+ m->map[1] = PA_CHANNEL_POSITION_CENTER;
+ m->map[2] = PA_CHANNEL_POSITION_RIGHT;
+ m->map[3] = PA_CHANNEL_POSITION_LFE;
+ return m;
+
+ default:
+ return NULL;
+ }
- case 3:
- m->map[0] = PA_CHANNEL_POSITION_LEFT;
- m->map[1] = PA_CHANNEL_POSITION_RIGHT;
- m->map[2] = PA_CHANNEL_POSITION_CENTER;
- return m;
+ case PA_CHANNEL_MAP_ALSA:
+
+ switch (channels) {
+ case 1:
+ m->map[0] = PA_CHANNEL_POSITION_MONO;
+ return m;
+
+ case 8:
+ m->map[6] = PA_CHANNEL_POSITION_SIDE_LEFT;
+ m->map[7] = PA_CHANNEL_POSITION_SIDE_RIGHT;
+ /* Fall through */
+
+ case 6:
+ m->map[5] = PA_CHANNEL_POSITION_LFE;
+ /* Fall through */
+
+ case 5:
+ m->map[4] = PA_CHANNEL_POSITION_FRONT_CENTER;
+ /* Fall through */
+
+ case 4:
+ m->map[2] = PA_CHANNEL_POSITION_REAR_LEFT;
+ m->map[3] = PA_CHANNEL_POSITION_REAR_RIGHT;
+ /* Fall through */
+
+ case 2:
+ m->map[0] = PA_CHANNEL_POSITION_FRONT_LEFT;
+ m->map[1] = PA_CHANNEL_POSITION_FRONT_RIGHT;
+ return m;
+
+ default:
+ return NULL;
+ }
- case 4:
- m->map[0] = PA_CHANNEL_POSITION_LEFT;
- m->map[1] = PA_CHANNEL_POSITION_CENTER;
- m->map[2] = PA_CHANNEL_POSITION_RIGHT;
- m->map[3] = PA_CHANNEL_POSITION_LFE;
- return m;
+ case PA_CHANNEL_MAP_AUX: {
+ unsigned i;
+
+ if (channels >= PA_CHANNELS_MAX)
+ return NULL;
+
+ for (i = 0; i < channels; i++)
+ m->map[i] = PA_CHANNEL_POSITION_AUX0 + i;
+ return m;
+ }
+
default:
return NULL;
}
diff --git a/src/polyp/channelmap.h b/src/polyp/channelmap.h
index 0fd1e593..8270a5b3 100644
--- a/src/polyp/channelmap.h
+++ b/src/polyp/channelmap.h
@@ -120,6 +120,15 @@ typedef enum pa_channel_position {
PA_CHANNEL_POSITION_MAX
} pa_channel_position_t;
+/** A list of channel mapping definitions for pa_channel_map_init_auto() */
+typedef enum pa_channel_map_def {
+ PA_CHANNEL_MAP_AIFF, /**< The mapping from RFC3551, which is based on AIFF-C */
+ PA_CHANNEL_MAP_ALSA, /**< The default mapping used by ALSA */
+ PA_CHANNEL_MAP_AUX, /**< Only aux channels */
+
+ PA_CHANNEL_MAP_DEFAULT = PA_CHANNEL_MAP_AIFF /**< The default channel map */
+} pa_channel_map_def_t;
+
/** A channel map which can be used to attach labels to specific
* channels of a stream. These values are relevant for conversion and
* mixing of streams */
@@ -138,9 +147,8 @@ pa_channel_map* pa_channel_map_init_mono(pa_channel_map *m);
pa_channel_map* pa_channel_map_init_stereo(pa_channel_map *m);
/** Initialize the specified channel map for the specified number
- * of channels using default labels and return a pointer to it.
- * Uses the mapping from RFC3551, which is based on AIFF-C. */
-pa_channel_map* pa_channel_map_init_auto(pa_channel_map *m, unsigned channels);
+ * of channels using default labels and return a pointer to it. */
+pa_channel_map* pa_channel_map_init_auto(pa_channel_map *m, unsigned channels, pa_channel_map_def_t def);
/** Return a text label for the specified channel position */
const char* pa_channel_position_to_string(pa_channel_position_t pos);
diff --git a/src/polyp/stream.c b/src/polyp/stream.c
index bccdebe5..b2711ce0 100644
--- a/src/polyp/stream.c
+++ b/src/polyp/stream.c
@@ -74,7 +74,7 @@ pa_stream *pa_stream_new(pa_context *c, const char *name, const pa_sample_spec *
if (map)
s->channel_map = *map;
else
- pa_channel_map_init_auto(&s->channel_map, ss->channels);
+ pa_channel_map_init_auto(&s->channel_map, ss->channels, PA_CHANNEL_MAP_DEFAULT);
s->channel = 0;
s->channel_valid = 0;
diff --git a/src/polypcore/core-scache.c b/src/polypcore/core-scache.c
index 82c61a1d..3bba38ed 100644
--- a/src/polypcore/core-scache.c
+++ b/src/polypcore/core-scache.c
@@ -141,7 +141,7 @@ int pa_scache_add_item(pa_core *c, const char *name, const pa_sample_spec *ss, c
if (ss) {
e->sample_spec = *ss;
- pa_channel_map_init_auto(&e->channel_map, ss->channels);
+ pa_channel_map_init_auto(&e->channel_map, ss->channels, PA_CHANNEL_MAP_DEFAULT);
e->volume.channels = e->sample_spec.channels;
}
diff --git a/src/polypcore/modargs.c b/src/polypcore/modargs.c
index 6a02df0a..713326bf 100644
--- a/src/polypcore/modargs.c
+++ b/src/polypcore/modargs.c
@@ -280,7 +280,7 @@ int pa_modargs_get_channel_map(pa_modargs *ma, pa_channel_map *rmap) {
return 0;
}
-int pa_modargs_get_sample_spec_and_channel_map(pa_modargs *ma, pa_sample_spec *rss, pa_channel_map *rmap) {
+int pa_modargs_get_sample_spec_and_channel_map(pa_modargs *ma, pa_sample_spec *rss, pa_channel_map *rmap, pa_channel_map_def_t def) {
pa_sample_spec ss;
pa_channel_map map;
@@ -293,7 +293,8 @@ int pa_modargs_get_sample_spec_and_channel_map(pa_modargs *ma, pa_sample_spec *r
if (pa_modargs_get_sample_spec(ma, &ss) < 0)
return -1;
- pa_channel_map_init_auto(&map, ss.channels);
+ if (!pa_channel_map_init_auto(&map, ss.channels, def))
+ map.channels = 0;
if (pa_modargs_get_channel_map(ma, &map) < 0)
return -1;
diff --git a/src/polypcore/modargs.h b/src/polypcore/modargs.h
index 481ead99..b6977d37 100644
--- a/src/polypcore/modargs.h
+++ b/src/polypcore/modargs.h
@@ -55,6 +55,6 @@ pa_modargs_get_channel_map(). Not always suitable, since this routine
initializes the map parameter based on the channels field of the ss
structure if no channel_map is found, using pa_channel_map_init_auto() */
-int pa_modargs_get_sample_spec_and_channel_map(pa_modargs *ma, pa_sample_spec *ss, pa_channel_map *map);
+int pa_modargs_get_sample_spec_and_channel_map(pa_modargs *ma, pa_sample_spec *ss, pa_channel_map *map, pa_channel_map_def_t def);
#endif
diff --git a/src/polypcore/resampler.c b/src/polypcore/resampler.c
index 7e85e270..b2a8874b 100644
--- a/src/polypcore/resampler.c
+++ b/src/polypcore/resampler.c
@@ -101,12 +101,12 @@ pa_resampler* pa_resampler_new(
if (am)
r->i_cm = *am;
else
- pa_channel_map_init_auto(&r->i_cm, r->i_ss.channels);
+ pa_channel_map_init_auto(&r->i_cm, r->i_ss.channels, PA_CHANNEL_MAP_DEFAULT);
if (bm)
r->o_cm = *bm;
else
- pa_channel_map_init_auto(&r->o_cm, r->o_ss.channels);
+ pa_channel_map_init_auto(&r->o_cm, r->o_ss.channels, PA_CHANNEL_MAP_DEFAULT);
r->i_fz = pa_frame_size(a);
r->o_fz = pa_frame_size(b);
diff --git a/src/polypcore/sink-input.c b/src/polypcore/sink-input.c
index 26e63b85..c1026390 100644
--- a/src/polypcore/sink-input.c
+++ b/src/polypcore/sink-input.c
@@ -32,32 +32,53 @@
#include <polypcore/xmalloc.h>
#include <polypcore/core-subscribe.h>
#include <polypcore/log.h>
+#include <polypcore/utf8.h>
#include "sink-input.h"
#define CONVERT_BUFFER_LENGTH 4096
+#define CHECK_VALIDITY_RETURN_NULL(condition) \
+do {\
+if (!(condition)) \
+ return NULL; \
+} while (0)
+
pa_sink_input* pa_sink_input_new(
- pa_sink *s,
- const char *driver,
- const char *name,
- const pa_sample_spec *spec,
- const pa_channel_map *map,
- const pa_cvolume *volume,
- int variable_rate,
- int resample_method) {
+ pa_sink *s,
+ const char *driver,
+ const char *name,
+ const pa_sample_spec *spec,
+ const pa_channel_map *map,
+ const pa_cvolume *volume,
+ int variable_rate,
+ int resample_method) {
pa_sink_input *i;
pa_resampler *resampler = NULL;
int r;
char st[256];
pa_channel_map tmap;
+ pa_cvolume tvol;
assert(s);
assert(spec);
assert(s->state == PA_SINK_RUNNING);
+ CHECK_VALIDITY_RETURN_NULL(pa_sample_spec_valid(spec));
+
+ if (!map)
+ map = pa_channel_map_init_auto(&tmap, spec->channels, PA_CHANNEL_MAP_DEFAULT);
+ if (!volume)
+ volume = pa_cvolume_reset(&tvol, spec->channels);
+ CHECK_VALIDITY_RETURN_NULL(map && pa_channel_map_valid(map));
+ CHECK_VALIDITY_RETURN_NULL(volume && pa_cvolume_valid(volume));
+ CHECK_VALIDITY_RETURN_NULL(map->channels == spec->channels);
+ CHECK_VALIDITY_RETURN_NULL(volume->channels == spec->channels);
+ CHECK_VALIDITY_RETURN_NULL(!driver || pa_utf8_valid(driver));
+ CHECK_VALIDITY_RETURN_NULL(pa_utf8_valid(name));
+
if (pa_idxset_size(s->inputs) >= PA_MAX_INPUTS_PER_SINK) {
pa_log_warn(__FILE__": Failed to create sink input: too many inputs per sink.");
return NULL;
@@ -66,19 +87,6 @@ pa_sink_input* pa_sink_input_new(
if (resample_method == PA_RESAMPLER_INVALID)
resample_method = s->core->resample_method;
- if (map && spec->channels != map->channels)
- return NULL;
-
- if (volume && spec->channels != volume->channels)
- return NULL;
-
- if (!map) {
- if (!(pa_channel_map_init_auto(&tmap, spec->channels)))
- return NULL;
-
- map = &tmap;
- }
-
if (variable_rate || !pa_sample_spec_equal(spec, &s->sample_spec) || !pa_channel_map_equal(map, &s->channel_map))
if (!(resampler = pa_resampler_new(spec, map, &s->sample_spec, &s->channel_map, s->core->memblock_stat, resample_method)))
return NULL;
@@ -94,12 +102,8 @@ pa_sink_input* pa_sink_input_new(
i->sample_spec = *spec;
i->channel_map = *map;
-
- if (volume)
- i->volume = *volume;
- else
- pa_cvolume_reset(&i->volume, spec->channels);
-
+ i->volume = *volume;
+
i->peek = NULL;
i->drop = NULL;
i->kill = NULL;
diff --git a/src/polypcore/sink.c b/src/polypcore/sink.c
index 17294059..b59f1eaa 100644
--- a/src/polypcore/sink.c
+++ b/src/polypcore/sink.c
@@ -29,6 +29,7 @@
#include <stdio.h>
#include <polyp/introspect.h>
+
#include <polypcore/sink-input.h>
#include <polypcore/namereg.h>
#include <polypcore/util.h>
@@ -36,29 +37,46 @@
#include <polypcore/xmalloc.h>
#include <polypcore/core-subscribe.h>
#include <polypcore/log.h>
+#include <polypcore/utf8.h>
#include "sink.h"
#define MAX_MIX_CHANNELS 32
+#define CHECK_VALIDITY_RETURN_NULL(condition) \
+do {\
+if (!(condition)) \
+ return NULL; \
+} while (0)
+
pa_sink* pa_sink_new(
- pa_core *core,
- const char *driver,
- const char *name,
- int fail,
- const pa_sample_spec *spec,
- const pa_channel_map *map) {
+ pa_core *core,
+ const char *driver,
+ const char *name,
+ int fail,
+ const pa_sample_spec *spec,
+ const pa_channel_map *map) {
pa_sink *s;
char *n = NULL;
char st[256];
int r;
+ pa_channel_map tmap;
assert(core);
assert(name);
- assert(*name);
assert(spec);
+ CHECK_VALIDITY_RETURN_NULL(pa_sample_spec_valid(spec));
+
+ if (!map)
+ map = pa_channel_map_init_auto(&tmap, spec->channels, PA_CHANNEL_MAP_DEFAULT);
+
+ CHECK_VALIDITY_RETURN_NULL(map && pa_channel_map_valid(map));
+ CHECK_VALIDITY_RETURN_NULL(map->channels == spec->channels);
+ CHECK_VALIDITY_RETURN_NULL(!driver || pa_utf8_valid(driver));
+ CHECK_VALIDITY_RETURN_NULL(pa_utf8_valid(name) && *name);
+
s = pa_xnew(pa_sink, 1);
if (!(name = pa_namereg_register(core, name, PA_NAMEREG_SINK, s, fail))) {
@@ -75,10 +93,7 @@ pa_sink* pa_sink_new(
s->owner = NULL;
s->sample_spec = *spec;
- if (map)
- s->channel_map = *map;
- else
- pa_channel_map_init_auto(&s->channel_map, spec->channels);
+ s->channel_map = *map;
s->inputs = pa_idxset_new(NULL, NULL);
diff --git a/src/polypcore/sound-file.c b/src/polypcore/sound-file.c
index a6ccb064..f0378009 100644
--- a/src/polypcore/sound-file.c
+++ b/src/polypcore/sound-file.c
@@ -75,7 +75,7 @@ int pa_sound_file_load(const char *fname, pa_sample_spec *ss, pa_channel_map *ma
}
if (map)
- pa_channel_map_init_auto(map, ss->channels);
+ pa_channel_map_init_auto(map, ss->channels, PA_CHANNEL_MAP_DEFAULT);
if ((l = pa_frame_size(ss)*sfinfo.frames) > PA_SCACHE_ENTRY_SIZE_MAX) {
pa_log(__FILE__": File too large");
diff --git a/src/polypcore/source-output.c b/src/polypcore/source-output.c
index 0cb5f356..b3113071 100644
--- a/src/polypcore/source-output.c
+++ b/src/polypcore/source-output.c
@@ -31,16 +31,23 @@
#include <polypcore/xmalloc.h>
#include <polypcore/core-subscribe.h>
#include <polypcore/log.h>
+#include <polypcore/utf8.h>
#include "source-output.h"
+#define CHECK_VALIDITY_RETURN_NULL(condition) \
+do {\
+if (!(condition)) \
+ return NULL; \
+} while (0)
+
pa_source_output* pa_source_output_new(
- pa_source *s,
- const char *driver,
- const char *name,
- const pa_sample_spec *spec,
- const pa_channel_map *map,
- int resample_method) {
+ pa_source *s,
+ const char *driver,
+ const char *name,
+ const pa_sample_spec *spec,
+ const pa_channel_map *map,
+ int resample_method) {
pa_source_output *o;
pa_resampler *resampler = NULL;
@@ -51,7 +58,17 @@ pa_source_output* pa_source_output_new(
assert(s);
assert(spec);
assert(s->state == PA_SOURCE_RUNNING);
+
+ CHECK_VALIDITY_RETURN_NULL(pa_sample_spec_valid(spec));
+
+ if (!map)
+ map = pa_channel_map_init_auto(&tmap, spec->channels, PA_CHANNEL_MAP_DEFAULT);
+ CHECK_VALIDITY_RETURN_NULL(map && pa_channel_map_valid(map));
+ CHECK_VALIDITY_RETURN_NULL(map->channels == spec->channels);
+ CHECK_VALIDITY_RETURN_NULL(!driver || pa_utf8_valid(driver));
+ CHECK_VALIDITY_RETURN_NULL(pa_utf8_valid(name));
+
if (pa_idxset_size(s->outputs) >= PA_MAX_OUTPUTS_PER_SOURCE) {
pa_log(__FILE__": Failed to create source output: too many outputs per source.");
return NULL;
@@ -60,16 +77,11 @@ pa_source_output* pa_source_output_new(
if (resample_method == PA_RESAMPLER_INVALID)
resample_method = s->core->resample_method;
- if (!map) {
- pa_channel_map_init_auto(&tmap, spec->channels);
- map = &tmap;
- }
-
if (!pa_sample_spec_equal(&s->sample_spec, spec) || !pa_channel_map_equal(&s->channel_map, map))
if (!(resampler = pa_resampler_new(&s->sample_spec, &s->channel_map, spec, map, s->core->memblock_stat, resample_method)))
return NULL;
- o = pa_xmalloc(sizeof(pa_source_output));
+ o = pa_xnew(pa_source_output, 1);
o->ref = 1;
o->state = PA_SOURCE_OUTPUT_RUNNING;
o->name = pa_xstrdup(name);
@@ -137,7 +149,6 @@ static void source_output_free(pa_source_output* o) {
pa_xfree(o);
}
-
void pa_source_output_unref(pa_source_output* o) {
assert(o);
assert(o->ref >= 1);
diff --git a/src/polypcore/source.c b/src/polypcore/source.c
index 3a78825b..fca281a7 100644
--- a/src/polypcore/source.c
+++ b/src/polypcore/source.c
@@ -34,26 +34,43 @@
#include <polypcore/core-subscribe.h>
#include <polypcore/log.h>
#include <polypcore/sample-util.h>
+#include <polypcore/utf8.h>
#include "source.h"
+#define CHECK_VALIDITY_RETURN_NULL(condition) \
+do {\
+if (!(condition)) \
+ return NULL; \
+} while (0)
+
pa_source* pa_source_new(
- pa_core *core,
- const char *driver,
- const char *name,
- int fail,
- const pa_sample_spec *spec,
- const pa_channel_map *map) {
+ pa_core *core,
+ const char *driver,
+ const char *name,
+ int fail,
+ const pa_sample_spec *spec,
+ const pa_channel_map *map) {
pa_source *s;
char st[256];
int r;
+ pa_channel_map tmap;
assert(core);
assert(name);
- assert(*name);
assert(spec);
+ CHECK_VALIDITY_RETURN_NULL(pa_sample_spec_valid(spec));
+
+ if (!map)
+ map = pa_channel_map_init_auto(&tmap, spec->channels, PA_CHANNEL_MAP_DEFAULT);
+
+ CHECK_VALIDITY_RETURN_NULL(map && pa_channel_map_valid(map));
+ CHECK_VALIDITY_RETURN_NULL(map->channels == spec->channels);
+ CHECK_VALIDITY_RETURN_NULL(!driver || pa_utf8_valid(driver));
+ CHECK_VALIDITY_RETURN_NULL(pa_utf8_valid(name) && *name);
+
s = pa_xnew(pa_source, 1);
if (!(name = pa_namereg_register(core, name, PA_NAMEREG_SOURCE, s, fail))) {
@@ -70,10 +87,7 @@ pa_source* pa_source_new(
s->owner = NULL;
s->sample_spec = *spec;
- if (map)
- s->channel_map = *map;
- else
- pa_channel_map_init_auto(&s->channel_map, spec->channels);
+ s->channel_map = *map;
s->outputs = pa_idxset_new(NULL, NULL);
s->monitor_of = NULL;
diff --git a/src/tests/channelmap-test.c b/src/tests/channelmap-test.c
index 522c136f..c6644229 100644
--- a/src/tests/channelmap-test.c
+++ b/src/tests/channelmap-test.c
@@ -10,10 +10,18 @@ int main(PA_GCC_UNUSED int argc, PA_GCC_UNUSED char *argv[]) {
char cm[PA_CHANNEL_MAP_SNPRINT_MAX];
pa_channel_map map, map2;
- pa_channel_map_init_auto(&map, 5);
+ pa_channel_map_init_auto(&map, 6, PA_CHANNEL_MAP_AIFF);
fprintf(stderr, "map: <%s>\n", pa_channel_map_snprint(cm, sizeof(cm), &map));
+ pa_channel_map_init_auto(&map, 6, PA_CHANNEL_MAP_AUX);
+
+ fprintf(stderr, "map: <%s>\n", pa_channel_map_snprint(cm, sizeof(cm), &map));
+
+ pa_channel_map_init_auto(&map, 6, PA_CHANNEL_MAP_ALSA);
+
+ fprintf(stderr, "map: <%s>\n", pa_channel_map_snprint(cm, sizeof(cm), &map));
+
pa_channel_map_parse(&map2, cm);
assert(pa_channel_map_equal(&map, &map2));