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. */ 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 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 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 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