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