Main Page | Namespace List | Class Hierarchy | Class List | File List | Namespace Members | Class Members | File Members | Related Pages

VrAudioSource.h

Go to the documentation of this file.
00001 /* -*- Mode: c++ -*- */ 00002 /* 00003 * Copyright 2001 Free Software Foundation, Inc. 00004 * 00005 * This file is part of GNU Radio 00006 * 00007 * GNU Radio is free software; you can redistribute it and/or modify 00008 * it under the terms of the GNU General Public License as published by 00009 * the Free Software Foundation; either version 2, or (at your option) 00010 * any later version. 00011 * 00012 * GNU Radio is distributed in the hope that it will be useful, 00013 * but WITHOUT ANY WARRANTY; without even the implied warranty of 00014 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the 00015 * GNU General Public License for more details. 00016 * 00017 * You should have received a copy of the GNU General Public License 00018 * along with GNU Radio; see the file COPYING. If not, write to 00019 * the Free Software Foundation, Inc., 59 Temple Place - Suite 330, 00020 * Boston, MA 02111-1307, USA. 00021 */ 00022 /* 00023 * Copyright 1997 Massachusetts Institute of Technology 00024 * 00025 * Permission to use, copy, modify, distribute, and sell this software and its 00026 * documentation for any purpose is hereby granted without fee, provided that 00027 * the above copyright notice appear in all copies and that both that 00028 * copyright notice and this permission notice appear in supporting 00029 * documentation, and that the name of M.I.T. not be used in advertising or 00030 * publicity pertaining to distribution of the software without specific, 00031 * written prior permission. M.I.T. makes no representations about the 00032 * suitability of this software for any purpose. It is provided "as is" 00033 * without express or implied warranty. 00034 * 00035 */ 00036 00037 #ifndef _VRAUDIOSOURCE_H_ 00038 #define _VRAUDIOSOURCE_H_ 00039 00040 #define AUDIOINCHUNKSIZE 200 00041 00042 extern "C" { 00043 #include <sys/soundcard.h> 00044 #include <sys/ioctl.h> 00045 #include <fcntl.h> 00046 #include <unistd.h> 00047 } 00048 00049 #include <VrSource.h> 00050 #include <fstream> 00051 #include <algorithm> 00052 #include <string> 00053 00054 template<class oType> 00055 class VrAudioSource : public VrSource<oType> { 00056 protected: 00057 int audiofd; 00058 long format; 00059 bool decimate; 00060 std::string device_name; 00061 public: 00062 virtual int work2(VrSampleRange output, void *o[]); 00063 virtual void initialize(); 00064 00065 VrAudioSource(double sampling_freq, const char* dev = "/dev/dsp") 00066 : audiofd(-1), decimate(false), device_name(dev){ 00067 00068 setSamplingFrequency (sampling_freq); 00069 setOutputSize (AUDIOINCHUNKSIZE); 00070 } 00071 00072 virtual const char *name() { return "VrAudioSource"; } 00073 00074 virtual ~VrAudioSource() {close(audiofd);} 00075 }; 00076 00077 00078 template<class oType> void 00079 VrAudioSource<oType>::initialize() 00080 { 00081 int temp = 0x7fff0004; 00082 if(audiofd==-1) { 00083 if ((audiofd = open(device_name.c_str(), O_RDONLY)) < 0) { 00084 cerr << "VrAudioSource: "; 00085 perror (device_name.c_str ()); 00086 exit(1); 00087 } 00088 if ((ioctl(audiofd,SNDCTL_DSP_SETFRAGMENT,&temp)) < 0) { 00089 fprintf (stderr, "VrAudioSource: set fragment returned %d\n", errno); 00090 exit(1); 00091 } 00092 } 00093 00094 if(sizeof(oType)==1) { 00095 format=AFMT_MU_LAW; 00096 } else if(sizeof(oType)==2) { 00097 printf("setting to 16 bits \n"); 00098 format = AFMT_S16_LE; 00099 } else { 00100 fprintf (stderr, 00101 "VrAudioSource: cannot handle data type of size %d\n", 00102 sizeof(oType)); 00103 exit(1); 00104 } 00105 00106 ioctl(audiofd,SNDCTL_DSP_RESET); 00107 00108 int origf=format; 00109 if((ioctl(audiofd,SNDCTL_DSP_SETFMT,&format)) < 0) { 00110 cerr << "VrAudioSource: " << device_name << " IOCTL failed with errno " << errno << "\n"; 00111 exit(1); 00112 } 00113 if(origf!=format) { 00114 fprintf (stderr, "VrAudioSource: Warning: unable to support format %d\n", origf); 00115 fprintf (stderr, " card requested %ld instead.\n", format); 00116 } 00117 00118 // set number of channels no matter what. Some hardware only does stereo 00119 00120 int noutputs = 1; // number of outputs 00121 int channels = noutputs; 00122 if (ioctl (audiofd, SNDCTL_DSP_CHANNELS, &channels) < 0){ 00123 perror ("VrAudioSink: SNDCTL_DSP_CHANNELS failed"); 00124 exit (1); 00125 } 00126 00127 if (channels != noutputs){ 00128 if (noutputs == 2){ 00129 fprintf(stderr, "VrAudioSource: could not set STEREO mode\n"); 00130 // FIXME, could fix this by duplicating mono input, or zeroing other channel 00131 exit(1); 00132 } 00133 else { 00134 // user asked for MONO, but got STEREO. We can work around this... 00135 fprintf (stderr, "VrAudioSource: could not set MONO mode\n"); 00136 decimate = true; 00137 } 00138 } 00139 00140 int sf = (int)getSamplingFrequency(); 00141 //cout <<"Sampling frequency = "<<sf<<endl; 00142 if ((ioctl(audiofd,SNDCTL_DSP_SPEED,&sf)) < 0) { 00143 cerr << device_name << ": Invalid sampling frequency...defaulting to 8 Khz\n"; 00144 sf = 8000; 00145 if ((ioctl(audiofd,SNDCTL_DSP_SPEED,&sf)) < 0) { 00146 fprintf (stderr, "Couldn't even manage that...aborting\n"); 00147 exit(1); 00148 } 00149 } 00150 if(sf!=getSamplingFrequency()) 00151 fprintf(stderr, "VrAudioSource Warning: soundcard defaulted to %d Hz\n", sf); 00152 } 00153 00154 00155 template<class oType> int 00156 VrAudioSource<oType>::work2(VrSampleRange output, void *ao[]) 00157 { 00158 unsigned units=output.size; 00159 oType **o= (oType **)ao; 00160 oType *curPos=o[0]; 00161 00162 if (decimate){ 00163 // convert STEREO input from sound card to MONO output 00164 while(units > 0) { 00165 const unsigned N = 2048; 00166 oType tmp[N*2]; 00167 00168 int nbytes = std::min (units, N) * (sizeof(oType) * 2); 00169 int count = read(audiofd, tmp, nbytes); 00170 00171 if(count < 0) { 00172 perror ("VrAudioSource"); 00173 exit(1); 00174 } 00175 00176 assert ((count & ((sizeof(oType) * 2) - 1)) == 0); 00177 00178 for (unsigned int i = 0; i < count / (sizeof (oType) * 2); i++){ 00179 curPos[i] = tmp[2*i]; 00180 } 00181 00182 units -= count / (sizeof (oType) * 2); 00183 curPos += count / (sizeof (oType) * 2); 00184 } 00185 return output.size; 00186 } 00187 00188 else { // normal 00189 while(units > 0) { 00190 int nbytes = units * sizeof(oType); 00191 int count = read(audiofd, curPos, nbytes); 00192 00193 if(count < 0) { 00194 perror ("VrAudioSource"); 00195 exit(1); 00196 } 00197 00198 assert ((count & (sizeof(oType) - 1)) == 0); 00199 00200 units -= count / sizeof (oType); 00201 curPos += count / sizeof (oType); 00202 } 00203 return output.size; 00204 } 00205 } 00206 00207 #endif

Generated on Wed Aug 4 02:22:05 2004 for GNU Radio by doxygen 1.3.8