1 /* Copyright (c) 2012 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 <fcntl.h>
7 #include <stdint.h>
8 #include <sys/mman.h>
9 #include <sys/types.h>
10 #include <syslog.h>
11 
12 #include "cras_audio_area.h"
13 #include "cras_config.h"
14 #include "cras_messages.h"
15 #include "cras_rclient.h"
16 #include "cras_rstream.h"
17 #include "cras_shm.h"
18 #include "cras_types.h"
19 #include "buffer_share.h"
20 #include "cras_system_state.h"
21 
22 /* Configure the shm area for the stream. */
setup_shm(struct cras_rstream * stream,struct cras_audio_shm * shm,struct rstream_shm_info * shm_info)23 static int setup_shm(struct cras_rstream *stream,
24 		     struct cras_audio_shm *shm,
25 		     struct rstream_shm_info *shm_info)
26 {
27 	size_t used_size, samples_size, frame_bytes;
28 	const struct cras_audio_format *fmt = &stream->format;
29 
30 	if (shm->area != NULL) /* already setup */
31 		return -EEXIST;
32 
33 	frame_bytes = snd_pcm_format_physical_width(fmt->format) / 8 *
34 			fmt->num_channels;
35 	used_size = stream->buffer_frames * frame_bytes;
36 	samples_size = used_size * CRAS_NUM_SHM_BUFFERS;
37 	shm_info->length = sizeof(struct cras_audio_shm_area) + samples_size;
38 
39 	snprintf(shm_info->shm_name, sizeof(shm_info->shm_name),
40 		 "/cras-%d-stream-%08x", getpid(), stream->stream_id);
41 
42 	shm_info->shm_fd = cras_shm_open_rw(shm_info->shm_name, shm_info->length);
43 	if (shm_info->shm_fd < 0)
44 		return shm_info->shm_fd;
45 
46 	/* mmap shm. */
47 	shm->area = mmap(NULL, shm_info->length,
48 			 PROT_READ | PROT_WRITE, MAP_SHARED,
49 			 shm_info->shm_fd, 0);
50 	if (shm->area == (struct cras_audio_shm_area *)-1) {
51 		close(shm_info->shm_fd);
52 		return errno;
53 	}
54 
55 	cras_shm_set_volume_scaler(shm, 1.0);
56 	/* Set up config and copy to shared area. */
57 	cras_shm_set_frame_bytes(shm, frame_bytes);
58 	shm->config.frame_bytes = frame_bytes;
59 	cras_shm_set_used_size(shm, used_size);
60 	memcpy(&shm->area->config, &shm->config, sizeof(shm->config));
61 	return 0;
62 }
63 
64 /* Setup the shared memory area used for audio samples. */
setup_shm_area(struct cras_rstream * stream)65 static inline int setup_shm_area(struct cras_rstream *stream)
66 {
67 	int rc;
68 
69 	rc = setup_shm(stream, &stream->shm,
70 			&stream->shm_info);
71 	if (rc)
72 		return rc;
73 	stream->audio_area =
74 		cras_audio_area_create(stream->format.num_channels);
75 	cras_audio_area_config_channels(stream->audio_area, &stream->format);
76 
77 	return 0;
78 }
79 
buffer_meets_size_limit(size_t buffer_size,size_t rate)80 static inline int buffer_meets_size_limit(size_t buffer_size, size_t rate)
81 {
82 	return buffer_size > (CRAS_MIN_BUFFER_TIME_IN_US * rate) / 1000000;
83 }
84 
85 /* Verifies that the given stream parameters are valid. */
verify_rstream_parameters(enum CRAS_STREAM_DIRECTION direction,const struct cras_audio_format * format,enum CRAS_STREAM_TYPE stream_type,size_t buffer_frames,size_t cb_threshold,struct cras_rclient * client,struct cras_rstream ** stream_out)86 static int verify_rstream_parameters(enum CRAS_STREAM_DIRECTION direction,
87 				     const struct cras_audio_format *format,
88 				     enum CRAS_STREAM_TYPE stream_type,
89 				     size_t buffer_frames,
90 				     size_t cb_threshold,
91 				     struct cras_rclient *client,
92 				     struct cras_rstream **stream_out)
93 {
94 	if (!buffer_meets_size_limit(buffer_frames, format->frame_rate)) {
95 		syslog(LOG_ERR, "rstream: invalid buffer_frames %zu\n",
96 		       buffer_frames);
97 		return -EINVAL;
98 	}
99 	if (stream_out == NULL) {
100 		syslog(LOG_ERR, "rstream: stream_out can't be NULL\n");
101 		return -EINVAL;
102 	}
103 	if (format == NULL) {
104 		syslog(LOG_ERR, "rstream: format can't be NULL\n");
105 		return -EINVAL;
106 	}
107 	if ((format->format != SND_PCM_FORMAT_S16_LE) &&
108 	    (format->format != SND_PCM_FORMAT_S32_LE) &&
109 	    (format->format != SND_PCM_FORMAT_U8) &&
110 	    (format->format != SND_PCM_FORMAT_S24_LE)) {
111 		syslog(LOG_ERR, "rstream: format %d not supported\n",
112 		       format->format);
113 		return -EINVAL;
114 	}
115 	if (direction != CRAS_STREAM_OUTPUT && direction != CRAS_STREAM_INPUT) {
116 		syslog(LOG_ERR, "rstream: Invalid direction.\n");
117 		return -EINVAL;
118 	}
119 	if (stream_type < CRAS_STREAM_TYPE_DEFAULT ||
120 	    stream_type >= CRAS_STREAM_NUM_TYPES) {
121 		syslog(LOG_ERR, "rstream: Invalid stream type.\n");
122 		return -EINVAL;
123 	}
124 	if (!buffer_meets_size_limit(cb_threshold, format->frame_rate)) {
125 		syslog(LOG_ERR, "rstream: cb_threshold too low\n");
126 		return -EINVAL;
127 	}
128 	return 0;
129 }
130 
131 /*
132  * Setting pending reply is only needed inside this module.
133  */
set_pending_reply(struct cras_rstream * stream)134 static void set_pending_reply(struct cras_rstream *stream)
135 {
136 	cras_shm_set_callback_pending(&stream->shm, 1);
137 }
138 
139 /*
140  * Clearing pending reply is only needed inside this module.
141  */
clear_pending_reply(struct cras_rstream * stream)142 static void clear_pending_reply(struct cras_rstream *stream)
143 {
144 	cras_shm_set_callback_pending(&stream->shm, 0);
145 }
146 
147 /*
148  * Reads one response of audio request from client.
149  * Args:
150  *   stream[in]: A pointer to cras_rstream.
151  *   msg[out]: A pointer to audio_message to hold the message.
152  * Returns:
153  *   Number of bytes read from the socket.
154  *   A negative error code if read fails or the message from client
155  *   has errors.
156  */
get_audio_request_reply(const struct cras_rstream * stream,struct audio_message * msg)157 static int get_audio_request_reply(
158 	const struct cras_rstream *stream, struct audio_message *msg)
159 {
160 	int rc;
161 
162 	rc = read(stream->fd, msg, sizeof(*msg));
163 	if (rc < 0)
164 		return -errno;
165 	if (rc == 0)
166 		return rc;
167 	if (msg->error < 0)
168 		return msg->error;
169 	return rc;
170 }
171 
172 /*
173  * Reads and handles one audio message from client.
174  * Returns:
175  *   Number of bytes read from the socket.
176  *   A negative error code if read fails or the message from client
177  *   has errors.
178  */
read_and_handle_client_message(struct cras_rstream * stream)179 static int read_and_handle_client_message(struct cras_rstream *stream) {
180 
181 	struct audio_message msg;
182 	int rc;
183 
184 	rc = get_audio_request_reply(stream, &msg);
185 	if (rc <= 0) {
186 		syslog(LOG_ERR, "Got error from client: rc: %d", rc);
187 		clear_pending_reply(stream);
188 		return rc;
189 	}
190 
191 	/*
192 	 * Got client reply that data in the input stream is captured.
193 	 */
194 	if (stream->direction == CRAS_STREAM_INPUT &&
195 	    msg.id == AUDIO_MESSAGE_DATA_CAPTURED) {
196 		clear_pending_reply(stream);
197 	}
198 
199 	/*
200 	 * Got client reply that data for output stream is ready in shm.
201 	 */
202 	if (stream->direction == CRAS_STREAM_OUTPUT &&
203 	    msg.id == AUDIO_MESSAGE_DATA_READY) {
204 		clear_pending_reply(stream);
205 	}
206 
207 	return rc;
208 }
209 
210 /* Exported functions */
211 
cras_rstream_create(struct cras_rstream_config * config,struct cras_rstream ** stream_out)212 int cras_rstream_create(struct cras_rstream_config *config,
213 			struct cras_rstream **stream_out)
214 {
215 	struct cras_rstream *stream;
216 	int rc;
217 
218 	rc = verify_rstream_parameters(config->direction, config->format,
219 				       config->stream_type,
220 				       config->buffer_frames,
221 				       config->cb_threshold, config->client,
222 				       stream_out);
223 	if (rc < 0)
224 		return rc;
225 
226 	stream = calloc(1, sizeof(*stream));
227 	if (stream == NULL)
228 		return -ENOMEM;
229 
230 	stream->stream_id = config->stream_id;
231 	stream->stream_type = config->stream_type;
232 	stream->direction = config->direction;
233 	stream->flags = config->flags;
234 	stream->format = *config->format;
235 	stream->buffer_frames = config->buffer_frames;
236 	stream->cb_threshold = config->cb_threshold;
237 	stream->client = config->client;
238 	stream->shm.area = NULL;
239 	stream->master_dev.dev_id = NO_DEVICE;
240 	stream->master_dev.dev_ptr = NULL;
241 	stream->is_pinned = (config->dev_idx != NO_DEVICE);
242 	stream->pinned_dev_idx = config->dev_idx;
243 	stream->fd = config->audio_fd;
244 
245 	rc = setup_shm_area(stream);
246 	if (rc < 0) {
247 		syslog(LOG_ERR, "failed to setup shm %d\n", rc);
248 		free(stream);
249 		return rc;
250 	}
251 
252 	stream->buf_state = buffer_share_create(stream->buffer_frames);
253 	stream->apm_list = (stream->direction == CRAS_STREAM_INPUT)
254 			? cras_apm_list_create(stream, config->effects)
255 			: NULL;
256 
257 	syslog(LOG_DEBUG, "stream %x frames %zu, cb_thresh %zu",
258 	       config->stream_id, config->buffer_frames, config->cb_threshold);
259 	*stream_out = stream;
260 
261 	cras_system_state_stream_added(stream->direction);
262 
263 	return 0;
264 }
265 
cras_rstream_destroy(struct cras_rstream * stream)266 void cras_rstream_destroy(struct cras_rstream *stream)
267 {
268 	cras_system_state_stream_removed(stream->direction);
269 	close(stream->fd);
270 	if (stream->shm.area != NULL) {
271 		munmap(stream->shm.area, stream->shm_info.length);
272 		cras_shm_close_unlink(stream->shm_info.shm_name,
273 				      stream->shm_info.shm_fd);
274 		cras_audio_area_destroy(stream->audio_area);
275 	}
276 	buffer_share_destroy(stream->buf_state);
277 	if (stream->apm_list)
278 		cras_apm_list_destroy(stream->apm_list);
279 	free(stream);
280 }
281 
cras_rstream_get_effects(const struct cras_rstream * stream)282 unsigned int cras_rstream_get_effects(const struct cras_rstream *stream)
283 {
284 	return stream->apm_list
285 			? cras_apm_list_get_effects(stream->apm_list)
286 			: 0;
287 }
288 
cras_rstream_post_processing_format(const struct cras_rstream * stream,void * dev_ptr)289 struct cras_audio_format *cras_rstream_post_processing_format(
290 		const struct cras_rstream *stream, void *dev_ptr)
291 {
292 	struct cras_apm *apm;
293 
294 	if (NULL == stream->apm_list)
295 		return NULL;
296 
297 	apm = cras_apm_list_get(stream->apm_list, dev_ptr);
298 	if (NULL == apm)
299 		return NULL;
300 	return cras_apm_list_get_format(apm);
301 }
302 
cras_rstream_record_fetch_interval(struct cras_rstream * rstream,const struct timespec * now)303 void cras_rstream_record_fetch_interval(struct cras_rstream *rstream,
304 					const struct timespec *now)
305 {
306 	struct timespec ts;
307 
308 	if (rstream->last_fetch_ts.tv_sec || rstream->last_fetch_ts.tv_nsec) {
309 		subtract_timespecs(now, &rstream->last_fetch_ts, &ts);
310 		if (timespec_after(&ts, &rstream->longest_fetch_interval))
311 			rstream->longest_fetch_interval = ts;
312 	}
313 }
314 
init_audio_message(struct audio_message * msg,enum CRAS_AUDIO_MESSAGE_ID id,uint32_t frames)315 static void init_audio_message(struct audio_message *msg,
316 			       enum CRAS_AUDIO_MESSAGE_ID id,
317 			       uint32_t frames)
318 {
319 	memset(msg, 0, sizeof(*msg));
320 	msg->id = id;
321 	msg->frames = frames;
322 }
323 
cras_rstream_request_audio(struct cras_rstream * stream,const struct timespec * now)324 int cras_rstream_request_audio(struct cras_rstream *stream,
325 			       const struct timespec *now)
326 {
327 	struct audio_message msg;
328 	int rc;
329 
330 	/* Only request samples from output streams. */
331 	if (stream->direction != CRAS_STREAM_OUTPUT)
332 		return 0;
333 
334 	stream->last_fetch_ts = *now;
335 
336 	init_audio_message(&msg, AUDIO_MESSAGE_REQUEST_DATA,
337 			   stream->cb_threshold);
338 	rc = write(stream->fd, &msg, sizeof(msg));
339 	if (rc < 0)
340 		return -errno;
341 
342 	set_pending_reply(stream);
343 
344 	return rc;
345 }
346 
cras_rstream_audio_ready(struct cras_rstream * stream,size_t count)347 int cras_rstream_audio_ready(struct cras_rstream *stream, size_t count)
348 {
349 	struct audio_message msg;
350 	int rc;
351 
352 	cras_shm_buffer_write_complete(&stream->shm);
353 
354 	/* Mark shm as used. */
355 	if (stream_is_server_only(stream)) {
356 		cras_shm_buffer_read_current(&stream->shm, count);
357 		return 0;
358 	}
359 
360 	init_audio_message(&msg, AUDIO_MESSAGE_DATA_READY, count);
361 	rc = write(stream->fd, &msg, sizeof(msg));
362 	if (rc < 0)
363 		return -errno;
364 
365 	set_pending_reply(stream);
366 
367 	return rc;
368 }
369 
cras_rstream_dev_attach(struct cras_rstream * rstream,unsigned int dev_id,void * dev_ptr)370 void cras_rstream_dev_attach(struct cras_rstream *rstream,
371 			     unsigned int dev_id,
372 			     void *dev_ptr)
373 {
374 	if (buffer_share_add_id(rstream->buf_state, dev_id, dev_ptr) == 0)
375 		rstream->num_attached_devs++;
376 
377 	/* TODO(hychao): Handle master device assignment for complicated
378 	 * routing case.
379 	 */
380 	if (rstream->master_dev.dev_id == NO_DEVICE) {
381 		rstream->master_dev.dev_id = dev_id;
382 		rstream->master_dev.dev_ptr = dev_ptr;
383 	}
384 }
385 
cras_rstream_dev_detach(struct cras_rstream * rstream,unsigned int dev_id)386 void cras_rstream_dev_detach(struct cras_rstream *rstream, unsigned int dev_id)
387 {
388 	if (buffer_share_rm_id(rstream->buf_state, dev_id) == 0)
389 		rstream->num_attached_devs--;
390 
391 	if (rstream->master_dev.dev_id == dev_id) {
392 		int i;
393 		struct id_offset *o;
394 
395 		/* Choose the first device id as master. */
396 		rstream->master_dev.dev_id = NO_DEVICE;
397 		rstream->master_dev.dev_ptr = NULL;
398 		for (i = 0; i < rstream->buf_state->id_sz; i++) {
399 			o = &rstream->buf_state->wr_idx[i];
400 			if (o->used) {
401 				rstream->master_dev.dev_id = o->id;
402 				rstream->master_dev.dev_ptr = o->data;
403 				break;
404 			}
405 		}
406 	}
407 }
408 
cras_rstream_dev_offset_update(struct cras_rstream * rstream,unsigned int frames,unsigned int dev_id)409 void cras_rstream_dev_offset_update(struct cras_rstream *rstream,
410 				    unsigned int frames,
411 				    unsigned int dev_id)
412 {
413 	buffer_share_offset_update(rstream->buf_state, dev_id, frames);
414 }
415 
cras_rstream_update_input_write_pointer(struct cras_rstream * rstream)416 void cras_rstream_update_input_write_pointer(struct cras_rstream *rstream)
417 {
418 	struct cras_audio_shm *shm = cras_rstream_input_shm(rstream);
419 	unsigned int nwritten = buffer_share_get_new_write_point(
420 					rstream->buf_state);
421 
422 	cras_shm_buffer_written(shm, nwritten);
423 }
424 
cras_rstream_update_output_read_pointer(struct cras_rstream * rstream)425 void cras_rstream_update_output_read_pointer(struct cras_rstream *rstream)
426 {
427 	struct cras_audio_shm *shm = cras_rstream_input_shm(rstream);
428 	unsigned int nwritten = buffer_share_get_new_write_point(
429 					rstream->buf_state);
430 
431 	cras_shm_buffer_read(shm, nwritten);
432 }
433 
cras_rstream_dev_offset(const struct cras_rstream * rstream,unsigned int dev_id)434 unsigned int cras_rstream_dev_offset(const struct cras_rstream *rstream,
435 				     unsigned int dev_id)
436 {
437 	return buffer_share_id_offset(rstream->buf_state, dev_id);
438 }
439 
cras_rstream_update_queued_frames(struct cras_rstream * rstream)440 void cras_rstream_update_queued_frames(struct cras_rstream *rstream)
441 {
442 	const struct cras_audio_shm *shm = cras_rstream_output_shm(rstream);
443 	rstream->queued_frames = MIN(cras_shm_get_frames(shm),
444 				     rstream->buffer_frames);
445 }
446 
cras_rstream_playable_frames(struct cras_rstream * rstream,unsigned int dev_id)447 unsigned int cras_rstream_playable_frames(struct cras_rstream *rstream,
448 					  unsigned int dev_id)
449 {
450 	return rstream->queued_frames -
451 			cras_rstream_dev_offset(rstream, dev_id);
452 }
453 
cras_rstream_get_volume_scaler(struct cras_rstream * rstream)454 float cras_rstream_get_volume_scaler(struct cras_rstream *rstream)
455 {
456 	const struct cras_audio_shm *shm = cras_rstream_output_shm(rstream);
457 
458 	return cras_shm_get_volume_scaler(shm);
459 }
460 
cras_rstream_get_readable_frames(struct cras_rstream * rstream,unsigned int offset,size_t * frames)461 uint8_t *cras_rstream_get_readable_frames(struct cras_rstream *rstream,
462 					  unsigned int offset,
463 					  size_t *frames)
464 {
465 	return cras_shm_get_readable_frames(&rstream->shm, offset, frames);
466 }
467 
cras_rstream_get_mute(const struct cras_rstream * rstream)468 int cras_rstream_get_mute(const struct cras_rstream *rstream)
469 {
470 	return cras_shm_get_mute(&rstream->shm);
471 }
472 
cras_rstream_is_pending_reply(const struct cras_rstream * stream)473 int cras_rstream_is_pending_reply(const struct cras_rstream *stream)
474 {
475 	return cras_shm_callback_pending(&stream->shm);
476 }
477 
cras_rstream_flush_old_audio_messages(struct cras_rstream * stream)478 int cras_rstream_flush_old_audio_messages(struct cras_rstream *stream)
479 {
480 	struct pollfd pollfd;
481 	int err;
482 
483 	if (!stream->fd)
484 		return 0;
485 
486 	if (stream_is_server_only(stream))
487 		return 0;
488 
489 	pollfd.fd = stream->fd;
490 	pollfd.events = POLLIN;
491 
492 	do {
493 		err = poll(&pollfd, 1, 0);
494 		if (pollfd.revents & POLLIN) {
495 			err = read_and_handle_client_message(stream);
496 		}
497 	} while (err > 0);
498 
499 	return 0;
500 }
501