)
set(Test.sources
+ source/test/audio_sink.cpp
source/test/base.cpp
+ source/test/keying_sink.cpp
source/test/tone.cpp
)
///
/// By Bruce Perens <bruce@perens.com>
///
+///
+/// \section overview OVERVIEW
+/// FreeDV-Server continues the Free Amateur Radio Digital Voice system
+/// created by David Rowe and Dave Witten. This version is a substantial
+/// rewrite, preserving the codec and modem, and it's currently my intent
+/// to save the existing WxWidgets GUI as a separate program that drives
+/// this program as a backend.
+///
+/// This version is intended to work from the command line in server mode,
+/// as the backend of a GUI program, or as embedded software in a hardware
+/// device. Thus, there is a very versatile system for selecting and
+/// configuring device drivers, and there are "test" drivers such as tone
+/// generators and audio sinks for testing all parts of the program as well
+/// as drivers for actual hardware.
+///
+/// The intent at this time is to base the event system on libevent and the
+/// audio drivers on portaudio 2.0's "blocking" interface (which provides an
+/// "I/O ready" indication and thus doesn't actually have to block). There
+/// will probably be a need to extend portaudio so that it can tie into
+/// libevent.
+///
+/// All of this software is developed using test-driven-development, with
+/// googletest as the unit test framework. The test-driven paradigm immediately
+/// showed its usefulness, as it made a few design mistakes immediately obvious.
+///
+// Doxygen is used as the documentation system.
+///
+/// \section sponsorship SPONSORSHIP
+///
+/// The current use of this program is HF, but it is also intended to work as
+/// part of a VHF/UHF SDR HT being developed by Algoram, the company founded
+/// by Chris Testa and myself. Its development is currently part of my personal
+/// investment in Algoram.
+///
/// \section licensing LICENSING
///
/// Copyright (C) Algoram. Contact us via Bruce Perens <bruce@perens.com>
AudioSink(const char * parameters);
~AudioSink();
- /// Get the current audio level, normalized to the range of 0.0 to 1.0.
- virtual float
- amplitude();
-
- /// Set the current audio level within the range of 0.0 to 1.0.
- virtual void
- amplitude(float value);
-
/// Write audio into the "short" type.
virtual std::size_t
write16(const int16_t * array, std::size_t length);
{
}
- float
- AudioSink::amplitude()
- {
- return 0;
- }
-
- void
- AudioSink::amplitude(float value)
- {
- }
-
// Write audio into the "short" type.
std::size_t
AudioSink::write16(const int16_t * array, std::size_t length)
{
- return 0;
+ return length;
}
AudioOutput *
for (auto i = codecs.begin(); i != codecs.end(); i++ )
s << i->first << " ";
s << endl;
- s << "Keying: ";
+ s << "KeyingOutput: ";
for (auto i = keying_output_drivers.begin(); i != keying_output_drivers.end(); i++ )
s << i->first << " ";
s << endl;
return 0;
}
- Keying *
+ KeyingOutput *
DriverManager::keying_output(const char * driver, const char * parameter)
{
- Keying * (* const creator)(const char * parameter) = keying_output_drivers[driver];
+ KeyingOutput * (* const creator)(const char * parameter) = keying_output_drivers[driver];
if(creator)
return creator(parameter);
}
void
- DriverManager::register_keying_output(const char * driver, Keying * (*creator)(const char *))
+ DriverManager::register_keying_output(const char * driver, KeyingOutput * (*creator)(const char *))
{
keying_output_drivers[driver] = creator;
}
return base.print(stream);
}
- // Virtual base class for AudioInput and AudioOutput.
+ /// Virtual base class for AudioInput and AudioOutput.
class AudioDevice : public ::FreeDV::Base {
protected:
+ /// The master volume control for the device.
float master_amplitude;
/// Create an AudioDevice instance.
};
/// Radio device keying driver.
- class Keying : public ::FreeDV::Base {
+ class KeyingOutput : public ::FreeDV::Base {
protected:
/// Create an radio keying output device 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.
- Keying(const char * name, const char * parameters);
+ KeyingOutput(const char * name, const char * parameters);
public:
/// Destroy the radio keying device instance.
- virtual ~Keying() = 0;
+ virtual ~KeyingOutput() = 0;
/// Key or un-key the transmitter.
/// \param value If true, key the transmitter. If false, un-key.
/// The event loop handler. This is specific to a GUI, or POSIX.
EventHandler * event_handler;
/// The output used to key the transmitter.
- Keying * keying_output;
+ KeyingOutput * keying_output;
/// The audio output which drives the loudspeaker or headphone.
AudioOutput * loudspeaker;
/// The audio input from the microphone.
AudioInput * Tone(const char * parameter);
AudioOutput * AudioSink(const char * parameter);
Codec * CodecNoOp(const char * parameter);
- Keying * KeyingSink(const char * parameter);
+ KeyingOutput * KeyingSink(const char * parameter);
EventHandler * LibEvent(const char * parameter);
Modem * ModemNoOp(const char * parameter);
PTTInput * PTTConstant(const char * parameter);
std::map<std::string, Codec *(*)(const char *)>
codecs;
- std::map<std::string, Keying *(*)(const char *)>
+ std::map<std::string, KeyingOutput *(*)(const char *)>
keying_output_drivers;
std::map<std::string, Modem *(*)(const char *)>
/// Instantiate a Keying driver.
/// \param driver The name of the driver.
/// \param parameters Driver-specific configuration parameters.
- Keying * keying_output(const char * driver, const char * parameters);
+ KeyingOutput * keying_output(const char * driver, const char * parameters);
/// Instantiate a softmodem.
/// \param driver The name of the driver.
/// \param parameters Driver-specific configuration parameters.
/// Register an audio input driver.
/// \param driver The name of the driver.
/// \param creator The coroutine that will instantiate the driver.
- void register_keying_output(const char * driver, Keying * (*creator)(const char *));
+ void register_keying_output(const char * driver, KeyingOutput * (*creator)(const char *));
/// Register an audio input driver.
/// \param driver The name of the driver.
/// \param creator The coroutine that will instantiate the driver.
-/// Keying driver.
+/// KeyingOutput driver.
#include "drivers.h"
namespace FreeDV {
- Keying::Keying(const char * name, const char * parameters)
+ KeyingOutput::KeyingOutput(const char * name, const char * parameters)
: Base(name, parameters)
{
}
- Keying::~Keying()
+ KeyingOutput::~KeyingOutput()
{
}
}
/// or use with VOX.
#include "drivers.h"
+#include <iostream>
namespace FreeDV {
- /// Keying output "sink", doesn't key anything. For testing or use with VOX.
- class KeyingSink : public Keying {
+ /// KeyingOutput output "sink", doesn't key anything. For testing or use with VOX.
+ class KeyingSink : public KeyingOutput {
public:
/// Instantiate keying sink driver.
KeyingSink(const char *);
virtual ~KeyingSink();
- virtual void
- key(bool value);
-
+ /// If the value is true, transmit. Otherwise receive.
+ void key(bool value);
};
KeyingSink::KeyingSink(const char * parameters)
- : Keying("sink", parameters)
+ : KeyingOutput("sink", parameters)
{
}
void
KeyingSink::key(bool value)
{
+ if ( value )
+ std::cerr << "keying: TRANSMIT" << std::endl;
+ else
+ std::cerr << "keying: RECEIVE" << std::endl;
}
- Keying *
+ KeyingOutput *
Driver::KeyingSink(const char * parameter)
{
return new ::FreeDV::KeyingSink(parameter);
--- /dev/null
+// Tests for the AudioSink class.
+#include <drivers.h>
+#include <gtest/gtest.h>
+
+using namespace FreeDV;
+
+class AudioSinkTest : public ::testing::Test {
+protected:
+ AudioOutput * o;
+
+ AudioSinkTest()
+ : o(0)
+ {
+ }
+
+ void SetUp() {
+ o = Driver::AudioSink("");
+ }
+
+ void TearDown() {
+ delete o;
+ }
+};
+
+TEST_F(AudioSinkTest, WriteReturnsSize) {
+ int16_t buffer[8];
+
+ size_t value = o->write16(buffer, sizeof(buffer) / sizeof(*buffer));
+
+ EXPECT_EQ(sizeof(buffer) / sizeof(*buffer), value);
+}
--- /dev/null
+// Tests for the KeyingSink class.
+#include <drivers.h>
+#include <gtest/gtest.h>
+
+using namespace FreeDV;
+
+class KeyingSinkTest : public ::testing::Test {
+protected:
+ KeyingOutput * k;
+
+ KeyingSinkTest()
+ : k(0)
+ {
+ }
+
+ void SetUp() {
+ k = Driver::KeyingSink("");
+ }
+
+ void TearDown() {
+ delete k;
+ }
+};
+
+TEST_F(KeyingSinkTest, CanCallKey) {
+
+ k->key(true);
+ k->key(false);
+}