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 }