Main Page | Class Hierarchy | Alphabetical List | Class List | Directories | File List | Class Members | File Members

OssDspSource.cpp

Go to the documentation of this file.
00001 /*------------------------------------------------------------------------------
00002 
00003    Copyright (c) 2000 Tyrell Corporation. All rights reserved.
00004 
00005    Tyrell DarkIce
00006 
00007    File     : OssDspSource.cpp
00008    Version  : $Revision: 1.13 $
00009    Author   : $Author: darkeye $
00010    Location : $Source: /cvsroot/darkice/darkice/src/OssDspSource.cpp,v $
00011    
00012    Copyright notice:
00013 
00014     This program is free software; you can redistribute it and/or
00015     modify it under the terms of the GNU General Public License  
00016     as published by the Free Software Foundation; either version 2
00017     of the License, or (at your option) any later version.
00018    
00019     This program is distributed in the hope that it will be useful,
00020     but WITHOUT ANY WARRANTY; without even the implied warranty of 
00021     MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the 
00022     GNU General Public License for more details.
00023    
00024     You should have received a copy of the GNU General Public License
00025     along with this program; if not, write to the Free Software
00026     Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA  02111-1307, USA.
00027 
00028 ------------------------------------------------------------------------------*/
00029 
00030 /* ============================================================ include files */
00031 
00032 #include "OssDspSource.h"
00033 
00034 #ifdef SUPPORT_OSS_DSP
00035 // only compile this code if there is support for it
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 /* ===================================================  local data structures */
00096 
00097 
00098 /* ================================================  local constants & macros */
00099 
00100 /*------------------------------------------------------------------------------
00101  *  File identity
00102  *----------------------------------------------------------------------------*/
00103 static const char fileid[] = "$Id: OssDspSource.cpp,v 1.13 2003/02/12 15:48:22 darkeye Exp $";
00104 
00105 /*------------------------------------------------------------------------------
00106  *  Define the natural endiannes of 16 bit recording if not defined,
00107  *  based on the endiannes of the system
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 /* ===============================================  local function prototypes */
00119 
00120 
00121 /* =============================================================  module code */
00122 
00123 /*------------------------------------------------------------------------------
00124  *  Tell if source id big endian
00125  *----------------------------------------------------------------------------*/
00126 bool
00127 OssDspSource :: isBigEndian ( void ) const                  throw ()
00128 {
00129     return AFMT_S16_NE == AFMT_S16_BE;
00130 }
00131 
00132 
00133 /*------------------------------------------------------------------------------
00134  *  Initialize the object
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  *  De-initialize the object
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  *  Open the audio source
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  *  Check wether read() would return anything
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         /* ugly workaround to get the dsp into recording state */
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  *  Read from the audio source
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  *  Close the audio source
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   $Source: /cvsroot/darkice/darkice/src/OssDspSource.cpp,v $
00308 
00309   $Log: OssDspSource.cpp,v $
00310   Revision 1.13  2003/02/12 15:48:22  darkeye
00311   added proper guessing for natural endiannes of 16 bit recording
00312 
00313   Revision 1.12  2002/12/20 10:40:40  darkeye
00314   added support for big endian OSS devices (like Linux PowerPC)
00315 
00316   Revision 1.11  2002/05/28 12:35:41  darkeye
00317   code cleanup: compiles under gcc-c++ 3.1, using -pedantic option
00318 
00319   Revision 1.10  2001/09/26 16:55:30  darkeye
00320   BSD port
00321 
00322   Revision 1.9  2001/09/11 15:05:21  darkeye
00323   added Solaris support
00324 
00325   Revision 1.8  2001/09/02 14:08:40  darkeye
00326   setting the sound card recording sample rate is now more relaxed
00327   there is no error reported if the sample rate is not exactly the same
00328 
00329   Revision 1.7  2001/08/30 17:25:56  darkeye
00330   renamed configure.h to config.h
00331 
00332   Revision 1.6  2000/12/01 15:03:28  darkeye
00333   bug fix in error reporting
00334 
00335   Revision 1.5  2000/11/17 15:50:48  darkeye
00336   added -Wall flag to compiler and eleminated new warnings
00337 
00338   Revision 1.4  2000/11/13 20:05:07  darkeye
00339   changed to workaround to start recording so that it reads one sample
00340   per channel, as opposed to only one sample (which misalignes the channels)
00341 
00342   Revision 1.3  2000/11/12 13:31:40  darkeye
00343   added kdoc-style documentation comments
00344 
00345   Revision 1.2  2000/11/05 14:08:28  darkeye
00346   changed builting to an automake / autoconf environment
00347 
00348   Revision 1.1.1.1  2000/11/05 10:05:53  darkeye
00349   initial version
00350 
00351   
00352 ------------------------------------------------------------------------------*/
00353 

Generated on Thu Apr 14 13:59:12 2005 for DarkIce by  doxygen 1.4.1