-rw-r--r-- | libopie2/examples/opiemm/osoundsystemdemo/osoundsystemdemo.cpp | 3 | ||||
-rw-r--r-- | libopie2/opiemm/osoundsystem.cpp | 25 | ||||
-rw-r--r-- | libopie2/opiemm/osoundsystem.h | 6 |
3 files changed, 30 insertions, 4 deletions
diff --git a/libopie2/examples/opiemm/osoundsystemdemo/osoundsystemdemo.cpp b/libopie2/examples/opiemm/osoundsystemdemo/osoundsystemdemo.cpp index b522441..f74a1b9 100644 --- a/libopie2/examples/opiemm/osoundsystemdemo/osoundsystemdemo.cpp +++ b/libopie2/examples/opiemm/osoundsystemdemo/osoundsystemdemo.cpp @@ -1,65 +1,66 @@ /* =. This file is part of the Opie Project .=l. Copyright (C) 2004 Opie Team <opie-devel@handhelds.org> .>+-= _;:, .> :=|. This library is free software; you can .> <`_, > . <= redistribute it and/or modify it under :`=1 )Y*s>-.-- : the terms of the GNU Library General Public .="- .-=="i, .._ License as published by the Free Software - . .-<_> .<> Foundation; either version 2 of the License, ._= =} : or (at your option) any later version. .%`+i> _;_. .i_,=:_. -<s. This library is distributed in the hope that + . -:. = it will be useful, but WITHOUT ANY WARRANTY; : .. .:, . . . without even the implied warranty of =_ + =;=|` MERCHANTABILITY or FITNESS FOR A _.=:. : :=>`: PARTICULAR PURPOSE. See the GNU ..}^=.= = ; Library General Public License for more ++= -. .` .: details. : = ...= . :.=- -. .:....=;==+<; You should have received a copy of the GNU -_. . . )=. = Library General Public License along with -- :-=` this library; see the file COPYING.LIB. If not, write to the Free Software Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. */ /* OPIE */ #include <opie2/osoundsystem.h> #include <opie2/odebug.h> using namespace Opie::MM; int main( int argc, char** argv ) { odebug << "OPIE Sound System Demo" << oendl; OSoundSystem* sound = OSoundSystem::instance(); OSoundSystem::CardIterator it = sound->iterator(); /* while ( it.current() ) { odebug << "DEMO: OSoundSystem contains Interface '" << it.current()->name() << "'" << oendl; ++it; } */ OSoundCard* card = it.current(); OMixerInterface* mixer = card->mixer(); QStringList channels = mixer->allChannels(); for ( QStringList::Iterator it = channels.begin(); it != channels.end(); ++it ) { - odebug << "OSSDEMO: Mixer has channel " << *it << "" << oendl; + bool stereo = mixer->isStereo( *it ); + odebug << "OSSDEMO: Mixer has channel " << *it << ( stereo ? "[stereo]" : "[mono]" ) << oendl; odebug << "OSSDEMO: +--- volume " << ( mixer->volume( *it ) & 0xff ) << " (left) | " << ( mixer->volume( *it ) >> 8 ) << " (right)" << oendl; } return 0; } diff --git a/libopie2/opiemm/osoundsystem.cpp b/libopie2/opiemm/osoundsystem.cpp index 13b26e6..09fd28f 100644 --- a/libopie2/opiemm/osoundsystem.cpp +++ b/libopie2/opiemm/osoundsystem.cpp @@ -133,188 +133,209 @@ OSoundCard::OSoundCard( QObject* parent, const char* name ) OSoundCard::~OSoundCard() { } void OSoundCard::init() { #ifdef QT_QWS_DEVFS _audio = new OAudioInterface( this, "/dev/sound/dsp" ); _mixer = new OMixerInterface( this, "/dev/sound/mixer" ); #else _audio = new OAudioInterface( this, "/dev/dsp" ); _mixer = new OMixerInterface( this, "/dev/mixer" ); #endif } /*====================================================================================== * OAudioInterface *======================================================================================*/ OAudioInterface::OAudioInterface( QObject* parent, const char* name ) :QObject( parent, name ), _sfd(0) { odebug << "OAudioInterface::OAudioInterface()" << oendl; init(); } OAudioInterface::~OAudioInterface() { } void OAudioInterface::init() { } /*====================================================================================== * OMixerInterface *======================================================================================*/ OMixerInterface::OMixerInterface( QObject* parent, const char* name ) :QObject( parent, name ) { odebug << "OMixerInterface::OMixerInterface()" << oendl; init(); } OMixerInterface::~OMixerInterface() { } void OMixerInterface::init() { // open the device _fd = ::open( name(), O_RDWR ); if ( _fd == -1 ) { - owarn << "OMixerInterface::init(): Can't open mixer." << oendl; + owarn << "OMixerInterface::init(): Can't open mixer " << name() << oendl; return; } // construct the device capabilities int devmask = 0; if ( ioctl( _fd, SOUND_MIXER_READ_DEVMASK, &devmask ) != -1 ) { if ( devmask & ( 1 << SOUND_MIXER_VOLUME ) ) _channels.insert( "PlayVolume", SOUND_MIXER_VOLUME ); if ( devmask & ( 1 << SOUND_MIXER_BASS ) ) _channels.insert( "PlayBass", SOUND_MIXER_BASS ); if ( devmask & ( 1 << SOUND_MIXER_TREBLE ) ) _channels.insert( "PlayTreble", SOUND_MIXER_TREBLE ); if ( devmask & ( 1 << SOUND_MIXER_SYNTH ) ) _channels.insert( "PlaySynth", SOUND_MIXER_SYNTH ); if ( devmask & ( 1 << SOUND_MIXER_PCM ) ) _channels.insert( "PlayPCM", SOUND_MIXER_PCM ); if ( devmask & ( 1 << SOUND_MIXER_SPEAKER ) ) _channels.insert( "PlaySpeaker", SOUND_MIXER_SPEAKER ); if ( devmask & ( 1 << SOUND_MIXER_LINE ) ) _channels.insert( "PlayLine", SOUND_MIXER_LINE ); if ( devmask & ( 1 << SOUND_MIXER_MIC ) ) _channels.insert( "PlayMic", SOUND_MIXER_MIC ); if ( devmask & ( 1 << SOUND_MIXER_CD ) ) _channels.insert( "PlayCD", SOUND_MIXER_CD ); if ( devmask & ( 1 << SOUND_MIXER_IMIX ) ) _channels.insert( "PlayInputMix", SOUND_MIXER_IMIX ); if ( devmask & ( 1 << SOUND_MIXER_ALTPCM ) ) _channels.insert( "PlayAltPCM", SOUND_MIXER_ALTPCM ); if ( devmask & ( 1 << SOUND_MIXER_RECLEV ) ) _channels.insert( "PlayRecord", SOUND_MIXER_RECLEV ); if ( devmask & ( 1 << SOUND_MIXER_IGAIN ) ) _channels.insert( "PlayInputGain", SOUND_MIXER_IGAIN ); if ( devmask & ( 1 << SOUND_MIXER_OGAIN ) ) _channels.insert( "PlayOutputGain", SOUND_MIXER_OGAIN ); //odebug << "devmask available and constructed." << oendl; } devmask = 0; if ( ioctl( _fd, SOUND_MIXER_READ_RECMASK, &devmask ) != -1 ) { if ( devmask & ( 1 << SOUND_MIXER_VOLUME ) ) _channels.insert( "RecVolume", SOUND_MIXER_VOLUME ); if ( devmask & ( 1 << SOUND_MIXER_BASS ) ) _channels.insert( "RecBass", SOUND_MIXER_BASS ); if ( devmask & ( 1 << SOUND_MIXER_TREBLE ) ) _channels.insert( "RecTreble", SOUND_MIXER_TREBLE ); if ( devmask & ( 1 << SOUND_MIXER_SYNTH ) ) _channels.insert( "RecSynth", SOUND_MIXER_SYNTH ); if ( devmask & ( 1 << SOUND_MIXER_PCM ) ) _channels.insert( "RecPCM", SOUND_MIXER_PCM ); if ( devmask & ( 1 << SOUND_MIXER_SPEAKER ) ) _channels.insert( "RecSpeaker", SOUND_MIXER_SPEAKER ); if ( devmask & ( 1 << SOUND_MIXER_LINE ) ) _channels.insert( "RecLine", SOUND_MIXER_LINE ); if ( devmask & ( 1 << SOUND_MIXER_MIC ) ) _channels.insert( "RecMic", SOUND_MIXER_MIC ); if ( devmask & ( 1 << SOUND_MIXER_CD ) ) _channels.insert( "RecCD", SOUND_MIXER_CD ); if ( devmask & ( 1 << SOUND_MIXER_IMIX ) ) _channels.insert( "RecInputMix", SOUND_MIXER_IMIX ); if ( devmask & ( 1 << SOUND_MIXER_ALTPCM ) ) _channels.insert( "RecAltPCM", SOUND_MIXER_ALTPCM ); if ( devmask & ( 1 << SOUND_MIXER_RECLEV ) ) _channels.insert( "RecRecord", SOUND_MIXER_RECLEV ); if ( devmask & ( 1 << SOUND_MIXER_IGAIN ) ) _channels.insert( "RecInputGain", SOUND_MIXER_IGAIN ); if ( devmask & ( 1 << SOUND_MIXER_OGAIN ) ) _channels.insert( "RecOutputGain", SOUND_MIXER_OGAIN ); //odebug << "recmask available and constructed." << oendl; } + devmask = 0; + if ( ioctl( _fd, SOUND_MIXER_READ_STEREODEVS, &devmask ) != -1 ) + { + odebug << "stereomask = " << devmask << oendl; + } + /* ChannelIterator it; for ( it = _channels.begin(); it != _channels.end(); ++it ) { odebug << "Channel " << it.key() << " available (bit " << it.data() << ")" << oendl; odebug << " +--- Volume: " << volume( it.key() ) & 0xff << " | " << volume( it.key() ) >> 8 << "" << oendl; } */ } QStringList OMixerInterface::allChannels() const { ChannelIterator it = _channels.begin(); QStringList channels; while ( it != _channels.end() ) { channels += it.key(); it++; } return channels; } QStringList OMixerInterface::recChannels() const { owarn << "NYI" << oendl; return QStringList(); } QStringList OMixerInterface::playChannels() const { owarn << "NYI" << oendl; return QStringList(); } -bool OMixerInterface::hasChannel( const QString& channel ) +bool OMixerInterface::hasChannel( const QString& channel ) const { return _channels.contains( channel ); } +bool OMixerInterface::isStereo( const QString& channel ) const +{ + bool result = false; + if ( _channels.contains( channel ) ) + { + int devmask = 0; + if ( ioctl( _fd, SOUND_MIXER_READ_STEREODEVS, &devmask ) != -1 ) + { + result = devmask & ( 1 << _channels[channel] ); + } + } + return result; +} + + void OMixerInterface::setVolume( const QString& channel, int left, int right ) { int volume = left; volume |= ( right == -1 ) ? left << 8 : right << 8; if ( _channels.contains( channel ) ) { int result = ioctl( _fd, MIXER_WRITE( _channels[channel] ), &volume ); if ( result == -1 ) { owarn << "Can't set volume: " << strerror( errno ) << oendl; } else { if ( result & 0xff != left ) { owarn << "Device adjusted volume from " << left << " to " << (result & 0xff) << oendl; } } } } int OMixerInterface::volume( const QString& channel ) const { int volume; if ( _channels.contains( channel ) ) { if ( ioctl( _fd, MIXER_READ( _channels[channel] ), &volume ) == -1 ) { owarn << "Can't get volume: " << strerror( errno ) << oendl; } else return volume; } return -1; } diff --git a/libopie2/opiemm/osoundsystem.h b/libopie2/opiemm/osoundsystem.h index bd69114..ac7a5a7 100644 --- a/libopie2/opiemm/osoundsystem.h +++ b/libopie2/opiemm/osoundsystem.h @@ -141,92 +141,96 @@ class OSoundCard : public QObject class OAudioInterface : public QObject { Q_OBJECT public: /** * Constructor. Normally you don't create @ref OAudioInterface objects yourself, * but access them via the @ref OSoundCard interface. */ OAudioInterface( QObject* parent, const char* name ); /** * Destructor. */ virtual ~OAudioInterface(); protected: const int _sfd; private: void init(); private: class Private; Private *d; }; /*====================================================================================== * OMixerInterface *======================================================================================*/ class OMixerInterface : public QObject { Q_OBJECT public: typedef QMap<QString,int>::ConstIterator ChannelIterator; /** * Constructor. Normally you don't create @ref OMixerInterface objects yourself, * but access them via the @ref OSoundCard interface. */ OMixerInterface( QObject* parent, const char* name ); /** * Destructor. */ virtual ~OMixerInterface(); /** * @returns all available channels. */ QStringList allChannels() const; /** * @returns recordable channels. */ QStringList recChannels() const; /** * @returns playable channels. */ QStringList playChannels() const; /** * @returns true, if @a channel exists. */ - bool hasChannel( const QString& channel ); + bool hasChannel( const QString& channel ) const; + /** + * @returns true, if @a channel is stereo. + */ + bool isStereo( const QString& channel ) const; /** * Set the @a left and @a right volumes for @a channel. * If no value for right is given, the value for left is taken for that. */ void setVolume( const QString& channel, int left, int right = -1 ); /** * @returns the volume of @a channel or -1, if the channel doesn't exist. * @note You might want to use @ref hasChannel() to check if a channel exists. */ int volume( const QString& channel ) const; protected: int _fd; QMap<QString, int> _channels; private: void init(); private: class Private; Private *d; }; } } #endif // OSOUNDSYSTEM_H |