From dd10c982414dfa8fbb9aeeeae61c68e4a6f081cc Mon Sep 17 00:00:00 2001 From: Lennart Poettering Date: Fri, 27 Jan 2006 16:25:31 +0000 Subject: Mega patch: * implement inner loops using liboil * drop "typeid" stuff * add support for channel maps * add support for seperate volumes per channel * add support for hardware mixer settings (only module-oss implements this for now) * fix a lot of types for _t suffix git-svn-id: file:///home/lennart/svn/public/pulseaudio/trunk@463 fefdeb5f-60dc-0310-8127-8f9354f1896f --- polyp/protocol-native.c | 108 +++++++++++++++++++++++++++++++----------------- 1 file changed, 70 insertions(+), 38 deletions(-) (limited to 'polyp/protocol-native.c') diff --git a/polyp/protocol-native.c b/polyp/protocol-native.c index b19d30d9..0491dc41 100644 --- a/polyp/protocol-native.c +++ b/polyp/protocol-native.c @@ -56,8 +56,6 @@ /* Don't accept more connection than this */ #define MAX_CONNECTIONS 10 -#define PA_TYPEID_NATIVE PA_TYPEID_MAKE('N', 'A', 'T', 'V') - struct connection; struct pa_protocol_native; @@ -88,6 +86,7 @@ struct upload_stream { size_t length; char *name; pa_sample_spec sample_spec; + pa_channel_map channel_map; }; struct output_stream { @@ -235,7 +234,12 @@ static const pa_pdispatch_callback command_table[PA_COMMAND_MAX] = { /* structure management */ -static struct upload_stream* upload_stream_new(struct connection *c, const pa_sample_spec *ss, const char *name, size_t length) { +static struct upload_stream* upload_stream_new( + struct connection *c, + const pa_sample_spec *ss, + const pa_channel_map *map, + const char *name, size_t length) { + struct upload_stream *s; assert(c && ss && name && length); @@ -243,6 +247,7 @@ static struct upload_stream* upload_stream_new(struct connection *c, const pa_sa s->type = UPLOAD_STREAM; s->connection = c; s->sample_spec = *ss; + s->channel_map = *map; s->name = pa_xstrdup(name); s->memchunk.memblock = NULL; @@ -268,13 +273,21 @@ static void upload_stream_free(struct upload_stream *o) { pa_xfree(o); } -static struct record_stream* record_stream_new(struct connection *c, pa_source *source, const pa_sample_spec *ss, const char *name, size_t maxlength, size_t fragment_size) { +static struct record_stream* record_stream_new( + struct connection *c, + pa_source *source, + const pa_sample_spec *ss, + const pa_channel_map *map, + const char *name, + size_t maxlength, + size_t fragment_size) { + struct record_stream *s; pa_source_output *source_output; size_t base; assert(c && source && ss && name && maxlength); - if (!(source_output = pa_source_output_new(source, PA_TYPEID_NATIVE, name, ss, -1))) + if (!(source_output = pa_source_output_new(source, __FILE__, name, ss, map, -1))) return NULL; s = pa_xmalloc(sizeof(struct record_stream)); @@ -308,17 +321,23 @@ static void record_stream_free(struct record_stream* r) { pa_xfree(r); } -static struct playback_stream* playback_stream_new(struct connection *c, pa_sink *sink, const pa_sample_spec *ss, const char *name, - size_t maxlength, - size_t tlength, - size_t prebuf, - size_t minreq, - pa_volume_t volume) { +static struct playback_stream* playback_stream_new( + struct connection *c, + pa_sink *sink, + const pa_sample_spec *ss, + const pa_channel_map *map, + const char *name, + size_t maxlength, + size_t tlength, + size_t prebuf, + size_t minreq, + pa_cvolume *volume) { + struct playback_stream *s; pa_sink_input *sink_input; assert(c && sink && ss && name && maxlength); - if (!(sink_input = pa_sink_input_new(sink, PA_TYPEID_NATIVE, name, ss, 0, -1))) + if (!(sink_input = pa_sink_input_new(sink, __FILE__, name, ss, map, 0, -1))) return NULL; s = pa_xmalloc(sizeof(struct playback_stream)); @@ -340,7 +359,7 @@ static struct playback_stream* playback_stream_new(struct connection *c, pa_sink s->requested_bytes = 0; s->drain_request = 0; - s->sink_input->volume = volume; + s->sink_input->volume = *volume; pa_idxset_put(c->output_streams, s, &s->index); return s; @@ -561,14 +580,17 @@ static void command_create_playback_stream(PA_GCC_UNUSED pa_pdispatch *pd, PA_GC uint32_t sink_index; const char *name, *sink_name; pa_sample_spec ss; + pa_channel_map map; pa_tagstruct *reply; pa_sink *sink; - pa_volume_t volume; + pa_cvolume volume; int corked; + assert(c && t && c->protocol && c->protocol->core); if (pa_tagstruct_gets(t, &name) < 0 || !name || pa_tagstruct_get_sample_spec(t, &ss) < 0 || + pa_tagstruct_get_channel_map(t, &map) < 0 || pa_tagstruct_getu32(t, &sink_index) < 0 || pa_tagstruct_gets(t, &sink_name) < 0 || pa_tagstruct_getu32(t, &maxlength) < 0 || @@ -576,13 +598,12 @@ static void command_create_playback_stream(PA_GCC_UNUSED pa_pdispatch *pd, PA_GC pa_tagstruct_getu32(t, &tlength) < 0 || pa_tagstruct_getu32(t, &prebuf) < 0 || pa_tagstruct_getu32(t, &minreq) < 0 || - pa_tagstruct_getu32(t, &volume) < 0 || + pa_tagstruct_get_cvolume(t, &volume) < 0 || !pa_tagstruct_eof(t)) { protocol_error(c); return; } - if (!c->authorized) { pa_pstream_send_error(c->pstream, tag, PA_ERROR_ACCESS); return; @@ -599,7 +620,7 @@ static void command_create_playback_stream(PA_GCC_UNUSED pa_pdispatch *pd, PA_GC return; } - if (!(s = playback_stream_new(c, sink, &ss, name, maxlength, tlength, prebuf, minreq, volume))) { + if (!(s = playback_stream_new(c, sink, &ss, &map, name, maxlength, tlength, prebuf, minreq, &volume))) { pa_pstream_send_error(c->pstream, tag, PA_ERROR_INVALID); return; } @@ -671,6 +692,7 @@ static void command_create_record_stream(PA_GCC_UNUSED pa_pdispatch *pd, PA_GCC_ uint32_t source_index; const char *name, *source_name; pa_sample_spec ss; + pa_channel_map map; pa_tagstruct *reply; pa_source *source; int corked; @@ -678,6 +700,7 @@ static void command_create_record_stream(PA_GCC_UNUSED pa_pdispatch *pd, PA_GCC_ if (pa_tagstruct_gets(t, &name) < 0 || !name || pa_tagstruct_get_sample_spec(t, &ss) < 0 || + pa_tagstruct_get_channel_map(t, &map) < 0 || pa_tagstruct_getu32(t, &source_index) < 0 || pa_tagstruct_gets(t, &source_name) < 0 || pa_tagstruct_getu32(t, &maxlength) < 0 || @@ -703,7 +726,7 @@ static void command_create_record_stream(PA_GCC_UNUSED pa_pdispatch *pd, PA_GCC_ return; } - if (!(s = record_stream_new(c, source, &ss, name, maxlength, fragment_size))) { + if (!(s = record_stream_new(c, source, &ss, &map, name, maxlength, fragment_size))) { pa_pstream_send_error(c->pstream, tag, PA_ERROR_INVALID); return; } @@ -984,11 +1007,13 @@ static void command_create_upload_stream(PA_GCC_UNUSED pa_pdispatch *pd, PA_GCC_ size_t length; const char *name; pa_sample_spec ss; + pa_channel_map map; pa_tagstruct *reply; assert(c && t && c->protocol && c->protocol->core); if (pa_tagstruct_gets(t, &name) < 0 || !name || pa_tagstruct_get_sample_spec(t, &ss) < 0 || + pa_tagstruct_get_channel_map(t, &map) < 0 || pa_tagstruct_getu32(t, &length) < 0 || !pa_tagstruct_eof(t)) { protocol_error(c); @@ -1005,7 +1030,7 @@ static void command_create_upload_stream(PA_GCC_UNUSED pa_pdispatch *pd, PA_GCC_ return; } - if (!(s = upload_stream_new(c, &ss, name, length))) { + if (!(s = upload_stream_new(c, &ss, &map, name, length))) { pa_pstream_send_error(c->pstream, tag, PA_ERROR_INVALID); return; } @@ -1042,21 +1067,22 @@ static void command_finish_upload_stream(PA_GCC_UNUSED pa_pdispatch *pd, PA_GCC_ return; } - pa_scache_add_item(c->protocol->core, s->name, &s->sample_spec, &s->memchunk, &idx); + pa_scache_add_item(c->protocol->core, s->name, &s->sample_spec, &s->channel_map, &s->memchunk, &idx); pa_pstream_send_simple_ack(c->pstream, tag); upload_stream_free(s); } static void command_play_sample(PA_GCC_UNUSED pa_pdispatch *pd, PA_GCC_UNUSED uint32_t command, uint32_t tag, pa_tagstruct *t, void *userdata) { struct connection *c = userdata; - uint32_t sink_index, volume; + uint32_t sink_index; + pa_cvolume volume; pa_sink *sink; const char *name, *sink_name; assert(c && t); if (pa_tagstruct_getu32(t, &sink_index) < 0 || pa_tagstruct_gets(t, &sink_name) < 0 || - pa_tagstruct_getu32(t, &volume) < 0 || + pa_tagstruct_get_cvolume(t, &volume) < 0 || pa_tagstruct_gets(t, &name) < 0 || !name || !pa_tagstruct_eof(t)) { protocol_error(c); @@ -1078,7 +1104,7 @@ static void command_play_sample(PA_GCC_UNUSED pa_pdispatch *pd, PA_GCC_UNUSED ui return; } - if (pa_scache_play_item(c->protocol->core, name, sink, volume) < 0) { + if (pa_scache_play_item(c->protocol->core, name, sink, &volume) < 0) { pa_pstream_send_error(c->pstream, tag, PA_ERROR_NOENTITY); return; } @@ -1116,12 +1142,13 @@ static void sink_fill_tagstruct(pa_tagstruct *t, pa_sink *sink) { pa_tagstruct_puts(t, sink->name); pa_tagstruct_puts(t, sink->description); pa_tagstruct_put_sample_spec(t, &sink->sample_spec); + pa_tagstruct_put_channel_map(t, &sink->channel_map); pa_tagstruct_putu32(t, sink->owner ? sink->owner->index : (uint32_t) -1); - pa_tagstruct_putu32(t, sink->volume); + pa_tagstruct_put_cvolume(t, pa_sink_get_volume(sink, PA_MIXER_HARDWARE)); pa_tagstruct_putu32(t, sink->monitor_source->index); pa_tagstruct_puts(t, sink->monitor_source->name); pa_tagstruct_put_usec(t, pa_sink_get_latency(sink)); - pa_tagstruct_putu32(t, sink->typeid); + pa_tagstruct_puts(t, sink->driver); } static void source_fill_tagstruct(pa_tagstruct *t, pa_source *source) { @@ -1130,11 +1157,12 @@ static void source_fill_tagstruct(pa_tagstruct *t, pa_source *source) { pa_tagstruct_puts(t, source->name); pa_tagstruct_puts(t, source->description); pa_tagstruct_put_sample_spec(t, &source->sample_spec); + pa_tagstruct_put_channel_map(t, &source->channel_map); pa_tagstruct_putu32(t, source->owner ? source->owner->index : (uint32_t) -1); pa_tagstruct_putu32(t, source->monitor_of ? source->monitor_of->index : (uint32_t) -1); pa_tagstruct_puts(t, source->monitor_of ? source->monitor_of->name : NULL); pa_tagstruct_put_usec(t, pa_source_get_latency(source)); - pa_tagstruct_putu32(t, source->typeid); + pa_tagstruct_puts(t, source->driver); } static void client_fill_tagstruct(pa_tagstruct *t, pa_client *client) { @@ -1142,7 +1170,7 @@ static void client_fill_tagstruct(pa_tagstruct *t, pa_client *client) { pa_tagstruct_putu32(t, client->index); pa_tagstruct_puts(t, client->name); pa_tagstruct_putu32(t, client->owner ? client->owner->index : (uint32_t) -1); - pa_tagstruct_putu32(t, client->typeid); + pa_tagstruct_puts(t, client->driver); } static void module_fill_tagstruct(pa_tagstruct *t, pa_module *module) { @@ -1162,11 +1190,12 @@ static void sink_input_fill_tagstruct(pa_tagstruct *t, pa_sink_input *s) { pa_tagstruct_putu32(t, s->client ? s->client->index : (uint32_t) -1); pa_tagstruct_putu32(t, s->sink->index); pa_tagstruct_put_sample_spec(t, &s->sample_spec); - pa_tagstruct_putu32(t, s->volume); + pa_tagstruct_put_channel_map(t, &s->channel_map); + pa_tagstruct_put_cvolume(t, &s->volume); pa_tagstruct_put_usec(t, pa_sink_input_get_latency(s)); pa_tagstruct_put_usec(t, pa_sink_get_latency(s->sink)); pa_tagstruct_puts(t, pa_resample_method_to_string(pa_sink_input_get_resample_method(s))); - pa_tagstruct_putu32(t, s->typeid); + pa_tagstruct_puts(t, s->driver); } static void source_output_fill_tagstruct(pa_tagstruct *t, pa_source_output *s) { @@ -1177,19 +1206,21 @@ static void source_output_fill_tagstruct(pa_tagstruct *t, pa_source_output *s) { pa_tagstruct_putu32(t, s->client ? s->client->index : (uint32_t) -1); pa_tagstruct_putu32(t, s->source->index); pa_tagstruct_put_sample_spec(t, &s->sample_spec); + pa_tagstruct_put_channel_map(t, &s->channel_map); pa_tagstruct_put_usec(t, pa_source_output_get_latency(s)); pa_tagstruct_put_usec(t, pa_source_get_latency(s->source)); pa_tagstruct_puts(t, pa_resample_method_to_string(pa_source_output_get_resample_method(s))); - pa_tagstruct_putu32(t, s->typeid); + pa_tagstruct_puts(t, s->driver); } static void scache_fill_tagstruct(pa_tagstruct *t, pa_scache_entry *e) { assert(t && e); pa_tagstruct_putu32(t, e->index); pa_tagstruct_puts(t, e->name); - pa_tagstruct_putu32(t, e->volume); + pa_tagstruct_put_cvolume(t, &e->volume); pa_tagstruct_put_usec(t, pa_bytes_to_usec(e->memchunk.length, &e->sample_spec)); pa_tagstruct_put_sample_spec(t, &e->sample_spec); + pa_tagstruct_put_channel_map(t, &e->channel_map); pa_tagstruct_putu32(t, e->memchunk.length); pa_tagstruct_put_boolean(t, e->lazy); pa_tagstruct_puts(t, e->filename); @@ -1379,7 +1410,7 @@ static void command_get_server_info(PA_GCC_UNUSED pa_pdispatch *pd, PA_GCC_UNUSE pa_pstream_send_tagstruct(c->pstream, reply); } -static void subscription_cb(pa_core *core, pa_subscription_event_type e, uint32_t idx, void *userdata) { +static void subscription_cb(pa_core *core, pa_subscription_event_type_t e, uint32_t idx, void *userdata) { pa_tagstruct *t; struct connection *c = userdata; assert(c && core); @@ -1395,7 +1426,7 @@ static void subscription_cb(pa_core *core, pa_subscription_event_type e, uint32_ static void command_subscribe(PA_GCC_UNUSED pa_pdispatch *pd, PA_GCC_UNUSED uint32_t command, uint32_t tag, pa_tagstruct *t, void *userdata) { struct connection *c = userdata; - pa_subscription_mask m; + pa_subscription_mask_t m; assert(c && t); if (pa_tagstruct_getu32(t, &m) < 0 || @@ -1423,7 +1454,8 @@ static void command_subscribe(PA_GCC_UNUSED pa_pdispatch *pd, PA_GCC_UNUSED uint static void command_set_volume(PA_GCC_UNUSED pa_pdispatch *pd, uint32_t command, uint32_t tag, pa_tagstruct *t, void *userdata) { struct connection *c = userdata; - uint32_t idx, volume; + uint32_t idx; + pa_cvolume volume; pa_sink *sink = NULL; pa_sink_input *si = NULL; const char *name = NULL; @@ -1431,7 +1463,7 @@ static void command_set_volume(PA_GCC_UNUSED pa_pdispatch *pd, uint32_t command, if (pa_tagstruct_getu32(t, &idx) < 0 || (command == PA_COMMAND_SET_SINK_VOLUME && pa_tagstruct_gets(t, &name) < 0) || - pa_tagstruct_getu32(t, &volume) || + pa_tagstruct_get_cvolume(t, &volume) || !pa_tagstruct_eof(t)) { protocol_error(c); return; @@ -1458,9 +1490,9 @@ static void command_set_volume(PA_GCC_UNUSED pa_pdispatch *pd, uint32_t command, } if (sink) - pa_sink_set_volume(sink, volume); + pa_sink_set_volume(sink, PA_MIXER_HARDWARE, &volume); else if (si) - pa_sink_input_set_volume(si, volume); + pa_sink_input_set_volume(si, &volume); pa_pstream_send_simple_ack(c->pstream, tag); } @@ -2032,7 +2064,7 @@ static void on_connection(PA_GCC_UNUSED pa_socket_server*s, pa_iochannel *io, vo c->protocol = p; assert(p->core); - c->client = pa_client_new(p->core, PA_TYPEID_NATIVE, "Client"); + c->client = pa_client_new(p->core, __FILE__, "Client"); assert(c->client); c->client->kill = client_kill_cb; c->client->userdata = c; -- cgit