TDE core libraries
You can not select more than 25 topics Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.

kaudiorecordstream.cpp 7.1KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269
  1. /*
  2. Copyright (C) 2001, 2002 Matthias Kretz
  3. kretz@kde.org
  4. 2003 Arnold Krille
  5. arnold@arnoldarts.de
  6. This library is free software; you can redistribute it and/or
  7. modify it under the terms of the GNU Library General Public
  8. License as published by the Free Software Foundation; either
  9. version 2 of the License, or (at your option) any later version.
  10. This library is distributed in the hope that it will be useful,
  11. but WITHOUT ANY WARRANTY; without even the implied warranty of
  12. MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
  13. Library General Public License for more details.
  14. You should have received a copy of the GNU Library General Public License
  15. along with this library; see the file COPYING.LIB. If not, write to
  16. the Free Software Foundation, Inc., 51 Franklin Street, Fifth Floor,
  17. Boston, MA 02110-1301, USA.
  18. */
  19. #include "kaudiorecordstream.h"
  20. #include "kaudiorecordstream_p.h"
  21. #include "kartsserver.h"
  22. #include <artsflow.h>
  23. #include <soundserver.h>
  24. #include <tdeglobal.h>
  25. #include <kdebug.h>
  26. #include <tqstring.h>
  27. #include <tqptrqueue.h>
  28. #include <tqcstring.h> //QByteArray
  29. #include <assert.h>
  30. struct KAudioRecordStream::Data
  31. {
  32. Arts::Synth_AMAN_RECORD in;
  33. Arts::AudioToByteStream convert;
  34. Arts::StereoEffectStack effectStack;
  35. Arts::ByteSoundReceiver receiver;
  36. KByteSoundReceiver * receiver_base;
  37. KArtsServer * kserver;
  38. bool attached;
  39. bool blocking;
  40. bool polling;
  41. unsigned int pos;
  42. TQPtrQueue<TQByteArray> inqueue;
  43. TQString title;
  44. };
  45. KAudioRecordStream::KAudioRecordStream( KArtsServer * kserver, const TQString & title, TQObject * parent, const char * name )
  46. : TQObject( parent, name )
  47. , d( new Data )
  48. {
  49. d->kserver = kserver;
  50. d->attached = false;
  51. d->blocking = true;
  52. d->polling = false;
  53. d->pos = 0;
  54. d->inqueue.setAutoDelete( true );
  55. d->title = title;
  56. connect( d->kserver, TQT_SIGNAL( restartedServer() ), TQT_SLOT( slotRestartedServer() ) );
  57. d->in = Arts::DynamicCast( d->kserver->server().createObject( "Arts::Synth_AMAN_RECORD" ) );
  58. d->effectStack = Arts::DynamicCast( d->kserver->server().createObject( "Arts::StereoEffectStack" ) );
  59. d->convert = Arts::DynamicCast( d->kserver->server().createObject( "Arts::AudioToByteStream" ) );
  60. if( d->in.isNull() )
  61. kdFatal( 400 ) << "couldn't create a Synth_AMAN_RECORD on the aRts server\n";
  62. if( d->effectStack.isNull() )
  63. kdFatal( 400 ) << "couldn't create a StereoEffectStack on the aRts server\n";
  64. if( d->convert.isNull() )
  65. kdFatal( 400 ) << "couldn't create a AudioToByteStream on the aRts server\n";
  66. d->in.title( ( const char * ) d->title.local8Bit() );
  67. Arts::connect( d->in, d->effectStack );
  68. d->in.start();
  69. d->effectStack.start();
  70. }
  71. KAudioRecordStream::~KAudioRecordStream()
  72. {
  73. d->receiver = Arts::ByteSoundReceiver::null();
  74. // don't delete receiver_base because aRts takes care of that (in the line
  75. // above)
  76. d->receiver_base = 0;
  77. delete d;
  78. }
  79. int KAudioRecordStream::read( char * buffer, int size )
  80. {
  81. kdDebug( 400 ) << k_funcinfo << endl;
  82. unsigned int remaining = size;
  83. while( remaining )
  84. {
  85. if( d->blocking )
  86. while( d->inqueue.isEmpty() )
  87. Arts::Dispatcher::the()->ioManager()->processOneEvent( true );
  88. else
  89. {
  90. if( d->inqueue.isEmpty() )
  91. Arts::Dispatcher::the()->ioManager()->processOneEvent( false );
  92. if( d->inqueue.isEmpty() )
  93. return size - remaining;
  94. }
  95. TQByteArray * data = d->inqueue.head();
  96. unsigned int tocopy = kMin( remaining, data->size() - d->pos );
  97. memcpy( buffer, data->data() + d->pos, tocopy );
  98. d->pos += tocopy;
  99. buffer += tocopy;
  100. remaining -= tocopy;
  101. if( d->pos == data->size() )
  102. {
  103. d->inqueue.remove();
  104. d->pos = 0;
  105. }
  106. }
  107. return size;
  108. }
  109. void KAudioRecordStream::setBlockingIO( bool blocking )
  110. {
  111. d->blocking = blocking;
  112. }
  113. bool KAudioRecordStream::blockingIO() const
  114. {
  115. return d->blocking;
  116. }
  117. void KAudioRecordStream::usePolling( bool polling )
  118. {
  119. d->polling = polling;
  120. if( ! polling )
  121. flush();
  122. }
  123. bool KAudioRecordStream::polling() const
  124. {
  125. return d->polling;
  126. }
  127. Arts::StereoEffectStack KAudioRecordStream::effectStack() const
  128. {
  129. return d->effectStack;
  130. }
  131. bool KAudioRecordStream::running() const
  132. {
  133. return d->attached;
  134. }
  135. void KAudioRecordStream::stop()
  136. {
  137. kdDebug( 400 ) << k_funcinfo << endl;
  138. if( d->attached )
  139. {
  140. d->receiver.stop();
  141. d->convert.stop();
  142. Arts::disconnect( d->convert, d->receiver );
  143. d->receiver = Arts::ByteSoundReceiver::null();
  144. d->receiver_base = 0;
  145. Arts::disconnect( d->effectStack, d->convert );
  146. d->attached = false;
  147. emit running( false );
  148. }
  149. }
  150. void KAudioRecordStream::start( int samplingRate, int bits, int channels )
  151. {
  152. kdDebug( 400 ) << k_funcinfo << "samplingRate: " << samplingRate << " bits: " << bits << " channels: " << channels << endl;
  153. if( ! d->attached )
  154. {
  155. assert( d->kserver );
  156. if( ( samplingRate < 500 || samplingRate > 2000000 )
  157. || ( channels != 1 && channels != 2 ) || ( bits != 8 && bits != 16 ) )
  158. {
  159. kdWarning( 400 ) << "invalid stream parameters: rate=" << samplingRate << ", " << bits << " bit, " << channels << " channels\n";
  160. }
  161. else
  162. {
  163. d->convert.samplingRate( samplingRate );
  164. d->convert.channels( channels );
  165. d->convert.bits( bits );
  166. Arts::connect( d->effectStack, d->convert );
  167. d->receiver_base = new KByteSoundReceiver( samplingRate, bits, channels, d->title.local8Bit() );
  168. d->receiver = Arts::ByteSoundReceiver::_from_base( d->receiver_base );
  169. connect( d->receiver_base, TQT_SIGNAL( data( const char *, unsigned int ) ),
  170. TQT_SLOT( slotData( const char *, unsigned int ) ) );
  171. Arts::connect( d->convert, "outdata", d->receiver, "indata" );
  172. d->convert.start();
  173. d->receiver.start();
  174. //### needed?
  175. Arts::Dispatcher::the()->ioManager()->processOneEvent( false );
  176. d->attached = true;
  177. emit running( true );
  178. }
  179. }
  180. }
  181. void KAudioRecordStream::flush()
  182. {
  183. kdDebug( 400 ) << k_funcinfo << endl;
  184. d->inqueue.clear();
  185. }
  186. void KAudioRecordStream::slotRestartedServer() { }
  187. void KAudioRecordStream::slotData( const char * contents, unsigned int size )
  188. {
  189. //kdDebug( 400 ) << k_funcinfo << endl;
  190. TQByteArray * bytearray = new TQByteArray( size );
  191. // copy the contents to the bytearray
  192. // this has to be deleted later
  193. bytearray->duplicate( contents, size );
  194. if( d->polling )
  195. {
  196. kdDebug( 400 ) << "enqueue the data\n";
  197. d->inqueue.enqueue( bytearray );
  198. }
  199. else
  200. {
  201. //kdDebug( 400 ) << "emit the data\n";
  202. emit data( *bytearray );
  203. //kdDebug( 400 ) << "delete the data\n";
  204. delete bytearray;
  205. }
  206. }
  207. ////////////////////////////////////////
  208. // ---*--- KByteSoundReceiver ---*--- //
  209. ////////////////////////////////////////
  210. KByteSoundReceiver::KByteSoundReceiver( int rate, int bits, int channels, const char * title )
  211. : _samplingRate( rate )
  212. , _bits( bits )
  213. , _channels( channels )
  214. , _title( title )
  215. {
  216. }
  217. KByteSoundReceiver::~KByteSoundReceiver()
  218. {
  219. }
  220. void KByteSoundReceiver::process_indata( Arts::DataPacket<Arts::mcopbyte> * inpacket )
  221. {
  222. //kdDebug( 400 ) << k_funcinfo << " size of the packet: " << inpacket->size << endl;
  223. emit data( (char *)inpacket->contents, inpacket->size );
  224. inpacket->processed();
  225. }
  226. // vim:sw=4:ts=4
  227. #include "kaudiorecordstream.moc"
  228. #include "kaudiorecordstream_p.moc"