audio: New features and improvements

- Seek(), position() and duration() functions are implemented
  - There are bugs in the test program :(
- Clean up next()

Signed-off-by: Anna Schumaker <schumaker.anna@gmail.com>
This commit is contained in:
Anna Schumaker 2013-12-24 22:07:23 -05:00 committed by Anna Schumaker
parent edbdd1c66f
commit ee9a98737a
4 changed files with 95 additions and 16 deletions

View File

@ -38,11 +38,14 @@ Audio: (lib/audio.cpp)
Change the gstreamer state to either GST_STATE_PLAYING or Change the gstreamer state to either GST_STATE_PLAYING or
GST_STATE_PAUSED. Return true on success and false otherwise. GST_STATE_PAUSED. Return true on success and false otherwise.
bool audio :: seek_to(int) bool audio :: seek_to(long)
Seek to a position X seconds into the track. Return true if Seek to a position X nanoseconds into the track. Return true
a track is loaded and the seek isn't out of bounds. False if track is loaded and the seek isn't out of bounds. False
otherwise. otherwise.
Seconds can be converted to nanoseconds by multiplying with
GST_SECOND.
void audio :: stop() void audio :: stop()
pause() pause()
seek_to(0) seek_to(0)
@ -75,4 +78,5 @@ Audio: (lib/audio.cpp)
unsigned int audio :: pause_count() unsigned int audio :: pause_count()
Return the number of tracks that will be played before Return the number of tracks that will be played before
playback pauses. playback pauses. Throw -1 if the user does not want us to
pause.

View File

@ -15,9 +15,13 @@ namespace audio
bool play(); bool play();
bool pause(); bool pause();
bool seek_to(double); bool stop();
bool next(); bool next();
unsigned int current_trackid();
bool seek_to(long);
long position();
long duration();
}; };
#endif /* OCARINA_AUDIO_H */ #endif /* OCARINA_AUDIO_H */

View File

@ -9,6 +9,7 @@
static GstElement *ocarina_player; static GstElement *ocarina_player;
static bool track_loaded = false; static bool track_loaded = false;
static unsigned int cur_trackid = 0;
static gboolean on_message(GstBus *bus, GstMessage *message, gpointer data) static gboolean on_message(GstBus *bus, GstMessage *message, gpointer data)
{ {
@ -71,30 +72,73 @@ bool audio :: pause()
return change_state(GST_STATE_PAUSED); return change_state(GST_STATE_PAUSED);
} }
bool audio :: seek_to(double pos) bool audio :: stop()
{ {
if (pause() == false)
return false;
return seek_to(0);
}
bool audio :: seek_to(long pos)
{
bool ret;
if (track_loaded == false) if (track_loaded == false)
return false; return false;
return gst_element_seek_simple(GST_ELEMENT(ocarina_player), ret = gst_element_seek_simple(GST_ELEMENT(ocarina_player),
GST_FORMAT_TIME, GST_FORMAT_TIME,
GST_SEEK_FLAG_FLUSH, GST_SEEK_FLAG_FLUSH,
pos); pos);
return ret;
}
static bool _next()
{
library :: Song song;
unsigned int id = deck :: next();
if (library :: lookup(id, &song) == false)
return false;
if (load_song(song) == false)
return false;
cur_trackid = id;
return true; return true;
} }
bool audio :: next() bool audio :: next()
{ {
unsigned int id;
library :: Song song;
try { try {
id = deck :: next(); track_loaded = _next();
if (library :: lookup(id, &song) == false)
track_loaded = false;
else
track_loaded = load_song(song);
} catch (int) { } catch (int) {
track_loaded = false; track_loaded = false;
} }
return track_loaded; return track_loaded;
} }
unsigned int audio :: current_trackid()
{
if (track_loaded == false)
throw -1;
return cur_trackid;
}
long audio :: position()
{
long position;
if (track_loaded == false)
return 0;
if (!gst_element_query_position(GST_ELEMENT(ocarina_player), GST_FORMAT_TIME, &position))
return 0;
return position;
}
long audio :: duration()
{
long duration;
if (track_loaded == false)
return 0;
if (!gst_element_query_duration(ocarina_player, GST_FORMAT_TIME, &duration))
return 0;
return duration;
}

View File

@ -25,6 +25,15 @@ void check_ret(const std :: string &test, bool ret, bool expected)
print("Failed.\n"); print("Failed.\n");
} }
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);
}
/* Call various functions without a track loaded */ /* Call various functions without a track loaded */
void test_0() void test_0()
{ {
@ -32,15 +41,33 @@ void test_0()
check_ret("0b", audio :: pause(), false); check_ret("0b", audio :: pause(), false);
check_ret("0c", audio :: seek_to(10), false); check_ret("0c", audio :: seek_to(10), false);
check_ret("0d", audio :: next(), false); check_ret("0d", audio :: next(), false);
check_ret("0e", audio :: stop(), false);
check_ret("0f", audio :: position(), 0);
check_ret("0g", audio :: duration(), 0);
try {
print("Test 0h: ");
audio :: current_trackid();
print("Failed.\n");
} catch (int error) {
print("Success!\n");
}
print("\n"); print("\n");
} }
void test_1() void test_1()
{ {
library :: Song song;
library :: lookup(0, &song);
check_ret("1a", audio :: next(), true); check_ret("1a", audio :: next(), true);
check_ret("1b", audio :: play(), true); check_ret("1b", audio :: play(), true);
check_ret("1c", audio :: pause(), true); check_ret("1c", audio :: pause(), true);
check_ret("1c", audio :: seek_to(10), true); check_ret("1d", audio :: seek_to(1 * GST_SECOND), true);
check_ret("1e", audio :: position(), 1 * GST_SECOND);
check_ret("1f", audio :: stop(), true);
check_ret("1g", audio :: current_trackid() == 0, true);
check_ret("1h", audio :: position(), 0);
check_ret("1i", audio :: duration(), song.track->length);
} }
int main(int argc, char **argv) int main(int argc, char **argv)