Changeset fa60cd69 in mainline


Ignore:
Timestamp:
2013-04-02T19:06:27Z (11 years ago)
Author:
Jan Vesely <jano.vesely@…>
Branches:
lfn, master, serial, ticket/834-toolchain-update, topic/msim-upgrade, topic/simplify-dev-export
Children:
35ab943
Parents:
39c4d1f
Message:

hound: add connection class

This will enable N to M routing in the future

Location:
uspace/srv/audio/hound
Files:
2 added
10 edited

Legend:

Unmodified
Added
Removed
  • uspace/srv/audio/hound/Makefile

    r39c4d1f rfa60cd69  
    4646        audio_sink.c \
    4747        audio_source.c \
     48        connection.c \
    4849        hound.c \
    4950        hound_ctx.c \
  • uspace/srv/audio/hound/audio_client.c

    r39c4d1f rfa60cd69  
    5555
    5656static int client_sink_connection_change(audio_sink_t *sink, bool new);
    57 static int client_source_connection_change(audio_source_t *source);
     57static int client_source_connection_change(audio_source_t *source, bool new);
    5858static int client_source_update_data(audio_source_t *source, size_t size);
    5959
     
    111111}
    112112
    113 static int client_source_connection_change(audio_source_t *source)
     113static int client_source_connection_change(audio_source_t *source, bool new)
    114114{
    115115        assert(source);
    116116        audio_client_t *client = source->private_data;
    117         if (source->connected_sink) {
     117        if (new && list_count(&source->connections) == 1) {
     118                assert(!client->exch);
    118119                client->exch = async_exchange_begin(client->sess);
    119120                return client->exch ? EOK : ENOMEM;
    120121        }
    121         async_exchange_end(client->exch);
    122         client->exch = NULL;
     122        if (list_count(&source->connections) == 0) {
     123                assert(!new);
     124                async_exchange_end(client->exch);
     125                client->exch = NULL;
     126        }
    123127        return EOK;
    124128}
  • uspace/srv/audio/hound/audio_device.c

    r39c4d1f rfa60cd69  
    4949
    5050static int device_sink_connection_callback(audio_sink_t *sink, bool new);
    51 static int device_source_connection_callback(audio_source_t *source);
     51static int device_source_connection_callback(audio_source_t *source, bool new);
    5252static void device_event_callback(ipc_callid_t iid, ipc_call_t *icall, void *arg);
    5353static int device_check_format(audio_sink_t* sink);
     
    9494        assert(sink);
    9595        audio_device_t *dev = sink->private_data;
    96         if (new && list_count(&sink->sources) == 1) {
     96        if (new && list_count(&sink->connections) == 1) {
    9797                log_verbose("First connection on device sink '%s'", sink->name);
    9898
     
    104104                }
    105105                audio_pcm_register_event_callback(dev->sess,
    106                     device_event_callback, dev);
     106                    device_event_callback, dev);\
     107                // TODO set formats
    107108
    108109                /* Fill the buffer first */
     
    110111                    dev->buffer.base, dev->buffer.size);
    111112
     113                log_verbose("Mixed inputs: %zu/(%u * %u)",
     114                    dev->buffer.size, BUFFER_PARTS, pcm_format_frame_size(&dev->sink.format));
    112115                const unsigned frames = dev->buffer.size /
    113116                    (BUFFER_PARTS * pcm_format_frame_size(&dev->sink.format));
     117                log_verbose("FRAME COUNT %u", frames);
    114118                ret = audio_pcm_start_playback_fragment(dev->sess, frames,
    115119                    dev->sink.format.channels, dev->sink.format.sampling_rate,
     
    122126                }
    123127        }
    124         if (list_count(&sink->sources) == 0) {
     128        if (list_count(&sink->connections) == 0) {
    125129                assert(!new);
    126130                log_verbose("No connections on device sink '%s'", sink->name);
     
    142146}
    143147
    144 static int device_source_connection_callback(audio_source_t *source)
     148static int device_source_connection_callback(audio_source_t *source, bool new)
    145149{
    146150        assert(source);
    147151        audio_device_t *dev = source->private_data;
    148         if (source->connected_sink) {
     152        if (new && list_count(&source->connections)) {
    149153                int ret = get_buffer(dev);
    150154                if (ret != EOK) {
     
    164168                        return ret;
    165169                }
    166         } else { /* Disconnected */
     170        }
     171        if (list_count(&source->connections) == 0) { /* Disconnected */
     172                assert(!new);
    167173                int ret = audio_pcm_stop_capture(dev->sess);
    168174                if (ret != EOK) {
  • uspace/srv/audio/hound/audio_sink.c

    r39c4d1f rfa60cd69  
    4141
    4242#include "audio_sink.h"
     43#include "connection.h"
    4344#include "log.h"
    4445
     
    5455        }
    5556        link_initialize(&sink->link);
    56         list_initialize(&sink->sources);
     57        list_initialize(&sink->connections);
    5758        sink->name = str_dup(name);
    5859        sink->private_data = private_data;
     
    6768{
    6869        assert(sink);
     70        assert(list_empty(&sink->connections));
    6971        assert(!sink->private_data);
    7072        free(sink->name);
     
    7274}
    7375
     76#if 0
    7477int audio_sink_add_source(audio_sink_t *sink, audio_source_t *source)
    7578{
     
    9295
    9396        audio_source_connected(source, sink);
    94 
    9597        if (sink->connection_change) {
    9698                log_verbose("Calling connection change");
     
    98100                if (ret != EOK) {
    99101                        log_debug("Connection hook failed.");
    100                         audio_source_connected(source, NULL);
    101                         list_remove(&source->link);
    102                         sink->format = old_format;
     102        //              audio_source_connected(source, NULL);
     103        //              list_remove(&source->link);
     104//                      sink->format = old_format;
    103105                        return ret;
    104106                }
     
    109111        return EOK;
    110112}
     113#endif
    111114
    112115int audio_sink_set_format(audio_sink_t *sink, const pcm_format_t *format)
     
    118121                return EEXISTS;
    119122        }
    120         const pcm_format_t old_format;
     123        const pcm_format_t old_format = sink->format;
    121124
    122125        if (pcm_format_is_any(format)) {
     
    140143}
    141144
     145#if 0
    142146int audio_sink_remove_source(audio_sink_t *sink, audio_source_t *source)
    143147{
     
    157161        return EOK;
    158162}
     163#endif
    159164
    160165
     
    165170
    166171        pcm_format_silence(dest, size, &sink->format);
    167         list_foreach(sink->sources, it) {
    168                 audio_source_t *source = audio_source_list_instance(it);
    169                 const int ret =
    170                     audio_source_add_self(source, dest, size, &sink->format);
     172        list_foreach(sink->connections, it) {
     173                connection_t * conn = connection_from_sink_list(it);
     174                const int ret = connection_add_source_data(
     175                    conn, dest, size, sink->format);
    171176                if (ret != EOK) {
    172                         log_warning("Failed to mix source %s: %s",
    173                             source->name, str_error(ret));
     177                        log_warning("Failed to add source %s: %s",
     178                            connection_source_name(conn), str_error(ret));
    174179                }
    175180        }
  • uspace/srv/audio/hound/audio_sink.h

    r39c4d1f rfa60cd69  
    4949struct audio_sink {
    5050        link_t link;
    51         list_t sources;
     51        list_t connections;
    5252        const char *name;
    5353        pcm_format_t format;
     
    6868
    6969int audio_sink_set_format(audio_sink_t *sink, const pcm_format_t *format);
    70 int audio_sink_add_source(audio_sink_t *sink, audio_source_t *source);
    71 int audio_sink_remove_source(audio_sink_t *sink, audio_source_t *source);
     70//int audio_sink_add_source(audio_sink_t *sink, audio_source_t *source);
     71//int audio_sink_remove_source(audio_sink_t *sink, audio_source_t *source);
    7272void audio_sink_mix_inputs(audio_sink_t *sink, void* dest, size_t size);
    7373
  • uspace/srv/audio/hound/audio_source.c

    r39c4d1f rfa60cd69  
    4747
    4848int audio_source_init(audio_source_t *source, const char *name, void *data,
    49     int (*connection_change)(audio_source_t *),
     49    int (*connection_change)(audio_source_t *, bool new),
    5050    int (*update_available_data)(audio_source_t *, size_t),
    5151    const pcm_format_t *f)
     
    5757        }
    5858        link_initialize(&source->link);
     59        list_initialize(&source->connections);
    5960        source->name = str_dup(name);
    6061        source->private_data = data;
    6162        source->connection_change = connection_change;
    6263        source->update_available_data = update_available_data;
    63         source->connected_sink = NULL;
    6464        source->format = *f;
    6565        source->available_data.base = NULL;
     
    7373{
    7474        assert(source);
    75         assert(source->connected_sink == NULL);
    7675        free(source->name);
    7776        source->name = NULL;
    78 }
    79 
    80 int audio_source_connected(audio_source_t *source, struct audio_sink *sink)
    81 {
    82         assert(source);
    83         audio_sink_t *old_sink = source->connected_sink;
    84         const pcm_format_t old_format = source->format;
    85 
    86         source->connected_sink = sink;
    87         if (pcm_format_is_any(&source->format)) {
    88                 assert(sink);
    89                 assert(!pcm_format_is_any(&sink->format));
    90                 source->format = sink->format;
    91         }
    92         if (source->connection_change) {
    93                 const int ret = source->connection_change(source);
    94                 if (ret != EOK) {
    95                         source->format = old_format;
    96                         source->connected_sink = old_sink;
    97                         return ret;
    98                 }
    99         }
    100         return EOK;
    10177}
    10278
  • uspace/srv/audio/hound/audio_source.h

    r39c4d1f rfa60cd69  
    4545struct audio_source {
    4646        link_t link;
     47        list_t connections;
    4748        const char *name;
    4849        pcm_format_t format;
    4950        void *private_data;
    50         int (*connection_change)(audio_source_t *source);
     51        int (*connection_change)(audio_source_t *source, bool added);
    5152        int (*update_available_data)(audio_source_t *source, size_t size);
    52         struct audio_sink *connected_sink;
    5353        struct {
    5454                void *position;
     
    6464
    6565int audio_source_init(audio_source_t *source, const char *name, void *data,
    66     int (*connection_change)(audio_source_t *),
     66    int (*connection_change)(audio_source_t *, bool),
    6767    int (*update_available_data)(audio_source_t *, size_t),
    6868    const pcm_format_t *f);
    6969void audio_source_fini(audio_source_t *source);
    70 int audio_source_connected(audio_source_t *source, struct audio_sink *sink);
     70//int audio_source_connected(audio_source_t *source, struct audio_sink *sink);
    7171int audio_source_add_self(audio_source_t *source, void *buffer, size_t size,
    7272    const pcm_format_t *f);
  • uspace/srv/audio/hound/hound.c

    r39c4d1f rfa60cd69  
    4343#include "audio_sink.h"
    4444#include "audio_source.h"
     45#include "connection.h"
    4546#include "log.h"
    4647#include "errno.h"
     
    8687        list_initialize(&hound->sources);
    8788        list_initialize(&hound->sinks);
     89        list_initialize(&hound->connections);
    8890        return EOK;
    8991}
     
    207209                return EEXISTS;
    208210        }
    209         list_foreach(hound->sinks, it) {
    210                 audio_sink_t *sink = audio_sink_list_instance(it);
    211                 if (find_source_by_name(&sink->sources, source->name)) {
    212                         log_debug("Source by that name already exists");
    213                         fibril_mutex_unlock(&hound->list_guard);
    214                         return EEXISTS;
    215                 }
    216         }
    217211        list_append(&source->link, &hound->sources);
    218212        fibril_mutex_unlock(&hound->list_guard);
     
    245239        log_verbose("Removing source '%s'.", source->name);
    246240        fibril_mutex_lock(&hound->list_guard);
    247         if (!list_member(&source->link, &hound->sources)) {
    248                 assert(source->connected_sink);
    249                 hound_disconnect_internal(hound, source->name,
    250                     source->connected_sink->name);
    251         }
     241
    252242        list_remove(&source->link);
    253243        fibril_mutex_unlock(&hound->list_guard);
     
    263253        fibril_mutex_lock(&hound->list_guard);
    264254
    265         if (!list_empty(&sink->sources)) {
     255        if (!list_empty(&sink->connections)) {
    266256                // TODO disconnect instead
    267257                fibril_mutex_unlock(&hound->list_guard);
     
    278268        log_verbose("Connecting '%s' to '%s'.", source_name, sink_name);
    279269        fibril_mutex_lock(&hound->list_guard);
     270
     271        if (list_empty(&hound->sinks)) {
     272                fibril_mutex_unlock(&hound->list_guard);
     273                log_debug("No sinks available");
     274                return EINVAL;
     275        }
     276
     277        if (list_empty(&hound->sources)) {
     278                fibril_mutex_unlock(&hound->list_guard);
     279                log_debug("No sinks available");
     280                return EINVAL;
     281        }
    280282
    281283        audio_source_t *source =
     
    294296                return ENOENT;
    295297        }
    296         list_remove(&source->link);
    297         const int ret = audio_sink_add_source(sink, source);
    298         if (ret != EOK) {
    299                 log_debug("Failed add source to sink list: %s", str_error(ret));
    300                 list_append(&source->link, &hound->sources);
    301         }
    302         fibril_mutex_unlock(&hound->list_guard);
     298        connection_t *conn = connection_create(source, sink);
     299        if (!conn) {
     300                fibril_mutex_unlock(&hound->list_guard);
     301                log_debug("Failed to create connection");
     302                return ENOMEM;
     303        }
     304        list_append(&conn->hound_link, &hound->connections);
     305        fibril_mutex_unlock(&hound->list_guard);
     306        log_debug("CONNECTED: %s -> %s", source_name, sink_name);
    303307        return EOK;
    304308}
     
    317321        assert(hound);
    318322        assert(fibril_mutex_is_locked(&hound->list_guard));
    319         log_verbose("Disconnecting '%s' to '%s'.", source_name, sink_name);
    320 
    321         audio_sink_t *sink =
    322             audio_sink_list_instance(list_first(&hound->sinks));
    323         if (str_cmp(sink_name, "default") != 0)
    324             sink = find_sink_by_name(&hound->sinks, sink_name);
    325 
    326         audio_source_t *source =
    327             audio_source_list_instance(list_first(&hound->sources));
    328         if (str_cmp(source_name, "default") != 0)
    329             source = sink ? find_source_by_name(&sink->sources, source_name) : NULL;
    330         if (!source || !sink) {
    331                 log_debug("Source (%p), or sink (%p) not found", source, sink);
    332                 return ENOENT;
    333         }
    334         const int ret = audio_sink_remove_source(sink, source);
    335         if (ret != EOK) {
    336                 log_debug("Failed remove source to sink list: %s", str_error(ret));
    337         } else {
    338                 list_append(&source->link, &hound->sources);
    339         }
     323        log_debug("Disconnecting '%s' to '%s'.", source_name, sink_name);
     324
     325        list_foreach_safe(hound->connections, it, next) {
     326                connection_t *conn = connection_from_hound_list(it);
     327                if (str_cmp(connection_source_name(conn), source_name) == 0 ||
     328                    str_cmp(connection_sink_name(conn), sink_name) == 0) {
     329                    log_debug("Removing %s -> %s", connection_source_name(conn),
     330                        connection_sink_name(conn));
     331                    list_remove(it);
     332                    connection_destroy(conn);
     333                }
     334        }
     335
    340336        return EOK;
    341337}
  • uspace/srv/audio/hound/hound.h

    r39c4d1f rfa60cd69  
    5656        list_t sources;
    5757        list_t sinks;
     58        list_t connections;
    5859} hound_t;
    5960
  • uspace/srv/audio/hound/main.c

    r39c4d1f rfa60cd69  
    132132                        hound_server_get_unregister_params(&name);
    133133                        int ret = ENOENT;
    134                         list_foreach(local_playback, it) {
     134                        list_foreach_safe(local_playback, it, next) {
    135135                                audio_client_t *client =
    136136                                    audio_client_list_instance(it);
     137                                log_fatal("UNREGISTER_PLAYBACK %p", client);
    137138                                if (str_cmp(client->name, name) == 0) {
    138139                                        ret = hound_remove_source(&hound,
     
    213214                                        list_first(&local_playback));
    214215                                list_remove(&client->link);
     216                                log_fatal("CASE 0 %p", client);
    215217                                hound_remove_source(&hound, &client->source);
    216218                                audio_client_destroy(client);
Note: See TracChangeset for help on using the changeset viewer.