driver: Create an audio driver class

The driver is used to select between gstreamer playback and a fake
playback mode used only when testing.

Currently the GSTDriver has empty functions.  It will be implemented as
the audio.cpp file is updated.

Signed-off-by: Anna Schumaker <Anna@OcarinaProject.net>
This commit is contained in:
Anna Schumaker 2014-05-31 10:25:25 -04:00
parent f8f389c7ed
commit edc4a2f4ee
6 changed files with 239 additions and 0 deletions

62
DESIGN
View File

@ -1299,6 +1299,68 @@ Deck:
Return the RecentQueue to the caller.
Audio Driver:
The audio driver creates a way to fake audio playback for testing. This
will allow for more accurate tests, since I will know in advance what
values are returned to the Audio layer. This layer will derive from
the Driver class to implement either the GSTDriver or the TestDriver.
- Driver:
class Driver {
protected:
void (*on_eos)();
public:
Driver();
~Driver();
virtual void init(int *, char ***, void (*)()) = 0;
virtual void load(const std::string &) = 0;
virtual void play() = 0;
virtual void pause() = 0;
virtual void seek_to(long) = 0;
virtual long position() = 0;
virtual long duration() = 0
};
- Driver API:
void Driver :: Driver();
Initialize the audio driver. This involves setting up a GST
Bus in the GSTDriver case.
void Driver :: ~Driver();
In the GSTDriver case, call gst_deinit() to avoid memory leak
false positives.
void Driver :: init(int argc, char **argv, void (*eos_cb)());
The GSTDriver will use this function to set up the playbin2.
When an end-of-stream message is received, call eos_cb().
void Driver :: load(const std::string &file);
Load file for playback, but do not begin playback yet.
void Driver :: play();
Start playback.
void Driver :: pause();
Pause playback.
void Driver :: seek_to(long pos);
Change playback position in the current track in nanoseconds.
long Driver :: position();
Return the current position in the track in nanoseconds.
long Driver :: duration();
Return the duration of the track in nanoseconds.
- API:
Driver *driver :: get_driver();
Return the current driver to be used for audio playback. This
could be either the GSTDriver or the TestDriver depending on
if CONFIG_TEST is set when compiling.

74
include/driver.h Normal file
View File

@ -0,0 +1,74 @@
/*
* Copyright 2014 (c) Anna Schumaker.
*/
#include <string>
class Driver {
protected:
void (*on_eos)();
public:
Driver();
~Driver();
virtual void init(int *, char ***, void (*)()) = 0;
virtual void load(const std::string &) = 0;
virtual void play() = 0;
virtual void pause() = 0;
virtual void seek_to(long) = 0;
virtual long position() = 0;
virtual long duration() = 0;
};
#ifdef CONFIG_TEST
class TestDriver : public Driver
{
public:
bool playing;
long cur_pos;
long cur_duration;
std::string cur_file;
TestDriver();
~TestDriver();
void init(int *, char ***, void (*)());
void load(const std::string &);
void play();
void pause();
void seek_to(long);
long position();
long duration();
void eos();
};
#else /* CONFIG_TEST */
class GSTDriver : public Driver
{
public:
GSTDriver();
~GSTDriver();
void init(int *, char ***, void (*)());
void load(const std::string &);
void play();
void pause();
void seek_to(long);
long position();
long duration();
};
#endif /* CONFIG_TEST */
namespace driver
{
Driver *get_driver();
}

54
lib/driver.cpp Normal file
View File

@ -0,0 +1,54 @@
/*
* Copyright 2014 (c) Anna Schumaker.
*/
#include <driver.h>
Driver :: Driver() {}
Driver :: ~Driver() {}
#ifdef CONFIG_TEST
TestDriver :: TestDriver() : playing(false), cur_pos(0), cur_duration(0) {}
TestDriver :: ~TestDriver() {}
void TestDriver :: init(int *argc, char ***argv, void (*eos_cb)()) { on_eos = eos_cb; }
void TestDriver :: load(const std::string &file) { cur_file = file; }
void TestDriver :: play() { playing = true; }
void TestDriver :: pause() { playing = false; }
void TestDriver :: seek_to(long pos) { cur_pos = pos; }
long TestDriver :: position() { return cur_pos; }
long TestDriver :: duration() { return cur_duration; }
void TestDriver :: eos() { on_eos(); }
#else /* CONFIG_TEST */
GSTDriver :: GSTDriver() {}
GSTDriver :: ~GSTDriver() {}
void GSTDriver :: init(int argc, char **argv, void (*eos_cb)()) { }
void GSTDriver :: load(const std::string &file) { }
void GSTDriver :: play() { }
void GSTDriver :: pause() { }
void GSTDriver :: seek_to(long pos) { }
long GSTDriver :: position() { return 0; }
long GSTDriver :: duration() { return 0; }
#endif /* CONFIG_TEST */
#ifdef CONFIG_TEST
static TestDriver cur_driver;
#else /* CONFIG_TEST */
static GSTDriver cur_driver;
#endif /* CONFIG_TEST */
Driver *driver :: get_driver()
{
return &cur_driver;
}

1
tests/.gitignore vendored
View File

@ -10,3 +10,4 @@ queue
library
playlist
deck
driver

View File

@ -21,6 +21,7 @@ tests = [
("library.cpp", True, [ "idle.cpp" ], []),
("playlist.cpp", True, [], []),
("deck.cpp", True, [], []),
("driver.cpp", False, [ "driver.cpp" ], []),
]

47
tests/driver.cpp Normal file
View File

@ -0,0 +1,47 @@
/*
* Copyright 2014 (c) Anna Schumaker.
*/
#include <driver.h>
#include "test.h"
static TestDriver *DRIVER_NULL = NULL;
static unsigned int eos_count = 0;
void on_eos()
{
eos_count++;
}
void test_driver()
{
TestDriver *driver = (TestDriver *)driver :: get_driver();
const std::string file = "/home/Zelda/Music/Wind Waker/1 - Outset Isle.ogg";
test_not_equal(driver, DRIVER_NULL);
driver->init(0, NULL, on_eos);
driver->load(file);
test_equal(driver->cur_file, file);
driver->play();
test_equal(driver->playing, true);
driver->pause();
test_equal(driver->playing, false);
driver->seek_to(4242);
test_equal(driver->cur_pos, (long)4242);
test_equal(driver->position(), (long)4242);
driver->cur_duration = 424242;
test_equal(driver->duration(), (long)424242);
driver->eos();
test_equal(eos_count, (unsigned)1);
}
int main(int argc, char **argv)
{
run_test("Test Audio Driver", test_driver);
return 0;
}