blob: eb6d8e6c646cace0bf98d81fbdda57d5c5395208 [file] [log] [blame]
/* Copyright (c) 2015 The Chromium OS Authors. All rights reserved.
* Use of this source code is governed by a BSD-style license that can be
* found in the LICENSE file.
* This example plays a file. The filename is the only argument. The file is
* assumed to contain raw stereo 16-bit PCM data to be played at 48kHz.
* usage: cplay <filename>
#include <cras_client.h>
#include <cras_helpers.h>
#include <stdio.h>
#include <stdint.h>
/* Used as a cookie for the playing stream. */
struct stream_data {
int fd;
unsigned int frame_bytes;
/* Run from callback thread. */
static int 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)
struct stream_data *data = (struct stream_data *)user_arg;
int nread;
nread = read(data->fd, playback_samples, frames * data->frame_bytes);
if (nread <= 0)
return EOF;
return nread / data->frame_bytes;
/* Run from callback thread. */
static int stream_error(struct cras_client *client, cras_stream_id_t stream_id,
int err, void *arg)
printf("Stream error %d\n", err);
return 0;
int main(int argc, char **argv)
struct cras_client *client;
cras_stream_id_t stream_id;
struct stream_data *data;
int rc = 0;
int fd;
const unsigned int block_size = 4800;
const unsigned int num_channels = 2;
const unsigned int rate = 48000;
const unsigned int flags = 0;
if (argc < 2)
printf("Usage: %s filename\n", argv[0]);
fd = open(argv[1], O_RDONLY);
if (fd < 0) {
perror("failed to open file");
return -errno;
rc = cras_helper_create_connect(&client);
if (rc < 0) {
fprintf(stderr, "Couldn't create client.\n");
return rc;
data = malloc(sizeof(*data));
data->fd = fd;
data->frame_bytes = 4;
rc = cras_helper_add_stream_simple(client, CRAS_STREAM_OUTPUT, data,
put_samples, stream_error,
num_channels, NO_DEVICE, &stream_id);
if (rc < 0) {
fprintf(stderr, "adding a stream %d\n", rc);
goto destroy_exit;
/* At this point the stream has been added and audio callbacks will
* start to fire. This app can now go off and do other things, but this
* example just loops forever. */
while (1) {
return rc;