kaudioplaystream.cpp

00001 /*  This file is part of the KDE project
00002     Copyright (C) 2003 Arnold Krille <arnold@arnoldarts.de>
00003 
00004     This library is free software; you can redistribute it and/or
00005     modify it under the terms of the GNU Library General Public
00006     License version 2 as published by the Free Software Foundation.
00007 
00008     This library is distributed in the hope that it will be useful,
00009     but WITHOUT ANY WARRANTY; without even the implied warranty of
00010     MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
00011     Library General Public License for more details.
00012 
00013     You should have received a copy of the GNU Library General Public License
00014     along with this library; see the file COPYING.LIB.  If not, write to
00015     the Free Software Foundation, Inc., 51 Franklin Street, Fifth Floor,
00016     Boston, MA 02110-1301, USA.
00017 
00018 */
00019 
00020 #include "kaudioplaystream.h"
00021 #include "kaudioplaystream_p.h"
00022 
00023 #include <kartsserver.h>
00024 #include <kaudiomanagerplay.h>
00025 
00026 #include <artsflow.h>
00027 #include <soundserver.h>
00028 
00029 #include <kglobal.h>
00030 #include <kdebug.h>
00031 
00032 #include <qstring.h>
00033 //#include <qptrqueue.h>
00034 //#include <qcstring.h> //QByteArray
00035 
00036 #include <string.h> // for strncpy
00037 
00038 //#include <assert.h>
00039 
00040 KAudioPlayStreamPrivate::KAudioPlayStreamPrivate( KArtsServer* server, const QString title, QObject* p, const char* n )
00041  : QObject( p,n )
00042  , _server( server )
00043  , _play( new KAudioManagerPlay( _server, title ) )
00044  , _effectrack( Arts::StereoEffectStack::null() )
00045  , _polling( true ), _attached( false ), _effects( true )
00046 {
00047 kdDebug( 400 ) << k_funcinfo << endl;
00048     initaRts();
00049 }
00050 
00051 KAudioPlayStreamPrivate::~KAudioPlayStreamPrivate()
00052 {
00053     kdDebug( 400 ) << k_funcinfo << endl;
00054     _play->stop();
00055     if ( _effects ) _effectrack.stop();
00056     _bs2a.stop();
00057 }
00058 
00059 void KAudioPlayStreamPrivate::initaRts() {
00060     kdDebug( 400 ) << k_funcinfo << endl;
00061 
00062     _effectrack = Arts::DynamicCast( _server->server().createObject( "Arts::StereoEffectStack" ) );
00063     if ( _effectrack.isNull() )
00064     {
00065         kdWarning( 400 ) << "Couldn't create EffectStack!" << endl;
00066         _effects = false;
00067     }
00068 
00069     _bs2a = Arts::DynamicCast( _server->server().createObject( "Arts::ByteStreamToAudio" ) );
00070     if ( _bs2a.isNull() )
00071         kdFatal( 400 ) << "Couldn't create ByteStreamToAudio" << endl;
00072 
00073     if ( _effects )
00074     {
00075         Arts::connect( _effectrack, _play->amanPlay() );
00076         Arts::connect( _bs2a, _effectrack );
00077     } else {
00078         Arts::connect( _bs2a, _play->amanPlay() );
00079     }
00080 
00081     _play->start();
00082     if ( _effects ) _effectrack.start();
00083 }
00084 
00085 KAudioPlayStream::KAudioPlayStream( KArtsServer* server, const QString title, QObject* p, const char* n )
00086  : QObject( p,n )
00087  , d( new KAudioPlayStreamPrivate( server, title, this ) )
00088 {
00089     kdDebug( 400 ) << k_funcinfo << endl;
00090 }
00091 KAudioPlayStream::~KAudioPlayStream()
00092 {
00093     kdDebug( 400 ) << k_funcinfo << endl;
00094 }
00095 
00096 void KAudioPlayStream::setPolling( bool n ) { d->_polling = n; }
00097 bool KAudioPlayStream::polling() const { return d->_polling; }
00098 
00099 bool KAudioPlayStream::running() const { return d->_attached; }
00100 
00101 Arts::StereoEffectStack KAudioPlayStream::effectStack() const {
00102     return d->_effectrack;
00103 }
00104 
00105 void KAudioPlayStream::start( int samplingRate, int bits, int channels )
00106 {
00107     kdDebug( 400 ) << k_funcinfo << "samplingRate: " << samplingRate << " bits: " << bits << " channels: " << channels << endl;
00108     if ( !d->_attached )
00109     {
00110         d->_bs2a.samplingRate( samplingRate );
00111         d->_bs2a.channels( channels );
00112         d->_bs2a.bits( bits );
00113 
00114         d->_sender = new KByteSoundProducer( this, d->_server->server().minStreamBufferTime(), samplingRate, bits, channels, "PS" );
00115         d->_artssender = Arts::ByteSoundProducerV2::_from_base( d->_sender );
00116         Arts::connect( d->_artssender, "outdata", d->_bs2a, "indata" );
00117 
00118         d->_bs2a.start();
00119         d->_artssender.start();
00120 
00121 //      // Needed?
00122         Arts::Dispatcher::the()->ioManager()->processOneEvent( false );
00123 
00124         d->_attached = true;
00125         emit running( d->_attached );
00126     }
00127 }
00128 void KAudioPlayStream::stop()
00129 {
00130     kdDebug( 400 ) << k_funcinfo << endl;
00131     if ( d->_attached )
00132     {
00133         d->_attached = false;
00134 
00135         d->_bs2a.stop();
00136         d->_artssender.stop();
00137 
00138         // Shortly stop the play so we dont get clicks and artefacts
00139         d->_play->stop();
00140         d->_play->start();
00141 
00142         Arts::disconnect( d->_artssender, d->_bs2a );
00143         d->_artssender = Arts::ByteSoundProducerV2::null();
00144         d->_sender = 0;
00145 
00146         emit running( d->_attached );
00147     }
00148 }
00149 
00150 void KAudioPlayStream::write( QByteArray& )
00151 {
00152 }
00153 
00154 void KAudioPlayStream::fillData( Arts::DataPacket<Arts::mcopbyte> *packet )
00155 {
00156     //kdDebug( 400 ) << k_funcinfo << "packet->size=" << packet->size << endl;
00157     if ( d->_polling )
00158     {
00159         QByteArray bytearray( packet->size );
00160         bytearray.setRawData( ( char* )packet->contents, packet->size );
00161         bytearray.fill( 0 );
00162         emit requestData( bytearray );
00163         bytearray.resetRawData( ( char* )packet->contents, packet->size );
00164 
00165         //for ( int i=0; i<10; i++ )
00166         //  kdDebug() << packet->contents[ i ] << " : " << bytearray.data()[ i ] << endl;
00167     } else {
00169     }
00170 }
00171 
00172 // * * * KByteSoundProducer * * *
00173 
00174 KByteSoundProducer::KByteSoundProducer( KAudioPlayStream* impl, float minBufferTime, int rate, int bits, int channels, const char * title )
00175  : _samplingRate( rate )
00176  , _channels( channels )
00177  , _bits( bits )
00178  , _packets( 7 )
00179  , _title( title )
00180  , _impl( impl )
00181 {
00182     // Calculate packet count (packetsize is fixed to packetCapacity = 4096
00183     float streamBufferTime;
00184     do {
00185         _packets++;
00186         streamBufferTime = ( float )( _packets * packetCapacity * 1000 )
00187             / ( float )( _samplingRate * _channels * 2 );
00188     } while ( streamBufferTime < minBufferTime );
00189     //kdDebug( 400 ) << k_funcinfo << "_packets:" << _packets << " packetCapacity:" << packetCapacity << endl;
00190 }
00191 
00192 KByteSoundProducer::~KByteSoundProducer()
00193 {
00194 }
00195 
00196 void KByteSoundProducer::streamStart() { outdata.setPull( _packets, packetCapacity ); }
00197 void KByteSoundProducer::streamEnd() { outdata.endPull(); }
00198 
00199 void KByteSoundProducer::request_outdata( Arts::DataPacket<Arts::mcopbyte> *packet )
00200 {
00201     if ( _impl->running() ) {
00202         _impl->fillData( packet );
00203         packet->send();
00204     }
00205 }
00206 
00207 // vim: sw=4 ts=4 tw=80
00208 
00209 #include "kaudioplaystream.moc"
00210 #include "kaudioplaystream_p.moc"
KDE Home | KDE Accessibility Home | Description of Access Keys