• Home
  • Line#
  • Scopes#
  • Navigate#
  • Raw
  • Download
1 /* Copyright (c) 2015 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  * This example plays a file.  The filename is the only argument.  The file is
6  * assumed to contain raw stereo 16-bit PCM data to be played at 48kHz.
7  * usage:  cplay <filename>
8  */
9 
10 #include <cras_client.h>
11 #include <cras_helpers.h>
12 #include <stdio.h>
13 #include <stdint.h>
14 
15 /* Used as a cookie for the playing stream. */
16 struct stream_data {
17 	int fd;
18 	unsigned int frame_bytes;
19 };
20 
21 /* Run from callback thread. */
put_samples(struct cras_client * client,cras_stream_id_t stream_id,uint8_t * captured_samples,uint8_t * playback_samples,unsigned int frames,const struct timespec * captured_time,const struct timespec * playback_time,void * user_arg)22 static int put_samples(struct cras_client *client, cras_stream_id_t stream_id,
23 		       uint8_t *captured_samples, uint8_t *playback_samples,
24 		       unsigned int frames,
25 		       const struct timespec *captured_time,
26 		       const struct timespec *playback_time, void *user_arg)
27 {
28 	struct stream_data *data = (struct stream_data *)user_arg;
29 	int nread;
30 
31 	nread = read(data->fd, playback_samples, frames * data->frame_bytes);
32 	if (nread <= 0)
33 		return EOF;
34 
35 	return nread / data->frame_bytes;
36 }
37 
38 /* Run from callback thread. */
stream_error(struct cras_client * client,cras_stream_id_t stream_id,int err,void * arg)39 static int stream_error(struct cras_client *client, cras_stream_id_t stream_id,
40 			int err, void *arg)
41 {
42 	printf("Stream error %d\n", err);
43 	exit(err);
44 	return 0;
45 }
46 
main(int argc,char ** argv)47 int main(int argc, char **argv)
48 {
49 	struct cras_client *client;
50 	cras_stream_id_t stream_id;
51 	struct stream_data *data;
52 	int rc = 0;
53 	int fd;
54 	const unsigned int block_size = 4800;
55 	const unsigned int num_channels = 2;
56 	const unsigned int rate = 48000;
57 	const unsigned int flags = 0;
58 
59 	if (argc < 2)
60 		printf("Usage: %s filename\n", argv[0]);
61 
62 	fd = open(argv[1], O_RDONLY);
63 	if (fd < 0) {
64 		perror("failed to open file");
65 		return -errno;
66 	}
67 
68 	rc = cras_helper_create_connect(&client);
69 	if (rc < 0) {
70 		fprintf(stderr, "Couldn't create client.\n");
71 		close(fd);
72 		return rc;
73 	}
74 
75 	data = malloc(sizeof(*data));
76 	data->fd = fd;
77 	data->frame_bytes = 4;
78 
79 	rc = cras_helper_add_stream_simple(client, CRAS_STREAM_OUTPUT, data,
80 					   put_samples, stream_error,
81 					   SND_PCM_FORMAT_S16_LE, rate,
82 					   num_channels, NO_DEVICE, &stream_id);
83 	if (rc < 0) {
84 		fprintf(stderr, "adding a stream %d\n", rc);
85 		goto destroy_exit;
86 	}
87 
88 	/* At this point the stream has been added and audio callbacks will
89 	 * start to fire.  This app can now go off and do other things, but this
90 	 * example just loops forever. */
91 	while (1) {
92 		sleep(1);
93 	}
94 
95 destroy_exit:
96 	cras_client_destroy(client);
97 	close(fd);
98 	free(data);
99 	return rc;
100 }
101