Changeset 6eeaf1d in mainline


Ignore:
Timestamp:
2013-04-11T22:29:14Z (12 years ago)
Author:
Jan Vesely <jano.vesely@…>
Branches:
lfn, master, serial, ticket/834-toolchain-update, topic/msim-upgrade, topic/simplify-dev-export
Children:
4e72a4c
Parents:
4eff63c
Message:

hound: implement context sink

File:
1 edited

Legend:

Unmodified
Added
Removed
  • uspace/srv/audio/hound/hound_ctx.c

    r4eff63c r6eeaf1d  
    3737#include <malloc.h>
    3838#include <macros.h>
     39#include <errno.h>
     40#include <str_error.h>
    3941
    4042#include "hound_ctx.h"
     
    4446
    4547static int update_data(audio_source_t *source, size_t size);
     48static int new_data(audio_sink_t *sink);
    4649
    4750/**
     
    6568                        return NULL;
    6669                }
    67                 // TODO provide sink functions
    6870                const int ret = audio_sink_init(ctx->sink, name, ctx, NULL,
    69                     NULL, NULL, &AUDIO_FORMAT_DEFAULT);
     71                    NULL, new_data, &AUDIO_FORMAT_DEFAULT);
    7072                if (ret != EOK) {
    7173                        free(ctx->sink);
     
    202204
    203205/**
     206 * Push new data to stream, do not block.
     207 * @param stream The target stream.
     208 * @param adata The new data.
     209 * @return Error code.
     210 */
     211static int stream_push_data(hound_ctx_stream_t *stream, audio_data_t *adata)
     212{
     213        assert(stream);
     214        assert(adata);
     215
     216        if (stream->allowed_size && adata->size > stream->allowed_size)
     217                return EINVAL;
     218
     219        fibril_mutex_lock(&stream->guard);
     220        if (stream->allowed_size &&
     221            (audio_pipe_bytes(&stream->fifo) + adata->size
     222                > stream->allowed_size)) {
     223                fibril_mutex_unlock(&stream->guard);
     224                return EOVERFLOW;
     225
     226        }
     227
     228        const int ret = audio_pipe_push(&stream->fifo, adata);
     229        fibril_mutex_unlock(&stream->guard);
     230        if (ret == EOK)
     231                fibril_condvar_signal(&stream->change);
     232        return ret;
     233}
     234
     235/**
    204236 * Old stream remove helper.
    205237 * @param ctx hound context.
     
    293325            audio_pipe_push_data(&stream->fifo, data, size, stream->format);
    294326        fibril_mutex_unlock(&stream->guard);
     327        if (ret == EOK)
     328                fibril_condvar_signal(&stream->change);
    295329        return ret;
    296330}
     
    305339int hound_ctx_stream_read(hound_ctx_stream_t *stream, void *data, size_t size)
    306340{
    307         log_verbose("%p:, %zu", stream, size);
    308         return ENOTSUP;
     341        assert(stream);
     342
     343        if (stream->allowed_size && size > stream->allowed_size)
     344                return EINVAL;
     345
     346        fibril_mutex_lock(&stream->guard);
     347        while (audio_pipe_bytes(&stream->fifo) < size) {
     348            fibril_condvar_wait(&stream->change, &stream->guard);
     349        }
     350
     351        pcm_format_silence(data, size, &stream->format);
     352        const int ret =
     353            audio_pipe_mix_data(&stream->fifo, data, size, &stream->format);
     354        fibril_mutex_unlock(&stream->guard);
     355        if (ret == EOK)
     356                fibril_condvar_signal(&stream->change);
     357        return ret;
    309358}
    310359
     
    385434}
    386435
     436int new_data(audio_sink_t *sink)
     437{
     438        assert(sink);
     439        assert(sink->private_data);
     440        hound_ctx_t *ctx = sink->private_data;
     441
     442        fibril_mutex_lock(&ctx->guard);
     443
     444        /* count available data */
     445        size_t available_frames = -1;  /* this is ugly.... */
     446        list_foreach(sink->connections, it) {
     447                connection_t *conn = connection_from_source_list(it);
     448                available_frames = min(available_frames,
     449                    audio_pipe_frames(&conn->fifo));
     450        }
     451
     452        const size_t bsize =
     453            available_frames * pcm_format_frame_size(&sink->format);
     454        void *buffer = malloc(bsize);
     455        if (!buffer) {
     456                fibril_mutex_unlock(&ctx->guard);
     457                return ENOMEM;
     458        }
     459        audio_data_t *adata = audio_data_create(buffer, bsize, sink->format);
     460        if (!adata) {
     461                fibril_mutex_unlock(&ctx->guard);
     462                free(buffer);
     463                return ENOMEM;
     464        }
     465
     466        /* mix data */
     467        pcm_format_silence(buffer, bsize, &sink->format);
     468        list_foreach(sink->connections, it) {
     469                connection_t *conn = connection_from_source_list(it);
     470                /* This should not trigger data update on the source */
     471                const size_t copied = connection_add_source_data(
     472                    conn, buffer, bsize, sink->format);
     473                if (copied != bsize)
     474                        log_error("Copied less than advertised data, "
     475                            "something is wrong");
     476        }
     477        /* push to all streams */
     478        list_foreach(ctx->streams, it) {
     479                hound_ctx_stream_t *stream = hound_ctx_stream_from_link(it);
     480                const int ret = stream_push_data(stream, adata);
     481                if (ret != EOK)
     482                        log_error("Failed to push data to stream: %s",
     483                                str_error(ret));
     484        }
     485        audio_data_unref(adata);
     486        fibril_mutex_unlock(&ctx->guard);
     487        return ENOTSUP;
     488}
     489
    387490/**
    388491 * @}
Note: See TracChangeset for help on using the changeset viewer.