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

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

hound: Implement disconnect

  • Property mode set to 100644
File size: 4.3 KB
Line 
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,
45 const audio_format_t *f, async_sess_t *sess)
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
56static int client_sink_connection_change(audio_sink_t *sink);
57static int client_source_connection_change(audio_source_t *source);
58static int client_source_update_data(audio_source_t *source, size_t size);
59
60
61audio_client_t *audio_client_get_playback(
62 const char *name, const audio_format_t *f, async_sess_t *sess)
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(
75 const char *name, const audio_format_t *f, async_sess_t *sess)
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,
82 client_sink_connection_change, f);
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
107static int client_sink_connection_change(audio_sink_t *sink)
108{
109 //TODO create fibril
110 return ENOTSUP;
111}
112
113static int client_source_connection_change(audio_source_t *source)
114{
115 assert(source);
116 audio_client_t *client = source->private_data;
117 if (source->connected_sink) {
118 client->exch = async_exchange_begin(client->sess);
119 return client->exch ? EOK : ENOMEM;
120 }
121 async_exchange_end(client->exch);
122 client->exch = NULL;
123 return EOK;
124}
125
126static int client_source_update_data(audio_source_t *source, size_t size)
127{
128 assert(source);
129 audio_client_t *client = source->private_data;
130 void *buffer = malloc(size);
131 if (!buffer)
132 return ENOMEM;
133 assert(client->exch);
134 const int ret = async_data_read_start(client->exch, buffer, size);
135 if (ret != EOK) {
136 log_debug("Failed to read data from client");
137 free(buffer);
138 return ret;
139 }
140 void *old_buffer = source->available_data.base;
141 source->available_data.base = buffer;
142 source->available_data.size = size;
143 free(old_buffer);
144
145 return EOK;
146}
Note: See TracBrowser for help on using the repository browser.