14765c439491ddda3de658e62cc4a64d10e726b34Iliyan Malchev/* 24765c439491ddda3de658e62cc4a64d10e726b34Iliyan Malchev** Copyright 2010, The Android Open-Source Project 34765c439491ddda3de658e62cc4a64d10e726b34Iliyan Malchev** Copyright (c) 2011-2012, Code Aurora Forum. All rights reserved. 44765c439491ddda3de658e62cc4a64d10e726b34Iliyan Malchev** 54765c439491ddda3de658e62cc4a64d10e726b34Iliyan Malchev** Licensed under the Apache License, Version 2.0 (the "License"); 64765c439491ddda3de658e62cc4a64d10e726b34Iliyan Malchev** you may not use this file except in compliance with the License. 74765c439491ddda3de658e62cc4a64d10e726b34Iliyan Malchev** You may obtain a copy of the License at 84765c439491ddda3de658e62cc4a64d10e726b34Iliyan Malchev** 94765c439491ddda3de658e62cc4a64d10e726b34Iliyan Malchev** http://www.apache.org/licenses/LICENSE-2.0 104765c439491ddda3de658e62cc4a64d10e726b34Iliyan Malchev** 114765c439491ddda3de658e62cc4a64d10e726b34Iliyan Malchev** Unless required by applicable law or agreed to in writing, software 124765c439491ddda3de658e62cc4a64d10e726b34Iliyan Malchev** distributed under the License is distributed on an "AS IS" BASIS, 134765c439491ddda3de658e62cc4a64d10e726b34Iliyan Malchev** WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 144765c439491ddda3de658e62cc4a64d10e726b34Iliyan Malchev** See the License for the specific language governing permissions and 154765c439491ddda3de658e62cc4a64d10e726b34Iliyan Malchev** limitations under the License. 164765c439491ddda3de658e62cc4a64d10e726b34Iliyan Malchev*/ 174765c439491ddda3de658e62cc4a64d10e726b34Iliyan Malchev 184765c439491ddda3de658e62cc4a64d10e726b34Iliyan Malchev#include <stdio.h> 194765c439491ddda3de658e62cc4a64d10e726b34Iliyan Malchev#include <stdlib.h> 204765c439491ddda3de658e62cc4a64d10e726b34Iliyan Malchev#include <fcntl.h> 214765c439491ddda3de658e62cc4a64d10e726b34Iliyan Malchev#include <unistd.h> 224765c439491ddda3de658e62cc4a64d10e726b34Iliyan Malchev#include <stdint.h> 234765c439491ddda3de658e62cc4a64d10e726b34Iliyan Malchev#include <string.h> 244765c439491ddda3de658e62cc4a64d10e726b34Iliyan Malchev#include <errno.h> 254765c439491ddda3de658e62cc4a64d10e726b34Iliyan Malchev#include <sys/poll.h> 264765c439491ddda3de658e62cc4a64d10e726b34Iliyan Malchev#include <sys/ioctl.h> 274765c439491ddda3de658e62cc4a64d10e726b34Iliyan Malchev#include <getopt.h> 284765c439491ddda3de658e62cc4a64d10e726b34Iliyan Malchev 294765c439491ddda3de658e62cc4a64d10e726b34Iliyan Malchev#include <sound/asound.h> 304765c439491ddda3de658e62cc4a64d10e726b34Iliyan Malchev#include "alsa_audio.h" 314765c439491ddda3de658e62cc4a64d10e726b34Iliyan Malchev 324765c439491ddda3de658e62cc4a64d10e726b34Iliyan Malchev#ifndef ANDROID 334765c439491ddda3de658e62cc4a64d10e726b34Iliyan Malchev#define strlcat g_strlcat 344765c439491ddda3de658e62cc4a64d10e726b34Iliyan Malchev#define strlcpy g_strlcpy 354765c439491ddda3de658e62cc4a64d10e726b34Iliyan Malchev#endif 364765c439491ddda3de658e62cc4a64d10e726b34Iliyan Malchev 374765c439491ddda3de658e62cc4a64d10e726b34Iliyan Malchev#define ID_RIFF 0x46464952 384765c439491ddda3de658e62cc4a64d10e726b34Iliyan Malchev#define ID_WAVE 0x45564157 394765c439491ddda3de658e62cc4a64d10e726b34Iliyan Malchev#define ID_FMT 0x20746d66 404765c439491ddda3de658e62cc4a64d10e726b34Iliyan Malchev#define ID_DATA 0x61746164 414765c439491ddda3de658e62cc4a64d10e726b34Iliyan Malchev 424765c439491ddda3de658e62cc4a64d10e726b34Iliyan Malchev#define FORMAT_PCM 1 434765c439491ddda3de658e62cc4a64d10e726b34Iliyan Malchev#define LOG_NDEBUG 1 444765c439491ddda3de658e62cc4a64d10e726b34Iliyan Malchevstatic pcm_flag = 1; 454765c439491ddda3de658e62cc4a64d10e726b34Iliyan Malchevstatic debug = 0; 464765c439491ddda3de658e62cc4a64d10e726b34Iliyan Malchevstatic uint32_t play_max_sz = 2147483648LL; 474765c439491ddda3de658e62cc4a64d10e726b34Iliyan Malchevstatic int format = SNDRV_PCM_FORMAT_S16_LE; 484765c439491ddda3de658e62cc4a64d10e726b34Iliyan Malchevstatic int period = 0; 494765c439491ddda3de658e62cc4a64d10e726b34Iliyan Malchevstatic int compressed = 0; 504765c439491ddda3de658e62cc4a64d10e726b34Iliyan Malchevstatic char *compr_codec; 514765c439491ddda3de658e62cc4a64d10e726b34Iliyan Malchevstatic int piped = 0; 524765c439491ddda3de658e62cc4a64d10e726b34Iliyan Malchev 534765c439491ddda3de658e62cc4a64d10e726b34Iliyan Malchevstatic struct option long_options[] = 544765c439491ddda3de658e62cc4a64d10e726b34Iliyan Malchev{ 554765c439491ddda3de658e62cc4a64d10e726b34Iliyan Malchev {"pcm", 0, 0, 'P'}, 564765c439491ddda3de658e62cc4a64d10e726b34Iliyan Malchev {"debug", 0, 0, 'V'}, 574765c439491ddda3de658e62cc4a64d10e726b34Iliyan Malchev {"Mmap", 0, 0, 'M'}, 584765c439491ddda3de658e62cc4a64d10e726b34Iliyan Malchev {"HW", 1, 0, 'D'}, 594765c439491ddda3de658e62cc4a64d10e726b34Iliyan Malchev {"Rate", 1, 0, 'R'}, 604765c439491ddda3de658e62cc4a64d10e726b34Iliyan Malchev {"channel", 1, 0, 'C'}, 614765c439491ddda3de658e62cc4a64d10e726b34Iliyan Malchev {"format", 1, 0, 'F'}, 624765c439491ddda3de658e62cc4a64d10e726b34Iliyan Malchev {"period", 1, 0, 'B'}, 634765c439491ddda3de658e62cc4a64d10e726b34Iliyan Malchev {"compressed", 0, 0, 'T'}, 644765c439491ddda3de658e62cc4a64d10e726b34Iliyan Malchev {0, 0, 0, 0} 654765c439491ddda3de658e62cc4a64d10e726b34Iliyan Malchev}; 664765c439491ddda3de658e62cc4a64d10e726b34Iliyan Malchev 674765c439491ddda3de658e62cc4a64d10e726b34Iliyan Malchevstruct wav_header { 684765c439491ddda3de658e62cc4a64d10e726b34Iliyan Malchev uint32_t riff_id; 694765c439491ddda3de658e62cc4a64d10e726b34Iliyan Malchev uint32_t riff_sz; 704765c439491ddda3de658e62cc4a64d10e726b34Iliyan Malchev uint32_t riff_fmt; 714765c439491ddda3de658e62cc4a64d10e726b34Iliyan Malchev uint32_t fmt_id; 724765c439491ddda3de658e62cc4a64d10e726b34Iliyan Malchev uint32_t fmt_sz; 734765c439491ddda3de658e62cc4a64d10e726b34Iliyan Malchev uint16_t audio_format; 744765c439491ddda3de658e62cc4a64d10e726b34Iliyan Malchev uint16_t num_channels; 754765c439491ddda3de658e62cc4a64d10e726b34Iliyan Malchev uint32_t sample_rate; 764765c439491ddda3de658e62cc4a64d10e726b34Iliyan Malchev uint32_t byte_rate; /* sample_rate * num_channels * bps / 8 */ 774765c439491ddda3de658e62cc4a64d10e726b34Iliyan Malchev uint16_t block_align; /* num_channels * bps / 8 */ 784765c439491ddda3de658e62cc4a64d10e726b34Iliyan Malchev uint16_t bits_per_sample; 794765c439491ddda3de658e62cc4a64d10e726b34Iliyan Malchev uint32_t data_id; 804765c439491ddda3de658e62cc4a64d10e726b34Iliyan Malchev uint32_t data_sz; 814765c439491ddda3de658e62cc4a64d10e726b34Iliyan Malchev}; 824765c439491ddda3de658e62cc4a64d10e726b34Iliyan Malchev 834765c439491ddda3de658e62cc4a64d10e726b34Iliyan Malchevstatic int set_params(struct pcm *pcm) 844765c439491ddda3de658e62cc4a64d10e726b34Iliyan Malchev{ 854765c439491ddda3de658e62cc4a64d10e726b34Iliyan Malchev struct snd_pcm_hw_params *params; 864765c439491ddda3de658e62cc4a64d10e726b34Iliyan Malchev struct snd_pcm_sw_params *sparams; 874765c439491ddda3de658e62cc4a64d10e726b34Iliyan Malchev 884765c439491ddda3de658e62cc4a64d10e726b34Iliyan Malchev unsigned long periodSize, bufferSize, reqBuffSize; 894765c439491ddda3de658e62cc4a64d10e726b34Iliyan Malchev unsigned int periodTime, bufferTime; 904765c439491ddda3de658e62cc4a64d10e726b34Iliyan Malchev unsigned int requestedRate = pcm->rate; 914765c439491ddda3de658e62cc4a64d10e726b34Iliyan Malchev int channels = (pcm->flags & PCM_MONO) ? 1 : ((pcm->flags & PCM_5POINT1)? 6 : 2 ); 924765c439491ddda3de658e62cc4a64d10e726b34Iliyan Malchev 934765c439491ddda3de658e62cc4a64d10e726b34Iliyan Malchev params = (struct snd_pcm_hw_params*) calloc(1, sizeof(struct snd_pcm_hw_params)); 944765c439491ddda3de658e62cc4a64d10e726b34Iliyan Malchev if (!params) { 954765c439491ddda3de658e62cc4a64d10e726b34Iliyan Malchev fprintf(stderr, "Aplay:Failed to allocate ALSA hardware parameters!"); 964765c439491ddda3de658e62cc4a64d10e726b34Iliyan Malchev return -ENOMEM; 974765c439491ddda3de658e62cc4a64d10e726b34Iliyan Malchev } 984765c439491ddda3de658e62cc4a64d10e726b34Iliyan Malchev 994765c439491ddda3de658e62cc4a64d10e726b34Iliyan Malchev param_init(params); 1004765c439491ddda3de658e62cc4a64d10e726b34Iliyan Malchev 1014765c439491ddda3de658e62cc4a64d10e726b34Iliyan Malchev param_set_mask(params, SNDRV_PCM_HW_PARAM_ACCESS, 1024765c439491ddda3de658e62cc4a64d10e726b34Iliyan Malchev (pcm->flags & PCM_MMAP)? SNDRV_PCM_ACCESS_MMAP_INTERLEAVED : SNDRV_PCM_ACCESS_RW_INTERLEAVED); 1034765c439491ddda3de658e62cc4a64d10e726b34Iliyan Malchev param_set_mask(params, SNDRV_PCM_HW_PARAM_FORMAT, pcm->format); 1044765c439491ddda3de658e62cc4a64d10e726b34Iliyan Malchev param_set_mask(params, SNDRV_PCM_HW_PARAM_SUBFORMAT, 1054765c439491ddda3de658e62cc4a64d10e726b34Iliyan Malchev SNDRV_PCM_SUBFORMAT_STD); 1064765c439491ddda3de658e62cc4a64d10e726b34Iliyan Malchev if (period) 1074765c439491ddda3de658e62cc4a64d10e726b34Iliyan Malchev param_set_min(params, SNDRV_PCM_HW_PARAM_PERIOD_BYTES, period); 1084765c439491ddda3de658e62cc4a64d10e726b34Iliyan Malchev else 1094765c439491ddda3de658e62cc4a64d10e726b34Iliyan Malchev param_set_min(params, SNDRV_PCM_HW_PARAM_PERIOD_TIME, 10); 1104765c439491ddda3de658e62cc4a64d10e726b34Iliyan Malchev param_set_int(params, SNDRV_PCM_HW_PARAM_SAMPLE_BITS, 16); 1114765c439491ddda3de658e62cc4a64d10e726b34Iliyan Malchev param_set_int(params, SNDRV_PCM_HW_PARAM_FRAME_BITS, 1124765c439491ddda3de658e62cc4a64d10e726b34Iliyan Malchev pcm->channels * 16); 1134765c439491ddda3de658e62cc4a64d10e726b34Iliyan Malchev param_set_int(params, SNDRV_PCM_HW_PARAM_CHANNELS, 1144765c439491ddda3de658e62cc4a64d10e726b34Iliyan Malchev pcm->channels); 1154765c439491ddda3de658e62cc4a64d10e726b34Iliyan Malchev param_set_int(params, SNDRV_PCM_HW_PARAM_RATE, pcm->rate); 1164765c439491ddda3de658e62cc4a64d10e726b34Iliyan Malchev param_set_hw_refine(pcm, params); 1174765c439491ddda3de658e62cc4a64d10e726b34Iliyan Malchev 1184765c439491ddda3de658e62cc4a64d10e726b34Iliyan Malchev if (param_set_hw_params(pcm, params)) { 1194765c439491ddda3de658e62cc4a64d10e726b34Iliyan Malchev fprintf(stderr, "Aplay:cannot set hw params\n"); 1204765c439491ddda3de658e62cc4a64d10e726b34Iliyan Malchev return -errno; 1214765c439491ddda3de658e62cc4a64d10e726b34Iliyan Malchev } 1224765c439491ddda3de658e62cc4a64d10e726b34Iliyan Malchev if (debug) 1234765c439491ddda3de658e62cc4a64d10e726b34Iliyan Malchev param_dump(params); 1244765c439491ddda3de658e62cc4a64d10e726b34Iliyan Malchev 1254765c439491ddda3de658e62cc4a64d10e726b34Iliyan Malchev pcm->buffer_size = pcm_buffer_size(params); 1264765c439491ddda3de658e62cc4a64d10e726b34Iliyan Malchev pcm->period_size = pcm_period_size(params); 1274765c439491ddda3de658e62cc4a64d10e726b34Iliyan Malchev pcm->period_cnt = pcm->buffer_size/pcm->period_size; 1284765c439491ddda3de658e62cc4a64d10e726b34Iliyan Malchev if (debug) { 1294765c439491ddda3de658e62cc4a64d10e726b34Iliyan Malchev fprintf (stderr,"period_cnt = %d\n", pcm->period_cnt); 1304765c439491ddda3de658e62cc4a64d10e726b34Iliyan Malchev fprintf (stderr,"period_size = %d\n", pcm->period_size); 1314765c439491ddda3de658e62cc4a64d10e726b34Iliyan Malchev fprintf (stderr,"buffer_size = %d\n", pcm->buffer_size); 1324765c439491ddda3de658e62cc4a64d10e726b34Iliyan Malchev } 1334765c439491ddda3de658e62cc4a64d10e726b34Iliyan Malchev sparams = (struct snd_pcm_sw_params*) calloc(1, sizeof(struct snd_pcm_sw_params)); 1344765c439491ddda3de658e62cc4a64d10e726b34Iliyan Malchev if (!sparams) { 1354765c439491ddda3de658e62cc4a64d10e726b34Iliyan Malchev fprintf(stderr, "Aplay:Failed to allocate ALSA software parameters!\n"); 1364765c439491ddda3de658e62cc4a64d10e726b34Iliyan Malchev return -ENOMEM; 1374765c439491ddda3de658e62cc4a64d10e726b34Iliyan Malchev } 1384765c439491ddda3de658e62cc4a64d10e726b34Iliyan Malchev // Get the current software parameters 1394765c439491ddda3de658e62cc4a64d10e726b34Iliyan Malchev sparams->tstamp_mode = SNDRV_PCM_TSTAMP_NONE; 1404765c439491ddda3de658e62cc4a64d10e726b34Iliyan Malchev sparams->period_step = 1; 1414765c439491ddda3de658e62cc4a64d10e726b34Iliyan Malchev 1424765c439491ddda3de658e62cc4a64d10e726b34Iliyan Malchev sparams->avail_min = pcm->period_size/(channels * 2) ; 1434765c439491ddda3de658e62cc4a64d10e726b34Iliyan Malchev sparams->start_threshold = pcm->period_size/(channels * 2) ; 1444765c439491ddda3de658e62cc4a64d10e726b34Iliyan Malchev sparams->stop_threshold = pcm->buffer_size ; 1454765c439491ddda3de658e62cc4a64d10e726b34Iliyan Malchev sparams->xfer_align = pcm->period_size/(channels * 2) ; /* needed for old kernels */ 1464765c439491ddda3de658e62cc4a64d10e726b34Iliyan Malchev 1474765c439491ddda3de658e62cc4a64d10e726b34Iliyan Malchev sparams->silence_size = 0; 1484765c439491ddda3de658e62cc4a64d10e726b34Iliyan Malchev sparams->silence_threshold = 0; 1494765c439491ddda3de658e62cc4a64d10e726b34Iliyan Malchev 1504765c439491ddda3de658e62cc4a64d10e726b34Iliyan Malchev if (param_set_sw_params(pcm, sparams)) { 1514765c439491ddda3de658e62cc4a64d10e726b34Iliyan Malchev fprintf(stderr, "Aplay:cannot set sw params"); 1524765c439491ddda3de658e62cc4a64d10e726b34Iliyan Malchev return -errno; 1534765c439491ddda3de658e62cc4a64d10e726b34Iliyan Malchev } 1544765c439491ddda3de658e62cc4a64d10e726b34Iliyan Malchev if (debug) { 1554765c439491ddda3de658e62cc4a64d10e726b34Iliyan Malchev fprintf (stderr,"sparams->avail_min= %lu\n", sparams->avail_min); 1564765c439491ddda3de658e62cc4a64d10e726b34Iliyan Malchev fprintf (stderr," sparams->start_threshold= %lu\n", sparams->start_threshold); 1574765c439491ddda3de658e62cc4a64d10e726b34Iliyan Malchev fprintf (stderr," sparams->stop_threshold= %lu\n", sparams->stop_threshold); 1584765c439491ddda3de658e62cc4a64d10e726b34Iliyan Malchev fprintf (stderr," sparams->xfer_align= %lu\n", sparams->xfer_align); 1594765c439491ddda3de658e62cc4a64d10e726b34Iliyan Malchev fprintf (stderr," sparams->boundary= %lu\n", sparams->boundary); 1604765c439491ddda3de658e62cc4a64d10e726b34Iliyan Malchev } 1614765c439491ddda3de658e62cc4a64d10e726b34Iliyan Malchev return 0; 1624765c439491ddda3de658e62cc4a64d10e726b34Iliyan Malchev} 1634765c439491ddda3de658e62cc4a64d10e726b34Iliyan Malchev 1644765c439491ddda3de658e62cc4a64d10e726b34Iliyan Malchevstatic int play_file(unsigned rate, unsigned channels, int fd, 1654765c439491ddda3de658e62cc4a64d10e726b34Iliyan Malchev unsigned flags, const char *device, unsigned data_sz) 1664765c439491ddda3de658e62cc4a64d10e726b34Iliyan Malchev{ 1674765c439491ddda3de658e62cc4a64d10e726b34Iliyan Malchev struct pcm *pcm; 1684765c439491ddda3de658e62cc4a64d10e726b34Iliyan Malchev struct mixer *mixer; 1694765c439491ddda3de658e62cc4a64d10e726b34Iliyan Malchev struct pcm_ctl *ctl = NULL; 1704765c439491ddda3de658e62cc4a64d10e726b34Iliyan Malchev unsigned bufsize; 1714765c439491ddda3de658e62cc4a64d10e726b34Iliyan Malchev char *data; 1724765c439491ddda3de658e62cc4a64d10e726b34Iliyan Malchev long avail; 1734765c439491ddda3de658e62cc4a64d10e726b34Iliyan Malchev long frames; 1744765c439491ddda3de658e62cc4a64d10e726b34Iliyan Malchev int nfds = 1; 1754765c439491ddda3de658e62cc4a64d10e726b34Iliyan Malchev struct snd_xferi x; 1764765c439491ddda3de658e62cc4a64d10e726b34Iliyan Malchev unsigned offset = 0; 1774765c439491ddda3de658e62cc4a64d10e726b34Iliyan Malchev int err; 1784765c439491ddda3de658e62cc4a64d10e726b34Iliyan Malchev static int start = 0; 1794765c439491ddda3de658e62cc4a64d10e726b34Iliyan Malchev struct pollfd pfd[1]; 1804765c439491ddda3de658e62cc4a64d10e726b34Iliyan Malchev int remainingData = 0; 1814765c439491ddda3de658e62cc4a64d10e726b34Iliyan Malchev 1824765c439491ddda3de658e62cc4a64d10e726b34Iliyan Malchev flags |= PCM_OUT; 1834765c439491ddda3de658e62cc4a64d10e726b34Iliyan Malchev 1844765c439491ddda3de658e62cc4a64d10e726b34Iliyan Malchev if (channels == 1) 1854765c439491ddda3de658e62cc4a64d10e726b34Iliyan Malchev flags |= PCM_MONO; 1864765c439491ddda3de658e62cc4a64d10e726b34Iliyan Malchev else if (channels == 6) 1874765c439491ddda3de658e62cc4a64d10e726b34Iliyan Malchev flags |= PCM_5POINT1; 1884765c439491ddda3de658e62cc4a64d10e726b34Iliyan Malchev else 1894765c439491ddda3de658e62cc4a64d10e726b34Iliyan Malchev flags |= PCM_STEREO; 1904765c439491ddda3de658e62cc4a64d10e726b34Iliyan Malchev 1914765c439491ddda3de658e62cc4a64d10e726b34Iliyan Malchev if (debug) 1924765c439491ddda3de658e62cc4a64d10e726b34Iliyan Malchev flags |= DEBUG_ON; 1934765c439491ddda3de658e62cc4a64d10e726b34Iliyan Malchev else 1944765c439491ddda3de658e62cc4a64d10e726b34Iliyan Malchev flags |= DEBUG_OFF; 1954765c439491ddda3de658e62cc4a64d10e726b34Iliyan Malchev 1964765c439491ddda3de658e62cc4a64d10e726b34Iliyan Malchev pcm = pcm_open(flags, device); 1974765c439491ddda3de658e62cc4a64d10e726b34Iliyan Malchev if (pcm < 0) 1984765c439491ddda3de658e62cc4a64d10e726b34Iliyan Malchev return pcm; 1994765c439491ddda3de658e62cc4a64d10e726b34Iliyan Malchev 2004765c439491ddda3de658e62cc4a64d10e726b34Iliyan Malchev if (!pcm_ready(pcm)) { 2014765c439491ddda3de658e62cc4a64d10e726b34Iliyan Malchev pcm_close(pcm); 2024765c439491ddda3de658e62cc4a64d10e726b34Iliyan Malchev return -EBADFD; 2034765c439491ddda3de658e62cc4a64d10e726b34Iliyan Malchev } 2044765c439491ddda3de658e62cc4a64d10e726b34Iliyan Malchev 2059746c4758b161e26eec92b1ef1ff1bf0ba0bd268Ajay Dudani#ifdef QCOM_COMPRESSED_AUDIO_ENABLED 2064765c439491ddda3de658e62cc4a64d10e726b34Iliyan Malchev if (compressed) { 2074765c439491ddda3de658e62cc4a64d10e726b34Iliyan Malchev struct snd_compr_caps compr_cap; 2084765c439491ddda3de658e62cc4a64d10e726b34Iliyan Malchev struct snd_compr_params compr_params; 2094765c439491ddda3de658e62cc4a64d10e726b34Iliyan Malchev if (ioctl(pcm->fd, SNDRV_COMPRESS_GET_CAPS, &compr_cap)) { 2104765c439491ddda3de658e62cc4a64d10e726b34Iliyan Malchev fprintf(stderr, "Aplay: SNDRV_COMPRESS_GET_CAPS, failed Error no %d \n", errno); 2114765c439491ddda3de658e62cc4a64d10e726b34Iliyan Malchev pcm_close(pcm); 2124765c439491ddda3de658e62cc4a64d10e726b34Iliyan Malchev return -errno; 2134765c439491ddda3de658e62cc4a64d10e726b34Iliyan Malchev } 2144765c439491ddda3de658e62cc4a64d10e726b34Iliyan Malchev if (!period) 2154765c439491ddda3de658e62cc4a64d10e726b34Iliyan Malchev period = compr_cap.min_fragment_size; 2164765c439491ddda3de658e62cc4a64d10e726b34Iliyan Malchev switch (get_compressed_format(compr_codec)) { 2174765c439491ddda3de658e62cc4a64d10e726b34Iliyan Malchev case FORMAT_MP3: 2184765c439491ddda3de658e62cc4a64d10e726b34Iliyan Malchev compr_params.codec.id = compr_cap.codecs[FORMAT_MP3]; 2194765c439491ddda3de658e62cc4a64d10e726b34Iliyan Malchev break; 2204765c439491ddda3de658e62cc4a64d10e726b34Iliyan Malchev case FORMAT_AC3_PASS_THROUGH: 2214765c439491ddda3de658e62cc4a64d10e726b34Iliyan Malchev compr_params.codec.id = compr_cap.codecs[FORMAT_AC3_PASS_THROUGH]; 2224765c439491ddda3de658e62cc4a64d10e726b34Iliyan Malchev printf("codec -d = %x\n", compr_params.codec.id); 2234765c439491ddda3de658e62cc4a64d10e726b34Iliyan Malchev break; 2244765c439491ddda3de658e62cc4a64d10e726b34Iliyan Malchev default: 2254765c439491ddda3de658e62cc4a64d10e726b34Iliyan Malchev break; 2264765c439491ddda3de658e62cc4a64d10e726b34Iliyan Malchev } 2274765c439491ddda3de658e62cc4a64d10e726b34Iliyan Malchev if (ioctl(pcm->fd, SNDRV_COMPRESS_SET_PARAMS, &compr_params)) { 2284765c439491ddda3de658e62cc4a64d10e726b34Iliyan Malchev fprintf(stderr, "Aplay: SNDRV_COMPRESS_SET_PARAMS,failed Error no %d \n", errno); 2294765c439491ddda3de658e62cc4a64d10e726b34Iliyan Malchev pcm_close(pcm); 2304765c439491ddda3de658e62cc4a64d10e726b34Iliyan Malchev return -errno; 2314765c439491ddda3de658e62cc4a64d10e726b34Iliyan Malchev } 2324765c439491ddda3de658e62cc4a64d10e726b34Iliyan Malchev } 2339746c4758b161e26eec92b1ef1ff1bf0ba0bd268Ajay Dudani#endif 2344765c439491ddda3de658e62cc4a64d10e726b34Iliyan Malchev pcm->channels = channels; 2354765c439491ddda3de658e62cc4a64d10e726b34Iliyan Malchev pcm->rate = rate; 2364765c439491ddda3de658e62cc4a64d10e726b34Iliyan Malchev pcm->flags = flags; 2374765c439491ddda3de658e62cc4a64d10e726b34Iliyan Malchev pcm->format = format; 2384765c439491ddda3de658e62cc4a64d10e726b34Iliyan Malchev if (set_params(pcm)) { 2394765c439491ddda3de658e62cc4a64d10e726b34Iliyan Malchev fprintf(stderr, "Aplay:params setting failed\n"); 2404765c439491ddda3de658e62cc4a64d10e726b34Iliyan Malchev pcm_close(pcm); 2414765c439491ddda3de658e62cc4a64d10e726b34Iliyan Malchev return -errno; 2424765c439491ddda3de658e62cc4a64d10e726b34Iliyan Malchev } 2434765c439491ddda3de658e62cc4a64d10e726b34Iliyan Malchev 2444765c439491ddda3de658e62cc4a64d10e726b34Iliyan Malchev if (!pcm_flag) { 2454765c439491ddda3de658e62cc4a64d10e726b34Iliyan Malchev if (pcm_prepare(pcm)) { 2464765c439491ddda3de658e62cc4a64d10e726b34Iliyan Malchev fprintf(stderr, "Aplay:Failed in pcm_prepare\n"); 2474765c439491ddda3de658e62cc4a64d10e726b34Iliyan Malchev pcm_close(pcm); 2484765c439491ddda3de658e62cc4a64d10e726b34Iliyan Malchev return -errno; 2494765c439491ddda3de658e62cc4a64d10e726b34Iliyan Malchev } 2504765c439491ddda3de658e62cc4a64d10e726b34Iliyan Malchev if (ioctl(pcm->fd, SNDRV_PCM_IOCTL_START)) { 2514765c439491ddda3de658e62cc4a64d10e726b34Iliyan Malchev fprintf(stderr, "Aplay: Hostless IOCTL_START Error no %d \n", errno); 2524765c439491ddda3de658e62cc4a64d10e726b34Iliyan Malchev pcm_close(pcm); 2534765c439491ddda3de658e62cc4a64d10e726b34Iliyan Malchev return -errno; 2544765c439491ddda3de658e62cc4a64d10e726b34Iliyan Malchev } 2554765c439491ddda3de658e62cc4a64d10e726b34Iliyan Malchev while(1); 2564765c439491ddda3de658e62cc4a64d10e726b34Iliyan Malchev } 2574765c439491ddda3de658e62cc4a64d10e726b34Iliyan Malchev 2584765c439491ddda3de658e62cc4a64d10e726b34Iliyan Malchev remainingData = data_sz; 2594765c439491ddda3de658e62cc4a64d10e726b34Iliyan Malchev 2604765c439491ddda3de658e62cc4a64d10e726b34Iliyan Malchev if (flags & PCM_MMAP) { 2614765c439491ddda3de658e62cc4a64d10e726b34Iliyan Malchev u_int8_t *dst_addr = NULL; 2624765c439491ddda3de658e62cc4a64d10e726b34Iliyan Malchev struct snd_pcm_sync_ptr *sync_ptr1 = pcm->sync_ptr; 2634765c439491ddda3de658e62cc4a64d10e726b34Iliyan Malchev if (mmap_buffer(pcm)) { 2644765c439491ddda3de658e62cc4a64d10e726b34Iliyan Malchev fprintf(stderr, "Aplay:params setting failed\n"); 2654765c439491ddda3de658e62cc4a64d10e726b34Iliyan Malchev pcm_close(pcm); 2664765c439491ddda3de658e62cc4a64d10e726b34Iliyan Malchev return -errno; 2674765c439491ddda3de658e62cc4a64d10e726b34Iliyan Malchev } 2684765c439491ddda3de658e62cc4a64d10e726b34Iliyan Malchev if (pcm_prepare(pcm)) { 2694765c439491ddda3de658e62cc4a64d10e726b34Iliyan Malchev fprintf(stderr, "Aplay:Failed in pcm_prepare\n"); 2704765c439491ddda3de658e62cc4a64d10e726b34Iliyan Malchev pcm_close(pcm); 2714765c439491ddda3de658e62cc4a64d10e726b34Iliyan Malchev return -errno; 2724765c439491ddda3de658e62cc4a64d10e726b34Iliyan Malchev } 2734765c439491ddda3de658e62cc4a64d10e726b34Iliyan Malchev 2744765c439491ddda3de658e62cc4a64d10e726b34Iliyan Malchev bufsize = pcm->period_size; 2754765c439491ddda3de658e62cc4a64d10e726b34Iliyan Malchev if (debug) 2764765c439491ddda3de658e62cc4a64d10e726b34Iliyan Malchev fprintf(stderr, "Aplay:bufsize = %d\n", bufsize); 2774765c439491ddda3de658e62cc4a64d10e726b34Iliyan Malchev 2784765c439491ddda3de658e62cc4a64d10e726b34Iliyan Malchev pfd[0].fd = pcm->timer_fd; 2794765c439491ddda3de658e62cc4a64d10e726b34Iliyan Malchev pfd[0].events = POLLIN; 2804765c439491ddda3de658e62cc4a64d10e726b34Iliyan Malchev 2814765c439491ddda3de658e62cc4a64d10e726b34Iliyan Malchev frames = (pcm->flags & PCM_MONO) ? (bufsize / 2) : (bufsize / 4); 2824765c439491ddda3de658e62cc4a64d10e726b34Iliyan Malchev for (;;) { 2834765c439491ddda3de658e62cc4a64d10e726b34Iliyan Malchev if (!pcm->running) { 2844765c439491ddda3de658e62cc4a64d10e726b34Iliyan Malchev if (pcm_prepare(pcm)) { 2854765c439491ddda3de658e62cc4a64d10e726b34Iliyan Malchev fprintf(stderr, "Aplay:Failed in pcm_prepare\n"); 2864765c439491ddda3de658e62cc4a64d10e726b34Iliyan Malchev pcm_close(pcm); 2874765c439491ddda3de658e62cc4a64d10e726b34Iliyan Malchev return -errno; 2884765c439491ddda3de658e62cc4a64d10e726b34Iliyan Malchev } 2894765c439491ddda3de658e62cc4a64d10e726b34Iliyan Malchev pcm->running = 1; 2904765c439491ddda3de658e62cc4a64d10e726b34Iliyan Malchev start = 0; 2914765c439491ddda3de658e62cc4a64d10e726b34Iliyan Malchev } 2924765c439491ddda3de658e62cc4a64d10e726b34Iliyan Malchev /* Sync the current Application pointer from the kernel */ 2934765c439491ddda3de658e62cc4a64d10e726b34Iliyan Malchev pcm->sync_ptr->flags = SNDRV_PCM_SYNC_PTR_APPL | SNDRV_PCM_SYNC_PTR_AVAIL_MIN;//SNDRV_PCM_SYNC_PTR_HWSYNC; 2944765c439491ddda3de658e62cc4a64d10e726b34Iliyan Malchev err = sync_ptr(pcm); 2954765c439491ddda3de658e62cc4a64d10e726b34Iliyan Malchev if (err == EPIPE) { 2964765c439491ddda3de658e62cc4a64d10e726b34Iliyan Malchev fprintf(stderr, "Aplay:Failed in sync_ptr \n"); 2974765c439491ddda3de658e62cc4a64d10e726b34Iliyan Malchev /* we failed to make our window -- try to restart */ 2984765c439491ddda3de658e62cc4a64d10e726b34Iliyan Malchev pcm->underruns++; 2994765c439491ddda3de658e62cc4a64d10e726b34Iliyan Malchev pcm->running = 0; 3004765c439491ddda3de658e62cc4a64d10e726b34Iliyan Malchev continue; 3014765c439491ddda3de658e62cc4a64d10e726b34Iliyan Malchev } 3024765c439491ddda3de658e62cc4a64d10e726b34Iliyan Malchev /* 3034765c439491ddda3de658e62cc4a64d10e726b34Iliyan Malchev * Check for the available buffer in driver. If available buffer is 3044765c439491ddda3de658e62cc4a64d10e726b34Iliyan Malchev * less than avail_min we need to wait 3054765c439491ddda3de658e62cc4a64d10e726b34Iliyan Malchev */ 3064765c439491ddda3de658e62cc4a64d10e726b34Iliyan Malchev avail = pcm_avail(pcm); 3074765c439491ddda3de658e62cc4a64d10e726b34Iliyan Malchev if (avail < 0) { 3084765c439491ddda3de658e62cc4a64d10e726b34Iliyan Malchev fprintf(stderr, "Aplay:Failed in pcm_avail\n"); 3094765c439491ddda3de658e62cc4a64d10e726b34Iliyan Malchev pcm_close(pcm); 3104765c439491ddda3de658e62cc4a64d10e726b34Iliyan Malchev return avail; 3114765c439491ddda3de658e62cc4a64d10e726b34Iliyan Malchev } 3124765c439491ddda3de658e62cc4a64d10e726b34Iliyan Malchev if (avail < pcm->sw_p->avail_min) { 3134765c439491ddda3de658e62cc4a64d10e726b34Iliyan Malchev poll(pfd, nfds, TIMEOUT_INFINITE); 3144765c439491ddda3de658e62cc4a64d10e726b34Iliyan Malchev continue; 3154765c439491ddda3de658e62cc4a64d10e726b34Iliyan Malchev } 3164765c439491ddda3de658e62cc4a64d10e726b34Iliyan Malchev /* 3174765c439491ddda3de658e62cc4a64d10e726b34Iliyan Malchev * Now that we have buffer size greater than avail_min available to 3184765c439491ddda3de658e62cc4a64d10e726b34Iliyan Malchev * to be written we need to calcutate the buffer offset where we can 3194765c439491ddda3de658e62cc4a64d10e726b34Iliyan Malchev * start writting. 3204765c439491ddda3de658e62cc4a64d10e726b34Iliyan Malchev */ 3214765c439491ddda3de658e62cc4a64d10e726b34Iliyan Malchev dst_addr = dst_address(pcm); 3224765c439491ddda3de658e62cc4a64d10e726b34Iliyan Malchev 3234765c439491ddda3de658e62cc4a64d10e726b34Iliyan Malchev if (debug) { 3244765c439491ddda3de658e62cc4a64d10e726b34Iliyan Malchev fprintf(stderr, "dst_addr = 0x%08x\n", dst_addr); 3254765c439491ddda3de658e62cc4a64d10e726b34Iliyan Malchev fprintf(stderr, "Aplay:avail = %d frames = %d\n",avail, frames); 3264765c439491ddda3de658e62cc4a64d10e726b34Iliyan Malchev fprintf(stderr, "Aplay:sync_ptr->s.status.hw_ptr %ld pcm->buffer_size %d sync_ptr->c.control.appl_ptr %ld\n", 3274765c439491ddda3de658e62cc4a64d10e726b34Iliyan Malchev pcm->sync_ptr->s.status.hw_ptr, 3284765c439491ddda3de658e62cc4a64d10e726b34Iliyan Malchev pcm->buffer_size, 3294765c439491ddda3de658e62cc4a64d10e726b34Iliyan Malchev pcm->sync_ptr->c.control.appl_ptr); 3304765c439491ddda3de658e62cc4a64d10e726b34Iliyan Malchev } 3314765c439491ddda3de658e62cc4a64d10e726b34Iliyan Malchev 3324765c439491ddda3de658e62cc4a64d10e726b34Iliyan Malchev /* 3334765c439491ddda3de658e62cc4a64d10e726b34Iliyan Malchev * Read from the file to the destination buffer in kernel mmaped buffer 3344765c439491ddda3de658e62cc4a64d10e726b34Iliyan Malchev * This reduces a extra copy of intermediate buffer. 3354765c439491ddda3de658e62cc4a64d10e726b34Iliyan Malchev */ 3364765c439491ddda3de658e62cc4a64d10e726b34Iliyan Malchev memset(dst_addr, 0x0, bufsize); 3374765c439491ddda3de658e62cc4a64d10e726b34Iliyan Malchev 3384765c439491ddda3de658e62cc4a64d10e726b34Iliyan Malchev if (data_sz && !piped) { 3394765c439491ddda3de658e62cc4a64d10e726b34Iliyan Malchev if (remainingData < bufsize) { 3404765c439491ddda3de658e62cc4a64d10e726b34Iliyan Malchev bufsize = remainingData; 3414765c439491ddda3de658e62cc4a64d10e726b34Iliyan Malchev frames = (pcm->flags & PCM_MONO) ? (remainingData / 2) : (remainingData / 4); 3424765c439491ddda3de658e62cc4a64d10e726b34Iliyan Malchev } 3434765c439491ddda3de658e62cc4a64d10e726b34Iliyan Malchev } 3444765c439491ddda3de658e62cc4a64d10e726b34Iliyan Malchev 3454765c439491ddda3de658e62cc4a64d10e726b34Iliyan Malchev err = read(fd, dst_addr , bufsize); 3464765c439491ddda3de658e62cc4a64d10e726b34Iliyan Malchev if (debug) 3474765c439491ddda3de658e62cc4a64d10e726b34Iliyan Malchev fprintf(stderr, "read %d bytes from file\n", err); 3484765c439491ddda3de658e62cc4a64d10e726b34Iliyan Malchev if (err <= 0) 3494765c439491ddda3de658e62cc4a64d10e726b34Iliyan Malchev break; 3504765c439491ddda3de658e62cc4a64d10e726b34Iliyan Malchev 3514765c439491ddda3de658e62cc4a64d10e726b34Iliyan Malchev if (data_sz && !piped) { 3524765c439491ddda3de658e62cc4a64d10e726b34Iliyan Malchev remainingData -= bufsize; 3534765c439491ddda3de658e62cc4a64d10e726b34Iliyan Malchev if (remainingData <= 0) 3544765c439491ddda3de658e62cc4a64d10e726b34Iliyan Malchev break; 3554765c439491ddda3de658e62cc4a64d10e726b34Iliyan Malchev } 3564765c439491ddda3de658e62cc4a64d10e726b34Iliyan Malchev 3574765c439491ddda3de658e62cc4a64d10e726b34Iliyan Malchev /* 3584765c439491ddda3de658e62cc4a64d10e726b34Iliyan Malchev * Increment the application pointer with data written to kernel. 3594765c439491ddda3de658e62cc4a64d10e726b34Iliyan Malchev * Update kernel with the new sync pointer. 3604765c439491ddda3de658e62cc4a64d10e726b34Iliyan Malchev */ 3614765c439491ddda3de658e62cc4a64d10e726b34Iliyan Malchev pcm->sync_ptr->c.control.appl_ptr += frames; 3624765c439491ddda3de658e62cc4a64d10e726b34Iliyan Malchev pcm->sync_ptr->flags = 0; 3634765c439491ddda3de658e62cc4a64d10e726b34Iliyan Malchev 3644765c439491ddda3de658e62cc4a64d10e726b34Iliyan Malchev err = sync_ptr(pcm); 3654765c439491ddda3de658e62cc4a64d10e726b34Iliyan Malchev if (err == EPIPE) { 3664765c439491ddda3de658e62cc4a64d10e726b34Iliyan Malchev fprintf(stderr, "Aplay:Failed in sync_ptr 2 \n"); 3674765c439491ddda3de658e62cc4a64d10e726b34Iliyan Malchev /* we failed to make our window -- try to restart */ 3684765c439491ddda3de658e62cc4a64d10e726b34Iliyan Malchev pcm->underruns++; 3694765c439491ddda3de658e62cc4a64d10e726b34Iliyan Malchev pcm->running = 0; 3704765c439491ddda3de658e62cc4a64d10e726b34Iliyan Malchev continue; 3714765c439491ddda3de658e62cc4a64d10e726b34Iliyan Malchev } 3724765c439491ddda3de658e62cc4a64d10e726b34Iliyan Malchev 3734765c439491ddda3de658e62cc4a64d10e726b34Iliyan Malchev if (debug) { 3744765c439491ddda3de658e62cc4a64d10e726b34Iliyan Malchev fprintf(stderr, "Aplay:sync_ptr->s.status.hw_ptr %ld sync_ptr->c.control.appl_ptr %ld\n", 3754765c439491ddda3de658e62cc4a64d10e726b34Iliyan Malchev pcm->sync_ptr->s.status.hw_ptr, 3764765c439491ddda3de658e62cc4a64d10e726b34Iliyan Malchev pcm->sync_ptr->c.control.appl_ptr); 3779746c4758b161e26eec92b1ef1ff1bf0ba0bd268Ajay Dudani#ifdef QCOM_COMPRESSED_AUDIO_ENABLED 3784765c439491ddda3de658e62cc4a64d10e726b34Iliyan Malchev if (compressed && start) { 3794765c439491ddda3de658e62cc4a64d10e726b34Iliyan Malchev struct snd_compr_tstamp tstamp; 3804765c439491ddda3de658e62cc4a64d10e726b34Iliyan Malchev if (ioctl(pcm->fd, SNDRV_COMPRESS_TSTAMP, &tstamp)) 3814765c439491ddda3de658e62cc4a64d10e726b34Iliyan Malchev fprintf(stderr, "Aplay: failed SNDRV_COMPRESS_TSTAMP\n"); 3824765c439491ddda3de658e62cc4a64d10e726b34Iliyan Malchev else 3834765c439491ddda3de658e62cc4a64d10e726b34Iliyan Malchev fprintf(stderr, "timestamp = %lld\n", tstamp.timestamp); 3844765c439491ddda3de658e62cc4a64d10e726b34Iliyan Malchev } 3859746c4758b161e26eec92b1ef1ff1bf0ba0bd268Ajay Dudani#endif 3864765c439491ddda3de658e62cc4a64d10e726b34Iliyan Malchev } 3874765c439491ddda3de658e62cc4a64d10e726b34Iliyan Malchev /* 3884765c439491ddda3de658e62cc4a64d10e726b34Iliyan Malchev * If we have reached start threshold of buffer prefill, 3894765c439491ddda3de658e62cc4a64d10e726b34Iliyan Malchev * its time to start the driver. 3904765c439491ddda3de658e62cc4a64d10e726b34Iliyan Malchev */ 3914765c439491ddda3de658e62cc4a64d10e726b34Iliyan Malchev if(start) 3924765c439491ddda3de658e62cc4a64d10e726b34Iliyan Malchev goto start_done; 3934765c439491ddda3de658e62cc4a64d10e726b34Iliyan Malchev if (ioctl(pcm->fd, SNDRV_PCM_IOCTL_START)) { 3944765c439491ddda3de658e62cc4a64d10e726b34Iliyan Malchev err = -errno; 3954765c439491ddda3de658e62cc4a64d10e726b34Iliyan Malchev if (errno == EPIPE) { 3964765c439491ddda3de658e62cc4a64d10e726b34Iliyan Malchev fprintf(stderr, "Aplay:Failed in SNDRV_PCM_IOCTL_START\n"); 3974765c439491ddda3de658e62cc4a64d10e726b34Iliyan Malchev /* we failed to make our window -- try to restart */ 3984765c439491ddda3de658e62cc4a64d10e726b34Iliyan Malchev pcm->underruns++; 3994765c439491ddda3de658e62cc4a64d10e726b34Iliyan Malchev pcm->running = 0; 4004765c439491ddda3de658e62cc4a64d10e726b34Iliyan Malchev continue; 4014765c439491ddda3de658e62cc4a64d10e726b34Iliyan Malchev } else { 4024765c439491ddda3de658e62cc4a64d10e726b34Iliyan Malchev fprintf(stderr, "Aplay:Error no %d \n", errno); 4034765c439491ddda3de658e62cc4a64d10e726b34Iliyan Malchev pcm_close(pcm); 4044765c439491ddda3de658e62cc4a64d10e726b34Iliyan Malchev return -errno; 4054765c439491ddda3de658e62cc4a64d10e726b34Iliyan Malchev } 4064765c439491ddda3de658e62cc4a64d10e726b34Iliyan Malchev } else 4074765c439491ddda3de658e62cc4a64d10e726b34Iliyan Malchev start = 1; 4084765c439491ddda3de658e62cc4a64d10e726b34Iliyan Malchev 4094765c439491ddda3de658e62cc4a64d10e726b34Iliyan Malchevstart_done: 4104765c439491ddda3de658e62cc4a64d10e726b34Iliyan Malchev offset += frames; 4114765c439491ddda3de658e62cc4a64d10e726b34Iliyan Malchev } 4124765c439491ddda3de658e62cc4a64d10e726b34Iliyan Malchev while(1) { 4134765c439491ddda3de658e62cc4a64d10e726b34Iliyan Malchev pcm->sync_ptr->flags = SNDRV_PCM_SYNC_PTR_APPL | SNDRV_PCM_SYNC_PTR_AVAIL_MIN;//SNDRV_PCM_SYNC_PTR_HWSYNC; 4144765c439491ddda3de658e62cc4a64d10e726b34Iliyan Malchev sync_ptr(pcm); 4154765c439491ddda3de658e62cc4a64d10e726b34Iliyan Malchev /* 4164765c439491ddda3de658e62cc4a64d10e726b34Iliyan Malchev * Check for the available buffer in driver. If available buffer is 4174765c439491ddda3de658e62cc4a64d10e726b34Iliyan Malchev * less than avail_min we need to wait 4184765c439491ddda3de658e62cc4a64d10e726b34Iliyan Malchev */ 4194765c439491ddda3de658e62cc4a64d10e726b34Iliyan Malchev if (pcm->sync_ptr->s.status.hw_ptr >= pcm->sync_ptr->c.control.appl_ptr) { 4204765c439491ddda3de658e62cc4a64d10e726b34Iliyan Malchev fprintf(stderr, "Aplay:sync_ptr->s.status.hw_ptr %ld sync_ptr->c.control.appl_ptr %ld\n", 4214765c439491ddda3de658e62cc4a64d10e726b34Iliyan Malchev pcm->sync_ptr->s.status.hw_ptr, 4224765c439491ddda3de658e62cc4a64d10e726b34Iliyan Malchev pcm->sync_ptr->c.control.appl_ptr); 4234765c439491ddda3de658e62cc4a64d10e726b34Iliyan Malchev break; 4244765c439491ddda3de658e62cc4a64d10e726b34Iliyan Malchev } else 4254765c439491ddda3de658e62cc4a64d10e726b34Iliyan Malchev poll(pfd, nfds, TIMEOUT_INFINITE); 4264765c439491ddda3de658e62cc4a64d10e726b34Iliyan Malchev } 4274765c439491ddda3de658e62cc4a64d10e726b34Iliyan Malchev } else { 4284765c439491ddda3de658e62cc4a64d10e726b34Iliyan Malchev if (pcm_prepare(pcm)) { 4294765c439491ddda3de658e62cc4a64d10e726b34Iliyan Malchev fprintf(stderr, "Aplay:Failed in pcm_prepare\n"); 4304765c439491ddda3de658e62cc4a64d10e726b34Iliyan Malchev pcm_close(pcm); 4314765c439491ddda3de658e62cc4a64d10e726b34Iliyan Malchev return -errno; 4324765c439491ddda3de658e62cc4a64d10e726b34Iliyan Malchev } 4334765c439491ddda3de658e62cc4a64d10e726b34Iliyan Malchev 4344765c439491ddda3de658e62cc4a64d10e726b34Iliyan Malchev bufsize = pcm->period_size; 4354765c439491ddda3de658e62cc4a64d10e726b34Iliyan Malchev 4364765c439491ddda3de658e62cc4a64d10e726b34Iliyan Malchev data = calloc(1, bufsize); 4374765c439491ddda3de658e62cc4a64d10e726b34Iliyan Malchev if (!data) { 4384765c439491ddda3de658e62cc4a64d10e726b34Iliyan Malchev fprintf(stderr, "Aplay:could not allocate %d bytes\n", bufsize); 4394765c439491ddda3de658e62cc4a64d10e726b34Iliyan Malchev pcm_close(pcm); 4404765c439491ddda3de658e62cc4a64d10e726b34Iliyan Malchev return -ENOMEM; 4414765c439491ddda3de658e62cc4a64d10e726b34Iliyan Malchev } 4424765c439491ddda3de658e62cc4a64d10e726b34Iliyan Malchev 4434765c439491ddda3de658e62cc4a64d10e726b34Iliyan Malchev if (data_sz && !piped) { 4444765c439491ddda3de658e62cc4a64d10e726b34Iliyan Malchev if (remainingData < bufsize) 4454765c439491ddda3de658e62cc4a64d10e726b34Iliyan Malchev bufsize = remainingData; 4464765c439491ddda3de658e62cc4a64d10e726b34Iliyan Malchev } 4474765c439491ddda3de658e62cc4a64d10e726b34Iliyan Malchev 4484765c439491ddda3de658e62cc4a64d10e726b34Iliyan Malchev while (read(fd, data, bufsize) > 0) { 4494765c439491ddda3de658e62cc4a64d10e726b34Iliyan Malchev if (pcm_write(pcm, data, bufsize)){ 4504765c439491ddda3de658e62cc4a64d10e726b34Iliyan Malchev fprintf(stderr, "Aplay: pcm_write failed\n"); 4514765c439491ddda3de658e62cc4a64d10e726b34Iliyan Malchev free(data); 4524765c439491ddda3de658e62cc4a64d10e726b34Iliyan Malchev pcm_close(pcm); 4534765c439491ddda3de658e62cc4a64d10e726b34Iliyan Malchev return -errno; 4544765c439491ddda3de658e62cc4a64d10e726b34Iliyan Malchev } 4554765c439491ddda3de658e62cc4a64d10e726b34Iliyan Malchev memset(data, 0, bufsize); 4564765c439491ddda3de658e62cc4a64d10e726b34Iliyan Malchev 4574765c439491ddda3de658e62cc4a64d10e726b34Iliyan Malchev if (data_sz && !piped) { 4584765c439491ddda3de658e62cc4a64d10e726b34Iliyan Malchev remainingData -= bufsize; 4594765c439491ddda3de658e62cc4a64d10e726b34Iliyan Malchev if (remainingData <= 0) 4604765c439491ddda3de658e62cc4a64d10e726b34Iliyan Malchev break; 4614765c439491ddda3de658e62cc4a64d10e726b34Iliyan Malchev if (remainingData < bufsize) 4624765c439491ddda3de658e62cc4a64d10e726b34Iliyan Malchev bufsize = remainingData; 4634765c439491ddda3de658e62cc4a64d10e726b34Iliyan Malchev } 4644765c439491ddda3de658e62cc4a64d10e726b34Iliyan Malchev } 4654765c439491ddda3de658e62cc4a64d10e726b34Iliyan Malchev free(data); 4664765c439491ddda3de658e62cc4a64d10e726b34Iliyan Malchev } 4674765c439491ddda3de658e62cc4a64d10e726b34Iliyan Malchev fprintf(stderr, "Aplay: Done playing\n"); 4684765c439491ddda3de658e62cc4a64d10e726b34Iliyan Malchev pcm_close(pcm); 4694765c439491ddda3de658e62cc4a64d10e726b34Iliyan Malchev return 0; 4704765c439491ddda3de658e62cc4a64d10e726b34Iliyan Malchev} 4714765c439491ddda3de658e62cc4a64d10e726b34Iliyan Malchev 4724765c439491ddda3de658e62cc4a64d10e726b34Iliyan Malchevint play_raw(const char *fg, int rate, int ch, const char *device, const char *fn) 4734765c439491ddda3de658e62cc4a64d10e726b34Iliyan Malchev{ 4744765c439491ddda3de658e62cc4a64d10e726b34Iliyan Malchev int fd; 4754765c439491ddda3de658e62cc4a64d10e726b34Iliyan Malchev unsigned flag = 0; 4764765c439491ddda3de658e62cc4a64d10e726b34Iliyan Malchev 4774765c439491ddda3de658e62cc4a64d10e726b34Iliyan Malchev if(!fn) { 4784765c439491ddda3de658e62cc4a64d10e726b34Iliyan Malchev fd = fileno(stdin); 4794765c439491ddda3de658e62cc4a64d10e726b34Iliyan Malchev piped = 1; 4804765c439491ddda3de658e62cc4a64d10e726b34Iliyan Malchev } else { 4814765c439491ddda3de658e62cc4a64d10e726b34Iliyan Malchev fd = open(fn, O_RDONLY); 4824765c439491ddda3de658e62cc4a64d10e726b34Iliyan Malchev if (fd < 0) { 4834765c439491ddda3de658e62cc4a64d10e726b34Iliyan Malchev fprintf(stderr, "Aplay:aplay: cannot open '%s'\n", fn); 4844765c439491ddda3de658e62cc4a64d10e726b34Iliyan Malchev return fd; 4854765c439491ddda3de658e62cc4a64d10e726b34Iliyan Malchev } 4864765c439491ddda3de658e62cc4a64d10e726b34Iliyan Malchev } 4874765c439491ddda3de658e62cc4a64d10e726b34Iliyan Malchev 4884765c439491ddda3de658e62cc4a64d10e726b34Iliyan Malchev if (!strncmp(fg, "M", sizeof("M"))) 4894765c439491ddda3de658e62cc4a64d10e726b34Iliyan Malchev flag = PCM_MMAP; 4904765c439491ddda3de658e62cc4a64d10e726b34Iliyan Malchev else if (!strncmp(fg, "N", sizeof("N"))) 4914765c439491ddda3de658e62cc4a64d10e726b34Iliyan Malchev flag = PCM_NMMAP; 4924765c439491ddda3de658e62cc4a64d10e726b34Iliyan Malchev 4934765c439491ddda3de658e62cc4a64d10e726b34Iliyan Malchev fprintf(stderr, "aplay: Playing '%s': format %s ch = %d\n", 4944765c439491ddda3de658e62cc4a64d10e726b34Iliyan Malchev fn, get_format_desc(format), ch ); 4954765c439491ddda3de658e62cc4a64d10e726b34Iliyan Malchev return play_file(rate, ch, fd, flag, device, 0); 4964765c439491ddda3de658e62cc4a64d10e726b34Iliyan Malchev} 4974765c439491ddda3de658e62cc4a64d10e726b34Iliyan Malchev 4984765c439491ddda3de658e62cc4a64d10e726b34Iliyan Malchevint play_wav(const char *fg, int rate, int ch, const char *device, const char *fn) 4994765c439491ddda3de658e62cc4a64d10e726b34Iliyan Malchev{ 5004765c439491ddda3de658e62cc4a64d10e726b34Iliyan Malchev struct wav_header hdr; 5014765c439491ddda3de658e62cc4a64d10e726b34Iliyan Malchev int fd; 5024765c439491ddda3de658e62cc4a64d10e726b34Iliyan Malchev unsigned flag = 0; 5034765c439491ddda3de658e62cc4a64d10e726b34Iliyan Malchev 5044765c439491ddda3de658e62cc4a64d10e726b34Iliyan Malchev if (pcm_flag) { 5054765c439491ddda3de658e62cc4a64d10e726b34Iliyan Malchev if(!fn) { 5064765c439491ddda3de658e62cc4a64d10e726b34Iliyan Malchev fd = fileno(stdin); 5074765c439491ddda3de658e62cc4a64d10e726b34Iliyan Malchev piped = 1; 5084765c439491ddda3de658e62cc4a64d10e726b34Iliyan Malchev } else { 5094765c439491ddda3de658e62cc4a64d10e726b34Iliyan Malchev fd = open(fn, O_RDONLY); 5104765c439491ddda3de658e62cc4a64d10e726b34Iliyan Malchev if (fd < 0) { 5114765c439491ddda3de658e62cc4a64d10e726b34Iliyan Malchev fprintf(stderr, "Aplay:aplay: cannot open '%s'\n", fn); 5124765c439491ddda3de658e62cc4a64d10e726b34Iliyan Malchev return fd; 5134765c439491ddda3de658e62cc4a64d10e726b34Iliyan Malchev } 5144765c439491ddda3de658e62cc4a64d10e726b34Iliyan Malchev } 5154765c439491ddda3de658e62cc4a64d10e726b34Iliyan Malchev if (compressed) { 5164765c439491ddda3de658e62cc4a64d10e726b34Iliyan Malchev hdr.sample_rate = rate; 5174765c439491ddda3de658e62cc4a64d10e726b34Iliyan Malchev hdr.num_channels = ch; 5184765c439491ddda3de658e62cc4a64d10e726b34Iliyan Malchev hdr.data_sz = 0; 5194765c439491ddda3de658e62cc4a64d10e726b34Iliyan Malchev goto ignore_header; 5204765c439491ddda3de658e62cc4a64d10e726b34Iliyan Malchev } 5214765c439491ddda3de658e62cc4a64d10e726b34Iliyan Malchev 5224765c439491ddda3de658e62cc4a64d10e726b34Iliyan Malchev if (read(fd, &hdr, sizeof(hdr)) != sizeof(hdr)) { 5234765c439491ddda3de658e62cc4a64d10e726b34Iliyan Malchev fprintf(stderr, "Aplay:aplay: cannot read header\n"); 5244765c439491ddda3de658e62cc4a64d10e726b34Iliyan Malchev return -errno; 5254765c439491ddda3de658e62cc4a64d10e726b34Iliyan Malchev } 5264765c439491ddda3de658e62cc4a64d10e726b34Iliyan Malchev 5274765c439491ddda3de658e62cc4a64d10e726b34Iliyan Malchev if ((hdr.riff_id != ID_RIFF) || 5284765c439491ddda3de658e62cc4a64d10e726b34Iliyan Malchev (hdr.riff_fmt != ID_WAVE) || 5294765c439491ddda3de658e62cc4a64d10e726b34Iliyan Malchev (hdr.fmt_id != ID_FMT)) { 5304765c439491ddda3de658e62cc4a64d10e726b34Iliyan Malchev fprintf(stderr, "Aplay:aplay: '%s' is not a riff/wave file\n", fn); 5314765c439491ddda3de658e62cc4a64d10e726b34Iliyan Malchev return -EINVAL; 5324765c439491ddda3de658e62cc4a64d10e726b34Iliyan Malchev } 5334765c439491ddda3de658e62cc4a64d10e726b34Iliyan Malchev if ((hdr.audio_format != FORMAT_PCM) || 5344765c439491ddda3de658e62cc4a64d10e726b34Iliyan Malchev (hdr.fmt_sz != 16)) { 5354765c439491ddda3de658e62cc4a64d10e726b34Iliyan Malchev fprintf(stderr, "Aplay:aplay: '%s' is not pcm format\n", fn); 5364765c439491ddda3de658e62cc4a64d10e726b34Iliyan Malchev return -EINVAL; 5374765c439491ddda3de658e62cc4a64d10e726b34Iliyan Malchev } 5384765c439491ddda3de658e62cc4a64d10e726b34Iliyan Malchev if (hdr.bits_per_sample != 16) { 5394765c439491ddda3de658e62cc4a64d10e726b34Iliyan Malchev fprintf(stderr, "Aplay:aplay: '%s' is not 16bit per sample\n", fn); 5404765c439491ddda3de658e62cc4a64d10e726b34Iliyan Malchev return -EINVAL; 5414765c439491ddda3de658e62cc4a64d10e726b34Iliyan Malchev } 5424765c439491ddda3de658e62cc4a64d10e726b34Iliyan Malchev } else { 5434765c439491ddda3de658e62cc4a64d10e726b34Iliyan Malchev fd = -EBADFD; 5444765c439491ddda3de658e62cc4a64d10e726b34Iliyan Malchev hdr.sample_rate = rate; 5454765c439491ddda3de658e62cc4a64d10e726b34Iliyan Malchev hdr.num_channels = ch; 5464765c439491ddda3de658e62cc4a64d10e726b34Iliyan Malchev hdr.data_sz = 0; 5474765c439491ddda3de658e62cc4a64d10e726b34Iliyan Malchev } 5484765c439491ddda3de658e62cc4a64d10e726b34Iliyan Malchev 5494765c439491ddda3de658e62cc4a64d10e726b34Iliyan Malchevignore_header: 5504765c439491ddda3de658e62cc4a64d10e726b34Iliyan Malchev if (!strncmp(fg, "M", sizeof("M"))) 5514765c439491ddda3de658e62cc4a64d10e726b34Iliyan Malchev flag = PCM_MMAP; 5524765c439491ddda3de658e62cc4a64d10e726b34Iliyan Malchev else if (!strncmp(fg, "N", sizeof("N"))) 5534765c439491ddda3de658e62cc4a64d10e726b34Iliyan Malchev flag = PCM_NMMAP; 5544765c439491ddda3de658e62cc4a64d10e726b34Iliyan Malchev fprintf(stderr, "aplay: Playing '%s':%s\n", fn, get_format_desc(format) ); 5554765c439491ddda3de658e62cc4a64d10e726b34Iliyan Malchev 5564765c439491ddda3de658e62cc4a64d10e726b34Iliyan Malchev return play_file(hdr.sample_rate, hdr.num_channels, fd, flag, device, hdr.data_sz); 5574765c439491ddda3de658e62cc4a64d10e726b34Iliyan Malchev} 5584765c439491ddda3de658e62cc4a64d10e726b34Iliyan Malchev 5594765c439491ddda3de658e62cc4a64d10e726b34Iliyan Malchevint main(int argc, char **argv) 5604765c439491ddda3de658e62cc4a64d10e726b34Iliyan Malchev{ 5614765c439491ddda3de658e62cc4a64d10e726b34Iliyan Malchev int option_index = 0; 5624765c439491ddda3de658e62cc4a64d10e726b34Iliyan Malchev int c,i; 5634765c439491ddda3de658e62cc4a64d10e726b34Iliyan Malchev int ch = 2; 5644765c439491ddda3de658e62cc4a64d10e726b34Iliyan Malchev int rate = 44100; 5654765c439491ddda3de658e62cc4a64d10e726b34Iliyan Malchev char *mmap = "N"; 5664765c439491ddda3de658e62cc4a64d10e726b34Iliyan Malchev char *device = "hw:0,0"; 5674765c439491ddda3de658e62cc4a64d10e726b34Iliyan Malchev char *filename; 5684765c439491ddda3de658e62cc4a64d10e726b34Iliyan Malchev int rc = 0; 5694765c439491ddda3de658e62cc4a64d10e726b34Iliyan Malchev 5704765c439491ddda3de658e62cc4a64d10e726b34Iliyan Malchev if (argc <2) { 5714765c439491ddda3de658e62cc4a64d10e726b34Iliyan Malchev printf("\nUsage: aplay [options] <file>\n" 5724765c439491ddda3de658e62cc4a64d10e726b34Iliyan Malchev "options:\n" 5734765c439491ddda3de658e62cc4a64d10e726b34Iliyan Malchev "-D <hw:C,D> -- Alsa PCM by name\n" 5744765c439491ddda3de658e62cc4a64d10e726b34Iliyan Malchev "-M -- Mmap stream\n" 5754765c439491ddda3de658e62cc4a64d10e726b34Iliyan Malchev "-P -- Hostless steam[No PCM]\n" 5764765c439491ddda3de658e62cc4a64d10e726b34Iliyan Malchev "-C -- Channels\n" 5774765c439491ddda3de658e62cc4a64d10e726b34Iliyan Malchev "-R -- Rate\n" 5784765c439491ddda3de658e62cc4a64d10e726b34Iliyan Malchev "-V -- verbose\n" 5794765c439491ddda3de658e62cc4a64d10e726b34Iliyan Malchev "-F -- Format\n" 5804765c439491ddda3de658e62cc4a64d10e726b34Iliyan Malchev "-B -- Period\n" 5814765c439491ddda3de658e62cc4a64d10e726b34Iliyan Malchev "-T <MP3, AAC, AC3_PASS_THROUGH> -- Compressed\n" 5824765c439491ddda3de658e62cc4a64d10e726b34Iliyan Malchev "<file> \n"); 5834765c439491ddda3de658e62cc4a64d10e726b34Iliyan Malchev fprintf(stderr, "Formats Supported:\n"); 5844765c439491ddda3de658e62cc4a64d10e726b34Iliyan Malchev for (i = 0; i <= SNDRV_PCM_FORMAT_LAST; ++i) 5854765c439491ddda3de658e62cc4a64d10e726b34Iliyan Malchev if (get_format_name(i)) 5864765c439491ddda3de658e62cc4a64d10e726b34Iliyan Malchev fprintf(stderr, "%s ", get_format_name(i)); 5874765c439491ddda3de658e62cc4a64d10e726b34Iliyan Malchev fprintf(stderr, "\nSome of these may not be available on selected hardware\n"); 5884765c439491ddda3de658e62cc4a64d10e726b34Iliyan Malchev return 0; 5894765c439491ddda3de658e62cc4a64d10e726b34Iliyan Malchev } 5904765c439491ddda3de658e62cc4a64d10e726b34Iliyan Malchev while ((c = getopt_long(argc, argv, "PVMD:R:C:F:B:T:", long_options, &option_index)) != -1) { 5914765c439491ddda3de658e62cc4a64d10e726b34Iliyan Malchev switch (c) { 5924765c439491ddda3de658e62cc4a64d10e726b34Iliyan Malchev case 'P': 5934765c439491ddda3de658e62cc4a64d10e726b34Iliyan Malchev pcm_flag = 0; 5944765c439491ddda3de658e62cc4a64d10e726b34Iliyan Malchev break; 5954765c439491ddda3de658e62cc4a64d10e726b34Iliyan Malchev case 'V': 5964765c439491ddda3de658e62cc4a64d10e726b34Iliyan Malchev debug = 1; 5974765c439491ddda3de658e62cc4a64d10e726b34Iliyan Malchev break; 5984765c439491ddda3de658e62cc4a64d10e726b34Iliyan Malchev case 'M': 5994765c439491ddda3de658e62cc4a64d10e726b34Iliyan Malchev mmap = "M"; 6004765c439491ddda3de658e62cc4a64d10e726b34Iliyan Malchev break; 6014765c439491ddda3de658e62cc4a64d10e726b34Iliyan Malchev case 'D': 6024765c439491ddda3de658e62cc4a64d10e726b34Iliyan Malchev device = optarg; 6034765c439491ddda3de658e62cc4a64d10e726b34Iliyan Malchev break; 6044765c439491ddda3de658e62cc4a64d10e726b34Iliyan Malchev case 'R': 6054765c439491ddda3de658e62cc4a64d10e726b34Iliyan Malchev rate = (int)strtol(optarg, NULL, 0); 6064765c439491ddda3de658e62cc4a64d10e726b34Iliyan Malchev break; 6074765c439491ddda3de658e62cc4a64d10e726b34Iliyan Malchev case 'C': 6084765c439491ddda3de658e62cc4a64d10e726b34Iliyan Malchev ch = (int)strtol(optarg, NULL, 0); 6094765c439491ddda3de658e62cc4a64d10e726b34Iliyan Malchev break; 6104765c439491ddda3de658e62cc4a64d10e726b34Iliyan Malchev case 'F': 6114765c439491ddda3de658e62cc4a64d10e726b34Iliyan Malchev printf("optarg = %s\n", optarg); 6124765c439491ddda3de658e62cc4a64d10e726b34Iliyan Malchev format = get_format(optarg); 6134765c439491ddda3de658e62cc4a64d10e726b34Iliyan Malchev break; 6144765c439491ddda3de658e62cc4a64d10e726b34Iliyan Malchev case 'B': 6154765c439491ddda3de658e62cc4a64d10e726b34Iliyan Malchev period = (int)strtol(optarg, NULL, 0); 6164765c439491ddda3de658e62cc4a64d10e726b34Iliyan Malchev break; 6174765c439491ddda3de658e62cc4a64d10e726b34Iliyan Malchev case 'T': 6184765c439491ddda3de658e62cc4a64d10e726b34Iliyan Malchev compressed = 1; 6194765c439491ddda3de658e62cc4a64d10e726b34Iliyan Malchev printf("compressed codec type requested = %s\n", optarg); 6204765c439491ddda3de658e62cc4a64d10e726b34Iliyan Malchev compr_codec = optarg; 6214765c439491ddda3de658e62cc4a64d10e726b34Iliyan Malchev break; 6224765c439491ddda3de658e62cc4a64d10e726b34Iliyan Malchev default: 6234765c439491ddda3de658e62cc4a64d10e726b34Iliyan Malchev printf("\nUsage: aplay [options] <file>\n" 6244765c439491ddda3de658e62cc4a64d10e726b34Iliyan Malchev "options:\n" 6254765c439491ddda3de658e62cc4a64d10e726b34Iliyan Malchev "-D <hw:C,D> -- Alsa PCM by name\n" 6264765c439491ddda3de658e62cc4a64d10e726b34Iliyan Malchev "-M -- Mmap stream\n" 6274765c439491ddda3de658e62cc4a64d10e726b34Iliyan Malchev "-P -- Hostless steam[No PCM]\n" 6284765c439491ddda3de658e62cc4a64d10e726b34Iliyan Malchev "-V -- verbose\n" 6294765c439491ddda3de658e62cc4a64d10e726b34Iliyan Malchev "-C -- Channels\n" 6304765c439491ddda3de658e62cc4a64d10e726b34Iliyan Malchev "-R -- Rate\n" 6314765c439491ddda3de658e62cc4a64d10e726b34Iliyan Malchev "-F -- Format\n" 6324765c439491ddda3de658e62cc4a64d10e726b34Iliyan Malchev "-B -- Period\n" 6334765c439491ddda3de658e62cc4a64d10e726b34Iliyan Malchev "-T -- Compressed\n" 6344765c439491ddda3de658e62cc4a64d10e726b34Iliyan Malchev "<file> \n"); 6354765c439491ddda3de658e62cc4a64d10e726b34Iliyan Malchev fprintf(stderr, "Formats Supported:\n"); 6364765c439491ddda3de658e62cc4a64d10e726b34Iliyan Malchev for (i = 0; i < SNDRV_PCM_FORMAT_LAST; ++i) 6374765c439491ddda3de658e62cc4a64d10e726b34Iliyan Malchev if (get_format_name(i)) 6384765c439491ddda3de658e62cc4a64d10e726b34Iliyan Malchev fprintf(stderr, "%s ", get_format_name(i)); 6394765c439491ddda3de658e62cc4a64d10e726b34Iliyan Malchev fprintf(stderr, "\nSome of these may not be available on selected hardware\n"); 6404765c439491ddda3de658e62cc4a64d10e726b34Iliyan Malchev return -EINVAL; 6414765c439491ddda3de658e62cc4a64d10e726b34Iliyan Malchev } 6424765c439491ddda3de658e62cc4a64d10e726b34Iliyan Malchev 6434765c439491ddda3de658e62cc4a64d10e726b34Iliyan Malchev } 6444765c439491ddda3de658e62cc4a64d10e726b34Iliyan Malchev filename = (char*) calloc(1, 30); 6454765c439491ddda3de658e62cc4a64d10e726b34Iliyan Malchev if (!filename) { 6464765c439491ddda3de658e62cc4a64d10e726b34Iliyan Malchev fprintf(stderr, "Aplay:Failed to allocate filename!"); 6474765c439491ddda3de658e62cc4a64d10e726b34Iliyan Malchev return -ENOMEM; 6484765c439491ddda3de658e62cc4a64d10e726b34Iliyan Malchev } 6494765c439491ddda3de658e62cc4a64d10e726b34Iliyan Malchev if (optind > argc - 1) { 6504765c439491ddda3de658e62cc4a64d10e726b34Iliyan Malchev free(filename); 6514765c439491ddda3de658e62cc4a64d10e726b34Iliyan Malchev filename = NULL; 6524765c439491ddda3de658e62cc4a64d10e726b34Iliyan Malchev } else { 6534765c439491ddda3de658e62cc4a64d10e726b34Iliyan Malchev strlcpy(filename, argv[optind++], 30); 6544765c439491ddda3de658e62cc4a64d10e726b34Iliyan Malchev } 6554765c439491ddda3de658e62cc4a64d10e726b34Iliyan Malchev 6564765c439491ddda3de658e62cc4a64d10e726b34Iliyan Malchev if (pcm_flag) { 6574765c439491ddda3de658e62cc4a64d10e726b34Iliyan Malchev if (format == SNDRV_PCM_FORMAT_S16_LE) 6584765c439491ddda3de658e62cc4a64d10e726b34Iliyan Malchev rc = play_wav(mmap, rate, ch, device, filename); 6594765c439491ddda3de658e62cc4a64d10e726b34Iliyan Malchev else 6604765c439491ddda3de658e62cc4a64d10e726b34Iliyan Malchev rc = play_raw(mmap, rate, ch, device, filename); 6614765c439491ddda3de658e62cc4a64d10e726b34Iliyan Malchev } else { 6624765c439491ddda3de658e62cc4a64d10e726b34Iliyan Malchev rc = play_wav(mmap, rate, ch, device, "dummy"); 6634765c439491ddda3de658e62cc4a64d10e726b34Iliyan Malchev } 6644765c439491ddda3de658e62cc4a64d10e726b34Iliyan Malchev if (filename) 6654765c439491ddda3de658e62cc4a64d10e726b34Iliyan Malchev free(filename); 6664765c439491ddda3de658e62cc4a64d10e726b34Iliyan Malchev 6674765c439491ddda3de658e62cc4a64d10e726b34Iliyan Malchev return rc; 6684765c439491ddda3de658e62cc4a64d10e726b34Iliyan Malchev} 6694765c439491ddda3de658e62cc4a64d10e726b34Iliyan Malchev 670