00001
00002
00003
00004
00005
00006
00007
00008
00009
00010
00011
00012
00013
00014
00015
00016
00017
00018
00019
00020
00021
00022
00023
00024
00025
00026
00027
00028
00029
00030
00031
00032
00033
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
00119
00120 int noutputs = 1;
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
00131 exit(1);
00132 }
00133 else {
00134
00135 fprintf (stderr, "VrAudioSource: could not set MONO mode\n");
00136 decimate = true;
00137 }
00138 }
00139
00140 int sf = (int)getSamplingFrequency();
00141
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
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 {
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