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

GrAudioSource.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 _GRAUDIOSOURCE_H_ 00038 #define _GRAUDIOSOURCE_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 GrAudioSource : public VrSource<oType> { 00056 protected: 00057 int audiofd; 00058 long format; 00059 std::string device_name; 00060 oType scale_factor; 00061 int num_streams; 00062 public: 00063 virtual int work2(VrSampleRange output, void *o[]); 00064 virtual void initialize(); 00065 00066 GrAudioSource(double sampling_freq, int streams, double output_range = 32767, 00067 const char* dev = "/dev/dsp") 00068 : VrSource<oType>(streams),audiofd(-1), device_name(dev),num_streams(streams) { 00069 setSamplingFrequency (sampling_freq); 00070 setOutputSize (AUDIOINCHUNKSIZE); 00071 scale_factor = (oType) (32767 / output_range); 00072 } 00073 00074 virtual const char *name() { return "GrAudioSource"; } 00075 00076 virtual ~GrAudioSource() {close(audiofd);} 00077 }; 00078 00079 00080 template<class oType> void 00081 GrAudioSource<oType>::initialize() 00082 { 00083 int temp = 0x7fff0004; 00084 if(audiofd==-1) { 00085 if ((audiofd = open(device_name.c_str(), O_RDONLY)) < 0) { 00086 cerr << "GrAudioSource: "; 00087 perror (device_name.c_str ()); 00088 exit(1); 00089 } 00090 if ((ioctl(audiofd,SNDCTL_DSP_SETFRAGMENT,&temp)) < 0) { 00091 fprintf (stderr, "GrAudioSource: set fragment returned %d\n", errno); 00092 exit(1); 00093 } 00094 } 00095 00096 // ioctl(audiofd,SNDCTL_DSP_RESET); 00097 00098 int format=AFMT_S16_NE; 00099 int origf=format; 00100 if((ioctl(audiofd,SNDCTL_DSP_SETFMT,&format)) < 0) { 00101 cerr << "GrAudioSource: " << device_name << " IOCTL failed with errno " << errno << "\n"; 00102 exit(1); 00103 } 00104 if(origf!=format) { 00105 fprintf (stderr, "GrAudioSource: Warning: unable to support format %d\n", origf); 00106 fprintf (stderr, " card requested %d instead.\n", format); 00107 } 00108 00109 // set number of channels no matter what. Some hardware only does stereo 00110 int channels = 2; 00111 if (ioctl (audiofd, SNDCTL_DSP_CHANNELS, &channels) < 0){ 00112 perror ("GrAudioSink: SNDCTL_DSP_CHANNELS failed"); 00113 exit (1); 00114 } 00115 00116 if (channels != 2){ 00117 fprintf(stderr, "GrAudioSource: could not set STEREO mode\n"); 00118 exit(1); 00119 } 00120 00121 // if(getInputSamplingFrequencyN(0)!=getInputSamplingFrequencyN(1)) 00122 // fprintf(stderr, "GrAudioSink Warning: left and right at different freq\n"); 00123 00124 int sf = (int)getSamplingFrequency(); 00125 cerr <<"GrAudioSource: Sampling frequency = "<<sf<<endl; 00126 00127 if ((ioctl(audiofd,SNDCTL_DSP_SPEED,&sf)) < 0) { 00128 cerr << device_name << ": Invalid sampling frequency...defaulting to 8 Khz\n"; 00129 sf = 8000; 00130 if ((ioctl(audiofd,SNDCTL_DSP_SPEED,&sf)) < 0) { 00131 fprintf (stderr, "Couldn't even manage that...aborting\n"); 00132 exit(1); 00133 } 00134 } 00135 if(sf!=getSamplingFrequency()) 00136 fprintf(stderr, "GrAudioSource Warning: soundcard defaulted to %d Hz\n", sf); 00137 } 00138 00139 00140 template<class oType> int 00141 GrAudioSource<oType>::work2(VrSampleRange output, void *ao[]) 00142 { 00143 sync (output.index); // force in-order execution 00144 00145 unsigned size = output.size; 00146 oType **o = (oType **)ao; 00147 00148 while(size > 0) { 00149 const unsigned N = 2048; 00150 short tmp[N*2]; 00151 int nbytes = std::min (size, N) * (sizeof(short) * 2); 00152 00153 int count = read(audiofd, tmp, nbytes); 00154 00155 if(count < 0) { 00156 perror ("GrAudioSource"); 00157 exit(1); 00158 } 00159 00160 assert ((count & ((sizeof(short) * 2) - 1)) == 0); 00161 00162 if(num_streams == 1) 00163 for (unsigned int i = 0; i < count / (sizeof (short) * 2); i++) { 00164 o[0][i] = (oType)tmp[2*i]/scale_factor; 00165 } 00166 else 00167 for (unsigned int i = 0; i < count / (sizeof (short) * 2); i++) { 00168 o[0][i] = (oType)tmp[2*i]/scale_factor; 00169 o[1][i] = (oType)tmp[2*i+1]/scale_factor; 00170 } 00171 00172 size -= count / (sizeof (short) * 2); 00173 o[0] += count / (sizeof (short) * 2); 00174 if(num_streams==2) 00175 o[1] += count / (sizeof (short) * 2); 00176 } 00177 return output.size; 00178 } 00179 00180 template<> int 00181 GrAudioSource<VrComplex>::work2(VrSampleRange output, void *ao[]) 00182 { 00183 unsigned size = output.size; 00184 VrComplex **o = (VrComplex **)ao; 00185 00186 while(size > 0) { 00187 const unsigned N = 2048; 00188 short tmp[N*2]; 00189 int nbytes = std::min (size, N) * (sizeof(short) * 2); 00190 00191 int count = read(audiofd, tmp, nbytes); 00192 00193 if(count < 0) { 00194 perror ("GrAudioSource"); 00195 exit(1); 00196 } 00197 00198 assert ((count & ((sizeof(short) * 2) - 1)) == 0); 00199 00200 for (unsigned int i = 0; i < count / (sizeof (short) * 2); i++) 00201 o[0][i] = VrComplex (tmp[2*i],tmp[2*i+1]) / scale_factor; 00202 00203 size -= count / (sizeof (short) * 2); 00204 o[0] += count / (sizeof (short) * 2); 00205 } 00206 return output.size; 00207 } 00208 00209 #endif

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