audio: Update the code to match the design
This patch reworks the unit test using the TestDriver audio driver. I also recode the audio layer to match the design and drastically clean up the code. Signed-off-by: Anna Schumaker <Anna@OcarinaProject.net>
This commit is contained in:
parent
b8ea2c989d
commit
1bfa299e08
25
DESIGN
25
DESIGN
|
@ -1305,6 +1305,9 @@ Audio Driver:
|
||||||
values are returned to the Audio layer. This layer will derive from
|
values are returned to the Audio layer. This layer will derive from
|
||||||
the Driver class to implement either the GSTDriver or the TestDriver.
|
the Driver class to implement either the GSTDriver or the TestDriver.
|
||||||
|
|
||||||
|
- Seconds -> Nanoseconds conversion:
|
||||||
|
static const unsigned long O_SECOND = 1000000000;
|
||||||
|
|
||||||
- Driver:
|
- Driver:
|
||||||
class Driver {
|
class Driver {
|
||||||
protected:
|
protected:
|
||||||
|
@ -1382,9 +1385,6 @@ Audio:
|
||||||
|
|
||||||
File << current_track->id << endl;
|
File << current_track->id << endl;
|
||||||
|
|
||||||
- Seconds -> Nanoseconds conversion:
|
|
||||||
#define O_SECOND 1000000000
|
|
||||||
|
|
||||||
- API:
|
- API:
|
||||||
void audio :: init(int *argc, char ***argv);
|
void audio :: init(int *argc, char ***argv);
|
||||||
Initialize the audio driver through argc and argv. Read in
|
Initialize the audio driver through argc and argv. Read in
|
||||||
|
@ -1396,6 +1396,10 @@ Audio:
|
||||||
Call the corresponding function from the audio driver, but only
|
Call the corresponding function from the audio driver, but only
|
||||||
if a track is loaded.
|
if a track is loaded.
|
||||||
|
|
||||||
|
void audio :: stop();
|
||||||
|
pause()
|
||||||
|
seek_to(0)
|
||||||
|
|
||||||
long audio :: position();
|
long audio :: position();
|
||||||
long audio :: duration();
|
long audio :: duration();
|
||||||
Call the corresponding function from the audio driver. Return
|
Call the corresponding function from the audio driver. Return
|
||||||
|
@ -1405,10 +1409,6 @@ Audio:
|
||||||
Return the current audio position in string form.
|
Return the current audio position in string form.
|
||||||
Return an empty string if there is no current track.
|
Return an empty string if there is no current track.
|
||||||
|
|
||||||
void audio :: stop();
|
|
||||||
pause()
|
|
||||||
seek_to(0)
|
|
||||||
|
|
||||||
void audio :: next();
|
void audio :: next();
|
||||||
Call the deck :: next() function to get the next track that
|
Call the deck :: next() function to get the next track that
|
||||||
should be played and use the audio driver to load the track.
|
should be played and use the audio driver to load the track.
|
||||||
|
@ -1421,15 +1421,15 @@ Audio:
|
||||||
|
|
||||||
Save that track's ID to the cur_track file.
|
Save that track's ID to the cur_track file.
|
||||||
|
|
||||||
Track *audio :: current_track();
|
|
||||||
Return the currently playing Track.
|
|
||||||
Return NULL if there is no current track.
|
|
||||||
|
|
||||||
void audio :: load_track(Track *track);
|
void audio :: load_track(Track *track);
|
||||||
Load the requested track.
|
Load the requested track.
|
||||||
|
|
||||||
Save that track's ID to the cur_track file.
|
Save that track's ID to the cur_track file.
|
||||||
|
|
||||||
|
Track *audio :: current_track();
|
||||||
|
Return the currently playing Track.
|
||||||
|
Return NULL if there is no current track.
|
||||||
|
|
||||||
void audio :: pause_after(bool enabled, unsigned int N);
|
void audio :: pause_after(bool enabled, unsigned int N);
|
||||||
If enabled == true:
|
If enabled == true:
|
||||||
Configure Ocarina to pause playback after N tracks
|
Configure Ocarina to pause playback after N tracks
|
||||||
|
@ -1437,6 +1437,9 @@ Audio:
|
||||||
If enabled == false:
|
If enabled == false:
|
||||||
Do not automatically pause.
|
Do not automatically pause.
|
||||||
|
|
||||||
|
If N is greater than the current pause count then enabled should
|
||||||
|
be set to true.
|
||||||
|
|
||||||
bool audio :: pause_enabled();
|
bool audio :: pause_enabled();
|
||||||
unsigned int audio :: pause_count();
|
unsigned int audio :: pause_count();
|
||||||
Use these functions to access the current "pause after N" state.
|
Use these functions to access the current "pause after N" state.
|
||||||
|
|
|
@ -4,32 +4,27 @@
|
||||||
#ifndef OCARINA_AUDIO_H
|
#ifndef OCARINA_AUDIO_H
|
||||||
#define OCARINA_AUDIO_H
|
#define OCARINA_AUDIO_H
|
||||||
|
|
||||||
#include <error.h>
|
#include <tags.h>
|
||||||
#include <queue.h>
|
|
||||||
|
|
||||||
#include <string>
|
#include <string>
|
||||||
|
|
||||||
namespace audio
|
namespace audio
|
||||||
{
|
{
|
||||||
|
|
||||||
void init(int *, char ***);
|
void init(int *, char ***);
|
||||||
void load_state();
|
|
||||||
void quit();
|
|
||||||
|
|
||||||
void play();
|
void play();
|
||||||
void pause();
|
void pause();
|
||||||
void toggle_play();
|
|
||||||
void stop();
|
|
||||||
void next();
|
|
||||||
void previous();
|
|
||||||
void load_trackid(unsigned int);
|
|
||||||
unsigned int current_trackid();
|
|
||||||
Queue *get_recent_pq();
|
|
||||||
|
|
||||||
void seek_to(long);
|
void seek_to(long);
|
||||||
|
void stop();
|
||||||
|
|
||||||
long position();
|
long position();
|
||||||
std::string position_str();
|
|
||||||
long duration();
|
long duration();
|
||||||
|
std::string position_str();
|
||||||
|
|
||||||
|
void next();
|
||||||
|
void prev();
|
||||||
|
void load_track(Track *track);
|
||||||
|
Track *current_track();
|
||||||
|
|
||||||
void pause_after(bool, unsigned int);
|
void pause_after(bool, unsigned int);
|
||||||
bool pause_enabled();
|
bool pause_enabled();
|
||||||
|
|
|
@ -4,6 +4,9 @@
|
||||||
|
|
||||||
#include <string>
|
#include <string>
|
||||||
|
|
||||||
|
static const unsigned long O_SECOND = 1000000000;
|
||||||
|
|
||||||
|
|
||||||
class Driver {
|
class Driver {
|
||||||
protected:
|
protected:
|
||||||
void (*on_eos)();
|
void (*on_eos)();
|
||||||
|
|
224
lib/audio.cpp
224
lib/audio.cpp
|
@ -5,103 +5,87 @@
|
||||||
#include <callback.h>
|
#include <callback.h>
|
||||||
#include <deck.h>
|
#include <deck.h>
|
||||||
#include <driver.h>
|
#include <driver.h>
|
||||||
#include <library.h>
|
|
||||||
|
|
||||||
#include <sstream>
|
#include <sstream>
|
||||||
#include <string.h>
|
#include <string.h>
|
||||||
|
|
||||||
static bool player_playing = false;
|
|
||||||
static bool track_loaded = false;
|
|
||||||
static unsigned int cur_trackid = 0;
|
|
||||||
|
|
||||||
static bool o_pause_enabled = false;
|
static bool _pause_enabled = false;
|
||||||
static unsigned int o_pause_count = 0;
|
static unsigned int _pause_count = 0;
|
||||||
static bool o_should_pause = false;
|
|
||||||
|
|
||||||
|
static Track *cur_track = NULL;
|
||||||
static File f_cur_track("cur_track", 0);
|
static File f_cur_track("cur_track", 0);
|
||||||
|
|
||||||
|
|
||||||
static void handle_pause_count()
|
|
||||||
{
|
|
||||||
if (o_pause_enabled == false)
|
|
||||||
return;
|
|
||||||
else if (o_pause_count == 0) {
|
|
||||||
o_should_pause = true;
|
|
||||||
o_pause_enabled = false;
|
|
||||||
get_callbacks()->on_pause();
|
|
||||||
} else
|
|
||||||
o_pause_count--;
|
|
||||||
get_callbacks()->on_pause_count_changed(o_pause_enabled, o_pause_count);
|
|
||||||
}
|
|
||||||
|
|
||||||
static void on_error()
|
|
||||||
{
|
|
||||||
audio :: next();
|
|
||||||
audio :: play();
|
|
||||||
}
|
|
||||||
|
|
||||||
static void on_eos()
|
|
||||||
{
|
|
||||||
Track *track;
|
|
||||||
|
|
||||||
handle_pause_count();
|
|
||||||
track = tagdb :: lookup(cur_trackid);
|
|
||||||
if (track) {
|
|
||||||
track->played();
|
|
||||||
library :: get_queue()->updated(track);
|
|
||||||
}
|
|
||||||
audio :: next();
|
|
||||||
audio :: seek_to(0);
|
|
||||||
}
|
|
||||||
|
|
||||||
static void save_state()
|
static void save_state()
|
||||||
{
|
{
|
||||||
f_cur_track.open(OPEN_WRITE);
|
f_cur_track.open(OPEN_WRITE);
|
||||||
f_cur_track << cur_trackid << std::endl;
|
f_cur_track << cur_track->id << std::endl;
|
||||||
f_cur_track.close();
|
f_cur_track.close();
|
||||||
}
|
}
|
||||||
|
|
||||||
static bool load_song(Track *track)
|
static void _load_track(Track *track, bool start_playback)
|
||||||
{
|
{
|
||||||
bool start_playback;
|
cur_track = track;
|
||||||
|
if (!track)
|
||||||
if (o_should_pause)
|
return;
|
||||||
start_playback = false;
|
|
||||||
else
|
|
||||||
start_playback = driver :: get_driver()->is_playing();
|
|
||||||
|
|
||||||
driver :: get_driver()->load(track->path());
|
driver :: get_driver()->load(track->path());
|
||||||
get_callbacks()->on_track_loaded(track);
|
get_callbacks()->on_track_loaded(track);
|
||||||
|
|
||||||
if (start_playback)
|
if (start_playback)
|
||||||
return driver :: get_driver()->play();
|
audio :: play();
|
||||||
else
|
else
|
||||||
return driver :: get_driver()->pause();
|
audio :: pause();
|
||||||
|
save_state();
|
||||||
|
}
|
||||||
|
|
||||||
|
static inline void _load_track_default(Track *track)
|
||||||
|
{
|
||||||
|
_load_track(track, driver :: get_driver()->is_playing());
|
||||||
|
}
|
||||||
|
|
||||||
|
static bool continue_playback()
|
||||||
|
{
|
||||||
|
bool ret = true;
|
||||||
|
|
||||||
|
if (_pause_enabled) {
|
||||||
|
if (_pause_count == 0) {
|
||||||
|
ret = false;
|
||||||
|
_pause_enabled = false;
|
||||||
|
} else
|
||||||
|
_pause_count--;
|
||||||
|
get_callbacks()->on_pause_count_changed(_pause_enabled, _pause_count);
|
||||||
|
}
|
||||||
|
|
||||||
|
return ret;
|
||||||
|
}
|
||||||
|
|
||||||
|
static void on_eos()
|
||||||
|
{
|
||||||
|
if (cur_track) {
|
||||||
|
cur_track->played();
|
||||||
|
library :: get_queue()->updated(cur_track);
|
||||||
|
}
|
||||||
|
|
||||||
|
_load_track(deck :: next(), continue_playback());
|
||||||
}
|
}
|
||||||
|
|
||||||
void audio :: init(int *argc, char ***argv)
|
void audio :: init(int *argc, char ***argv)
|
||||||
{
|
|
||||||
driver :: get_driver()->init(argc, argv, on_eos, on_error);
|
|
||||||
}
|
|
||||||
|
|
||||||
void audio :: load_state()
|
|
||||||
{
|
{
|
||||||
unsigned int id;
|
unsigned int id;
|
||||||
|
|
||||||
|
driver :: get_driver()->init(argc, argv, on_eos, audio :: next);
|
||||||
if (f_cur_track.exists()) {
|
if (f_cur_track.exists()) {
|
||||||
f_cur_track.open(OPEN_READ);
|
f_cur_track.open(OPEN_READ);
|
||||||
f_cur_track >> id;
|
f_cur_track >> id;
|
||||||
f_cur_track.close();
|
f_cur_track.close();
|
||||||
audio :: load_trackid(id);
|
audio :: load_track(tagdb :: lookup(id));
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
void audio :: quit()
|
|
||||||
{
|
|
||||||
}
|
|
||||||
|
|
||||||
void audio :: play()
|
void audio :: play()
|
||||||
{
|
{
|
||||||
if (track_loaded == false)
|
if (!cur_track)
|
||||||
return;
|
return;
|
||||||
if (driver :: get_driver()->play())
|
if (driver :: get_driver()->play())
|
||||||
get_callbacks()->on_play();
|
get_callbacks()->on_play();
|
||||||
|
@ -109,18 +93,17 @@ void audio :: play()
|
||||||
|
|
||||||
void audio :: pause()
|
void audio :: pause()
|
||||||
{
|
{
|
||||||
if (track_loaded == false)
|
if (!cur_track)
|
||||||
return;
|
return;
|
||||||
if (driver :: get_driver()->pause())
|
if (driver :: get_driver()->pause())
|
||||||
get_callbacks()->on_pause();
|
get_callbacks()->on_pause();
|
||||||
}
|
}
|
||||||
|
|
||||||
void audio :: toggle_play()
|
void audio :: seek_to(long pos)
|
||||||
{
|
{
|
||||||
if (player_playing == true)
|
if (!cur_track)
|
||||||
pause();
|
return;
|
||||||
else
|
driver :: get_driver()->seek_to(pos);
|
||||||
play();
|
|
||||||
}
|
}
|
||||||
|
|
||||||
void audio :: stop()
|
void audio :: stop()
|
||||||
|
@ -129,76 +112,24 @@ void audio :: stop()
|
||||||
seek_to(0);
|
seek_to(0);
|
||||||
}
|
}
|
||||||
|
|
||||||
void audio :: seek_to(long pos)
|
|
||||||
{
|
|
||||||
if (track_loaded == false)
|
|
||||||
return;
|
|
||||||
driver :: get_driver()->seek_to(pos);
|
|
||||||
}
|
|
||||||
|
|
||||||
void audio :: next()
|
|
||||||
{
|
|
||||||
Track *track;
|
|
||||||
|
|
||||||
track_loaded = false;
|
|
||||||
track = deck :: next();
|
|
||||||
load_song(track);
|
|
||||||
track_loaded = true;
|
|
||||||
|
|
||||||
cur_trackid = track->id;
|
|
||||||
save_state();
|
|
||||||
}
|
|
||||||
|
|
||||||
void audio :: previous()
|
|
||||||
{
|
|
||||||
Track *track = deck :: prev();
|
|
||||||
if (track->id == cur_trackid)
|
|
||||||
return;
|
|
||||||
|
|
||||||
load_song(track);
|
|
||||||
cur_trackid = track->id;
|
|
||||||
save_state();
|
|
||||||
}
|
|
||||||
|
|
||||||
void audio :: load_trackid(unsigned int track_id)
|
|
||||||
{
|
|
||||||
Track *track;
|
|
||||||
|
|
||||||
if ((track_id == cur_trackid) && (track_loaded == true))
|
|
||||||
return;
|
|
||||||
|
|
||||||
track_loaded = false;
|
|
||||||
try {
|
|
||||||
track = tagdb :: lookup(track_id);
|
|
||||||
} catch (int err) {
|
|
||||||
return;
|
|
||||||
}
|
|
||||||
load_song(track);
|
|
||||||
track_loaded = true;
|
|
||||||
|
|
||||||
cur_trackid = track_id;
|
|
||||||
save_state();
|
|
||||||
deck :: get_queue()->add(track);
|
|
||||||
}
|
|
||||||
|
|
||||||
unsigned int audio :: current_trackid()
|
|
||||||
{
|
|
||||||
if (track_loaded == false)
|
|
||||||
throw -E_EXIST;
|
|
||||||
return cur_trackid;
|
|
||||||
}
|
|
||||||
|
|
||||||
long audio :: position()
|
long audio :: position()
|
||||||
{
|
{
|
||||||
if (track_loaded == false)
|
if (!cur_track)
|
||||||
return 0;
|
return 0;
|
||||||
return driver :: get_driver()->position();
|
return driver :: get_driver()->position();
|
||||||
}
|
}
|
||||||
|
|
||||||
|
long audio :: duration()
|
||||||
|
{
|
||||||
|
if (!cur_track)
|
||||||
|
return 0;
|
||||||
|
return driver :: get_driver()->duration();
|
||||||
|
}
|
||||||
|
|
||||||
std::string audio :: position_str()
|
std::string audio :: position_str()
|
||||||
{
|
{
|
||||||
std::stringstream ss;
|
std::stringstream ss;
|
||||||
long cur = position() / GST_SECOND;
|
long cur = position() / O_SECOND;
|
||||||
unsigned int minutes = cur / 60;
|
unsigned int minutes = cur / 60;
|
||||||
unsigned int seconds = cur % 60;
|
unsigned int seconds = cur % 60;
|
||||||
|
|
||||||
|
@ -209,29 +140,46 @@ std::string audio :: position_str()
|
||||||
return ss.str();
|
return ss.str();
|
||||||
}
|
}
|
||||||
|
|
||||||
long audio :: duration()
|
void audio :: next()
|
||||||
{
|
{
|
||||||
if (track_loaded == false)
|
_load_track_default(deck :: next());
|
||||||
return 0;
|
}
|
||||||
return driver :: get_driver()->duration();
|
|
||||||
|
void audio :: prev()
|
||||||
|
{
|
||||||
|
_load_track_default(deck :: prev());
|
||||||
|
}
|
||||||
|
|
||||||
|
void audio :: load_track(Track *track)
|
||||||
|
{
|
||||||
|
if (!track || track == cur_track)
|
||||||
|
return;
|
||||||
|
|
||||||
|
_load_track(track, driver :: get_driver()->is_playing());
|
||||||
|
deck :: get_queue()->add(cur_track);
|
||||||
|
}
|
||||||
|
|
||||||
|
Track *audio :: current_track()
|
||||||
|
{
|
||||||
|
return cur_track;
|
||||||
}
|
}
|
||||||
|
|
||||||
void audio :: pause_after(bool enabled, unsigned int n)
|
void audio :: pause_after(bool enabled, unsigned int n)
|
||||||
{
|
{
|
||||||
if (n > o_pause_count)
|
if (n > _pause_count)
|
||||||
enabled = true;
|
enabled = true;
|
||||||
|
|
||||||
o_pause_enabled = enabled;
|
_pause_enabled = enabled;
|
||||||
o_pause_count = n;
|
_pause_count = n;
|
||||||
get_callbacks()->on_pause_count_changed(enabled, n);
|
get_callbacks()->on_pause_count_changed(enabled, n);
|
||||||
}
|
}
|
||||||
|
|
||||||
bool audio :: pause_enabled()
|
bool audio :: pause_enabled()
|
||||||
{
|
{
|
||||||
return o_pause_enabled;
|
return _pause_enabled;
|
||||||
}
|
}
|
||||||
|
|
||||||
unsigned int audio :: pause_count()
|
unsigned int audio :: pause_count()
|
||||||
{
|
{
|
||||||
return o_pause_count;
|
return _pause_count;
|
||||||
}
|
}
|
||||||
|
|
|
@ -15,7 +15,8 @@ TestDriver :: ~TestDriver() {}
|
||||||
|
|
||||||
void TestDriver :: init(int *argc, char ***argv, void (*eos_cb)(), void (*error_cb)())
|
void TestDriver :: init(int *argc, char ***argv, void (*eos_cb)(), void (*error_cb)())
|
||||||
{ on_eos = eos_cb; on_error = error_cb; }
|
{ on_eos = eos_cb; on_error = error_cb; }
|
||||||
void TestDriver :: load(const std::string &file) { cur_file = file; }
|
void TestDriver :: load(const std::string &file)
|
||||||
|
{ cur_file = file; playing = false; cur_pos = 0; }
|
||||||
bool TestDriver :: play() { playing = true; return true; }
|
bool TestDriver :: play() { playing = true; return true; }
|
||||||
bool TestDriver :: pause() { playing = false; return true; }
|
bool TestDriver :: pause() { playing = false; return true; }
|
||||||
bool TestDriver :: is_playing() { return playing; }
|
bool TestDriver :: is_playing() { return playing; }
|
||||||
|
|
|
@ -11,3 +11,4 @@ library
|
||||||
playlist
|
playlist
|
||||||
deck
|
deck
|
||||||
driver
|
driver
|
||||||
|
audio
|
||||||
|
|
|
@ -0,0 +1 @@
|
||||||
|
3
|
|
@ -22,6 +22,7 @@ tests = [
|
||||||
("playlist.cpp", True, [], []),
|
("playlist.cpp", True, [], []),
|
||||||
("deck.cpp", True, [], []),
|
("deck.cpp", True, [], []),
|
||||||
("driver.cpp", False, [ "driver.cpp" ], []),
|
("driver.cpp", False, [ "driver.cpp" ], []),
|
||||||
|
("audio.cpp", True, [ "driver.cpp" ], []),
|
||||||
|
|
||||||
]
|
]
|
||||||
|
|
||||||
|
|
|
@ -0,0 +1,170 @@
|
||||||
|
/*
|
||||||
|
* Copyright 2013 (c) Anna Schumaker.
|
||||||
|
*/
|
||||||
|
#include <audio.h>
|
||||||
|
#include <driver.h>
|
||||||
|
#include <library.h>
|
||||||
|
#include "test.h"
|
||||||
|
|
||||||
|
Track *TRACK_NULL = NULL;
|
||||||
|
|
||||||
|
void test_pre_init()
|
||||||
|
{
|
||||||
|
TestDriver *driver = (TestDriver *)driver :: get_driver();
|
||||||
|
|
||||||
|
test_equal(audio :: current_track(), TRACK_NULL);
|
||||||
|
|
||||||
|
audio :: play();
|
||||||
|
test_equal(driver->playing, false);
|
||||||
|
|
||||||
|
driver->playing = true;
|
||||||
|
audio :: pause();
|
||||||
|
test_equal(driver->playing, true);
|
||||||
|
audio :: stop();
|
||||||
|
test_equal(driver->playing, true);
|
||||||
|
driver->playing = false;
|
||||||
|
|
||||||
|
audio :: seek_to(4242);
|
||||||
|
test_equal(driver->position(), (long)0);
|
||||||
|
|
||||||
|
driver->cur_pos = 4242;
|
||||||
|
test_equal(audio :: position(), (long)0);
|
||||||
|
driver->cur_pos = 0;
|
||||||
|
|
||||||
|
driver->cur_duration = 4242;
|
||||||
|
test_equal(audio :: duration(), (long)0);
|
||||||
|
driver->cur_duration = 0;
|
||||||
|
|
||||||
|
audio :: next();
|
||||||
|
test_equal(audio :: current_track(), TRACK_NULL);
|
||||||
|
|
||||||
|
audio :: prev();
|
||||||
|
test_equal(audio :: current_track(), TRACK_NULL);
|
||||||
|
}
|
||||||
|
|
||||||
|
void test_init(int argc, char **argv)
|
||||||
|
{
|
||||||
|
Track *track;
|
||||||
|
|
||||||
|
test :: cp_data_dir();
|
||||||
|
audio :: init(&argc, &argv);
|
||||||
|
|
||||||
|
track = audio :: current_track();
|
||||||
|
test_equal(track, TRACK_NULL);
|
||||||
|
|
||||||
|
tagdb :: init();
|
||||||
|
library :: init();
|
||||||
|
audio :: init(&argc, &argv);
|
||||||
|
|
||||||
|
track = audio :: current_track();
|
||||||
|
test_not_equal(track, TRACK_NULL);
|
||||||
|
}
|
||||||
|
|
||||||
|
void test_playback_controls()
|
||||||
|
{
|
||||||
|
TestDriver *driver = (TestDriver *)driver :: get_driver();
|
||||||
|
|
||||||
|
audio :: play();
|
||||||
|
test_equal(driver->playing, true);
|
||||||
|
|
||||||
|
audio :: pause();
|
||||||
|
test_equal(driver->playing, false);
|
||||||
|
|
||||||
|
audio :: seek_to(4242);
|
||||||
|
test_equal(driver->cur_pos, (long)4242);
|
||||||
|
test_equal(audio :: position(), (long)4242);
|
||||||
|
|
||||||
|
audio :: play();
|
||||||
|
audio :: stop();
|
||||||
|
test_equal(driver->playing, false);
|
||||||
|
test_equal(driver->cur_pos, (long)0);
|
||||||
|
|
||||||
|
audio :: seek_to(4242);
|
||||||
|
driver->cur_duration = 424242;
|
||||||
|
test_equal(audio :: position(), (long)4242);
|
||||||
|
test_equal(audio :: duration(), (long)424242);
|
||||||
|
|
||||||
|
audio :: seek_to(83 * O_SECOND);
|
||||||
|
test_equal(audio :: position_str(), (std::string)"1:23");
|
||||||
|
}
|
||||||
|
|
||||||
|
void test_track_controls()
|
||||||
|
{
|
||||||
|
Track *track = NULL;
|
||||||
|
|
||||||
|
TestDriver *driver = (TestDriver *)driver :: get_driver();
|
||||||
|
library :: get_queue()->unset_flag(Q_RANDOM);
|
||||||
|
|
||||||
|
audio :: pause();
|
||||||
|
audio :: next();
|
||||||
|
test_not_equal(audio :: current_track()->id, (unsigned)2);
|
||||||
|
test_equal(driver->is_playing(), false);
|
||||||
|
|
||||||
|
audio :: play();
|
||||||
|
audio :: next();
|
||||||
|
test_equal(driver->is_playing(), true);
|
||||||
|
|
||||||
|
audio :: load_track(track);
|
||||||
|
test_not_equal(audio :: current_track(), track);
|
||||||
|
|
||||||
|
track = tagdb :: lookup(0);
|
||||||
|
audio :: seek_to(4242);
|
||||||
|
audio :: load_track(track);
|
||||||
|
test_equal(driver->is_playing(), true);
|
||||||
|
test_equal(audio :: position(), (long)0);
|
||||||
|
|
||||||
|
audio :: seek_to(4242);
|
||||||
|
audio :: load_track(track);
|
||||||
|
test_equal(driver->is_playing(), true);
|
||||||
|
test_equal(audio :: position(), (long)4242);
|
||||||
|
|
||||||
|
driver->error();
|
||||||
|
test_not_equal(audio :: current_track(), track);
|
||||||
|
|
||||||
|
track = audio :: current_track();
|
||||||
|
driver->eos();
|
||||||
|
test_not_equal(audio :: current_track(), track);
|
||||||
|
}
|
||||||
|
|
||||||
|
void test_autopause()
|
||||||
|
{
|
||||||
|
TestDriver *driver = (TestDriver *)driver :: get_driver();
|
||||||
|
|
||||||
|
audio :: play();
|
||||||
|
test_equal(audio :: pause_enabled(), false);
|
||||||
|
test_equal(audio :: pause_count(), (unsigned)0);
|
||||||
|
|
||||||
|
audio :: pause_after(true, 3);
|
||||||
|
test_equal(audio :: pause_enabled(), true);
|
||||||
|
test_equal(audio :: pause_count(), (unsigned)3);
|
||||||
|
|
||||||
|
audio :: pause_after(false, 3);
|
||||||
|
test_equal(audio :: pause_enabled(), false);
|
||||||
|
test_equal(audio :: pause_count(), (unsigned)3);
|
||||||
|
|
||||||
|
audio :: pause_after(false, 5);
|
||||||
|
test_equal(audio :: pause_enabled(), true);
|
||||||
|
test_equal(audio :: pause_count(), (unsigned)5);
|
||||||
|
|
||||||
|
for (int i = 4; i >= 0; i--) {
|
||||||
|
driver->eos();
|
||||||
|
test_equal(audio :: pause_enabled(), true);
|
||||||
|
test_equal(audio :: pause_count(), (unsigned)i);
|
||||||
|
test_equal(driver->is_playing(), true);
|
||||||
|
}
|
||||||
|
|
||||||
|
driver->eos();
|
||||||
|
test_equal(audio :: pause_enabled(), false);
|
||||||
|
test_equal(audio :: pause_count(), (unsigned)0);
|
||||||
|
test_equal(driver->is_playing(), false);
|
||||||
|
}
|
||||||
|
|
||||||
|
int main(int argc, char **argv)
|
||||||
|
{
|
||||||
|
run_test("Test Audio Pre-Init", test_pre_init);
|
||||||
|
run_test("Test Audio Init", test_init, argc, argv);
|
||||||
|
run_test("Test Audio Playback Controls", test_playback_controls);
|
||||||
|
run_test("Test Audio Track Controls", test_track_controls);
|
||||||
|
run_test("Test Audio Automatic Pausing", test_autopause);
|
||||||
|
return 0;
|
||||||
|
}
|
|
@ -1,6 +0,0 @@
|
||||||
#!/usr/bin/python
|
|
||||||
Import("Test", "CONFIG")
|
|
||||||
|
|
||||||
CONFIG.AUDIO = True
|
|
||||||
|
|
||||||
Test("audio", "audio.cpp")
|
|
|
@ -1,226 +0,0 @@
|
||||||
/*
|
|
||||||
* Copyright 2013 (c) Anna Schumaker.
|
|
||||||
*/
|
|
||||||
#include <audio.h>
|
|
||||||
#include <deck.h>
|
|
||||||
#include <idle.h>
|
|
||||||
#include <library.h>
|
|
||||||
#include <print.h>
|
|
||||||
|
|
||||||
#include <stdlib.h>
|
|
||||||
#include <string>
|
|
||||||
#include <unistd.h>
|
|
||||||
|
|
||||||
void gen_library()
|
|
||||||
{
|
|
||||||
system("tests/library/gen_library.sh");
|
|
||||||
print("\n");
|
|
||||||
}
|
|
||||||
|
|
||||||
void check_ret(const std :: string &test, bool ret, bool expected)
|
|
||||||
{
|
|
||||||
print("Test %s: ", test.c_str());
|
|
||||||
if (ret == expected)
|
|
||||||
print("Success!\n");
|
|
||||||
else
|
|
||||||
print("Failed.\n");
|
|
||||||
}
|
|
||||||
|
|
||||||
template <class T>
|
|
||||||
void check_ret(const std :: string &test, long ret, long expected)
|
|
||||||
{
|
|
||||||
print("Test %s: ", test.c_str());
|
|
||||||
if (ret == expected)
|
|
||||||
print("Success!\n");
|
|
||||||
else
|
|
||||||
print("Failed (Expected %ld but got %ld)\n", expected, ret);
|
|
||||||
}
|
|
||||||
|
|
||||||
void check_error(int error, int expected)
|
|
||||||
{
|
|
||||||
if (expected == 0) {
|
|
||||||
if (error == 0)
|
|
||||||
print("Success!\n");
|
|
||||||
else
|
|
||||||
print("Failed with error: %d\n", error);
|
|
||||||
} else {
|
|
||||||
if (error == 0)
|
|
||||||
print("Failed (expected error: %d)\n", expected);
|
|
||||||
else
|
|
||||||
print("Success!\n");
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
void call_func(const std :: string &test, void (*func)(), int expected)
|
|
||||||
{
|
|
||||||
print("Test %s: ", test.c_str());
|
|
||||||
try {
|
|
||||||
func();
|
|
||||||
check_error(0, expected);
|
|
||||||
} catch (int error) {
|
|
||||||
check_error(error, expected);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
void call_func(const std :: string &test, void (*func)(long), long arg, int expected)
|
|
||||||
{
|
|
||||||
print("Test %s: ", test.c_str());
|
|
||||||
try {
|
|
||||||
func(arg);
|
|
||||||
check_error(0, expected);
|
|
||||||
} catch (int error) {
|
|
||||||
check_error(error, expected);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
/* Call various functions without a track loaded */
|
|
||||||
void test_0()
|
|
||||||
{
|
|
||||||
call_func("0a", audio :: play, 0);
|
|
||||||
call_func("0b", audio :: pause, 0);
|
|
||||||
call_func("0c", audio :: seek_to, 10, 0);
|
|
||||||
call_func("0d", audio :: next, -E_EXIST);
|
|
||||||
call_func("0e", audio :: stop, 0);
|
|
||||||
check_ret("0f", audio :: position(), 0);
|
|
||||||
check_ret("0g", audio :: duration(), 0);
|
|
||||||
try {
|
|
||||||
print("Test 0h: ");
|
|
||||||
audio :: current_trackid();
|
|
||||||
check_error(0, -E_EXIST);
|
|
||||||
} catch (int error) {
|
|
||||||
check_error(error, -E_EXIST);
|
|
||||||
}
|
|
||||||
call_func("0i", audio :: previous, -E_EXIST);
|
|
||||||
print("\n");
|
|
||||||
}
|
|
||||||
|
|
||||||
void test_1()
|
|
||||||
{
|
|
||||||
library :: Song song;
|
|
||||||
library :: lookup(0, &song);
|
|
||||||
|
|
||||||
call_func("1a", audio :: next, 0);
|
|
||||||
call_func("1b", audio :: play, 0);
|
|
||||||
call_func("1c", audio :: pause, 0);
|
|
||||||
call_func("1d", audio :: seek_to, 1 * GST_SECOND, 0);
|
|
||||||
call_func("1e", audio :: stop, 0);
|
|
||||||
check_ret("1f", audio :: current_trackid() == 0, true);
|
|
||||||
check_ret("1g", audio :: position(), 0);
|
|
||||||
call_func("1h", audio :: previous, 0);
|
|
||||||
check_ret("1i", audio :: current_trackid() == 0, true);
|
|
||||||
audio :: next();
|
|
||||||
audio :: next();
|
|
||||||
call_func("1j", audio :: previous, 0);
|
|
||||||
check_ret("1k", audio :: current_trackid() == 1, true);
|
|
||||||
call_func("1l", audio :: previous, 0);
|
|
||||||
check_ret("1m", audio :: current_trackid() == 0, true);
|
|
||||||
print("\n");
|
|
||||||
}
|
|
||||||
|
|
||||||
/* Test pause_after() */
|
|
||||||
unsigned int test_2_count = 0;
|
|
||||||
int test_2_cb(gpointer data)
|
|
||||||
{
|
|
||||||
long seek_pos, pos, max;
|
|
||||||
library :: Song song;
|
|
||||||
GMainLoop *loop = (GMainLoop *)data;
|
|
||||||
|
|
||||||
library :: lookup(audio :: current_trackid(), &song);
|
|
||||||
pos = audio :: position();
|
|
||||||
|
|
||||||
switch (test_2_count) {
|
|
||||||
case 0:
|
|
||||||
break;
|
|
||||||
case 1:
|
|
||||||
check_ret("2g", audio :: duration(), song.track->length * GST_SECOND);
|
|
||||||
seek_pos = (song.track->length * GST_SECOND) - GST_SECOND;
|
|
||||||
call_func("2h", audio :: seek_to, seek_pos, 0);
|
|
||||||
break;
|
|
||||||
case 2:
|
|
||||||
max = (song.track->length * GST_SECOND) - GST_SECOND + (501 * GST_MSECOND);
|
|
||||||
|
|
||||||
check_ret("2i", pos <= max, true);
|
|
||||||
call_func("2j", audio :: stop, 0);
|
|
||||||
break;
|
|
||||||
case 3:
|
|
||||||
check_ret("2k", pos, 0);
|
|
||||||
call_func("2l", audio :: play, 0);
|
|
||||||
call_func("2m", audio :: seek_to, audio :: duration() - 1, 0);
|
|
||||||
break;
|
|
||||||
case 4:
|
|
||||||
check_ret("2n", audio :: pause_count(), (long)2);
|
|
||||||
call_func("2o", audio :: seek_to, audio :: duration() - 1, 0);
|
|
||||||
break;
|
|
||||||
case 5:
|
|
||||||
check_ret("2p", audio :: pause_count(), (long)1);
|
|
||||||
call_func("2q", audio :: seek_to, audio :: duration() - 1, 0);
|
|
||||||
break;
|
|
||||||
case 6:
|
|
||||||
check_ret("2r", audio :: pause_count(), (long)0);
|
|
||||||
call_func("2s", audio :: seek_to, audio :: duration() - 1, 0);
|
|
||||||
break;
|
|
||||||
case 7:
|
|
||||||
check_ret("2t", audio :: pause_enabled(), false);
|
|
||||||
check_ret("2u", audio :: pause_count(), (long)0);
|
|
||||||
break;
|
|
||||||
case 8:
|
|
||||||
pos = audio :: position();
|
|
||||||
check_ret("2v", (0 <= pos) && (pos <= GST_MSECOND), true);
|
|
||||||
break;
|
|
||||||
case 9:
|
|
||||||
pos = audio :: position();
|
|
||||||
check_ret("2w", (0 <= pos) && (pos <= GST_MSECOND), true);
|
|
||||||
default:
|
|
||||||
g_main_quit(loop);
|
|
||||||
}
|
|
||||||
|
|
||||||
test_2_count++;
|
|
||||||
return true;
|
|
||||||
}
|
|
||||||
|
|
||||||
void test_2()
|
|
||||||
{
|
|
||||||
GMainLoop *loop;
|
|
||||||
|
|
||||||
check_ret("2a", audio :: pause_enabled(), false);
|
|
||||||
check_ret("2b", audio :: pause_count(), (long)0);
|
|
||||||
audio :: pause_after(true, 3);
|
|
||||||
check_ret("2c", audio :: pause_enabled(), true);
|
|
||||||
check_ret("2d", audio :: pause_count(), (long)3);
|
|
||||||
audio :: next();
|
|
||||||
check_ret("2e", audio :: pause_enabled(), true);
|
|
||||||
check_ret("2f", audio :: pause_count(), (long)3);
|
|
||||||
|
|
||||||
audio :: play();
|
|
||||||
loop = g_main_loop_new(NULL, FALSE);
|
|
||||||
g_timeout_add(500, test_2_cb, loop);
|
|
||||||
g_main_loop_run(loop);
|
|
||||||
}
|
|
||||||
|
|
||||||
int main(int argc, char **argv)
|
|
||||||
{
|
|
||||||
Playqueue *pqueue;
|
|
||||||
|
|
||||||
gen_library();
|
|
||||||
|
|
||||||
/* Initialize before testing */
|
|
||||||
audio :: init(&argc, &argv);
|
|
||||||
test_0();
|
|
||||||
|
|
||||||
/* Read in library, set up a playlist */
|
|
||||||
library::init();
|
|
||||||
deck::init();
|
|
||||||
library :: reset();
|
|
||||||
library :: add_path("/tmp/library/0");
|
|
||||||
while (idle :: run_task());
|
|
||||||
|
|
||||||
pqueue = deck :: create(false);
|
|
||||||
for (unsigned int i = 0; i < 150; i++)
|
|
||||||
pqueue->add(i);
|
|
||||||
|
|
||||||
test_1();
|
|
||||||
test_2();
|
|
||||||
|
|
||||||
audio :: quit();
|
|
||||||
return 0;
|
|
||||||
}
|
|
|
@ -1,53 +0,0 @@
|
||||||
Generating library: 0
|
|
||||||
Generating library: 1
|
|
||||||
Generating library: 2
|
|
||||||
Generating library: 3
|
|
||||||
Generating library: 4
|
|
||||||
|
|
||||||
Test 0a: Success!
|
|
||||||
Test 0b: Success!
|
|
||||||
Test 0c: Success!
|
|
||||||
Test 0d: Success!
|
|
||||||
Test 0e: Success!
|
|
||||||
Test 0f: Success!
|
|
||||||
Test 0g: Success!
|
|
||||||
Test 0h: Success!
|
|
||||||
Test 0i: Success!
|
|
||||||
|
|
||||||
Test 1a: Success!
|
|
||||||
Test 1b: Success!
|
|
||||||
Test 1c: Success!
|
|
||||||
Test 1d: Success!
|
|
||||||
Test 1e: Success!
|
|
||||||
Test 1f: Success!
|
|
||||||
Test 1g: Success!
|
|
||||||
Test 1h: Success!
|
|
||||||
Test 1i: Success!
|
|
||||||
Test 1j: Success!
|
|
||||||
Test 1k: Success!
|
|
||||||
Test 1l: Success!
|
|
||||||
Test 1m: Success!
|
|
||||||
|
|
||||||
Test 2a: Success!
|
|
||||||
Test 2b: Success!
|
|
||||||
Test 2c: Success!
|
|
||||||
Test 2d: Success!
|
|
||||||
Test 2e: Success!
|
|
||||||
Test 2f: Success!
|
|
||||||
Test 2g: Success!
|
|
||||||
Test 2h: Success!
|
|
||||||
Test 2i: Success!
|
|
||||||
Test 2j: Success!
|
|
||||||
Test 2k: Success!
|
|
||||||
Test 2l: Success!
|
|
||||||
Test 2m: Success!
|
|
||||||
Test 2n: Success!
|
|
||||||
Test 2o: Success!
|
|
||||||
Test 2p: Success!
|
|
||||||
Test 2q: Success!
|
|
||||||
Test 2r: Success!
|
|
||||||
Test 2s: Success!
|
|
||||||
Test 2t: Success!
|
|
||||||
Test 2u: Success!
|
|
||||||
Test 2v: Success!
|
|
||||||
Test 2w: Success!
|
|
|
@ -50,6 +50,12 @@ void test_driver()
|
||||||
|
|
||||||
driver->error();
|
driver->error();
|
||||||
test_equal(error_count, (unsigned)1);
|
test_equal(error_count, (unsigned)1);
|
||||||
|
|
||||||
|
driver->play();
|
||||||
|
driver->seek_to(4242);
|
||||||
|
driver->load(file);
|
||||||
|
test_equal(driver->is_playing(), false);
|
||||||
|
test_equal(driver->position(), (long)0);
|
||||||
}
|
}
|
||||||
|
|
||||||
int main(int argc, char **argv)
|
int main(int argc, char **argv)
|
||||||
|
|
Loading…
Reference in New Issue