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