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

osoundsystem.cpp

Go to the documentation of this file.
00001 /*
00002                              This file is part of the Opie Project
00003               =.             (C) 2003-2005 Michael 'Mickey' Lauer <mickey@Vanille.de>
00004             .=l.
00005            .>+-=
00006  _;:,     .>    :=|.         This program is free software; you can
00007 .> <`_,   >  .   <=          redistribute it and/or  modify it under
00008 :`=1 )Y*s>-.--   :           the terms of the GNU Library General Public
00009 .="- .-=="i,     .._         License as published by the Free Software
00010  - .   .-<_>     .<>         Foundation; either version 2 of the License,
00011      ._= =}       :          or (at your option) any later version.
00012     .%`+i>       _;_.
00013     .i_,=:_.      -<s.       This program is distributed in the hope that
00014      +  .  -:.       =       it will be useful,  but WITHOUT ANY WARRANTY;
00015     : ..    .:,     . . .    without even the implied warranty of
00016     =_        +     =;=|`    MERCHANTABILITY or FITNESS FOR A
00017   _.=:.       :    :=>`:     PARTICULAR PURPOSE. See the GNU
00018 ..}^=.=       =       ;      Library General Public License for more
00019 ++=   -.     .`     .:       details.
00020  :     =  ...= . :.=-
00021  -.   .:....=;==+<;          You should have received a copy of the GNU
00022   -_. . .   )=.  =           Library General Public License along with
00023     --        :-=`           this library; see the file COPYING.LIB.
00024                              If not, write to the Free Software Foundation,
00025                              Inc., 59 Temple Place - Suite 330,
00026                              Boston, MA 02111-1307, USA.
00027 
00028 */
00029 
00030 #include "osoundsystem.h"
00031 using namespace Opie::MM;
00032 
00033 /* OPIE */
00034 #include <opie2/odebug.h>
00035 using namespace Opie::Core;
00036 
00037 /* STD */
00038 #include <errno.h>
00039 #include <fcntl.h>
00040 #include <string.h>
00041 #include <sys/ioctl.h>
00042 #include <sys/types.h>
00043 #include <sys/soundcard.h>
00044 #include <sys/stat.h>
00045 
00046 static const char* device_label[] = SOUND_DEVICE_LABELS;
00047 static int max_device_nr = sizeof device_label / sizeof (const char*);
00048 
00049 /*======================================================================================
00050  * OSoundSystem
00051  *======================================================================================*/
00052 
00053 OSoundSystem* OSoundSystem::_instance = 0;
00054 
00055 OSoundSystem::OSoundSystem()
00056 {
00057     odebug << "OSoundSystem::OSoundSystem()" << oendl;
00058     synchronize();
00059 }
00060 
00061 void OSoundSystem::synchronize()
00062 {
00063     _interfaces.clear();
00064     _interfaces.insert( "soundcard", new OSoundCard( this, "soundcard" ) );
00065     
00066     /*
00067 
00068     QString str;
00069     QFile f( "/dev/sound" );
00070     bool hasFile = f.open( IO_ReadOnly );
00071     if ( !hasFile )
00072     {
00073         odebug << "OSoundSystem: /dev/sound not existing. No sound devices available" << oendl;
00074         return;
00075     }
00076     QTextStream s( &f );
00077     s.readLine();
00078     s.readLine();
00079     while ( !s.atEnd() )
00080     {
00081         s >> str;
00082         str.truncate( str.find( ':' ) );
00083         odebug << "OSoundSystem: found interface '" <<  str << "'" << oendl;
00084         OAudioInterface* iface;
00085         iface = new OAudioInterface( this, (const char*) str );
00086 
00087         _interfaces.insert( str, iface );
00088         s.readLine();
00089     }
00090 */
00091 }
00092 
00093 
00094 int OSoundSystem::count() const
00095 {
00096     return _interfaces.count();
00097 }
00098 
00099 
00100 OSoundCard* OSoundSystem::card( const QString& iface ) const
00101 {
00102     return _interfaces[iface];
00103 }
00104 
00105 
00106 OSoundSystem* OSoundSystem::instance()
00107 {
00108     if ( !_instance ) _instance = new OSoundSystem();
00109     return _instance;
00110 }
00111 
00112 
00113 OSoundSystem::CardIterator OSoundSystem::iterator() const
00114 {
00115     return OSoundSystem::CardIterator( _interfaces );
00116 }
00117 
00118 
00119 /*======================================================================================
00120  * OSoundCard
00121  *======================================================================================*/
00122 
00123 OSoundCard::OSoundCard( QObject* parent, const char* name )
00124                  :QObject( parent, name ), _audio( 0 ), _mixer( 0 )
00125 {
00126     odebug << "OSoundCard::OSoundCard()" << oendl;
00127     init();
00128 }
00129 
00130 
00131 OSoundCard::~OSoundCard()
00132 {
00133 }
00134 
00135 
00136 void OSoundCard::init()
00137 {
00138 #ifdef QT_QWS_DEVFS
00139     _audio = new OAudioInterface( this, "/dev/sound/dsp" );
00140     _mixer = new OMixerInterface( this, "/dev/sound/mixer" );
00141 #else
00142     _audio = new OAudioInterface( this, "/dev/dsp" );
00143     _mixer = new OMixerInterface( this, "/dev/mixer" );
00144 #endif
00145 }
00146 
00147 
00148 /*======================================================================================
00149  * OAudioInterface
00150  *======================================================================================*/
00151 
00152 OAudioInterface::OAudioInterface( QObject* parent, const char* name )
00153                  :QObject( parent, name ), _sfd(0)
00154 {
00155     odebug << "OAudioInterface::OAudioInterface()" << oendl;
00156     init();
00157 }
00158 
00159 
00160 OAudioInterface::~OAudioInterface()
00161 {
00162 }
00163 
00164 
00165 void OAudioInterface::init()
00166 {
00167 
00168 
00169 }
00170 
00171 
00172 /*======================================================================================
00173  * OMixerInterface
00174  *======================================================================================*/
00175 
00176 OMixerInterface::OMixerInterface( QObject* parent, const char* name )
00177                  :QObject( parent, name ), _devmask( 0 ), _recmask( 0 ), _stmask( 0 )
00178 {
00179     odebug << "OMixerInterface::OMixerInterface()" << oendl;
00180     init();
00181 }
00182 
00183 
00184 OMixerInterface::~OMixerInterface()
00185 {
00186 }
00187 
00188 
00189 void OMixerInterface::init()
00190 {
00191     // open the device
00192     _fd = ::open( name(), O_RDWR );
00193     if ( _fd == -1 )
00194     {
00195         owarn << "OMixerInterface::init(): Can't open mixer " << name() << oendl;
00196         return;
00197     }
00198 
00199     // construct the device capabilities
00200     if ( ioctl( _fd, SOUND_MIXER_READ_CAPS, &_capmask ) != -1 )
00201     {
00202         odebug << "OMixerInterface::init() - capmask = " << _capmask << oendl;
00203     }
00204     if ( ioctl( _fd, SOUND_MIXER_READ_DEVMASK, &_devmask ) != -1 )
00205     {
00206         odebug << "OMixerInterface::init() - devmask = " << _devmask << oendl;
00207     }
00208     if ( ioctl( _fd, SOUND_MIXER_READ_RECMASK, &_recmask ) != -1 )
00209     {
00210         odebug << "OMixerInterface::init() - recmask = " << _recmask << oendl;
00211     }
00212     if ( ioctl( _fd, SOUND_MIXER_READ_STEREODEVS, &_stmask ) != -1 )
00213     {
00214         odebug << "OMixerInterface::init() - stereomask = " << _stmask << oendl;
00215     }
00216     for ( int i = 0; i < max_device_nr; ++i )
00217     {
00218         if ( _devmask & ( 1 << i ) ) 
00219         {
00220             _channels.insert( QString( device_label[i] ).stripWhiteSpace(), i );
00221             odebug << "OMixerInterface::init() - channel '" << device_label[i] << "'" << oendl;
00222         }
00223     }
00224 }    
00225     
00226 
00227 QStringList OMixerInterface::allChannels() const
00228 {
00229     ChannelIterator it = _channels.begin();
00230     QStringList channels;
00231     while ( it != _channels.end() )
00232     {
00233         channels += it++.key();
00234     }
00235     return channels;
00236 }
00237 
00238 
00239 QStringList OMixerInterface::recChannels() const
00240 {
00241     ChannelIterator it = _channels.begin();
00242     QStringList channels;
00243     while ( it != _channels.end() )
00244     {
00245         if ( _recmask & ( 1 << _channels[it.key()] ) ) channels += it++.key();
00246     }
00247     return channels;
00248 }
00249 
00250 
00251 QStringList OMixerInterface::playChannels() const
00252 {
00253     return allChannels();
00254 }
00255 
00256 
00257 bool OMixerInterface::hasMultipleRecording() const
00258 {
00259     return !( _capmask & SOUND_CAP_EXCL_INPUT );
00260 }
00261 
00262 
00263 bool OMixerInterface::hasChannel( const QString& channel ) const
00264 {
00265     return _channels.contains( channel );
00266 }
00267 
00268 
00269 bool OMixerInterface::isStereo( const QString& channel ) const
00270 {
00271     return _channels.contains( channel ) && ( _stmask & ( 1 << _channels[channel] ) );
00272 }
00273 
00274 
00275 bool OMixerInterface::isRecordable( const QString& channel ) const
00276 {
00277     return _channels.contains( channel ) && ( _recmask & ( 1 << _channels[channel] ) );
00278 }
00279 
00280 
00281 void OMixerInterface::setVolume( const QString& channel, int left, int right )
00282 {
00283     int volume = left;
00284     volume |= ( right == -1 ) ? left << 8 : right << 8;
00285 
00286     if ( _channels.contains( channel ) )
00287     {
00288         int result = ioctl( _fd, MIXER_WRITE( _channels[channel] ), &volume );
00289         if ( result == -1 )
00290         {
00291             owarn << "Can't set volume: " << strerror( errno ) << oendl;
00292         }
00293         else
00294         {
00295             if ( result & 0xff != left )
00296             {
00297                 owarn << "Device adjusted volume from " << left << " to " << (result & 0xff) << oendl;
00298             }
00299         }
00300     }
00301 }
00302 
00303 
00304 int OMixerInterface::volume( const QString& channel ) const
00305 {
00306     int volume;
00307 
00308     if ( _channels.contains( channel ) )
00309     {
00310         if ( ioctl( _fd, MIXER_READ( _channels[channel] ), &volume ) == -1 )
00311         {
00312             owarn << "Can't get volume: " << strerror( errno ) << oendl;
00313         }
00314         else return volume;
00315     }
00316     return -1;
00317 }

Generated on Sat Nov 5 16:16:12 2005 for OPIE by  doxygen 1.4.2