static bool
initializer()
{
- init_driver_manager().register_audio_output("sink", Driver::AudioSink);
+ driver_manager()->register_audio_output("sink", Driver::AudioSink);
return true;
}
static const bool initialized = initializer();
static void drivers()
{
- driver_manager.print(cout);
+ driver_manager()->print(cout);
}
static void help(const char * name)
Interfaces i;
const char * driver;
const char * parameter;
+ const DriverManager * const m = driver_manager();
if ( argc > 1 ) {
while ((command = getopt_long(argc, argv, "c:dhi:k:l:m:M:n:p:r:t:x:", options, NULL)) != -1) {
switch (command) {
case 'c':
- i.codec = driver_manager.codec(driver, parameter);
+ i.codec = m->codec(driver, parameter);
break;
case 'd':
drivers();
i.fill_in();
break;
case 'f':
- i.framer = driver_manager.framer(driver, parameter);
+ i.framer = m->framer(driver, parameter);
break;
case 'g':
- i.user_interface = driver_manager.user_interface(driver, parameter, &i);
+ i.user_interface = m->user_interface(driver, parameter, &i);
break;
default:
case 'h':
exit(1);
break;
case 'k':
- i.keying_output = driver_manager.keying_output(driver, parameter);
+ i.keying_output = m->keying_output(driver, parameter);
break;
case 'l':
- i.loudspeaker = driver_manager.audio_output(driver, parameter);
+ i.loudspeaker = m->audio_output(driver, parameter);
break;
case 'm':
- i.microphone = driver_manager.audio_input(driver, parameter);
+ i.microphone = m->audio_input(driver, parameter);
break;
case 'M':
- i.modem = driver_manager.modem(driver, parameter);
+ i.modem = m->modem(driver, parameter);
break;
case 'p':
- i.ptt_input_digital = driver_manager.ptt_input(driver, parameter);
+ i.ptt_input_digital = m->ptt_input(driver, parameter);
break;
case 'P':
- i.ptt_input_ssb = driver_manager.ptt_input(driver, parameter);
+ i.ptt_input_ssb = m->ptt_input(driver, parameter);
break;
case 'r':
- i.receiver = driver_manager.audio_input(driver, parameter);
+ i.receiver = m->audio_input(driver, parameter);
break;
case 't':
- i.transmitter = driver_manager.audio_output(driver, parameter);
+ i.transmitter = m->audio_output(driver, parameter);
break;
case 'x':
- i.text_input = driver_manager.text_input(driver, parameter);
+ i.text_input = m->text_input(driver, parameter);
break;
case 'C':
i.fill_in();
static bool
initializer()
{
- init_driver_manager().register_user_interface("blank-panel", Driver::BlankPanel);
+ driver_manager()->register_user_interface("blank-panel", Driver::BlankPanel);
return true;
}
static const bool initialized = initializer();
static bool
initializer()
{
- init_driver_manager().register_codec("no-op", Driver::CodecNoOp);
+ driver_manager()->register_codec("no-op", Driver::CodecNoOp);
return true;
}
static const bool initialized = initializer();
static std::ostream &
enumerate(std::ostream & stream, const DriverList * list)
{
+ if ( list == 0 )
+ return stream;
+
while ( list->key ) {
stream << list->key << ' ';
list++;
{
DriverList * next;
- if ( list ) {
+ if ( *list ) {
next = *list;
while ( next->key )
next++;
}
AudioInput *
- DriverManager::audio_input(const char * driver, const char * parameter)
+ DriverManager::audio_input(const char * driver, const char * parameter) const
{
return (AudioInput *)pick(driver, parameter, audio_input_drivers);
}
AudioOutput *
- DriverManager::audio_output(const char * driver, const char * parameter)
+ DriverManager::audio_output(const char * driver, const char * parameter) const
{
return (AudioOutput *)pick(driver, parameter, audio_output_drivers);
}
Codec *
- DriverManager::codec(const char * driver, const char * parameter)
+ DriverManager::codec(const char * driver, const char * parameter) const
{
return (Codec *)pick(driver, parameter, codecs);
}
Framer *
- DriverManager::framer(const char * driver, const char * parameter)
+ DriverManager::framer(const char * driver, const char * parameter) const
{
return (Framer *)pick(driver, parameter, framers);
}
KeyingOutput *
- DriverManager::keying_output(const char * driver, const char * parameter)
+ DriverManager::keying_output(const char * driver, const char * parameter) const
{
return (KeyingOutput *)pick(driver, parameter, keying_output_drivers);
}
Modem *
- DriverManager::modem(const char * driver, const char * parameter)
+ DriverManager::modem(const char * driver, const char * parameter) const
{
return (Modem *)pick(driver, parameter, modems);
}
PTTInput *
- DriverManager::ptt_input(const char * driver, const char * parameter)
+ DriverManager::ptt_input(const char * driver, const char * parameter) const
{
return (PTTInput *)pick(driver, parameter, ptt_input_drivers);
}
TextInput *
- DriverManager::text_input(const char * driver, const char * parameter)
+ DriverManager::text_input(const char * driver, const char * parameter) const
{
return (TextInput *)pick(driver, parameter, text_input_drivers);
}
UserInterface *
- DriverManager::user_interface(const char * driver, const char * parameter, Interfaces * interfaces)
+ DriverManager::user_interface(const char * driver, const char * parameter, Interfaces * interfaces) const
{
return (UserInterface *)pick(driver, parameter, user_interface_drivers);
}
place(driver, (base_creator)creator, &user_interface_drivers);
}
- /// Automatic initializer for the driver manager.
- /// This has to be a function to get around the static initalization order
- /// problem.
- DriverManager &
- init_driver_manager()
+ DriverManager * const
+ driver_manager()
{
- static DriverManager manager;
- return manager;
+ static DriverManager * const d(new DriverManager());
+ return d;
}
-
- /// Global reference to the driver manager instance.
- DriverManager & driver_manager = init_driver_manager();
}
/// Instantiate an AudioInput driver.
/// \param driver The name of the driver.
/// \param parameters Driver-specific configuration parameters.
- AudioInput * audio_input(const char * driver, const char * parameters);
+ AudioInput * audio_input(const char * driver, const char * parameters) const;
/// Instantiate an AudioOutput driver.
/// \param driver The name of the driver.
/// \param parameters Driver-specific configuration parameters.
- AudioOutput * audio_output(const char * driver, const char * parameters);
+ AudioOutput * audio_output(const char * driver, const char * parameters) const;
/// Instantiate a Codec.
/// \param driver The name of the driver.
/// \param parameters Driver-specific configuration parameters.
- Codec * codec(const char * driver, const char * parameters);
+ Codec * codec(const char * driver, const char * parameters) const;
/// Instantiate a Framer.
/// \param driver The name of the driver.
/// \param parameters Driver-specific configuration parameters.
- Framer * framer(const char * driver, const char * parameters);
+ Framer * framer(const char * driver, const char * parameters) const;
/// Instantiate a Keying driver.
/// \param driver The name of the driver.
/// \param parameters Driver-specific configuration parameters.
- KeyingOutput * keying_output(const char * driver, const char * parameters);
+ KeyingOutput * keying_output(const char * driver, const char * parameters) const;
/// Instantiate a softmodem.
/// \param driver The name of the driver.
/// \param parameters Driver-specific configuration parameters.
- Modem * modem(const char * driver, const char * parameters);
+ Modem * modem(const char * driver, const char * parameters) const;
/// Instantiate a PTT input driver.
/// \param driver The name of the driver.
/// \param parameters Driver-specific configuration parameters.
- PTTInput * ptt_input(const char * driver, const char * parameters);
+ PTTInput * ptt_input(const char * driver, const char * parameters) const;
/// Instantiate a text input driver.
/// \param driver The name of the driver.
/// \param parameters Driver-specific configuration parameters.
- TextInput * text_input(const char * driver, const char * parameters);
+ TextInput * text_input(const char * driver, const char * parameters) const;
/// Instantiate a user interface driver.
/// \param driver The name of the driver.
/// \param parameters Driver-specific configuration parameters.
/// \param interfaces Interfaces object used to hold all of the
/// current device driver instances.
- UserInterface * user_interface(const char * driver, const char * parameters, Interfaces * interfaces);
+ UserInterface * user_interface(const char * driver, const char * parameters, Interfaces * interfaces) const;
/// Register an audio input driver.
/// \param driver The name of the driver.
return d.print(stream);
}
-
/// Global reference to the driver manager.
- extern DriverManager & driver_manager;
-
- /// Return a reference to the driver manager instance.
- /// This is a function because it is called in static initializers.
- extern DriverManager & init_driver_manager();
+ extern DriverManager * const driver_manager();
}
--- /dev/null
+/// The Protocol Framer base class.
+
+#include "drivers.h"
+
+namespace FreeDV {
+ Framer::Framer(const char * name, const char * parameters)
+ : Base(name, parameters)
+ {
+ }
+
+ Framer::~Framer()
+ {
+ }
+}
--- /dev/null
+/// The No-Op Framer, for digital voice that is not framed in a protocol.
+/// FreeDV would be the obvious example.
+
+#include "drivers.h"
+#include <string.h>
+
+namespace FreeDV {
+ /// Framer "no-op", just copies its input to its output.
+ class FramerNoOp : public ::FreeDV::Framer {
+ public:
+ /// Create a framer instance.
+ /// \param name Name of the driver. This is expected to be a single
+ /// constant static string per driver class.
+ /// \param parameters Driver-specific configuration parameters.
+ FramerNoOp(const char * parameters);
+
+ /// Destroy a framer instance.
+ virtual ~FramerNoOp();
+
+ /// Return the maximum number of data bytes expected to store a wrapped
+ /// protocol frame. The result is invariant for a particular configuration
+ /// which may include such things as length of addresses and protocol
+ /// options.
+ /// \return The maximum number of data bytes expected to store a wrapped
+ /// protocol frame.
+ /// frame.
+ virtual std::size_t const
+ max_wrapped_bytes_per_frame() const;
+
+ /// Return the maximum number of data bytes expected to store the unwrapped
+ /// codec data. The result is invariant for a particular configuration.
+ /// \return The maximum number of data bytes expected to store the unwrapped
+ /// codec data.
+ /// frame.
+ virtual std::size_t const
+ max_unwrapped_bytes_per_frame() const;
+
+ /// Return the minimum number of data bytes expected to store the unwrapped
+ /// codec data. The result is invariant for a particular configuration.
+ /// \return The minimum number of data bytes expected to store the unwrapped
+ /// codec data.
+ /// frame.
+ virtual std::size_t const
+ min_unwrapped_bytes_per_frame() const;
+
+ /// Return the minimum number of data bytes expected to store a wrapped
+ /// protocol frame. The result is invariant for a particular configuration
+ /// which may include such things as length of addresses and protocol
+ /// options.
+ /// \return The minimum number of data bytes expected to store a wrapped
+ /// protocol frame.
+ /// frame.
+ virtual std::size_t const
+ min_wrapped_bytes_per_frame() const;
+
+ /// Decode from modem data to codec frames, removing the wrapping protocol.
+ /// \param i The encoded data, in an array of unsigned 8-bit integers.
+ /// \param o The array of codec data after decoding, in an array
+ /// of unsigned 8-bit integers.
+ /// \param input_length When called: The number of bytes of data that are
+ /// available to be unwrap. On return: the number of bytes of data
+ /// that were consumed.
+ /// \param output_length The number of codec data bytes that can be
+ /// unwrapped.
+ /// \return The number of data bytes that were actually decoded.
+ virtual std::size_t
+ unwrap(const std::uint8_t * i,
+ std::uint8_t * o,
+ std::size_t * input_length,
+ std::size_t output_length);
+
+ /// Wrap codec data bytes in a protocol for transmission through the modem.
+ /// \param i The array of data bytes to be encoded, in an array
+ /// of unsigned 8-bit integers.
+ /// \param o The encoded data, in an array of unsigned 8-bit integers.
+ /// \param input_length The number of data bytes to be wrapped.
+ /// \param output_length The number of data bytes available to store the
+ /// wrapped data.
+ /// \return The number of std::uint8_t elements in the wrapped array.
+ virtual std::size_t
+ wrap(
+ const std::uint8_t * i,
+ std::uint8_t * o,
+ std::size_t * input_length,
+ std::size_t output_length);
+ };
+
+ FramerNoOp::FramerNoOp(const char * parameters)
+ : Framer("no-op", parameters)
+ {
+ }
+
+ FramerNoOp::~FramerNoOp()
+ {
+ }
+
+ std::size_t const
+ FramerNoOp::max_wrapped_bytes_per_frame() const
+ {
+ return 1;
+ }
+
+ std::size_t const
+ FramerNoOp::max_unwrapped_bytes_per_frame() const
+ {
+ return 1;
+ }
+
+ std::size_t const
+ FramerNoOp::min_unwrapped_bytes_per_frame() const
+ {
+ return 1;
+ }
+
+ std::size_t const
+ FramerNoOp::min_wrapped_bytes_per_frame() const
+ {
+ return 1;
+ }
+
+ std::size_t
+ FramerNoOp::unwrap(const std::uint8_t * i,
+ std::uint8_t * o,
+ std::size_t * input_length,
+ std::size_t output_length)
+ {
+ const std::size_t length = std::min(*input_length, output_length);
+ memcpy(o, i, length);
+ *input_length = length;
+ return length;
+ }
+
+ std::size_t
+ FramerNoOp::wrap(
+ const std::uint8_t * i,
+ std::uint8_t * o,
+ std::size_t * input_length,
+ std::size_t output_length)
+ {
+ const std::size_t length = std::min(*input_length, output_length);
+ memcpy(o, i, length);
+ *input_length = length;
+ return length;
+ }
+
+ Framer *
+ Driver::FramerNoOp(const char * parameter)
+ {
+ return new ::FreeDV::FramerNoOp(parameter);
+ }
+
+#ifndef NO_INITIALIZERS
+ static bool
+ initializer()
+ {
+ driver_manager()->register_framer("no-op", Driver::FramerNoOp);
+ return true;
+ }
+ static const bool initialized = initializer();
+#endif
+}
static bool
initializer()
{
- init_driver_manager().register_keying_output("sink", Driver::KeyingSink);
+ driver_manager()->register_keying_output("sink", Driver::KeyingSink);
return true;
}
static const bool initialized = initializer();
static bool
initializer()
{
- init_driver_manager().register_codec("no-op", Driver::CodecNoOp);
+ driver_manager()->register_codec("no-op", Driver::CodecNoOp);
return true;
}
static const bool initialized = initializer();
static bool
initializer()
{
- init_driver_manager().register_modem("no-op", Driver::ModemNoOp);
+ driver_manager()->register_modem("no-op", Driver::ModemNoOp);
return true;
}
static const bool initialized = initializer();
static bool
initializer()
{
- init_driver_manager().register_ptt_input("constant", Driver::PTTConstant);
+ driver_manager()->register_ptt_input("constant", Driver::PTTConstant);
return true;
}
static const bool initialized = initializer();
static bool
initializer()
{
- init_driver_manager().register_text_input("constant", Driver::TextConstant);
+ driver_manager()->register_text_input("constant", Driver::TextConstant);
return true;
}
static const bool initialized = initializer();
static bool
initializer()
{
- init_driver_manager().register_audio_input("tone", Driver::Tone);
+ driver_manager()->register_audio_input("tone", Driver::Tone);
return true;
}
static const bool initialized = initializer();