From: bruceperens Date: Thu, 16 Jan 2014 03:13:48 +0000 (+0000) Subject: Add event handling, write doxygen documentation into drivers.h . X-Git-Url: http://git.whiteaudio.com/gitweb/?a=commitdiff_plain;h=e8e2d14dd5e307357994d3ce268871c41766a0f2;p=freetel-svn-tracking.git Add event handling, write doxygen documentation into drivers.h . git-svn-id: https://svn.code.sf.net/p/freetel/code@1354 01035d8c-6547-0410-b346-abe4f91aad63 --- diff --git a/freedv-server/source/audio_input.cpp b/freedv-server/source/audio_input.cpp index 2f1b2087..d8e1ce17 100644 --- a/freedv-server/source/audio_input.cpp +++ b/freedv-server/source/audio_input.cpp @@ -1,7 +1,7 @@ #include "drivers.h" namespace FreeDV { - AudioInput::AudioInput() + AudioInput::AudioInput(const char * parameters) { } @@ -9,8 +9,8 @@ namespace FreeDV { { } - bool - AudioInput::captive() + bool const + AudioInput::captive() const { return false; } diff --git a/freedv-server/source/audio_output.cpp b/freedv-server/source/audio_output.cpp index 27ed71a6..d34ed8a6 100644 --- a/freedv-server/source/audio_output.cpp +++ b/freedv-server/source/audio_output.cpp @@ -1,7 +1,7 @@ #include "drivers.h" namespace FreeDV { - AudioOutput::AudioOutput() + AudioOutput::AudioOutput(const char * parameters) { } @@ -9,8 +9,8 @@ namespace FreeDV { { } - bool - AudioOutput::captive() + bool const + AudioOutput::captive() const { return false; } diff --git a/freedv-server/source/audio_sink.cpp b/freedv-server/source/audio_sink.cpp index db10e59c..0410d578 100644 --- a/freedv-server/source/audio_sink.cpp +++ b/freedv-server/source/audio_sink.cpp @@ -6,7 +6,7 @@ namespace FreeDV { class AudioSink : public AudioOutput { public: - AudioSink(const char *); + AudioSink(const char * parameters); ~AudioSink(); // Get the current audio level, normalized to the range of 0.0 to 1.0. @@ -16,10 +16,12 @@ namespace FreeDV { float level(float value); // Write audio into the "short" type. - int write_short(short * array, int length); + std::size_t + write16(const int16_t * array, std::size_t length); }; - AudioSink::AudioSink(const char *) + AudioSink::AudioSink(const char * parameters) + : AudioOutput(parameters) { } @@ -40,8 +42,8 @@ namespace FreeDV { } // Write audio into the "short" type. - int - AudioSink::write_short(short * array, int length) + std::size_t + AudioSink::write16(const int16_t * array, std::size_t length) { return 0; } diff --git a/freedv-server/source/big_main.cpp b/freedv-server/source/big_main.cpp index 25e108ef..59cd0fe1 100644 --- a/freedv-server/source/big_main.cpp +++ b/freedv-server/source/big_main.cpp @@ -1,13 +1,13 @@ #ifndef NO_INITIALIZERS /* * This is the main program for applications that are not space-limited. - * Any application that is space limited should have its own main that wires drivers to the - * Interfaces class without using DriverManager. Thus, you can get rid of all of the STL - * template use, etc. + * Any application that is space limited should have its own main that + * wires drivers to the Interfaces class without using DriverManager. + * Thus, you can get rid of all of the STL template use, etc. * - * For the sake of correctness and optimization, I have written whatever I can to be without - * side-effects, a style inherited from functional programming. Thus, the excessive use of - * "const". - Bruce + * For the sake of correctness and optimization, I have written whatever I + * can to be without side-effects, a style inherited from functional programming. + * Thus, the excessive use of "const". - Bruce */ #include #include @@ -34,28 +34,35 @@ static void help(const char * name) { static const char message[] = " [options]\n" - "\n\tWhere options are these flags:\n\n" - "\t\t--codec or -c\t\tSelect the voice codec.\n" - "\t\t--drivers or -d\t\tPrint a list of the available device drivers.\n" - "\t\t--help or -h\t\tPrint this message.\n" - "\t\t--interface or -i\tSelect the user-interface (graphical or otherwise).\n" - "\t\t--keying or -k\t\tSelect the transmitter keying interface.\n" - "\t\t--loudspeaker or -l\tSelect the operator audio output interface.\n" - "\t\t--microphone or -m\tSelect the operator audio input interface.\n" - "\t\t--modem or -M\t\tSelect RF modem.\n" - "\t\t--ptt or -p\t\tSelect the push-to-talk input interface.\n" - "\t\t--receiver or -r\tSelect the interface for audio input from the receiver.\n" - "\t\t--text or -x\t\tSelect the interface for text to be transmitted.\n" - "\t\t--transmitter or -t\tSelect the interface for audio output to the transmitter.\n" - "\n\tLong flags with parameters are in the form of --=\n" - "\tShort flags with parameters are in the form of - \n" - "\n\tFor example, both of these flags have the same effect:\n" - "\t\t-M codec2:1600\n" - "\t\t--modem=codec2:1600\n" - "\n\tAll of the flags except for -h or --help must have a \":\" argument\n" - "\twhere is the name of a device driver and is specific to the driver.\n" - "\n\tExample:\n" - "\t\t --loudspeaker=alsa:default\n" + "\nWhere options are these flags:\n\n" + "--codec or -c\t\tSelect the voice codec.\n" + "--drivers or -d\t\tPrint a list of the available device drivers.\n" + "--help or -h\t\tPrint this message.\n" + "--interface or -i\tSelect the user-interface (graphical or otherwise).\n" + "--keying or -k\t\tSelect the transmitter keying interface.\n" + "--loudspeaker or -l\tSelect the operator audio output interface.\n" + "--microphone or -m\tSelect the operator audio input interface.\n" + "--modem or -M\t\tSelect RF modem.\n" + "--ptt-digital or -p\tSelect the push-to-talk input interface for " + "digital voice.\n" + "--ptt-ssb or -P\t\tSelect the push-to-talk input interface for " + "SSB.\n" + "--receiver or -r\tSelect the interface for audio input from the " + "receiver.\n" + "--text or -x\t\tSelect the interface for text to be transmitted.\n" + "--transmitter or -t\tSelect the interface for audio output to the " + "transmitter.\n" + "\nLong flags with parameters are in the form of --=\n" + "Short flags with parameters are in the form of - \n" + "\nFor example, both of these flags have the same effect:\n" + "\t-M codec2:1600\n" + "\t--modem=codec2:1600\n" + "\nAll of the flags except for -h or --help must have a " + "\":\"\n" + "argument, where is the name of a device driver and is\n" + "specific to the driver.\n" + "\nExample:\n" + "\t --loudspeaker=alsa:default\n" ; cerr << "\nUsage: " << name << message << endl; } @@ -69,7 +76,8 @@ static const struct option options[] = { { "loudspeaker", required_argument, 0, 'l' }, { "microphone", required_argument, 0, 'm' }, { "modem", required_argument, 0, 'M' }, - { "ptt", required_argument, 0, 'p' }, + { "ptt-digital", required_argument, 0, 'p' }, + { "ptt-ssb", required_argument, 0, 'P' }, { "receiver", required_argument, 0, 'r' }, { "text", required_argument, 0, 'x' }, { "transmitter", required_argument, 0, 't' }, @@ -92,6 +100,7 @@ main(int argc, char * * argv) case 'l': case 'm': case 'p': + case 'P': case 'r': case 't': case 'x': @@ -121,7 +130,7 @@ main(int argc, char * * argv) exit(1); break; case 'k': - i.keying = driver_manager.keying(driver, parameter); + i.keying_output = driver_manager.keying_output(driver, parameter); break; case 'l': i.loudspeaker = driver_manager.audio_output(driver, parameter); @@ -133,7 +142,10 @@ main(int argc, char * * argv) i.modem = driver_manager.modem(driver, parameter); break; case 'p': - i.ptt = driver_manager.ptt_input(driver, parameter); + i.ptt_input_digital = driver_manager.ptt_input(driver, parameter); + break; + case 'P': + i.ptt_input_ssb = driver_manager.ptt_input(driver, parameter); break; case 'r': i.receiver = driver_manager.audio_input(driver, parameter); diff --git a/freedv-server/source/blank_panel.cpp b/freedv-server/source/blank_panel.cpp index 5bb284d0..b2da0171 100644 --- a/freedv-server/source/blank_panel.cpp +++ b/freedv-server/source/blank_panel.cpp @@ -1,15 +1,15 @@ #include "drivers.h" -// This is a test driver that provides tones. namespace FreeDV { class BlankPanel : public UserInterface { public: - BlankPanel(const char * parameter); + BlankPanel(const char * parameter, Interfaces * interfaces); virtual ~BlankPanel(); }; - BlankPanel::BlankPanel(const char * parameter) + BlankPanel::BlankPanel(const char * parameter, Interfaces * interfaces) + : UserInterface(parameter, interfaces) { } @@ -19,9 +19,9 @@ namespace FreeDV { #ifndef NO_INITIALIZERS static UserInterface * - creator(const char * parameter) + creator(const char * parameter, Interfaces * interfaces) { - return new BlankPanel(parameter); + return new BlankPanel(parameter, interfaces); } static bool diff --git a/freedv-server/source/codec.cpp b/freedv-server/source/codec.cpp index 78413ed2..2ef80060 100644 --- a/freedv-server/source/codec.cpp +++ b/freedv-server/source/codec.cpp @@ -1,7 +1,7 @@ #include "drivers.h" namespace FreeDV { - Codec::Codec() + Codec::Codec(const char * parameters) { } diff --git a/freedv-server/source/codec_noop.cpp b/freedv-server/source/codec_noop.cpp index dc9da954..74dab64e 100644 --- a/freedv-server/source/codec_noop.cpp +++ b/freedv-server/source/codec_noop.cpp @@ -8,11 +8,54 @@ namespace FreeDV { CodecNoOp(const char *); ~CodecNoOp(); - void key(bool value); + /// Encode from an array of the signed 16-bit integer type to an + /// array of the unsigned 8-bit integer type (this is usually + /// implemented as unsigned char). + /// \param i The array of audio samples to be encoded, in an array + /// of signed 16-bit integers. + /// \param o The encoded data, in an array of unsigned 8-bit integers. + /// \return The number of uint8_t elements in the encoded array. + virtual std::size_t + encode16(const int16_t * i, uint8_t * o, \ + std::size_t length); + + /// Return the size of uint8_t array necessary to encode the given + /// number of audio samples. Sample rate is 8K samples/second. + /// The result is invariant for a given input. + /// \param sample_count The number of audio samples to encode. + /// Must be a multiple of frame_size(). + /// \return The size of uint8_t array necessary to encode the given + /// number of audio samples. + virtual std::size_t const + encoded_buffer_size(std::size_t sample_count) const; + + /// Return the duration of a frame in milliseconds. + /// \return The duration of a frame in milliseconds. + virtual int const + frame_duration() const; + + /// Return the number of audio samples necessary to decode the given + /// encoded buffer size. Sample rate is 8K samples/second. + /// \param buffer_size is the size of the encoded buffer. It must + /// encode a multiple of frame_size() audio samples. + /// \return The number of audio samples necessary to decode the given + /// encoded buffer size. The result is invariant for a given input. + virtual std::size_t const + samples_per_buffer(std::size_t buffer_size) const; + + /// Return the number of audio samples expected to create a codec + /// frame. Samples provided to encode_buffer_size must be a multiple + /// of this value. Sample rate is 8K samples/second. + /// The result for a particular input is invariant. + /// \return The number of audio samples expected to create a codec + /// frame. + virtual std::size_t const + samples_per_frame() const; }; - CodecNoOp::CodecNoOp(const char *) + CodecNoOp::CodecNoOp(const char * parameters) + : Codec(parameters) { } @@ -20,6 +63,37 @@ namespace FreeDV { { } + std::size_t + CodecNoOp::encode16(const int16_t * i, uint8_t * o, std::size_t length) + { + return 0; + } + + std::size_t const + CodecNoOp::encoded_buffer_size(std::size_t sample_count) const + { + return 0; + } + + int const + CodecNoOp::frame_duration() const + { + return 0; + } + + std::size_t const + CodecNoOp::samples_per_buffer(std::size_t buffer_size) const + { + return 0; + } + + + std::size_t const + CodecNoOp::samples_per_frame() const + { + return 0; + } + #ifndef NO_INITIALIZERS static Codec * creator(const char * parameter) diff --git a/freedv-server/source/driver_manager.cpp b/freedv-server/source/driver_manager.cpp index 81b81682..f6442267 100644 --- a/freedv-server/source/driver_manager.cpp +++ b/freedv-server/source/driver_manager.cpp @@ -1,6 +1,7 @@ #ifndef NO_INITIALIZERS /* - * Don't use DriverManager and main.cpp in space-limited applications. STL stuff it uses is too large. + * Don't use DriverManager and main.cpp in space-limited applications. + * STL stuff it uses is too large. */ #include #include "drivers.h" @@ -35,7 +36,7 @@ namespace FreeDV { s << i->first << " "; s << endl; s << "Keying: "; - for (auto i = keying_drivers.begin(); i != keying_drivers.end(); i++ ) + for (auto i = keying_output_drivers.begin(); i != keying_output_drivers.end(); i++ ) s << i->first << " "; s << endl; s << "Modem: "; @@ -84,9 +85,9 @@ namespace FreeDV { } Keying * - DriverManager::keying(const char * driver, const char * parameter) + DriverManager::keying_output(const char * driver, const char * parameter) { - Keying * (* const creator)(const char * parameter) = keying_drivers[driver]; + Keying * (* const creator)(const char * parameter) = keying_output_drivers[driver]; if(creator) return creator(parameter); @@ -128,12 +129,12 @@ namespace FreeDV { } UserInterface * - DriverManager::user_interface(const char * driver, const char * parameter) + DriverManager::user_interface(const char * driver, const char * parameter, Interfaces * interfaces) { - UserInterface * (* const creator)(const char * parameter) = user_interface_drivers[driver]; + UserInterface * (* const creator)(const char * parameters, Interfaces *) = user_interface_drivers[driver]; if(creator) - return creator(parameter); + return creator(parameter, interfaces); else return 0; } @@ -157,9 +158,9 @@ namespace FreeDV { } void - DriverManager::register_keying(const char * driver, Keying * (*creator)(const char *)) + DriverManager::register_keying_output(const char * driver, Keying * (*creator)(const char *)) { - keying_drivers[driver] = creator; + keying_output_drivers[driver] = creator; } void @@ -182,7 +183,7 @@ namespace FreeDV { } void - DriverManager::register_user_interface(const char * driver, UserInterface * (*creator)(const char *)) + DriverManager::register_user_interface(const char * driver, UserInterface * (*creator)(const char *, Interfaces *)) { user_interface_drivers[driver] = creator; } diff --git a/freedv-server/source/drivers.h b/freedv-server/source/drivers.h index 89074d87..3f91c7b7 100644 --- a/freedv-server/source/drivers.h +++ b/freedv-server/source/drivers.h @@ -1,169 +1,339 @@ -/* - * FreeDV driver interface definitions. - */ - +/// FreeDV driver interface definitions. +#include +/// Namespace used for all code in this program. namespace FreeDV { + + /// Virtual base class for audio input drivers. class AudioInput { protected: - // Create an AudioInput device instance. + /// Create an AudioInput device instance. + /// \param parameters Driver-specific configuration parameters. + AudioInput(const char * parameters); - // What shall we do about the audio rate? - - AudioInput(); + /// Destroy an AudioInput device instance. virtual ~AudioInput() = 0; public: - // Return true if this object is owned by a UserInterface object, in which case we should not - // destroy it separately. - virtual bool captive(); - - // Get the current audio level, normalized to the range of 0.0 to 1.0. + /// Return true if this object is owned by a UserInterface object. + /// In that case we should not destroy it separately. + /// The default implementation always returns false. + /// \return True if this object is owned by a UserInterface object. + /// The return value is invariant for the particular object. + virtual bool const + captive() const; + + /// Get the current audio level. + /// \return The current audio level. + /// The value is normalized to the range of 0.0 to 1.0. virtual float level() = 0; - // Set the current audio level within the range of 0.0 to 1.0. - virtual float level(float value) = 0; + /// Set the current audio level. + /// \param value The new value for the current audio level. + /// The value must be normalized within the range of 0.0 to 1.0. + virtual void level(float value) = 0; - // Read audio into the "short" type. - virtual int read_short(short * array, int length) = 0; + /// Read audio into an array of the signed 16-bit integer type. + virtual std::size_t + read16(int16_t * array, std::size_t length) = 0; }; + /// Virtual base class for audio output drivers. class AudioOutput { protected: - // Create an AudioOutput device instance. - - // What shall we do about the audio rate? + /// Create an AudioOutput device instance. + /// \param parameters Driver-specific configuration parameters. + AudioOutput(const char * parameters); - AudioOutput(); + /// Destroy an AudioOutput device instance. virtual ~AudioOutput() = 0; public: - // Return true if this object is owned by a UserInterface object, in which case we should not - // destroy it separately. - virtual bool captive(); - - // Get the current audio level, normalized to the range of 0.0 to 1.0. + /// Return true if this object is owned by a UserInterface object. + /// In that case we should not destroy it separately. + /// The default implementation always returns false. + /// \return True if this object is owned by a UserInterface object. + /// The return value is invariant for the particular object. + virtual bool const + captive() const; + + /// Get the current audio level. + /// The value is normalized to the range of 0.0 to 1.0. virtual float level() = 0; - // Set the current audio level within the range of 0.0 to 1.0. + /// Set the current audio level. + /// The value must be within the range of 0.0 to 1.0. virtual float level(float value) = 0; - // Write audio into the "short" type. - virtual int write_short(short * array, int length) = 0; + /// Write audio from an array of the signed 16-bit integer type. + virtual std::size_t + write16(const int16_t * array, std::size_t length) = 0; }; + /// Virtual base class for codecs. class Codec { protected: - // Create a codec instance. + /// Create a codec instance. + /// \param parameters Driver-specific configuration parameters. + Codec(const char * parameters); - Codec(); + /// Destroy a codec instance. virtual ~Codec() = 0; public: + /// Encode from an array of the signed 16-bit integer type to an + /// array of the unsigned 8-bit integer type (this is usually + /// implemented as unsigned char). + /// \param i The array of audio samples to be encoded, in an array + /// of signed 16-bit integers. + /// \param o The encoded data, in an array of unsigned 8-bit integers. + /// \return The number of uint8_t elements in the encoded array. + virtual std::size_t + encode16(const int16_t * i, uint8_t * o, \ + std::size_t length) = 0; + + /// Return the size of uint8_t array necessary to encode the given + /// number of audio samples. Sample rate is 8K samples/second. + /// The result is invariant for a given input. + /// \param sample_count The number of audio samples to encode. + /// Must be a multiple of frame_size(). + /// \return The size of uint8_t array necessary to encode the given + /// number of audio samples. + virtual std::size_t const + encoded_buffer_size(std::size_t sample_count) const = 0; + + /// Return the duration of a frame in milliseconds. + /// \return The duration of a frame in milliseconds. + virtual int const + frame_duration() const = 0; + + /// Return the number of audio samples necessary to decode the given + /// encoded buffer size. Sample rate is 8K samples/second. + /// \param buffer_size is the size of the encoded buffer. It must + /// encode a multiple of frame_size() audio samples. + /// \return The number of audio samples necessary to decode the given + /// encoded buffer size. The result is invariant for a given input. + virtual std::size_t const + samples_per_buffer(std::size_t buffer_size) const = 0; + + /// Return the number of audio samples expected to create a codec + /// frame. Samples provided to encode_buffer_size must be a multiple + /// of this value. Sample rate is 8K samples/second. + /// The result for a particular input is invariant. + /// \return The number of audio samples expected to create a codec + /// frame. + virtual std::size_t const + samples_per_frame() const = 0; + }; + /// Event handler class, indirects the event handler of the particular GUI + /// software or POSIX. + class EventHandler { + private: + bool do_exit; + + protected: + /// Bit field of status values for file descriptor events. + /// This is an argument to the coroutine called by monitor(). + /// This is a simplification on all of the values that POSIX + /// poll() can return. Events that aren't read or write are mapped + /// to one of those. + const unsigned int Read = 1; + const unsigned int Write = 2; + + /// Create an event handler instance. + EventHandler() + : do_exit(false) + { + } + virtual ~EventHandler() = 0; + + inline bool get_exit() { + if ( do_exit ) { + do_exit = false; + return true; + } + else + return false; + } + + /// Run one iteration of the event handler. + /// The default implementation throws std::runtime_error. + /// + /// If iterate() is not implemented in the child class, + /// the child class must implement loop(), and the child class + /// implementation of loop() must not call iterate(). + void iterate(); + + inline void set_exit() { do_exit = true; } + public: + /// Return true if this object is owned by a UserInterface object. + /// In that case we should not destroy it separately. + /// The default implementation always returns false. + /// \return True if this object is owned by a UserInterface object. + /// The return value is invariant for the particular object. + virtual bool const + captive() const; + + /// Run the event loop. + /// The default implementation iterates checking get_exit(), returning + /// if its value is true and otherwise and calling iterate(). + /// If you provide your own implementation of loop(), you must check + /// get_exit() and return from this method if its value is true. + /// If you provide your own implementation of loop(), it's your choice + /// whether or not to implement and call iterate(). + void loop(); + + /// Monitor a file descriptor in the event loop. Call a function if the + /// file descriptor is ready for I/O. + /// \param fd The file descriptor to monitor. + /// \param type A bit-field of values defined in this class, + /// indicating the kinds of events to listen for. + /// \param private_data Private data to be passed to the event + /// function. + /// \param event A coroutine to call when there is a status change + /// on the file descriptor. The arguments of the coroutine are + /// - fd: The file descriptor that has an event. + /// - type: A bit-field of FDStatus values indicating the events + /// received. + /// - private: The address of opaque data to be passed to the driver. + virtual void monitor(int fd, unsigned int type, void * private_data, + void (*event)(int fd, unsigned int type, void * private_data) + ) = 0; + + /// Remove all monitoring of the given file descriptor by the event + /// loop handler. + /// \param fd The file descriptor to be removed from monitoring. + virtual void unmonitor(int fd) = 0; + }; + + /// Radio device keying driver. class Keying { protected: - // Create an radio keying device instance. + /// Create an radio keying device instance. + /// \param parameters Driver-specific configuration parameters. + Keying(const char * parameters); - Keying(); + /// Destroy the radio keying device instance. virtual ~Keying() = 0; public: - // If true, key the transmitter. If false, unkey. + /// Key or un-key the transmitter. + /// \param value If true, key the transmitter. If false, un-key. virtual void key(bool value) = 0; }; + /// Softmodem driver. class Modem { protected: - // Create a modem instance. + /// Create a modem instance. + /// \param parameters Driver-specific configuration parameters. - Modem(); + Modem(const char * parameters); virtual ~Modem() = 0; public: }; + /// Push-to-talk input driver. class PTTInput { + private: + void (*callback)(bool); + protected: // The driver calls this member to inform FreeDV that the PTT switch value has changed. // the value is true for key-down, false for key-up. void changed(bool value); - // Create a push-to-talk switch instance. + /// Create a push-to-talk switch instance. + /// \param parameters Driver-specific configuration parameters. - PTTInput(); + PTTInput(const char * parameters); virtual ~PTTInput() = 0; public: - // Return true if this object is owned by a UserInterface object, in which case we should not - // destroy it separately. - virtual bool captive(); - + /// Return true if this object is owned by a + /// UserInterface object. In that case we should + /// not destroy it separately. + /// The default implementation always returns false. + /// \return True if this object is owned by a UserInterface object. + /// The return value is invariant for the particular object. + virtual bool const + captive() const; + + void set_callback(void (*value)(bool)); }; + /// Driver for the text message source function. class TextInput { protected: // The driver calls this member to set the text. void set(const char * text); - // Type for the text message source function. This is mostly used to set the text to a constant value. - // Create a push-to-talk switch instance. - TextInput(); + /// Create a text source instance. + /// \param parameters Driver-specific configuration parameters. + + TextInput(const char * parameters); virtual ~TextInput() = 0; public: - // Return true if this object is owned by a UserInterface object, in which case we should not - // destroy it separately. - virtual bool captive(); - + /// Return true if this object is owned by a + /// UserInterface object. In that case we should + /// not destroy it separately. + /// The default implementation always returns false. + /// \return True if this object is owned by a UserInterface object. + /// The return value is invariant for the particular object. + virtual bool const + captive() const; }; - class UserInterface { - // Generic interface to user interfaces. They may be graphical, they may be server-client interfaces, - // they may be specialized hardware devices, especially if this software is embedded. - // There must be inputs and callbacks for many things here. - // UserInterfaces may provide their own drivers for microphone, loudspeaker, TextInput, and PTT. + class Interfaces; + /// Generic base class for user interfaces. + /// They may be graphical, they may be server-client interfaces, + /// they may be specialized hardware devices, especially if this + /// software is embedded. + /// There must be inputs and callbacks for many things here. + /// UserInterfaces may provide their own drivers for microphone, + /// loudspeaker, TextInput, both forms of PTT, and EventHandler. + class UserInterface { protected: - // All of the callbacks from the user interface are implemented in the base class and declared here. - - UserInterface(); + /// Create an instance of the UserInterface object. + /// \param parameters Driver-specific configuration parameters. + /// \param interfaces An Interface object. The UserInterface object + /// may set various fields of Interface to be its own captive driver + /// objects, and they may change during operation if the user changes + /// device driver parameters. + UserInterface(const char * parameters, Interfaces * interfaces); virtual ~UserInterface() = 0; public: - // If this interface prodvides its own microphone driver, return it. Otherwise return 0. - // This is guaranteed to return the same object every time, for the lifetime of this object. - virtual AudioInput * microphone(); - - // If this interface prodvides its own loudspeaker driver, return it. Otherwise return 0. - // This is guaranteed to return the same object every time, for the lifetime of this object. - virtual AudioOutput * loudspeaker(); - - // If this interface prodvides its own text input driver, return it. Otherwise return 0. - // This is guaranteed to return the same object every time, for the lifetime of this object. - virtual TextInput * text_input(); - - // If this interface prodvides its own push-to-talk input driver, return it. Otherwise return 0. - // This is guaranteed to return the same object every time, for the lifetime of this object. - virtual PTTInput * ptt_input(); }; + /// Structure used to pass all of the drivers. Can be modified from + /// UserInterface while within the event loop, if a user changes a device + /// from the GUI. class Interfaces { public: - Interfaces() : codec(0), keying(0), loudspeaker(0), microphone(0), modem(0), ptt(0), - receiver(0), text(0), transmitter(0), user_interface(0) + Interfaces() : codec(0), event_handler(0), + keying_output(0), loudspeaker(0), microphone(0), + modem(0), ptt_input_digital(0), ptt_input_ssb(0), + receiver(0), text(0), transmitter(0), + user_interface(0) { } Codec * codec; - Keying * keying; + EventHandler * event_handler; + Keying * keying_output; AudioOutput * loudspeaker; AudioInput * microphone; Modem * modem; - PTTInput * ptt; + PTTInput * ptt_input_digital; + PTTInput * ptt_input_ssb; TextInput * text; AudioOutput * transmitter; AudioInput * receiver; @@ -175,17 +345,21 @@ namespace FreeDV { #include #include #include + +/// Namespace used for the entire program. namespace FreeDV { + /// Device driver manager. Allows for registration and enumeration of device + /// drivers. Instantiates device drivers on request. class DriverManager { private: std::map audio_input_drivers; std::map audio_output_drivers; std::map codecs; - std::map keying_drivers; + std::map keying_output_drivers; std::map modems; std::map ptt_input_drivers; std::map text_input_drivers; - std::map user_interface_drivers; + std::map user_interface_drivers; public: DriverManager(); ~DriverManager(); @@ -195,20 +369,20 @@ namespace FreeDV { AudioInput * audio_input(const char * driver, const char * parameter); AudioOutput * audio_output(const char * driver, const char * parameter); Codec * codec(const char * driver, const char * parameter); - Keying * keying(const char * driver, const char * parameter); + Keying * keying_output(const char * driver, const char * parameter); Modem * modem(const char * driver, const char * parameter); PTTInput * ptt_input(const char * driver, const char * parameter); TextInput * text_input(const char * driver, const char * parameter); - UserInterface * user_interface(const char * driver, const char * parameter); + UserInterface * user_interface(const char * driver, const char * parameter, Interfaces * interfaces); void register_audio_input(const char * driver, AudioInput * (*creator)(const char *)); void register_audio_output(const char * driver, AudioOutput * (*creator)(const char *)); void register_codec(const char * driver, Codec * (*creator)(const char *)); - void register_keying(const char * driver, Keying * (*creator)(const char *)); + void register_keying_output(const char * driver, Keying * (*creator)(const char *)); void register_modem(const char * driver, Modem * (*creator)(const char *)); void register_ptt_input(const char * driver, PTTInput * (*creator)(const char *)); void register_text_input(const char * driver, TextInput * (*creator)(const char *)); - void register_user_interface(const char * driver, UserInterface * (*creator)(const char *)); + void register_user_interface(const char * driver, UserInterface * (*creator)(const char *, Interfaces *)); }; extern DriverManager & driver_manager; diff --git a/freedv-server/source/keying.cpp b/freedv-server/source/keying.cpp index 00ad6074..484cdffe 100644 --- a/freedv-server/source/keying.cpp +++ b/freedv-server/source/keying.cpp @@ -1,7 +1,7 @@ #include "drivers.h" namespace FreeDV { - Keying::Keying() + Keying::Keying(const char * parameters) { } diff --git a/freedv-server/source/keying_sink.cpp b/freedv-server/source/keying_sink.cpp index 275c1d6a..8f8cf9f4 100644 --- a/freedv-server/source/keying_sink.cpp +++ b/freedv-server/source/keying_sink.cpp @@ -12,7 +12,8 @@ namespace FreeDV { }; - KeyingSink::KeyingSink(const char *) + KeyingSink::KeyingSink(const char * parameters) + : Keying(parameters) { } @@ -35,7 +36,7 @@ namespace FreeDV { static bool initializer() { - init_driver_manager().register_keying("sink", creator); + init_driver_manager().register_keying_output("sink", creator); return true; } static const bool initialized = initializer(); diff --git a/freedv-server/source/linux/.gitignore b/freedv-server/source/linux/.gitignore new file mode 100644 index 00000000..e69de29b diff --git a/freedv-server/source/macos/.gitignore b/freedv-server/source/macos/.gitignore new file mode 100644 index 00000000..e69de29b diff --git a/freedv-server/source/modem.cpp b/freedv-server/source/modem.cpp index 71cb64d9..de7716f7 100644 --- a/freedv-server/source/modem.cpp +++ b/freedv-server/source/modem.cpp @@ -1,7 +1,7 @@ #include "drivers.h" namespace FreeDV { - Modem::Modem() + Modem::Modem(const char * parameters) { } diff --git a/freedv-server/source/modem_noop.cpp b/freedv-server/source/modem_noop.cpp index 27ead319..4ce4dc25 100644 --- a/freedv-server/source/modem_noop.cpp +++ b/freedv-server/source/modem_noop.cpp @@ -12,7 +12,8 @@ namespace FreeDV { }; - ModemNoOp::ModemNoOp(const char *) + ModemNoOp::ModemNoOp(const char * parameters) + : Modem(parameters) { } diff --git a/freedv-server/source/mswin/.gitignore b/freedv-server/source/mswin/.gitignore new file mode 100644 index 00000000..e69de29b diff --git a/freedv-server/source/ptt_constant.cpp b/freedv-server/source/ptt_constant.cpp index 2cc25f01..4f3ac4c6 100644 --- a/freedv-server/source/ptt_constant.cpp +++ b/freedv-server/source/ptt_constant.cpp @@ -4,12 +4,13 @@ namespace FreeDV { class PTTConstant : public PTTInput { public: - PTTConstant(const char * parameter); + PTTConstant(const char * parameters); virtual ~PTTConstant(); }; - PTTConstant::PTTConstant(const char * parameter) + PTTConstant::PTTConstant(const char * parameters) + : PTTInput(parameters) { } diff --git a/freedv-server/source/ptt_input.cpp b/freedv-server/source/ptt_input.cpp index 0496f5cb..fe792ed5 100644 --- a/freedv-server/source/ptt_input.cpp +++ b/freedv-server/source/ptt_input.cpp @@ -1,7 +1,7 @@ #include "drivers.h" namespace FreeDV { - PTTInput::PTTInput() + PTTInput::PTTInput(const char * parameters) { } @@ -9,9 +9,22 @@ namespace FreeDV { { } - bool - PTTInput::captive() + bool const + PTTInput::captive() const { return false; } + + void + PTTInput::changed(bool value) + { + if ( callback ) + (*callback)(value); + } + + void + PTTInput::set_callback(void (*c)(bool)) + { + callback = c; + } } diff --git a/freedv-server/source/run.cpp b/freedv-server/source/run.cpp index 615eef6a..efa417f0 100644 --- a/freedv-server/source/run.cpp +++ b/freedv-server/source/run.cpp @@ -1,9 +1,25 @@ #include "drivers.h" namespace FreeDV { + static void + ptt_digital(bool value) + { + } + + static void + ptt_ssb(bool value) + { + } + int run(Interfaces * i) { + if ( i->ptt_input_digital ) + i->ptt_input_digital->set_callback(ptt_digital); + + if ( i->ptt_input_ssb ) + i->ptt_input_ssb->set_callback(ptt_ssb); + return 0; } } diff --git a/freedv-server/source/text_constant.cpp b/freedv-server/source/text_constant.cpp index 3aa23a1b..ea5fa14e 100644 --- a/freedv-server/source/text_constant.cpp +++ b/freedv-server/source/text_constant.cpp @@ -9,7 +9,8 @@ namespace FreeDV { }; - TextConstant::TextConstant(const char * parameter) + TextConstant::TextConstant(const char * parameters) + : TextInput(parameters) { } diff --git a/freedv-server/source/text_input.cpp b/freedv-server/source/text_input.cpp index c9daf63e..65f6b23b 100644 --- a/freedv-server/source/text_input.cpp +++ b/freedv-server/source/text_input.cpp @@ -1,7 +1,7 @@ #include "drivers.h" namespace FreeDV { - TextInput::TextInput() + TextInput::TextInput(const char * parameters) { } @@ -9,8 +9,8 @@ namespace FreeDV { { } - bool - TextInput::captive() + bool const + TextInput::captive() const { return false; } diff --git a/freedv-server/source/tone.cpp b/freedv-server/source/tone.cpp index 93126aea..46431518 100644 --- a/freedv-server/source/tone.cpp +++ b/freedv-server/source/tone.cpp @@ -11,13 +11,14 @@ namespace FreeDV { virtual float level(); // Set the current audio level within the range of 0.0 to 1.0. - virtual float level(float value); + virtual void level(float value); // Read audio into the "short" type. - virtual int read_short(short * array, int length); + virtual std::size_t read16(int16_t * array, std::size_t length); }; - Tone::Tone(const char * parameter) + Tone::Tone(const char * parameters) + : AudioInput(parameters) { } @@ -31,14 +32,13 @@ namespace FreeDV { return 0; } - float + void Tone::level(float value) { - return value; } - int - Tone::read_short(short * array, int length) + std::size_t + Tone::read16(int16_t * array, std::size_t length) { return 0; } diff --git a/freedv-server/source/user_interface.cpp b/freedv-server/source/user_interface.cpp index a43a92e9..2721ece0 100644 --- a/freedv-server/source/user_interface.cpp +++ b/freedv-server/source/user_interface.cpp @@ -1,35 +1,11 @@ #include "drivers.h" namespace FreeDV { - UserInterface::UserInterface() + UserInterface::UserInterface(const char * parameters, Interfaces * interfaces) { } UserInterface::~UserInterface() { } - - AudioInput * - UserInterface::microphone() - { - return 0; - } - - AudioOutput * - UserInterface::loudspeaker() - { - return 0; - } - - TextInput * - UserInterface::text_input() - { - return 0; - } - - PTTInput * - UserInterface::ptt_input() - { - return 0; - } } diff --git a/freedv-server/source/wx/.gitignore b/freedv-server/source/wx/.gitignore new file mode 100644 index 00000000..e69de29b