/* * Copyright (c) 2012 Jan Vesely * All rights reserved. * * Redistribution and use in source and binary forms, with or without * modification, are permitted provided that the following conditions * are met: * * - Redistributions of source code must retain the above copyright * notice, this list of conditions and the following disclaimer. * - Redistributions in binary form must reproduce the above copyright * notice, this list of conditions and the following disclaimer in the * documentation and/or other materials provided with the distribution. * - The name of the author may not be used to endorse or promote products * derived from this software without specific prior written permission. * * THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``AS IS'' AND ANY EXPRESS OR * IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES * OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. * IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY DIRECT, INDIRECT, * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT * NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF * THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. */ /** @addtogroup audio * @brief HelenOS sound server * @{ */ /** @file */ #include <assert.h> #include <errno.h> #include <macros.h> #include <stdlib.h> #include <str.h> #include <str_error.h> #include "audio_data.h" #include "audio_source.h" #include "audio_sink.h" #include "connection.h" #include "log.h" /** * Initialize audio source strcture. * @param source The structure to initialize. * @param name String identifier of the audio source. * @param data Backend data. * @param connection_change Connect/disconnect callback. * @param update_available_data Data request callback. * @return Error code. */ errno_t audio_source_init(audio_source_t *source, const char *name, void *data, errno_t (*connection_change)(audio_source_t *, bool new), errno_t (*update_available_data)(audio_source_t *, size_t), const pcm_format_t *f) { assert(source); if (!name || !f) { log_debug("Incorrect parameters."); return EINVAL; } link_initialize(&source->link); list_initialize(&source->connections); source->name = str_dup(name); if (!source->name) return ENOMEM; source->private_data = data; source->connection_change = connection_change; source->update_available_data = update_available_data; source->format = *f; log_verbose("Initialized source (%p) '%s'", source, source->name); return EOK; } /** * Release resources claimed by initialization. * @param source The structure to cleanup. */ void audio_source_fini(audio_source_t *source) { assert(source); free(source->name); source->name = NULL; } /** * Push data to all connections. * @param source The source of the data. * @param dest Destination buffer. * @param size size of the @p dest buffer. * @return Error code. */ errno_t audio_source_push_data(audio_source_t *source, void *data, size_t size) { assert(source); assert(data); audio_data_t *adata = audio_data_create(data, size, source->format); if (!adata) return ENOMEM; list_foreach(source->connections, source_link, connection_t, conn) { const errno_t ret = connection_push_data(conn, adata); if (ret != EOK) { log_warning("Failed push data to %s: %s", connection_sink_name(conn), str_error(ret)); } } audio_data_unref(adata); return EOK; } /** * @} */