source: mainline/uspace/srv/audio/hound/main.c@ 39c4d1f

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

Merge mainline changes.

Conflict resulting from bool.h → stdbool.h move and ddf structs turning opaque.
Fails to boot to shell console.

  • Property mode set to 100644
File size: 7.0 KB
RevLine 
[737b4c0]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/**
30 * @addtogroup audio
31 * @brief HelenOS sound server.
32 * @{
33 */
34/** @file
35 */
36
37#include <async.h>
38#include <errno.h>
39#include <stdio.h>
40#include <stdlib.h>
41#include <str_error.h>
[eceb300]42#include <hound/server.h>
43
[737b4c0]44
45#include "hound.h"
46
47#define NAMESPACE "audio"
48#define NAME "hound"
49#define CATEGORY "audio-pcm"
50
[1df3018a]51#include "audio_client.h"
[737b4c0]52#include "log.h"
[1df3018a]53
54static hound_t hound;
55
[eceb300]56static int device_callback(service_id_t id, const char *name)
[1df3018a]57{
[eceb300]58 return hound_add_device(&hound, id, name);
[1df3018a]59}
[737b4c0]60
61static void scan_for_devices(void)
62{
[eceb300]63 hound_server_devices_iterate(device_callback);
[737b4c0]64}
65
[1df3018a]66static void client_connection(ipc_callid_t iid, ipc_call_t *icall, void *arg)
67{
68 async_answer_0(iid, EOK);
69
70 LIST_INITIALIZE(local_playback);
71 LIST_INITIALIZE(local_recording);
[ea6c838]72 pcm_format_t format = {0};
[eceb300]73 const char *name = NULL;
74 async_sess_t *sess = NULL;
[1df3018a]75
76 while (1) {
77 ipc_call_t call;
78 ipc_callid_t callid = async_get_call(&call);
79 switch (IPC_GET_IMETHOD(call)) {
80 case HOUND_REGISTER_PLAYBACK: {
[eceb300]81 hound_server_get_register_params(&name, &sess,
82 &format.channels, &format.sampling_rate,
83 &format.sample_format);
[63d6ff9]84 audio_client_t *client =
[1df3018a]85 audio_client_get_playback(name, &format, sess);
[63d6ff9]86 free(name);
[1df3018a]87 if (!client) {
88 log_error("Failed to create playback client");
89 async_answer_0(callid, ENOMEM);
[63d6ff9]90 break;
[1df3018a]91 }
92 int ret = hound_add_source(&hound, &client->source);
93 if (ret != EOK){
94 audio_client_destroy(client);
95 log_error("Failed to add audio source: %s",
96 str_error(ret));
97 async_answer_0(callid, ret);
98 break;
99 }
[63d6ff9]100 log_info("Added audio client %p '%s'",
101 client, client->name);
[1df3018a]102 async_answer_0(callid, EOK);
103 list_append(&client->link, &local_playback);
104 break;
105 }
106 case HOUND_REGISTER_RECORDING: {
[eceb300]107 hound_server_get_register_params(&name, &sess,
108 &format.channels, &format.sampling_rate,
109 &format.sample_format);
110 audio_client_t *client =
[1df3018a]111 audio_client_get_recording(name, &format, sess);
[6424800]112 free(name);
[1df3018a]113 if (!client) {
114 log_error("Failed to create recording client");
115 async_answer_0(callid, ENOMEM);
116 break;
117 }
118 int ret = hound_add_sink(&hound, &client->sink);
119 if (ret != EOK){
120 audio_client_destroy(client);
121 log_error("Failed to add audio sink: %s",
122 str_error(ret));
123 async_answer_0(callid, ret);
124 break;
125 }
126 async_answer_0(callid, EOK);
127 list_append(&client->link, &local_recording);
128 break;
129 }
130 case HOUND_UNREGISTER_PLAYBACK: {
[eceb300]131 const char *name = NULL;
132 hound_server_get_unregister_params(&name);
[6424800]133 int ret = ENOENT;
134 list_foreach(local_playback, it) {
135 audio_client_t *client =
136 audio_client_list_instance(it);
137 if (str_cmp(client->name, name) == 0) {
138 ret = hound_remove_source(&hound,
139 &client->source);
140 if (ret == EOK) {
141 list_remove(&client->link);
142 audio_client_destroy(client);
143 }
144 break;
145 }
146 }
147 free(name);
148 async_answer_0(callid, ret);
[1df3018a]149 break;
150 }
151 case HOUND_UNREGISTER_RECORDING: {
[eceb300]152 const char *name = NULL;
153 hound_server_get_unregister_params(&name);
[6424800]154 int ret = ENOENT;
155 list_foreach(local_recording, it) {
156 audio_client_t *client =
157 audio_client_list_instance(it);
158 if (str_cmp(client->name, name) == 0) {
159 ret = hound_remove_sink(&hound,
160 &client->sink);
161 if (ret == EOK) {
162 list_remove(&client->link);
163 audio_client_destroy(client);
164 }
165 break;
166 }
167 }
168 free(name);
169 async_answer_0(callid, ret);
[1df3018a]170 break;
171 }
172 case HOUND_CONNECT: {
[eceb300]173 const char *source = NULL, *sink = NULL;
174 hound_server_get_connection_params(&source, &sink);
175 const int ret = hound_connect(&hound, source, sink);
[f3fced0]176 if (ret != EOK)
177 log_error("Failed to connect '%s' to '%s': %s",
[eceb300]178 source, sink, str_error(ret));
179 free(source);
180 free(sink);
[f3fced0]181 async_answer_0(callid, ret);
[1df3018a]182 break;
183 }
184 case HOUND_DISCONNECT: {
[eceb300]185 const char *source = NULL, *sink = NULL;
186 hound_server_get_connection_params(&source, &sink);
187 const int ret = hound_disconnect(&hound, source, sink);
[f3fced0]188 if (ret != EOK)
189 log_error("Failed to disconnect '%s' from '%s'"
[eceb300]190 ": %s", source, sink, str_error(ret));
191 free(source);
192 free(sink);
[f3fced0]193 async_answer_0(callid, ret);
[1df3018a]194 break;
195 }
196 default:
[f3fced0]197 log_debug("Got unknown method %u",
198 IPC_GET_IMETHOD(call));
[1df3018a]199 async_answer_0(callid, ENOTSUP);
200 break;
201 case 0:
[6424800]202 while(!list_empty(&local_recording)) {
203 audio_client_t *client =
204 audio_client_list_instance(
205 list_first(&local_recording));
206 list_remove(&client->link);
207 hound_remove_sink(&hound, &client->sink);
208 audio_client_destroy(client);
209 }
210 while(!list_empty(&local_playback)) {
211 audio_client_t *client =
212 audio_client_list_instance(
213 list_first(&local_playback));
214 list_remove(&client->link);
215 hound_remove_source(&hound, &client->source);
216 audio_client_destroy(client);
217 }
[1df3018a]218 return;
219 }
220 }
221}
[737b4c0]222
223int main(int argc, char **argv)
224{
225 printf("%s: HelenOS sound service\n", NAME);
226
227 int ret = hound_init(&hound);
228 if (ret != EOK) {
[1df3018a]229 log_fatal("Failed to initialize hound structure: %s",
230 str_error(ret));
231 return -ret;
232 }
233
234 async_set_client_connection(client_connection);
235
236 service_id_t id = 0;
[eceb300]237 ret = hound_server_register(NAME, &id);
[1df3018a]238 if (ret != EOK) {
[eceb300]239 log_fatal("Failed to register server: %s", str_error(ret));
[1df3018a]240 return -ret;
[737b4c0]241 }
242
[eceb300]243 ret = hound_server_set_device_change_callback(scan_for_devices);
[1df3018a]244 if (ret != EOK) {
[eceb300]245 log_fatal("Failed to register for device changes: %s",
[1df3018a]246 str_error(ret));
[eceb300]247 hound_server_unregister(id);
[1df3018a]248 return -ret;
249 }
250 log_info("Running with service id %u", id);
[737b4c0]251
252 scan_for_devices();
253
254 async_manager();
255 return 0;
256}
257
258/**
259 * @}
260 */
Note: See TracBrowser for help on using the repository browser.