• Skip to content
  • Skip to link menu
KDE 4.0 API Reference
  • KDE API Reference
  • kdegraphics
  • Sitemap
  • Contact Us
 

okular

audioplayer.cpp

Go to the documentation of this file.
00001 /***************************************************************************
00002  *   Copyright (C) 2007 by Pino Toscano <pino@kde.org>                     *
00003  *                                                                         *
00004  *   This program is free software; you can redistribute it and/or modify  *
00005  *   it under the terms of the GNU General Public License as published by  *
00006  *   the Free Software Foundation; either version 2 of the License, or     *
00007  *   (at your option) any later version.                                   *
00008  ***************************************************************************/
00009 
00010 #include "audioplayer.h"
00011 #include "audioplayer_p.h"
00012 
00013 // qt/kde includes
00014 #include <qbuffer.h>
00015 #include <qdir.h>
00016 #include <kdebug.h>
00017 #include <krandom.h>
00018 #include <Phonon/Path>
00019 #include <phonon/audiooutput.h>
00020 #include <phonon/abstractmediastream.h>
00021 #include <phonon/mediaobject.h>
00022 
00023 // local includes
00024 #include "action.h"
00025 #include "debug_p.h"
00026 #include "sound.h"
00027 
00028 using namespace Okular;
00029 
00030 // helper class used to store info about a sound to be played
00031 class SoundInfo
00032 {
00033 public:
00034     explicit SoundInfo( const Sound * s = 0, const SoundAction * ls = 0 )
00035       : sound( s ), volume( 0.5 ), synchronous( false ), repeat( false ),
00036         mix( false )
00037     {
00038         if ( ls )
00039         {
00040             volume = ls->volume();
00041             synchronous = ls->synchronous();
00042             repeat = ls->repeat();
00043             mix = ls->mix();
00044         }
00045     }
00046 
00047     const Sound * sound;
00048     double volume;
00049     bool synchronous;
00050     bool repeat;
00051     bool mix;
00052 };
00053 
00054 
00055 class PlayData
00056 {
00057 public:
00058     PlayData()
00059         : m_mediaobject( 0 ), m_output( 0 ), m_buffer( 0 )
00060     {
00061     }
00062 
00063     void play()
00064     {
00065         if ( m_buffer )
00066         {
00067             m_buffer->open( QIODevice::ReadOnly );
00068         }
00069         m_mediaobject->play();
00070     }
00071 
00072     ~PlayData()
00073     {
00074         m_mediaobject->stop();
00075         delete m_mediaobject;
00076         delete m_output;
00077         delete m_buffer;
00078     }
00079 
00080     Phonon::MediaObject * m_mediaobject;
00081     Phonon::AudioOutput * m_output;
00082     QBuffer * m_buffer;
00083     SoundInfo m_info;
00084 };
00085 
00086 
00087 AudioPlayerPrivate::AudioPlayerPrivate( AudioPlayer * qq )
00088     : q( qq )
00089 {
00090     QObject::connect( &m_mapper, SIGNAL( mapped( int ) ), q, SLOT( finished( int ) ) );
00091 }
00092 
00093 AudioPlayerPrivate::~AudioPlayerPrivate()
00094 {
00095     stopPlayings();
00096 }
00097 
00098 int AudioPlayerPrivate::newId() const
00099 {
00100     int newid = 0;
00101     QHash< int, PlayData * >::const_iterator it;
00102     QHash< int, PlayData * >::const_iterator itEnd = m_playing.constEnd();
00103     do
00104     {
00105         newid = KRandom::random();
00106         it = m_playing.constFind( newid );
00107     } while ( it != itEnd );
00108     return newid;
00109 }
00110 
00111 bool AudioPlayerPrivate::play( const SoundInfo& si )
00112 {
00113     kDebug() ;
00114     PlayData * data = new PlayData();
00115     data->m_output = new Phonon::AudioOutput( Phonon::NotificationCategory );
00116     data->m_output->setVolume( si.volume );
00117     data->m_mediaobject = new Phonon::MediaObject();
00118     Phonon::createPath(data->m_mediaobject, data->m_output);
00119     data->m_info = si;
00120     bool valid = false;
00121 
00122     switch ( si.sound->soundType() )
00123     {
00124         case Sound::External:
00125         {
00126             QString url = si.sound->url();
00127             kDebug(OkularDebug) << "External," << url;
00128             if ( !url.isEmpty() )
00129             {
00130                 int newid = newId();
00131                 m_mapper.setMapping( data->m_mediaobject, newid );
00132                 KUrl newurl;
00133                 if ( KUrl::isRelativeUrl( url ) )
00134                 {
00135                     newurl = m_currentDocument;
00136                     newurl.setFileName( url );
00137                 }
00138                 else
00139                 {
00140                     newurl = url;
00141                 }
00142                 data->m_mediaobject->setCurrentSource( newurl );
00143                 m_playing.insert( newid, data );
00144                 valid = true;
00145             }
00146             break;
00147         }
00148         case Sound::Embedded:
00149         {
00150             QByteArray filedata = si.sound->data();
00151             kDebug(OkularDebug) << "Embedded," << filedata.length();
00152             if ( !filedata.isEmpty() )
00153             {
00154                 kDebug(OkularDebug) << "Mediaobject:" << data->m_mediaobject;
00155                 int newid = newId();
00156                 m_mapper.setMapping( data->m_mediaobject, newid );
00157                 data->m_buffer = new QBuffer();
00158                 data->m_buffer->setData( filedata );
00159                 data->m_mediaobject->setCurrentSource( Phonon::MediaSource( data->m_buffer ) );
00160                 m_playing.insert( newid, data );
00161                 valid = true;
00162             }
00163             break;
00164         }
00165     }
00166     if ( !valid )
00167     {
00168         delete data;
00169         data = 0;
00170     }
00171     if ( data )
00172     {
00173         QObject::connect( data->m_mediaobject, SIGNAL( finished() ), &m_mapper, SLOT( map() ) );
00174         kDebug(OkularDebug) << "PLAY";
00175         data->play();
00176     }
00177     return valid;
00178 }
00179 
00180 void AudioPlayerPrivate::stopPlayings()
00181 {
00182     qDeleteAll( m_playing );
00183     m_playing.clear();
00184 }
00185 
00186 void AudioPlayerPrivate::finished( int id )
00187 {
00188     QHash< int, PlayData * >::iterator it = m_playing.find( id );
00189     if ( it == m_playing.end() )
00190         return;
00191 
00192     SoundInfo si = it.value()->m_info;
00193     // if the sound must be repeated indefinitely, then start the playback
00194     // again, otherwise destroy the PlayData as it's no more useful
00195     if ( si.repeat )
00196     {
00197         it.value()->play();
00198     }
00199     else
00200     {
00201         delete it.value();
00202         m_playing.erase( it );
00203     }
00204     kDebug(OkularDebug) << "finished," << m_playing.count();
00205 }
00206 
00207 
00208 AudioPlayer::AudioPlayer()
00209   : QObject(), d( new AudioPlayerPrivate( this ) )
00210 {
00211 }
00212 
00213 AudioPlayer::~AudioPlayer()
00214 {
00215     delete d;
00216 }
00217 
00218 AudioPlayer * AudioPlayer::instance()
00219 {
00220     static AudioPlayer ap;
00221     return &ap;
00222 }
00223 
00224 void AudioPlayer::playSound( const Sound * sound, const SoundAction * linksound )
00225 {
00226     // we can't play null pointers ;)
00227     if ( !sound )
00228         return;
00229 
00230     // we don't play external sounds for remote documents
00231     if ( sound->soundType() == Sound::External && !d->m_currentDocument.isLocalFile() )
00232         return;
00233 
00234     kDebug() ;
00235     SoundInfo si( sound, linksound );
00236 
00237     // if the mix flag of the new sound is false, then the currently playing
00238     // sounds must be stopped.
00239     if ( !si.mix )
00240         d->stopPlayings();
00241 
00242     d->play( si );
00243 }
00244 
00245 void AudioPlayer::stopPlaybacks()
00246 {
00247     d->stopPlayings();
00248 }
00249 
00250 #include "audioplayer.moc"

okular

Skip menu "okular"
  • Main Page
  • Namespace List
  • Class Hierarchy
  • Alphabetical List
  • Class List
  • File List
  • Namespace Members
  • Class Members
  • Related Pages

kdegraphics

Skip menu "kdegraphics"
  • okular
Generated for kdegraphics by doxygen 1.5.4
This website is maintained by Adriaan de Groot and Allen Winter.
KDE® and the K Desktop Environment® logo are registered trademarks of KDE e.V. | Legal