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 #include "OssDspSource.h"
00033
00034 #ifdef SUPPORT_OSS_DSP
00035
00036
00037 #ifdef HAVE_CONFIG_H
00038 #include "config.h"
00039 #endif
00040
00041 #ifdef HAVE_UNISTD_H
00042 #include <unistd.h>
00043 #else
00044 #error need unistd.h
00045 #endif
00046
00047 #ifdef HAVE_STRING_H
00048 #include <string.h>
00049 #else
00050 #error need string.h
00051 #endif
00052
00053 #ifdef HAVE_SYS_TYPES_H
00054 #include <sys/types.h>
00055 #else
00056 #error need sys/types.h
00057 #endif
00058
00059 #ifdef HAVE_SYS_STAT_H
00060 #include <sys/stat.h>
00061 #else
00062 #error need sys/stat.h
00063 #endif
00064
00065 #ifdef HAVE_FCNTL_H
00066 #include <fcntl.h>
00067 #else
00068 #error need fcntl.h
00069 #endif
00070
00071 #ifdef HAVE_SYS_TIME_H
00072 #include <sys/time.h>
00073 #else
00074 #error need sys/time.h
00075 #endif
00076
00077 #ifdef HAVE_SYS_IOCTL_H
00078 #include <sys/ioctl.h>
00079 #else
00080 #error need sys/ioctl.h
00081 #endif
00082
00083 #ifdef HAVE_SYS_SOUNDCARD_H
00084 #include <sys/soundcard.h>
00085 #else
00086 #error need sys/soundcard.h
00087 #endif
00088
00089
00090 #include "Util.h"
00091 #include "Exception.h"
00092 #include "OssDspSource.h"
00093
00094
00095
00096
00097
00098
00099
00100
00101
00102
00103 static const char fileid[] = "$Id: OssDspSource.cpp,v 1.13 2003/02/12 15:48:22 darkeye Exp $";
00104
00105
00106
00107
00108
00109 #ifndef AFMT_S16_NE
00110 # ifdef WORDS_BIGENDIAN
00111 # define AFMT_S16_NE AFMT_S16_BE
00112 # else
00113 # define AFMT_S16_NE AFMT_S16_LE
00114 # endif
00115 #endif
00116
00117
00118
00119
00120
00121
00122
00123
00124
00125
00126 bool
00127 OssDspSource :: isBigEndian ( void ) const throw ()
00128 {
00129 return AFMT_S16_NE == AFMT_S16_BE;
00130 }
00131
00132
00133
00134
00135
00136 void
00137 OssDspSource :: init ( const char * name ) throw ( Exception )
00138 {
00139 fileName = Util::strDup( name);
00140 fileDescriptor = 0;
00141 running = false;
00142 }
00143
00144
00145
00146
00147
00148 void
00149 OssDspSource :: strip ( void ) throw ( Exception )
00150 {
00151 if ( isOpen() ) {
00152 close();
00153 }
00154
00155 delete[] fileName;
00156 }
00157
00158
00159
00160
00161
00162 bool
00163 OssDspSource :: open ( void ) throw ( Exception )
00164 {
00165 int format;
00166 int i;
00167 unsigned int u;
00168
00169 if ( isOpen() ) {
00170 return false;
00171 }
00172
00173 switch ( getBitsPerSample() ) {
00174 case 8:
00175 format = AFMT_U8;
00176 break;
00177
00178 case 16:
00179 format = AFMT_S16_NE;
00180 break;
00181
00182 default:
00183 return false;
00184 }
00185
00186 if ( (fileDescriptor = ::open( fileName, O_RDONLY)) == -1 ) {
00187 fileDescriptor = 0;
00188 return false;
00189 }
00190
00191 i = format;
00192 if ( ioctl( fileDescriptor, SNDCTL_DSP_SETFMT, &i) == -1 ||
00193 i != format ) {
00194
00195 close();
00196 throw Exception( __FILE__, __LINE__, "can't set format", i);
00197 }
00198
00199 u = getChannel();
00200 if ( ioctl( fileDescriptor, SNDCTL_DSP_CHANNELS, &u) == -1 ||
00201 u != getChannel() ) {
00202
00203 close();
00204 throw Exception( __FILE__, __LINE__, "can't set channels", u);
00205 }
00206
00207 u = getSampleRate();
00208 if ( ioctl( fileDescriptor, SNDCTL_DSP_SPEED, &u) == -1 ) {
00209
00210 close();
00211 throw Exception( __FILE__, __LINE__,
00212 "can't set soundcard recording sample rate", u);
00213 }
00214 if ( u != getSampleRate() ) {
00215 reportEvent( 2, "sound card recording sample rate set to ", u,
00216 " while trying to set it to ", getSampleRate());
00217 reportEvent( 2, "this is probably not a problem, but a slight "
00218 "drift in the sound card driver");
00219 }
00220
00221 return true;
00222 }
00223
00224
00225
00226
00227
00228 bool
00229 OssDspSource :: canRead ( unsigned int sec,
00230 unsigned int usec ) throw ( Exception )
00231 {
00232 fd_set fdset;
00233 struct timeval tv;
00234 int ret;
00235
00236 if ( !isOpen() ) {
00237 return false;
00238 }
00239
00240 if ( !running ) {
00241
00242 unsigned char * b =
00243 new unsigned char[getChannel()*getBitsPerSample()/8];
00244 read( b, getChannel()*getBitsPerSample()/8);
00245 delete[] b;
00246 }
00247
00248 FD_ZERO( &fdset);
00249 FD_SET( fileDescriptor, &fdset);
00250 tv.tv_sec = sec;
00251 tv.tv_usec = usec;
00252
00253 ret = select( fileDescriptor + 1, &fdset, NULL, NULL, &tv);
00254
00255 if ( ret == -1 ) {
00256 throw Exception( __FILE__, __LINE__, "select error");
00257 }
00258
00259 return ret > 0;
00260 }
00261
00262
00263
00264
00265
00266 unsigned int
00267 OssDspSource :: read ( void * buf,
00268 unsigned int len ) throw ( Exception )
00269 {
00270 ssize_t ret;
00271
00272 if ( !isOpen() ) {
00273 return 0;
00274 }
00275
00276 ret = ::read( fileDescriptor, buf, len);
00277
00278 if ( ret == -1 ) {
00279 throw Exception( __FILE__, __LINE__, "read error");
00280 }
00281
00282 running = true;
00283 return ret;
00284 }
00285
00286
00287
00288
00289
00290 void
00291 OssDspSource :: close ( void ) throw ( Exception )
00292 {
00293 if ( !isOpen() ) {
00294 return;
00295 }
00296
00297 ::close( fileDescriptor);
00298 fileDescriptor = 0;
00299 running = false;
00300 }
00301
00302 #endif // SUPPORT_OSS_DSP
00303
00304
00305
00306
00307
00308
00309
00310
00311
00312
00313
00314
00315
00316
00317
00318
00319
00320
00321
00322
00323
00324
00325
00326
00327
00328
00329
00330
00331
00332
00333
00334
00335
00336
00337
00338
00339
00340
00341
00342
00343
00344
00345
00346
00347
00348
00349
00350
00351
00352
00353