1 /* Copyright 2018 The Chromium OS Authors. All rights reserved.
2 * Use of this source code is governed by a BSD-style license that can be
3 * found in the LICENSE file.
4 */
5
6 #include <syslog.h>
7
8 #include "cras_rstream.h"
9 #include "cras_server.h"
10 #include "cras_system_state.h"
11 #include "cras_types.h"
12 #include "server_stream.h"
13 #include "stream_list.h"
14
15
16 /* Parameters used for server stream. */
17 static unsigned int server_stream_block_size = 480;
18
19 /*
20 * Server stream doesn't care what format is used, because no
21 * client is reading data from stream. The main point is to
22 * make pinned device open and let data flow through its dsp
23 * pipeline.
24 */
25 static struct cras_audio_format format =
26 {
27 SND_PCM_FORMAT_S16_LE,
28 48000,
29 2,
30 };
31
32 /*
33 * Information of a stream created by server. Currently only
34 * one server stream is allowed, for echo reference use.
35 */
36 static struct cras_rstream_config *stream_config;
37
38 /* Actually create the server stream and add to stream list. */
server_stream_add_cb(void * data)39 static void server_stream_add_cb(void *data)
40 {
41 struct stream_list *stream_list = (struct stream_list *)data;
42 struct cras_rstream *stream;
43
44 if (!stream_config)
45 return;
46
47 stream_list_add(stream_list, stream_config, &stream);
48 }
49
server_stream_create(struct stream_list * stream_list,unsigned int dev_idx)50 void server_stream_create(struct stream_list *stream_list, unsigned int dev_idx)
51 {
52 if (stream_config) {
53 syslog(LOG_ERR, "server stream already exists, dev %u",
54 stream_config->dev_idx);
55 return;
56 }
57
58 stream_config = (struct cras_rstream_config *)
59 calloc(1, sizeof(*stream_config));
60 stream_config->format = &format;
61 stream_config->stream_id =
62 cras_get_stream_id(SERVER_STREAM_CLIENT_ID, 0);
63 stream_config->stream_type = CRAS_STREAM_TYPE_DEFAULT;
64 stream_config->direction = CRAS_STREAM_INPUT;
65 stream_config->flags = SERVER_ONLY;
66 stream_config->buffer_frames = server_stream_block_size;
67 stream_config->cb_threshold = server_stream_block_size;
68 stream_config->dev_idx = dev_idx;
69 stream_config->audio_fd = -1;
70
71 /* Schedule add stream in next main thread loop. */
72 cras_system_add_task(server_stream_add_cb, stream_list);
73 }
74
server_stream_rm_cb(void * data)75 static void server_stream_rm_cb(void *data)
76 {
77 struct stream_list *stream_list = (struct stream_list *)data;
78
79 if (stream_config == NULL)
80 return;
81
82 if (stream_list_rm(stream_list, stream_config->stream_id))
83 syslog(LOG_ERR, "Server stream %x no longer exist",
84 stream_config->stream_id);
85
86 free(stream_config);
87 stream_config = NULL;
88 }
89
server_stream_destroy(struct stream_list * stream_list,unsigned int dev_idx)90 void server_stream_destroy(struct stream_list *stream_list,
91 unsigned int dev_idx)
92 {
93 if (!stream_config || stream_config->dev_idx != dev_idx) {
94 syslog(LOG_ERR, "No server stream to destroy");
95 return;
96 }
97 /* Schedule remove stream in next main thread loop. */
98 cras_system_add_task(server_stream_rm_cb, stream_list);
99 }
100