Add event handling, write doxygen documentation into drivers.h .
authorbruceperens <bruceperens@01035d8c-6547-0410-b346-abe4f91aad63>
Thu, 16 Jan 2014 03:13:48 +0000 (03:13 +0000)
committerbruceperens <bruceperens@01035d8c-6547-0410-b346-abe4f91aad63>
Thu, 16 Jan 2014 03:13:48 +0000 (03:13 +0000)
git-svn-id: https://svn.code.sf.net/p/freetel/code@1354 01035d8c-6547-0410-b346-abe4f91aad63

24 files changed:
freedv-server/source/audio_input.cpp
freedv-server/source/audio_output.cpp
freedv-server/source/audio_sink.cpp
freedv-server/source/big_main.cpp
freedv-server/source/blank_panel.cpp
freedv-server/source/codec.cpp
freedv-server/source/codec_noop.cpp
freedv-server/source/driver_manager.cpp
freedv-server/source/drivers.h
freedv-server/source/keying.cpp
freedv-server/source/keying_sink.cpp
freedv-server/source/linux/.gitignore [new file with mode: 0644]
freedv-server/source/macos/.gitignore [new file with mode: 0644]
freedv-server/source/modem.cpp
freedv-server/source/modem_noop.cpp
freedv-server/source/mswin/.gitignore [new file with mode: 0644]
freedv-server/source/ptt_constant.cpp
freedv-server/source/ptt_input.cpp
freedv-server/source/run.cpp
freedv-server/source/text_constant.cpp
freedv-server/source/text_input.cpp
freedv-server/source/tone.cpp
freedv-server/source/user_interface.cpp
freedv-server/source/wx/.gitignore [new file with mode: 0644]

index 2f1b208746534aee98f2ad8386757146c1e17ccf..d8e1ce17b6400870c397f4a710f55b12a0f7225a 100644 (file)
@@ -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;
   }
index 27ed71a6cef71a41a1a30e86f07f3252a60cce47..d34ed8a617f1e3e3013c9c3da6656d283d97e3ea 100644 (file)
@@ -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;
   }
index db10e59c2741eb50ed5ae1b953a3fa5f7385359f..0410d5786b621f4f8f07f8aac849a637a8945c06 100644 (file)
@@ -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;
   }
index 25e108ef2ae6483b6ec37362e20b0d640aef6469..59cd0fe105a77af7a2156e9e99441d0c711f7940 100644 (file)
@@ -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 <stdlib.h>
 #include <string.h>
@@ -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 --<flag>=<parameter>\n"
-    "\tShort flags with parameters are in the form of -<letter> <parameter>\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 \"<driver>:<parameter>\" argument\n"
-    "\twhere <driver> is the name of a device driver and <parameter> 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 --<flag>=<parameter>\n"
+    "Short flags with parameters are in the form of -<letter> <parameter>\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 "
+    "\"<driver>:<parameter>\"\n"
+    "argument, where <driver> is the name of a device driver and <parameter> 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);
index 5bb284d0cf133db91d54162f0471b179f00d7e93..b2da0171025a42192a8c01198bde1822c95460a6 100644 (file)
@@ -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
index 78413ed292b7d7df29a96bd61a8a21808f420855..2ef800609ee2e707d2ccd36f9593b95570ff3a05 100644 (file)
@@ -1,7 +1,7 @@
 #include "drivers.h"
 
 namespace FreeDV {
-  Codec::Codec()
+  Codec::Codec(const char * parameters)
   {
   }
 
index dc9da95442cbe514795f38ddbc31601b6bfcad0b..74dab64e1cdbe48db0439efe8221360f05f94937 100644 (file)
@@ -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)
index 81b81682c5b8d7add919acefa280159ee2c06aaa..f6442267c7de15f8c343d4fb793b6ed6feb8413e 100644 (file)
@@ -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 <iostream>
 #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;
   }
index 89074d872e95624f3fd5e387799a2963187665ce..3f91c7b78493766f818bf794e35e856f2d371c93 100644 (file)
-/*
- * FreeDV driver interface definitions.
- */
-
+/// FreeDV driver interface definitions.
+#include <cstdint>
 
 
+/// 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 <iostream>
 #include <map>
 #include <string>
+
+/// 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<std::string, AudioInput *(*)(const char *)> audio_input_drivers;
                        std::map<std::string, AudioOutput *(*)(const char *)> audio_output_drivers;
                        std::map<std::string, Codec *(*)(const char *)> codecs;
-                       std::map<std::string, Keying *(*)(const char *)> keying_drivers;
+                       std::map<std::string, Keying *(*)(const char *)> keying_output_drivers;
                        std::map<std::string, Modem *(*)(const char *)> modems;
                        std::map<std::string, PTTInput *(*)(const char *)> ptt_input_drivers;
                        std::map<std::string, TextInput *(*)(const char *)> text_input_drivers;
-                       std::map<std::string, UserInterface *(*)(const char *)> user_interface_drivers;
+                       std::map<std::string, UserInterface *(*)(const char *, Interfaces *)> 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;
index 00ad6074b8aef58c592fee9db8b5f17eb4ff134a..484cdffeb53cff2ce69f76528d1cc528bb4576dd 100644 (file)
@@ -1,7 +1,7 @@
 #include "drivers.h"
 
 namespace FreeDV {
-  Keying::Keying()
+  Keying::Keying(const char * parameters)
   {
   }
 
index 275c1d6a9c8820e6ee4111ecf4cf99a932adbf2e..8f8cf9f423b71b1d1429792c652673ed748bac76 100644 (file)
@@ -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 (file)
index 0000000..e69de29
diff --git a/freedv-server/source/macos/.gitignore b/freedv-server/source/macos/.gitignore
new file mode 100644 (file)
index 0000000..e69de29
index 71cb64d96b7913c0197a218e8233ba5ded4f9dd5..de7716f739b586770369343c07c10c6922f6dc56 100644 (file)
@@ -1,7 +1,7 @@
 #include "drivers.h"
 
 namespace FreeDV {
-  Modem::Modem()
+  Modem::Modem(const char * parameters)
   {
   }
 
index 27ead319c0381e61c76e1d2f244e266597fd6606..4ce4dc2576c57df4f754f848222b9781e5541e11 100644 (file)
@@ -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 (file)
index 0000000..e69de29
index 2cc25f01fb2fa824a4cce9d798da605c695d13fd..4f3ac4c66e142ebe9a5977b22299c4f306e5140a 100644 (file)
@@ -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)
   {
   }
 
index 0496f5cb67a994b1d75f00477b8b22abbf768655..fe792ed51a4135ab67f3723170c1d4b53d265802 100644 (file)
@@ -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;
+  }
 }
index 615eef6a172507634ed3c3f0aa3cfc88954a9745..efa417f0c3c3ee33e8074d50795a2574606c1119 100644 (file)
@@ -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;
   }
 }
index 3aa23a1b173b0476ef4938c148b23bb5f1f3e58a..ea5fa14e80b88264dfa39c3bdbea1debe5ac9379 100644 (file)
@@ -9,7 +9,8 @@ namespace FreeDV {
     
   };
 
-  TextConstant::TextConstant(const char * parameter)
+  TextConstant::TextConstant(const char * parameters)
+  : TextInput(parameters)
   {
   }
 
index c9daf63ebe01a80730d633ad440b7fe7eced1bfe..65f6b23be7c4ec375ef9fb625b2dc7027ef5e15b 100644 (file)
@@ -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;
   }
index 93126aeaae4172bd7746b2082f9cbe689f37b0af..464315180e264fda18dce907e69880d46ce2dac2 100644 (file)
@@ -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;
   }
index a43a92e917e939037229eb58966797be8359dc94..2721ece027b369b245dd0e646c33c80625d45cf5 100644 (file)
@@ -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 (file)
index 0000000..e69de29