[prev in list] [next in list] [prev in thread] [next in thread]
List: kde-multimedia
Subject: Re: recording stream
From: Stefan Westerfeld <stefan () space ! twc ! de>
Date: 2001-10-26 16:39:44
[Download RAW message or body]
Hi!
On Sun, Oct 21, 2001 at 09:29:56PM +0200, Matthias Kretz wrote:
> I finally got recording from aRts working. I did a lot of stuff so let me sum
> up:
>
> - A play stream works using the ByteSoundProducer interface. Therefor I
> created a ByteSoundReceiver.
Good.
> - Now the ByteSoundProducer was attached to the soundserver using
> SimpleSoundServer->attach(ByteSoundProducer). To make it usable for me I
> created another interface ByteSoundStream that is used for both the
> ByteSoundProducer and ByteSoundReceiver. So I changed the method to
> SimpleSoundServer->attach(ByteSoundStream). This is, of course, not binary
> compatible. I don't know about wire compatibility (I only know that noatun
> 1.2.0 (KDE 2.2) still works).
> Uhmm, while testing for WC I found out that artscat and artsdsp (from KDE
> 2.2) won't work with my changes. But it works if I don't use the
> ByteSoundStream interface but simply SynthModule. So the method would be
> SimpleSoundServer->attach(SynthModule). I guess this is the better way, and
> probably the more flexible, too. If I'm right WC will be preserved this way.
Yes, it /should/ be preserved that way. It's not exactly pretty, though,
because we'll be stuck with this completely underspecified type-unsafe attach
method. Besides, changing signatures of existing methods is at best bad for
compatibility with existing clients, at worst (with a correct MCOP
implementation that compares the signatures (see object.cc:907)) it will not
work.
I think adding new methods like this:
void attachRecorder(...);
void detachRecorder(...);
would be better. It's slightly asymmetric then as well, but I think it is the
best possible hack.
> - RecordStreamJob: The same as the PlaySreamJob, only using an
> AudioToByteStream instead of ByteToAudioStream.
Ok.
> - artsdump: The same as artscat for dumping a ByteStream from aRts to a file
> or stdout.
It needs to be called artsrec (or artsmon, if it captures the artsd overall
output), to correspond the esd name for this. I think we should make switching
easy.
> - The AudioToByteStream interface was another hurdle on the way. If I read
> the code correctly the Resampler isn't able to convert from an aRts input to
> a bytestream, and also can't be fitted to do that easily. So I wrote my own
> resampler in this class. I'm not sure whether this is the right way to go and
> I'm open for better ideas.
Reimplementing all resampling conversion code into artsd to a common code base
would be the better idea. I have been toying with the idea for some time now,
and have a few concrete thoughts how it should work. But it takes a week of
doing nothing else to unify all of them and get it right, I think ;). I might
be doing this together with Tim Janik and put the result into GSL when I have
time to do it.
> - Finally I worked on the artsc interface to support the new recording
> capabilities.
> In artscbackend.cc there was one class Sender that would create the
> bytestream. I copied this to a new class Stream that holds everything a
> Receiver needs as well. Receiver and Sender inherit from Stream. Now the only
> problem were the ArtsCApi methods that would have to be able to call methods
> of Sender as well as of Receiver while they only receive a void*. I tried to
> cast like this:
>
> int stream_set(arts_stream_t stream, arts_parameter_t param, int value)
> {
> SynthModule *_stream = (SynthModule *)stream;
> if( _stream->_interfaceName() == "Arts::ByteStreamProducer" )
> }
>
> But the program would just crash in _stream->_interfaceName() because
> somewhere a dangling pointer, that should be pointing to the base class, was
> being used. So I tried something else:
>
> int stream_set(arts_stream_t stream, arts_parameter_t param, int value)
> {
> Stream *_stream = (Stream *)stream;
> if( _stream->direction() == Stream::RECORDSTREAM )
>
> But now _stream would somehow (I have no clue, but gdb said so) be 0x0 when
> _stream->direction() gets called. I finally got it working by doing the
> following:
>
> int stream_set(arts_stream_t stream, arts_parameter_t param, int value)
> {
> Sender *_stream = (Sender *)stream;
> _stream->stream_set(param,value);
> }
>
> That works even if stream is a Receiver. I have a bad feeling about this, but
> this is the only way I found to get it working.
That sounds like a horrible hack. Basically, you need to make sure that you
take exactly this out of a void* which you put in. One way to ensure this
would be:
class Stream : virtual public X, virtual public Y {
public:
virtual void *castSender() { return 0; }
virtual void *castReceiver() { return 0; }
};
class Sender : virtual public B, virtual public Stream {
virtual void *castSender() { return (Sender *)this; }
};
class Receiver : virtual public C, virtual public Stream {
virtual void *castReceiver() { return (Receiver *)this; }
};
and to put always explicitely a
(Stream*)xxx;
into the arts_stream_t. You can then explicitely ask:
Sender *sender = (Stream*)(xxx)->castSender();
if(sender) sender->foo();
Receiver *receiver = (Receiver*)(xxx)->castReceiver();
if(receiver) receiver->foo();
I mean, thats just RTTI done by hand, but it will work, always. Putting
anything into a void pointer, and taking out another type is very very
dangerous. If you use single, nonvirtual interitance only, it will work,
but otherwise, it will fail badly.
Two other remarks:
* please adapt documentation where necessary:
- in the IDL file
- in the aRts handbook (kdemultimedia/doc/artsbuilder)
* (coding style): I strongly recommend that you read the "Coding Standards"
section in the aRts Handbook. Especially, I do recommend not using
long m_foo; /* wrong! ;) */
if you have an interface { attribute long foo; }, but _foo to store it,
thats done this way in all aRts, and if we keep it consistent, that would
be nice. ;)
Especially, I don't see why
- return packetCount * packetCapacity;
+ return m_packetCount * m_packetCapacity;
is very useful, unless you convince me that it should be changed
everywhere in all aRts sources for all times ;). It's like the 4 spaces
tabs thing - better that always than something else sometimes.
Random changes between the two styles just make CVS logs harder to read.
Otherwise, the changes look quite nice.
Cu... Stefan
--
-* Stefan Westerfeld, stefan@space.twc.de (PGP!), Hamburg/Germany
KDE Developer, project infos at http://space.twc.de/~stefan/kde *-
_______________________________________________
kde-multimedia mailing list
kde-multimedia@mail.kde.org
http://mail.kde.org/mailman/listinfo/kde-multimedia
[prev in list] [next in list] [prev in thread] [next in thread]
Configure |
About |
News |
Add a list |
Sponsored by KoreLogic