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
GST_STATE_PAUSED. Return true on success and false otherwise.
bool audio :: seek_to(int)
Seek to a position X seconds into the track. Return true if
a track is loaded and the seek isn't out of bounds. False
bool audio :: seek_to(long)
Seek to a position X nanoseconds into the track. Return true
if track is loaded and the seek isn't out of bounds. False
otherwise.
Seconds can be converted to nanoseconds by multiplying with
GST_SECOND.
void audio :: stop()
pause()
seek_to(0)
@ -75,4 +78,5 @@ Audio: (lib/audio.cpp)
unsigned int audio :: pause_count()
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 pause();
bool seek_to(double);
bool stop();
bool next();
unsigned int current_trackid();
bool seek_to(long);
long position();
long duration();
};
#endif /* OCARINA_AUDIO_H */

View File

@ -9,6 +9,7 @@
static GstElement *ocarina_player;
static bool track_loaded = false;
static unsigned int cur_trackid = 0;
static gboolean on_message(GstBus *bus, GstMessage *message, gpointer data)
{
@ -71,30 +72,73 @@ bool audio :: pause()
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)
return false;
return gst_element_seek_simple(GST_ELEMENT(ocarina_player),
ret = gst_element_seek_simple(GST_ELEMENT(ocarina_player),
GST_FORMAT_TIME,
GST_SEEK_FLAG_FLUSH,
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;
}
bool audio :: next()
{
unsigned int id;
library :: Song song;
try {
id = deck :: next();
if (library :: lookup(id, &song) == false)
track_loaded = false;
else
track_loaded = load_song(song);
track_loaded = _next();
} catch (int) {
track_loaded = false;
}
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");
}
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 */
void test_0()
{
@ -32,15 +41,33 @@ void test_0()
check_ret("0b", audio :: pause(), false);
check_ret("0c", audio :: seek_to(10), 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");
}
void test_1()
{
library :: Song song;
library :: lookup(0, &song);
check_ret("1a", audio :: next(), true);
check_ret("1b", audio :: play(), 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)