source: mainline/uspace/srv/audio/hound/audio_client.c@ fa60cd69

lfn serial ticket/834-toolchain-update topic/msim-upgrade topic/simplify-dev-export
Last change on this file since fa60cd69 was fa60cd69, checked in by Jan Vesely <jano.vesely@…>, 12 years ago

hound: add connection class

This will enable N to M routing in the future

  • Property mode set to 100644
File size: 4.5 KB
RevLine 
[1df3018a]1/*
2 * Copyright (c) 2012 Jan Vesely
3 * All rights reserved.
4 *
5 * Redistribution and use in source and binary forms, with or without
6 * modification, are permitted provided that the following conditions
7 * are met:
8 *
9 * - Redistributions of source code must retain the above copyright
10 * notice, this list of conditions and the following disclaimer.
11 * - Redistributions in binary form must reproduce the above copyright
12 * notice, this list of conditions and the following disclaimer in the
13 * documentation and/or other materials provided with the distribution.
14 * - The name of the author may not be used to endorse or promote products
15 * derived from this software without specific prior written permission.
16 *
17 * THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``AS IS'' AND ANY EXPRESS OR
18 * IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES
19 * OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED.
20 * IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY DIRECT, INDIRECT,
21 * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT
22 * NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
23 * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
24 * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
25 * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF
26 * THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
27 */
28
29/** @addtogroup audio
30 * @brief HelenOS sound server
31 * @{
32 */
33/** @file
34 */
35
36#include <assert.h>
37#include <errno.h>
38#include <stdlib.h>
39#include <str.h>
40
41#include "audio_client.h"
42#include "log.h"
43
44static void init_common(audio_client_t *client, const char *name,
[ea6c838]45 const pcm_format_t *f, async_sess_t *sess)
[1df3018a]46{
47 link_initialize(&client->link);
48 client->name = str_dup(name);
49 client->format = *f;
50 client->sess = sess;
51 client->exch = NULL;
52 client->is_playback = false;
53 client->is_recording = false;
54}
55
[13df13c8]56static int client_sink_connection_change(audio_sink_t *sink, bool new);
[fa60cd69]57static int client_source_connection_change(audio_source_t *source, bool new);
[1df3018a]58static int client_source_update_data(audio_source_t *source, size_t size);
59
60
61audio_client_t *audio_client_get_playback(
[ea6c838]62 const char *name, const pcm_format_t *f, async_sess_t *sess)
[1df3018a]63{
64 audio_client_t *client = malloc(sizeof(audio_client_t));
65 if (!client)
66 return NULL;
67 init_common(client, name, f, sess);
68 audio_source_init(&client->source, name, client,
69 client_source_connection_change, client_source_update_data, f);
70 client->is_playback = true;
71 return client;
72}
73
74audio_client_t *audio_client_get_recording(
[ea6c838]75 const char *name, const pcm_format_t *f, async_sess_t *sess)
[1df3018a]76{
77 audio_client_t *client = malloc(sizeof(audio_client_t));
78 if (!client)
79 return NULL;
80 init_common(client, name, f, sess);
81 audio_sink_init(&client->sink, name, client,
[389ef25]82 client_sink_connection_change, NULL, f);
[1df3018a]83 client->is_recording = true;
84 return client;
85}
86
87void audio_client_destroy(audio_client_t *client)
88{
89 if (!client)
90 return;
91 if (client->is_recording) {
92 /* There is a fibril running */
93 client->is_recording = false;
94 return;
95 }
96 async_exchange_end(client->exch);
97 async_hangup(client->sess);
98 free(client->name);
99 if (client->is_playback) {
100 audio_source_fini(&client->source);
101 } else { /* was recording */
102 audio_sink_fini(&client->sink);
103 }
104 free(client);
105}
106
[13df13c8]107static int client_sink_connection_change(audio_sink_t *sink, bool new)
[1df3018a]108{
109 //TODO create fibril
110 return ENOTSUP;
111}
112
[fa60cd69]113static int client_source_connection_change(audio_source_t *source, bool new)
[1df3018a]114{
115 assert(source);
116 audio_client_t *client = source->private_data;
[fa60cd69]117 if (new && list_count(&source->connections) == 1) {
118 assert(!client->exch);
[1df3018a]119 client->exch = async_exchange_begin(client->sess);
120 return client->exch ? EOK : ENOMEM;
121 }
[fa60cd69]122 if (list_count(&source->connections) == 0) {
123 assert(!new);
124 async_exchange_end(client->exch);
125 client->exch = NULL;
126 }
[1df3018a]127 return EOK;
128}
129
130static int client_source_update_data(audio_source_t *source, size_t size)
131{
132 assert(source);
133 audio_client_t *client = source->private_data;
134 void *buffer = malloc(size);
135 if (!buffer)
136 return ENOMEM;
137 assert(client->exch);
[1c33539]138 const int ret = async_data_read_start(client->exch, buffer, size);
[1df3018a]139 if (ret != EOK) {
140 log_debug("Failed to read data from client");
141 free(buffer);
142 return ret;
143 }
144 void *old_buffer = source->available_data.base;
[ab07cf0]145 source->available_data.position = buffer;
[1df3018a]146 source->available_data.base = buffer;
147 source->available_data.size = size;
148 free(old_buffer);
149
150 return EOK;
151}
Note: See TracBrowser for help on using the repository browser.