arts Library API Documentation

kaudiorecordstream.cpp

00001 /* 00002 00003 Copyright (C) 2001, 2002 Matthias Kretz 00004 kretz@kde.org 00005 2003 Arnold Krille 00006 arnold@arnoldarts.de 00007 00008 This library is free software; you can redistribute it and/or 00009 modify it under the terms of the GNU Library General Public 00010 License as published by the Free Software Foundation; either 00011 version 2 of the License, or (at your option) any later version. 00012 00013 This library is distributed in the hope that it will be useful, 00014 but WITHOUT ANY WARRANTY; without even the implied warranty of 00015 MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU 00016 Library General Public License for more details. 00017 00018 You should have received a copy of the GNU Library General Public License 00019 along with this library; see the file COPYING.LIB. If not, write to 00020 the Free Software Foundation, Inc., 59 Temple Place - Suite 330, 00021 Boston, MA 02111-1307, USA. 00022 00023 */ 00024 00025 #include "kaudiorecordstream.h" 00026 #include "kaudiorecordstream_p.h" 00027 #include "kartsserver.h" 00028 00029 #include <artsflow.h> 00030 #include <soundserver.h> 00031 00032 #include <kglobal.h> 00033 #include <kdebug.h> 00034 00035 #include <qstring.h> 00036 #include <qptrqueue.h> 00037 #include <qcstring.h> //QByteArray 00038 00039 #include <assert.h> 00040 00041 struct KAudioRecordStream::Data 00042 { 00043 Arts::Synth_AMAN_RECORD in; 00044 Arts::AudioToByteStream convert; 00045 Arts::StereoEffectStack effectStack; 00046 Arts::ByteSoundReceiver receiver; 00047 KByteSoundReceiver * receiver_base; 00048 KArtsServer * kserver; 00049 bool attached; 00050 bool blocking; 00051 bool polling; 00052 unsigned int pos; 00053 QPtrQueue<QByteArray> inqueue; 00054 QString title; 00055 }; 00056 00057 KAudioRecordStream::KAudioRecordStream( KArtsServer * kserver, const QString & title, QObject * parent, const char * name ) 00058 : QObject( parent, name ) 00059 , d( new Data ) 00060 { 00061 d->kserver = kserver; 00062 d->attached = false; 00063 d->blocking = true; 00064 d->polling = false; 00065 d->pos = 0; 00066 d->inqueue.setAutoDelete( true ); 00067 d->title = title; 00068 00069 connect( d->kserver, SIGNAL( restartedServer() ), SLOT( slotRestartedServer() ) ); 00070 00071 d->in = Arts::DynamicCast( d->kserver->server().createObject( "Arts::Synth_AMAN_RECORD" ) ); 00072 d->effectStack = Arts::DynamicCast( d->kserver->server().createObject( "Arts::StereoEffectStack" ) ); 00073 d->convert = Arts::DynamicCast( d->kserver->server().createObject( "Arts::AudioToByteStream" ) ); 00074 if( d->in.isNull() ) 00075 kdFatal( 400 ) << "couldn't create a Synth_AMAN_RECORD on the aRts server\n"; 00076 if( d->effectStack.isNull() ) 00077 kdFatal( 400 ) << "couldn't create a StereoEffectStack on the aRts server\n"; 00078 if( d->convert.isNull() ) 00079 kdFatal( 400 ) << "couldn't create a AudioToByteStream on the aRts server\n"; 00080 00081 d->in.title( ( const char * ) d->title.local8Bit() ); 00082 Arts::connect( d->in, d->effectStack ); 00083 d->in.start(); 00084 d->effectStack.start(); 00085 } 00086 00087 KAudioRecordStream::~KAudioRecordStream() 00088 { 00089 d->receiver = Arts::ByteSoundReceiver::null(); 00090 // don't delete receiver_base because aRts takes care of that (in the line 00091 // above) 00092 d->receiver_base = 0; 00093 delete d; 00094 } 00095 00096 int KAudioRecordStream::read( char * buffer, int size ) 00097 { 00098 kdDebug( 400 ) << k_funcinfo << endl; 00099 unsigned int remaining = size; 00100 while( remaining ) 00101 { 00102 if( d->blocking ) 00103 while( d->inqueue.isEmpty() ) 00104 Arts::Dispatcher::the()->ioManager()->processOneEvent( true ); 00105 else 00106 { 00107 if( d->inqueue.isEmpty() ) 00108 Arts::Dispatcher::the()->ioManager()->processOneEvent( false ); 00109 if( d->inqueue.isEmpty() ) 00110 return size - remaining; 00111 } 00112 QByteArray * data = d->inqueue.head(); 00113 unsigned int tocopy = kMin( remaining, data->size() - d->pos ); 00114 memcpy( buffer, data->data() + d->pos, tocopy ); 00115 d->pos += tocopy; 00116 buffer += tocopy; 00117 remaining -= tocopy; 00118 if( d->pos == data->size() ) 00119 { 00120 d->inqueue.remove(); 00121 d->pos = 0; 00122 } 00123 } 00124 return size; 00125 } 00126 00127 void KAudioRecordStream::setBlockingIO( bool blocking ) 00128 { 00129 d->blocking = blocking; 00130 } 00131 00132 bool KAudioRecordStream::blockingIO() const 00133 { 00134 return d->blocking; 00135 } 00136 00137 void KAudioRecordStream::usePolling( bool polling ) 00138 { 00139 d->polling = polling; 00140 if( ! polling ) 00141 flush(); 00142 } 00143 00144 bool KAudioRecordStream::polling() const 00145 { 00146 return d->polling; 00147 } 00148 00149 Arts::StereoEffectStack KAudioRecordStream::effectStack() const 00150 { 00151 return d->effectStack; 00152 } 00153 00154 bool KAudioRecordStream::running() const 00155 { 00156 return d->attached; 00157 } 00158 00159 void KAudioRecordStream::stop() 00160 { 00161 kdDebug( 400 ) << k_funcinfo << endl; 00162 if( d->attached ) 00163 { 00164 d->receiver.stop(); 00165 d->convert.stop(); 00166 00167 Arts::disconnect( d->convert, d->receiver ); 00168 d->receiver = Arts::ByteSoundReceiver::null(); 00169 d->receiver_base = 0; 00170 00171 Arts::disconnect( d->effectStack, d->convert ); 00172 00173 d->attached = false; 00174 emit running( false ); 00175 } 00176 } 00177 00178 void KAudioRecordStream::start( int samplingRate, int bits, int channels ) 00179 { 00180 kdDebug( 400 ) << k_funcinfo << "samplingRate: " << samplingRate << " bits: " << bits << " channels: " << channels << endl; 00181 if( ! d->attached ) 00182 { 00183 assert( d->kserver ); 00184 00185 if( ( samplingRate < 500 || samplingRate > 2000000 ) 00186 || ( channels != 1 && channels != 2 ) || ( bits != 8 && bits != 16 ) ) 00187 { 00188 kdWarning( 400 ) << "invalid stream parameters: rate=" << samplingRate << ", " << bits << " bit, " << channels << " channels\n"; 00189 } 00190 else 00191 { 00192 d->convert.samplingRate( samplingRate ); 00193 d->convert.channels( channels ); 00194 d->convert.bits( bits ); 00195 Arts::connect( d->effectStack, d->convert ); 00196 00197 d->receiver_base = new KByteSoundReceiver( samplingRate, bits, channels, d->title.local8Bit() ); 00198 d->receiver = Arts::ByteSoundReceiver::_from_base( d->receiver_base ); 00199 connect( d->receiver_base, SIGNAL( data( const char *, unsigned int ) ), 00200 SLOT( slotData( const char *, unsigned int ) ) ); 00201 Arts::connect( d->convert, "outdata", d->receiver, "indata" ); 00202 00203 d->convert.start(); 00204 d->receiver.start(); 00205 00206 //### needed? 00207 Arts::Dispatcher::the()->ioManager()->processOneEvent( false ); 00208 d->attached = true; 00209 emit running( true ); 00210 } 00211 } 00212 } 00213 00214 void KAudioRecordStream::flush() 00215 { 00216 kdDebug( 400 ) << k_funcinfo << endl; 00217 d->inqueue.clear(); 00218 } 00219 00220 void KAudioRecordStream::slotRestartedServer() { } 00221 00222 void KAudioRecordStream::slotData( const char * contents, unsigned int size ) 00223 { 00224 //kdDebug( 400 ) << k_funcinfo << endl; 00225 QByteArray * bytearray = new QByteArray( size ); 00226 // copy the contents to the bytearray 00227 // this has to be deleted later 00228 bytearray->duplicate( contents, size ); 00229 if( d->polling ) 00230 { 00231 kdDebug( 400 ) << "enqueue the data\n"; 00232 d->inqueue.enqueue( bytearray ); 00233 } 00234 else 00235 { 00236 //kdDebug( 400 ) << "emit the data\n"; 00237 emit data( *bytearray ); 00238 //kdDebug( 400 ) << "delete the data\n"; 00239 delete bytearray; 00240 } 00241 } 00242 00244 // ---*--- KByteSoundReceiver ---*--- // 00246 00247 KByteSoundReceiver::KByteSoundReceiver( int rate, int bits, int channels, const char * title ) 00248 : _samplingRate( rate ) 00249 , _bits( bits ) 00250 , _channels( channels ) 00251 , _title( title ) 00252 { 00253 } 00254 00255 KByteSoundReceiver::~KByteSoundReceiver() 00256 { 00257 } 00258 00259 void KByteSoundReceiver::process_indata( Arts::DataPacket<Arts::mcopbyte> * inpacket ) 00260 { 00261 //kdDebug( 400 ) << k_funcinfo << " size of the packet: " << inpacket->size << endl; 00262 emit data( (char *)inpacket->contents, inpacket->size ); 00263 inpacket->processed(); 00264 } 00265 00266 // vim:sw=4:ts=4 00267 00268 #include "kaudiorecordstream.moc" 00269 #include "kaudiorecordstream_p.moc"
KDE Logo
This file is part of the documentation for arts Library Version 3.2.3.
Documentation copyright © 1996-2004 the KDE developers.
Generated on Fri Aug 20 09:49:27 2004 by doxygen 1.3.7 written by Dimitri van Heesch, © 1997-2003