acarsdec

an ACARS decoder
git clone git://r-36.net/acarsdec
Log | Files | Refs | 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 }