audio: Implement pause after N tracks feature
This patch implements the pause-after-N-tracks feature. I also included various improvements to the audio code. Signed-off-by: Anna Schumaker <schumaker.anna@gmail.com>
This commit is contained in:
parent
ee9a98737a
commit
c65c8b06f2
|
@ -33,6 +33,9 @@ Audio: (lib/audio.cpp)
|
|||
options from the argv array as they are processed, so pass
|
||||
pointers to argc and argv to this function.
|
||||
|
||||
void audio :: quit()
|
||||
Clean up memory allocated by gstreamer.
|
||||
|
||||
bool audio :: play()
|
||||
bool audio :: pause()
|
||||
Change the gstreamer state to either GST_STATE_PLAYING or
|
||||
|
@ -71,12 +74,19 @@ Audio: (lib/audio.cpp)
|
|||
unsigned int audio :: duration()
|
||||
Return the duration of the current song in seconds.
|
||||
|
||||
void audio :: pause_after(unsigned int)
|
||||
Pause after N tracks, pass a negative number to disable. The
|
||||
count will only be decremented when an end-of-stream message
|
||||
is received by the gstreamer pipeline.
|
||||
void audio :: pause_after(bool enabled, unsigned int N)
|
||||
Pause after N tracks. The first parameter is a bool
|
||||
representing if this feature is enabled or not (true == enabled,
|
||||
false == disabled).
|
||||
|
||||
The count will only be decremented when an end-of-stream message
|
||||
is received by the gstreamer pipeline, and not when calling
|
||||
next().
|
||||
|
||||
bool audio :: pause_enabled()
|
||||
Return true if pausing is enabled, and false if pausing is
|
||||
disabled.
|
||||
|
||||
unsigned int audio :: pause_count()
|
||||
Return the number of tracks that will be played before
|
||||
playback pauses. Throw -1 if the user does not want us to
|
||||
pause.
|
||||
playback pauses.
|
||||
|
|
|
@ -12,6 +12,7 @@ namespace audio
|
|||
{
|
||||
|
||||
void init(int *, char ***);
|
||||
void quit();
|
||||
|
||||
bool play();
|
||||
bool pause();
|
||||
|
@ -22,6 +23,10 @@ namespace audio
|
|||
bool seek_to(long);
|
||||
long position();
|
||||
long duration();
|
||||
|
||||
void pause_after(bool, unsigned int);
|
||||
bool pause_enabled();
|
||||
unsigned int pause_count();
|
||||
};
|
||||
|
||||
#endif /* OCARINA_AUDIO_H */
|
||||
|
|
|
@ -8,11 +8,49 @@
|
|||
#include <string.h>
|
||||
|
||||
static GstElement *ocarina_player;
|
||||
|
||||
static bool track_loaded = false;
|
||||
static unsigned int cur_trackid = 0;
|
||||
|
||||
static bool o_pause_enabled = false;
|
||||
static unsigned int o_pause_count = 0;
|
||||
static bool o_should_pause = false;
|
||||
|
||||
static void parse_error(GstMessage *error)
|
||||
{
|
||||
GError *err;
|
||||
gchar *debug;
|
||||
|
||||
gst_message_parse_error(error, &err, &debug);
|
||||
g_print("Error: %s\n", err->message);
|
||||
g_error_free(err);
|
||||
g_free(debug);
|
||||
}
|
||||
|
||||
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;
|
||||
} else
|
||||
o_pause_count--;
|
||||
}
|
||||
|
||||
static gboolean on_message(GstBus *bus, GstMessage *message, gpointer data)
|
||||
{
|
||||
switch (GST_MESSAGE_TYPE(message)) {
|
||||
case GST_MESSAGE_ERROR:
|
||||
parse_error(message);
|
||||
audio :: next();
|
||||
break;
|
||||
case GST_MESSAGE_EOS:
|
||||
handle_pause_count();
|
||||
audio :: next();
|
||||
default:
|
||||
break;
|
||||
}
|
||||
return TRUE;
|
||||
}
|
||||
|
||||
|
@ -36,9 +74,15 @@ static bool load_song(library :: Song &song)
|
|||
gchar *escaped;
|
||||
std::string filepath = song.library->root_path + "/" + song.track->filepath;
|
||||
|
||||
gst_element_get_state(GST_ELEMENT(ocarina_player), &state,
|
||||
NULL, GST_CLOCK_TIME_NONE);
|
||||
if (o_should_pause == true) {
|
||||
state = GST_STATE_PAUSED;
|
||||
o_should_pause = false;
|
||||
} else {
|
||||
gst_element_get_state(GST_ELEMENT(ocarina_player), &state,
|
||||
NULL, GST_CLOCK_TIME_NONE);
|
||||
}
|
||||
|
||||
change_state(GST_STATE_NULL);
|
||||
escaped = gst_filename_to_uri(filepath.c_str(), NULL);
|
||||
g_object_set(G_OBJECT(ocarina_player), "uri", escaped, NULL);
|
||||
g_free(escaped);
|
||||
|
@ -58,6 +102,11 @@ void audio :: init(int *argc, char ***argv)
|
|||
gst_bus_add_watch(bus, on_message, NULL);
|
||||
}
|
||||
|
||||
void audio :: quit()
|
||||
{
|
||||
gst_deinit();
|
||||
}
|
||||
|
||||
bool audio :: play()
|
||||
{
|
||||
if (track_loaded == false)
|
||||
|
@ -142,3 +191,19 @@ long audio :: duration()
|
|||
return 0;
|
||||
return duration;
|
||||
}
|
||||
|
||||
void audio :: pause_after(bool enabled, unsigned int n)
|
||||
{
|
||||
o_pause_enabled = enabled;
|
||||
o_pause_count = n;
|
||||
}
|
||||
|
||||
bool audio :: pause_enabled()
|
||||
{
|
||||
return o_pause_enabled;
|
||||
}
|
||||
|
||||
unsigned int audio :: pause_count()
|
||||
{
|
||||
return o_pause_count;
|
||||
}
|
||||
|
|
|
@ -63,11 +63,90 @@ void test_1()
|
|||
check_ret("1b", audio :: play(), true);
|
||||
check_ret("1c", audio :: pause(), 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);
|
||||
check_ret("1e", audio :: stop(), true);
|
||||
check_ret("1f", audio :: current_trackid() == 0, true);
|
||||
check_ret("1g", audio :: position(), 0);
|
||||
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;
|
||||
check_ret("2h", audio :: seek_to(seek_pos), true);
|
||||
break;
|
||||
case 2:
|
||||
max = (song.track->length * GST_SECOND) - GST_SECOND + (501 * GST_MSECOND);
|
||||
|
||||
check_ret("2i", pos <= max, true);
|
||||
check_ret("2j", audio :: stop(), true);
|
||||
break;
|
||||
case 3:
|
||||
check_ret("2k", pos, 0);
|
||||
check_ret("2l", audio :: play(), true);
|
||||
check_ret("2m", audio :: seek_to(audio :: duration() - 1), true);
|
||||
break;
|
||||
case 4:
|
||||
check_ret("2n", audio :: pause_count(), (long)2);
|
||||
check_ret("2o", audio :: seek_to(audio :: duration() - 1), true);
|
||||
break;
|
||||
case 5:
|
||||
check_ret("2p", audio :: pause_count(), (long)1);
|
||||
check_ret("2q", audio :: seek_to(audio :: duration() - 1), true);
|
||||
break;
|
||||
case 6:
|
||||
check_ret("2r", audio :: pause_count(), (long)0);
|
||||
check_ret("2s", audio :: seek_to(audio :: duration() - 1), true);
|
||||
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)
|
||||
|
@ -87,6 +166,8 @@ int main(int argc, char **argv)
|
|||
plist->add(i);
|
||||
|
||||
test_1();
|
||||
test_2();
|
||||
|
||||
//audio :: quit();
|
||||
return 0;
|
||||
}
|
||||
|
|
|
@ -0,0 +1,46 @@
|
|||
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 1a: Success!
|
||||
Test 1b: Success!
|
||||
Test 1c: Success!
|
||||
Test 1d: Success!
|
||||
Test 1e: Success!
|
||||
Test 1f: Success!
|
||||
Test 1g: 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!
|
Loading…
Reference in New Issue