Hi TimurTimur
Doumler wrote on 18.06.19 16:29:
4.
There seem to be deeper portability issues with the implementation
defined types leaking and providing setters for them. What kind of
operations would be possible on such a type, how could it be set to a
different value than one previously received in a portable way. Why not
provide a strong type wrapper (e.g., for sample_rate_t and
buffer_size_t) with defined operations instead, so that it is clear,
what are supported. Are set/get really the right API, or is a
"Change/AdjustBy" a better API. I do not know the domain, so that makes
me unsure, but obtaining a value, doing arbitrary arithmetic, then
setting a value seems not a good abstraction.
See above. And no,
change/adjustBy is not an appropriate API here. The way you set up audio
devices is like this:
- you acquire a handle to it
- you negotiate
what settings you can use
- then you “start” the
device, at which time it starts asynchronously processing stuff. it’s
“running” now.
- you can’t change any settings
anymore on a “running” device. To do that, it has to be stopped and
restarted.
This
seems to be a stateful interface. While that is typical, I wonder if
this must be implemented in a single type. Why not split the C++ part in
a preparation type that does all the negotiation and then acts as a
factory for the device that operates. If both use the same native
handle, you can make the
audio_processing_device
getMeTheRealAudioThing() && ;
a rvalue-ref qualified
member to denote that the "AudioDeviceConfigurator" is no longer useful,
because it passed out its handle and the
So there are two
things lurking in audio_device:
1. audio_device_configurator
2.
audio_processing_device
Where the roughly first half of the
member functions are part of the audio_device_configurator and the
second half part of the audio_processing_device.
You should not
carry on the problems of a stateful underlying system API to your users.
Clearly make the distinction.
Drawing the actual state diagram
of the lifetime of a system audio device can help to figure out where to
make the cut and figure out, if there are even more things lurking,
such as the interdependency of sample rate and buffer size. May be that
forms actually a combined abstraction (audio_performance_params?). Then
something like
audio_device_configurator::canHandle(audio_performance_params) can be
used to allow to check before trying to set parameters and then one can
guarantee (modulo races) that the combination works. With such an
abstraction, one might even be giving a "best effort" mechanism, e.g. if
I ask for 7.1 channels I get mono 9.6kbit sampling on my radio clock on
the nightstand instead.
Regards
Peter.