input.c - acarsdec - an ACARS decoder
 (HTM) git clone git://r-36.net/acarsdec
 (DIR) Log
 (DIR) Files
 (DIR) Refs
 (DIR) README
       ---
       input.c (4677B)
       ---
            1 /*
            2  *  Copyright (c) 2007 by Thierry Leconte (F4DWV)
            3  *              (c) 2010-12 by Christoph Lohmann <20h@r-36.net>
            4  *
            5  *      $Id: input.c,v 1.3 2007/03/29 16:21:49 f4dwv Exp $
            6  *
            7  *   This library is free software; you can redistribute it and/or modify
            8  *   it under the terms of the GNU Library General Public License version 2
            9  *   published by the Free Software Foundation.
           10  *
           11  *   This program is distributed in the hope that it will be useful,
           12  *   but WITHOUT ANY WARRANTY; without even the implied warranty of
           13  *   MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
           14  *   GNU Library General Public License for more details.
           15  *
           16  *   You should have received a copy of the GNU Library General Public
           17  *   License along with this library; if not, write to the Free Software
           18  *   Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
           19  *
           20  */
           21 
           22 #include <stdlib.h>
           23 #include <sndfile.h>
           24 #include <alsa/asoundlib.h>
           25 
           26 #include "acarsdec.h"
           27 
           28 static int source = 0;
           29 static int nbch = 0;
           30 
           31 static SNDFILE *inwav;
           32 static int initstdin(void)
           33 {
           34         SF_INFO infwav;
           35 
           36         infwav.format = 0;
           37         inwav = sf_open_fd(STDIN_FILENO, SFM_READ, &infwav, SF_TRUE);
           38         if (inwav == NULL) {
           39                 fprintf(stderr, "could not open stdin\n");
           40                 return 0;
           41         }
           42         if (infwav.samplerate != 48000) {
           43                 fprintf(stderr,
           44                         "Bad Input File sample rate: %d. Must be 48000\n",
           45                         infwav.samplerate);
           46                 return 0;
           47         }
           48         nbch = infwav.channels;
           49 
           50         return infwav.channels;
           51 }
           52 
           53 static SNDFILE *inwav;
           54 static int initsnd(char *filename)
           55 {
           56         SF_INFO infwav;
           57 
           58         /* open wav input file */
           59         infwav.format = 0;
           60         inwav = sf_open(filename, SFM_READ, &infwav);
           61         if (inwav == NULL) {
           62                 fprintf(stderr, "could not open %s\n", filename);
           63                 return 0;
           64         }
           65         if (infwav.samplerate != 48000) {
           66                 fprintf(stderr,
           67                         "Bad Input File sample rate: %d. Must be 48000\n",
           68                         infwav.samplerate);
           69                 return 0;
           70         }
           71         nbch = infwav.channels;
           72 
           73         return infwav.channels;
           74 }
           75 
           76 static snd_pcm_t *capture_handle;
           77 static int initalsa(char *filename)
           78 {
           79         snd_pcm_hw_params_t *hw_params;
           80         int err;
           81 
           82         if ((err =
           83              snd_pcm_open(&capture_handle, filename,
           84                           SND_PCM_STREAM_CAPTURE, 0)) < 0) {
           85                 fprintf(stderr, "cannot open audio device %s (%s)\n",
           86                         filename, snd_strerror(err));
           87                 return 0;
           88         }
           89 
           90         if ((err = snd_pcm_hw_params_malloc(&hw_params)) < 0) {
           91                 fprintf(stderr,
           92                         "cannot allocate hardware parameter structure (%s)\n",
           93                         snd_strerror(err));
           94                 return 0;
           95         }
           96 
           97         if ((err = snd_pcm_hw_params_any(capture_handle, hw_params)) < 0) {
           98                 fprintf(stderr,
           99                         "cannot initialize hardware parameter structure (%s)\n",
          100                         snd_strerror(err));
          101                 return 0;
          102         }
          103 
          104         if ((err =
          105              snd_pcm_hw_params_set_access(capture_handle, hw_params,
          106                                           SND_PCM_ACCESS_RW_INTERLEAVED)) <
          107             0) {
          108                 fprintf(stderr, "cannot set access type (%s)\n",
          109                         snd_strerror(err));
          110                 return 0;
          111         }
          112 
          113         if ((err =
          114              snd_pcm_hw_params_set_format(capture_handle, hw_params,
          115                                           SND_PCM_FORMAT_S16)) < 0) {
          116                 fprintf(stderr, "cannot set sample format (%s)\n",
          117                         snd_strerror(err));
          118                 return 0;
          119         }
          120 
          121         if ((err = snd_pcm_hw_params_set_rate(capture_handle, hw_params, 48000,
          122                                         0)) < 0) {
          123                 fprintf(stderr, "cannot set sample rate (%s)\n",
          124                         snd_strerror(err));
          125                 return 0;
          126         }
          127 
          128         for(nbch = 2; nbch > 0; nbch--)  {
          129                 if (snd_pcm_hw_params_set_channels(capture_handle,
          130                                         hw_params, nbch) == 0) {
          131                         break;
          132                 }
          133         }
          134 
          135         if (nbch == 0) {
          136                 fprintf(stderr, "cannot set number of channels\n");
          137                 return 0;
          138         }
          139 
          140         if ((err = snd_pcm_hw_params(capture_handle, hw_params)) < 0) {
          141                 fprintf(stderr, "cannot set parameters (%s)\n",
          142                         snd_strerror(err));
          143                 return 0;
          144         }
          145         snd_pcm_hw_params_free(hw_params);
          146 
          147         if ((err = snd_pcm_prepare(capture_handle)) < 0) {
          148                 fprintf(stderr,
          149                         "cannot prepare audio interface for use (%s)\n",
          150                         snd_strerror(err));
          151                 return 0;
          152         }
          153         return nbch;
          154 }
          155 
          156 /* open input source*/
          157 int initsample(char *sourcename, int src)
          158 {
          159         source = src;
          160         switch(src) {
          161         case IN_STDIN:
          162                 return initstdin();
          163         case IN_FILE:
          164                 return initsnd(sourcename);
          165         case IN_ALSA:
          166                 return initalsa(sourcename);
          167         }
          168 
          169         return 0;
          170 }
          171 
          172 int getsample(short *sample, int nb)
          173 {
          174         int r = -1;
          175 
          176         switch(source) {
          177         case IN_STDIN:
          178                 r = sf_read_short(inwav, sample, nb / nbch);
          179                 break;
          180         case IN_FILE:
          181                 r = sf_read_short(inwav, sample, nb / nbch);
          182                 if (r == 0)
          183                         r = -1;        /* this is the end */
          184                 break;
          185         case IN_ALSA:
          186                 r = snd_pcm_readi(capture_handle, sample, nb / nbch);
          187                 if (r <= 0)
          188                         fprintf(stderr,
          189                                 "cannot read from interface (%s)\n",
          190                                 snd_strerror(r));
          191                 r = r * nbch;
          192                 break;
          193         }
          194         return r;
          195 }
          196 
          197 void endsample(void)
          198 {
          199         switch(source) {
          200         case IN_FILE:
          201         case IN_STDIN:
          202                 sf_close(inwav);
          203                 break;
          204         case IN_ALSA:
          205                 snd_pcm_close(capture_handle);
          206                 break;
          207         }
          208 }