From ce4a32fe52ef09d8f5ff1dd22c001110902b60a2 Mon Sep 17 00:00:00 2001 From: toma Date: Wed, 25 Nov 2009 17:56:58 +0000 Subject: Copy the KDE 3.5 branch to branches/trinity for new KDE 3.5 features. BUG:215923 git-svn-id: svn://anonsvn.kde.org/home/kde/branches/trinity/kdelibs@1054174 283d02a7-25f6-0310-bc7c-ecb5cbfe19da --- arts/kde/kaudiorecordstream.cpp | 269 ++++++++++++++++++++++++++++++++++++++++ 1 file changed, 269 insertions(+) create mode 100644 arts/kde/kaudiorecordstream.cpp (limited to 'arts/kde/kaudiorecordstream.cpp') diff --git a/arts/kde/kaudiorecordstream.cpp b/arts/kde/kaudiorecordstream.cpp new file mode 100644 index 000000000..53788e296 --- /dev/null +++ b/arts/kde/kaudiorecordstream.cpp @@ -0,0 +1,269 @@ + /* + + Copyright (C) 2001, 2002 Matthias Kretz + kretz@kde.org + 2003 Arnold Krille + arnold@arnoldarts.de + + This library is free software; you can redistribute it and/or + modify it under the terms of the GNU Library General Public + License as published by the Free Software Foundation; either + version 2 of the License, or (at your option) any later version. + + 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., 51 Franklin Street, Fifth Floor, + Boston, MA 02110-1301, USA. + + */ + +#include "kaudiorecordstream.h" +#include "kaudiorecordstream_p.h" +#include "kartsserver.h" + +#include +#include + +#include +#include + +#include +#include +#include //QByteArray + +#include + +struct KAudioRecordStream::Data +{ + Arts::Synth_AMAN_RECORD in; + Arts::AudioToByteStream convert; + Arts::StereoEffectStack effectStack; + Arts::ByteSoundReceiver receiver; + KByteSoundReceiver * receiver_base; + KArtsServer * kserver; + bool attached; + bool blocking; + bool polling; + unsigned int pos; + QPtrQueue inqueue; + QString title; +}; + +KAudioRecordStream::KAudioRecordStream( KArtsServer * kserver, const QString & title, QObject * parent, const char * name ) + : QObject( parent, name ) + , d( new Data ) +{ + d->kserver = kserver; + d->attached = false; + d->blocking = true; + d->polling = false; + d->pos = 0; + d->inqueue.setAutoDelete( true ); + d->title = title; + + connect( d->kserver, SIGNAL( restartedServer() ), SLOT( slotRestartedServer() ) ); + + d->in = Arts::DynamicCast( d->kserver->server().createObject( "Arts::Synth_AMAN_RECORD" ) ); + d->effectStack = Arts::DynamicCast( d->kserver->server().createObject( "Arts::StereoEffectStack" ) ); + d->convert = Arts::DynamicCast( d->kserver->server().createObject( "Arts::AudioToByteStream" ) ); + if( d->in.isNull() ) + kdFatal( 400 ) << "couldn't create a Synth_AMAN_RECORD on the aRts server\n"; + if( d->effectStack.isNull() ) + kdFatal( 400 ) << "couldn't create a StereoEffectStack on the aRts server\n"; + if( d->convert.isNull() ) + kdFatal( 400 ) << "couldn't create a AudioToByteStream on the aRts server\n"; + + d->in.title( ( const char * ) d->title.local8Bit() ); + Arts::connect( d->in, d->effectStack ); + d->in.start(); + d->effectStack.start(); +} + +KAudioRecordStream::~KAudioRecordStream() +{ + d->receiver = Arts::ByteSoundReceiver::null(); + // don't delete receiver_base because aRts takes care of that (in the line + // above) + d->receiver_base = 0; + delete d; +} + +int KAudioRecordStream::read( char * buffer, int size ) +{ + kdDebug( 400 ) << k_funcinfo << endl; + unsigned int remaining = size; + while( remaining ) + { + if( d->blocking ) + while( d->inqueue.isEmpty() ) + Arts::Dispatcher::the()->ioManager()->processOneEvent( true ); + else + { + if( d->inqueue.isEmpty() ) + Arts::Dispatcher::the()->ioManager()->processOneEvent( false ); + if( d->inqueue.isEmpty() ) + return size - remaining; + } + QByteArray * data = d->inqueue.head(); + unsigned int tocopy = kMin( remaining, data->size() - d->pos ); + memcpy( buffer, data->data() + d->pos, tocopy ); + d->pos += tocopy; + buffer += tocopy; + remaining -= tocopy; + if( d->pos == data->size() ) + { + d->inqueue.remove(); + d->pos = 0; + } + } + return size; +} + +void KAudioRecordStream::setBlockingIO( bool blocking ) +{ + d->blocking = blocking; +} + +bool KAudioRecordStream::blockingIO() const +{ + return d->blocking; +} + +void KAudioRecordStream::usePolling( bool polling ) +{ + d->polling = polling; + if( ! polling ) + flush(); +} + +bool KAudioRecordStream::polling() const +{ + return d->polling; +} + +Arts::StereoEffectStack KAudioRecordStream::effectStack() const +{ + return d->effectStack; +} + +bool KAudioRecordStream::running() const +{ + return d->attached; +} + +void KAudioRecordStream::stop() +{ + kdDebug( 400 ) << k_funcinfo << endl; + if( d->attached ) + { + d->receiver.stop(); + d->convert.stop(); + + Arts::disconnect( d->convert, d->receiver ); + d->receiver = Arts::ByteSoundReceiver::null(); + d->receiver_base = 0; + + Arts::disconnect( d->effectStack, d->convert ); + + d->attached = false; + emit running( false ); + } +} + +void KAudioRecordStream::start( int samplingRate, int bits, int channels ) +{ + kdDebug( 400 ) << k_funcinfo << "samplingRate: " << samplingRate << " bits: " << bits << " channels: " << channels << endl; + if( ! d->attached ) + { + assert( d->kserver ); + + if( ( samplingRate < 500 || samplingRate > 2000000 ) + || ( channels != 1 && channels != 2 ) || ( bits != 8 && bits != 16 ) ) + { + kdWarning( 400 ) << "invalid stream parameters: rate=" << samplingRate << ", " << bits << " bit, " << channels << " channels\n"; + } + else + { + d->convert.samplingRate( samplingRate ); + d->convert.channels( channels ); + d->convert.bits( bits ); + Arts::connect( d->effectStack, d->convert ); + + d->receiver_base = new KByteSoundReceiver( samplingRate, bits, channels, d->title.local8Bit() ); + d->receiver = Arts::ByteSoundReceiver::_from_base( d->receiver_base ); + connect( d->receiver_base, SIGNAL( data( const char *, unsigned int ) ), + SLOT( slotData( const char *, unsigned int ) ) ); + Arts::connect( d->convert, "outdata", d->receiver, "indata" ); + + d->convert.start(); + d->receiver.start(); + + //### needed? + Arts::Dispatcher::the()->ioManager()->processOneEvent( false ); + d->attached = true; + emit running( true ); + } + } +} + +void KAudioRecordStream::flush() +{ + kdDebug( 400 ) << k_funcinfo << endl; + d->inqueue.clear(); +} + +void KAudioRecordStream::slotRestartedServer() { } + +void KAudioRecordStream::slotData( const char * contents, unsigned int size ) +{ + //kdDebug( 400 ) << k_funcinfo << endl; + QByteArray * bytearray = new QByteArray( size ); + // copy the contents to the bytearray + // this has to be deleted later + bytearray->duplicate( contents, size ); + if( d->polling ) + { + kdDebug( 400 ) << "enqueue the data\n"; + d->inqueue.enqueue( bytearray ); + } + else + { + //kdDebug( 400 ) << "emit the data\n"; + emit data( *bytearray ); + //kdDebug( 400 ) << "delete the data\n"; + delete bytearray; + } +} + +//////////////////////////////////////// +// ---*--- KByteSoundReceiver ---*--- // +//////////////////////////////////////// + +KByteSoundReceiver::KByteSoundReceiver( int rate, int bits, int channels, const char * title ) + : _samplingRate( rate ) + , _bits( bits ) + , _channels( channels ) + , _title( title ) +{ +} + +KByteSoundReceiver::~KByteSoundReceiver() +{ +} + +void KByteSoundReceiver::process_indata( Arts::DataPacket * inpacket ) +{ + //kdDebug( 400 ) << k_funcinfo << " size of the packet: " << inpacket->size << endl; + emit data( (char *)inpacket->contents, inpacket->size ); + inpacket->processed(); +} + +// vim:sw=4:ts=4 + +#include "kaudiorecordstream.moc" +#include "kaudiorecordstream_p.moc" -- cgit v1.2.1