core/audio: Add on_state_change() audio operation

Called to notify when playback state has changed.

Signed-off-by: Anna Schumaker <Anna@OcarinaProject.net>
This commit is contained in:
Anna Schumaker 2015-12-18 08:09:34 -05:00
parent ed5f035855
commit 0cf5187867
4 changed files with 54 additions and 40 deletions

View File

@ -24,9 +24,14 @@ static void __audio_save()
static bool __audio_change_state(GstState state) static bool __audio_change_state(GstState state)
{ {
GstStateChangeReturn ret = GST_STATE_CHANGE_FAILURE; GstStateChangeReturn ret = GST_STATE_CHANGE_FAILURE;
if (audio_cur_state() != state) if (audio_cur_state() != state)
ret = gst_element_set_state(audio_player, state); ret = gst_element_set_state(audio_player, state);
return ret != GST_STATE_CHANGE_FAILURE; if (ret == GST_STATE_CHANGE_FAILURE)
return false;
audio_ops->on_state_change(state);
return true;
} }
static bool __audio_load(struct track *track, GstState state) static bool __audio_load(struct track *track, GstState state)
@ -42,8 +47,8 @@ static bool __audio_load(struct track *track, GstState state)
gst_element_set_state(audio_player, GST_STATE_NULL); gst_element_set_state(audio_player, GST_STATE_NULL);
g_object_set(G_OBJECT(audio_player), "uri", uri, NULL); g_object_set(G_OBJECT(audio_player), "uri", uri, NULL);
audio_ops->on_load(track);
__audio_change_state(state); __audio_change_state(state);
audio_ops->on_load(track, state);
__audio_save(); __audio_save();
g_free(uri); g_free(uri);

View File

@ -38,13 +38,7 @@ static void set_markup(Gtk::Label *label, const std::string &size,
Glib::Markup::escape_text(text) + "</span>"); Glib::Markup::escape_text(text) + "</span>");
} }
static void on_pause() static void on_load(struct track *track)
{
o_play->show();
o_pause->hide();
}
static void on_load(struct track *track, GstState state)
{ {
gchar *str = g_strdup_printf("From: %s", track->tr_album->al_name); gchar *str = g_strdup_printf("From: %s", track->tr_album->al_name);
set_markup(o_album, "x-large", str); set_markup(o_album, "x-large", str);
@ -61,9 +55,17 @@ static void on_load(struct track *track, GstState state)
g_free(str); g_free(str);
plist :: track_loaded(track); plist :: track_loaded(track);
}
if (state != GST_STATE_PLAYING) static void on_change_state(GstState state)
on_pause(); {
if (state == GST_STATE_PLAYING) {
o_play->hide();
o_pause->show();
} else {
o_play->show();
o_pause->hide();
}
} }
static void on_config_pause(int n) static void on_config_pause(int n)
@ -79,6 +81,7 @@ static void on_config_pause(int n)
struct audio_ops audio_ops = { struct audio_ops audio_ops = {
on_load, on_load,
on_change_state,
on_config_pause, on_config_pause,
}; };
@ -116,25 +119,9 @@ static bool on_timeout()
void gst :: play() void gst :: play() { audio_play(); }
{ void gst :: pause() { audio_pause(); }
if (audio_play()) { void gst :: stop() { audio_stop(); }
o_play->hide();
o_pause->show();
}
}
void gst :: pause()
{
if (audio_pause()) {
on_pause();
}
}
void gst :: stop() {
if (audio_stop())
on_pause();
}
void gst :: next() void gst :: next()
{ {

View File

@ -9,7 +9,10 @@
struct audio_ops { struct audio_ops {
/* Called when a track is loaded. */ /* Called when a track is loaded. */
void (*on_load)(struct track *, GstState); void (*on_load)(struct track *);
/* Called when playback state changes. */
void (*on_state_change)(GstState);
/* Called when the automatic pause state changes. */ /* Called when the automatic pause state changes. */
void (*on_config_pause)(int); void (*on_config_pause)(int);

View File

@ -10,6 +10,7 @@
#include <tests/test.h> #include <tests/test.h>
static unsigned int load_count = 0; static unsigned int load_count = 0;
static unsigned int state_count = 0;
static int pause_count = 0; static int pause_count = 0;
@ -38,15 +39,13 @@ static void test_send_error()
} }
static void test_audio_load(struct track *track, GstState state) static void test_audio_load(struct track *track) { load_count++; }
{ static void test_change_state(GstState state) { state_count++; }
load_count++;
}
static void test_config_pause(int n) { pause_count = n; } static void test_config_pause(int n) { pause_count = n; }
static struct audio_ops test_audio_ops = { static struct audio_ops test_audio_ops = {
test_audio_load, test_audio_load,
test_change_state,
test_config_pause, test_config_pause,
}; };
@ -80,7 +79,8 @@ static void test_init()
test_equal(audio_duration(), 0); test_equal(audio_duration(), 0);
test_equal((void *)audio_cur_track(), NULL); test_equal((void *)audio_cur_track(), NULL);
test_equal(audio_cur_state(), GST_STATE_NULL); test_equal(audio_cur_state(), GST_STATE_NULL);
test_equal(load_count, 0); test_equal(load_count, 0);
test_equal(state_count, 0);
collection_add("tests/Music/Hyrule Symphony"); collection_add("tests/Music/Hyrule Symphony");
while (idle_run_task()) {}; while (idle_run_task()) {};
@ -92,33 +92,39 @@ static void test_init()
static void test_playback() static void test_playback()
{ {
test_equal(audio_load(track_get(0)), (bool)true); test_equal(audio_load(track_get(0)), (bool)true);
test_equal(load_count, 1); test_equal(load_count, 1);
test_equal(state_count, 0);
test_equal((void *)audio_cur_track(), (void *)track_get(0)); test_equal((void *)audio_cur_track(), (void *)track_get(0));
test_equal(audio_cur_state(), GST_STATE_NULL); test_equal(audio_cur_state(), GST_STATE_NULL);
test_equal(queue_size(history_get_queue()), 1); test_equal(queue_size(history_get_queue()), 1);
test_equal(audio_duration(), track_get(0)->tr_length * GST_SECOND); test_equal(audio_duration(), track_get(0)->tr_length * GST_SECOND);
test_equal(audio_load(NULL), (bool)false); test_equal(audio_load(NULL), (bool)false);
test_equal(load_count, 1); test_equal(load_count, 1);
test_equal(state_count, 0);
test_equal((void *)audio_cur_track(), (void *)track_get(0)); test_equal((void *)audio_cur_track(), (void *)track_get(0));
test_equal(queue_size(history_get_queue()), 1); test_equal(queue_size(history_get_queue()), 1);
test_equal(audio_load(track_get(0)), (bool)false); test_equal(audio_load(track_get(0)), (bool)false);
test_equal(load_count, 1); test_equal(load_count, 1);
test_equal(state_count, 0);
test_equal(queue_size(history_get_queue()), 1); test_equal(queue_size(history_get_queue()), 1);
test_equal(audio_play(), (bool)true); test_equal(audio_play(), (bool)true);
test_equal(audio_play(), (bool)false); test_equal(audio_play(), (bool)false);
test_equal(state_count, 1);
test_equal(audio_cur_state(), GST_STATE_PLAYING); test_equal(audio_cur_state(), GST_STATE_PLAYING);
test_equal(audio_pause(), (bool)true); test_equal(audio_pause(), (bool)true);
test_equal(audio_pause(), (bool)false); test_equal(audio_pause(), (bool)false);
test_equal(state_count, 2);
test_equal(audio_cur_state(), GST_STATE_PAUSED); test_equal(audio_cur_state(), GST_STATE_PAUSED);
test_equal(test_audio_seek(5 * GST_SECOND), (bool)true); test_equal(test_audio_seek(5 * GST_SECOND), (bool)true);
test_equal(audio_position(), 5 * GST_SECOND); test_equal(audio_position(), 5 * GST_SECOND);
test_equal(audio_stop(), (bool)true); test_equal(audio_stop(), (bool)true);
test_equal(state_count, 2);
test_equal(audio_position(), 0); test_equal(audio_position(), 0);
test_equal(audio_cur_state(), GST_STATE_PAUSED); test_equal(audio_cur_state(), GST_STATE_PAUSED);
@ -126,7 +132,9 @@ static void test_playback()
test_equal(audio_position(), 42 * GST_SECOND); test_equal(audio_position(), 42 * GST_SECOND);
test_equal(audio_play(), (bool)true); test_equal(audio_play(), (bool)true);
test_equal(state_count, 3);
test_equal(audio_stop(), (bool)true); test_equal(audio_stop(), (bool)true);
test_equal(state_count, 4);
test_equal(audio_cur_state(), GST_STATE_PAUSED); test_equal(audio_cur_state(), GST_STATE_PAUSED);
test_equal(audio_position(), 0); test_equal(audio_position(), 0);
@ -140,6 +148,7 @@ static void test_next()
struct queue *temp_q = tempq_alloc(NULL, 0); struct queue *temp_q = tempq_alloc(NULL, 0);
int i; int i;
state_count = 0;
/* First, let's test getting tracks from a temporary queue. */ /* First, let's test getting tracks from a temporary queue. */
queue_add(temp_q, track_get(2)); queue_add(temp_q, track_get(2));
queue_add(temp_q, track_get(1)); queue_add(temp_q, track_get(1));
@ -157,6 +166,7 @@ static void test_next()
test_loop_equal((void *)audio_cur_track(), test_loop_equal((void *)audio_cur_track(),
(void *)track_get(i), i); (void *)track_get(i), i);
} test_loop_passed(); } test_loop_passed();
test_equal(state_count, 3);
test_equal((void *)tempq_get(0), NULL); test_equal((void *)tempq_get(0), NULL);
/* Tracks should now be picked from the collection. */ /* Tracks should now be picked from the collection. */
@ -170,6 +180,7 @@ static void test_next()
test_loop_equal(audio_cur_state(), GST_STATE_PLAYING, i); test_loop_equal(audio_cur_state(), GST_STATE_PLAYING, i);
test_loop_equal(audio_cur_track()->tr_track, i, i); test_loop_equal(audio_cur_track()->tr_track, i, i);
} test_loop_passed(); } test_loop_passed();
test_equal(state_count, 7);
} }
static void test_prev() static void test_prev()
@ -177,31 +188,37 @@ static void test_prev()
struct queue *history_q = history_get_queue(); struct queue *history_q = history_get_queue();
struct track *track = queue_at(history_q, 0); struct track *track = queue_at(history_q, 0);
state_count = 0;
test_equal(audio_prev()->tr_track, 2); test_equal(audio_prev()->tr_track, 2);
test_equal((void *)queue_at(history_q, 0), (void *)track); test_equal((void *)queue_at(history_q, 0), (void *)track);
test_equal(audio_cur_state(), GST_STATE_PLAYING); test_equal(audio_cur_state(), GST_STATE_PLAYING);
test_equal(audio_cur_track()->tr_track, 2); test_equal(audio_cur_track()->tr_track, 2);
test_equal(state_count, 1);
test_equal(audio_prev()->tr_track, 1); test_equal(audio_prev()->tr_track, 1);
test_equal((void *)queue_at(history_q, 0), (void *)track); test_equal((void *)queue_at(history_q, 0), (void *)track);
test_equal(audio_cur_state(), GST_STATE_PLAYING); test_equal(audio_cur_state(), GST_STATE_PLAYING);
test_equal(audio_cur_track()->tr_track, 1); test_equal(audio_cur_track()->tr_track, 1);
test_equal(state_count, 2);
test_equal(audio_pause(), (bool)true); test_equal(audio_pause(), (bool)true);
test_equal(audio_prev()->tr_dbe.dbe_index, 0); test_equal(audio_prev()->tr_dbe.dbe_index, 0);
test_equal((void *)queue_at(history_q, 0), (void *)track); test_equal((void *)queue_at(history_q, 0), (void *)track);
test_equal(audio_cur_state(), GST_STATE_PAUSED); test_equal(audio_cur_state(), GST_STATE_PAUSED);
test_equal(audio_cur_track()->tr_dbe.dbe_index, 0); test_equal(audio_cur_track()->tr_dbe.dbe_index, 0);
test_equal(state_count, 4);
test_equal(audio_prev()->tr_dbe.dbe_index, 1); test_equal(audio_prev()->tr_dbe.dbe_index, 1);
test_equal((void *)queue_at(history_q, 0), (void *)track); test_equal((void *)queue_at(history_q, 0), (void *)track);
test_equal(audio_cur_state(), GST_STATE_PAUSED); test_equal(audio_cur_state(), GST_STATE_PAUSED);
test_equal(audio_cur_track()->tr_dbe.dbe_index, 1); test_equal(audio_cur_track()->tr_dbe.dbe_index, 1);
test_equal(state_count, 5);
test_equal(audio_prev()->tr_dbe.dbe_index, 2); test_equal(audio_prev()->tr_dbe.dbe_index, 2);
test_equal((void *)queue_at(history_q, 0), (void *)track); test_equal((void *)queue_at(history_q, 0), (void *)track);
test_equal(audio_cur_state(), GST_STATE_PAUSED); test_equal(audio_cur_state(), GST_STATE_PAUSED);
test_equal(audio_cur_track()->tr_dbe.dbe_index, 2); test_equal(audio_cur_track()->tr_dbe.dbe_index, 2);
test_equal(state_count, 6);
} }
void test_autopause() void test_autopause()
@ -222,6 +239,7 @@ void test_autopause()
audio_pause_after(5); audio_pause_after(5);
test_equal(pause_count, 5); test_equal(pause_count, 5);
state_count = 0;
for (i = 4; i > -1; i--) { for (i = 4; i > -1; i--) {
audio_eos(); audio_eos();
test_loop_equal(pause_count, i, i); test_loop_equal(pause_count, i, i);
@ -229,6 +247,7 @@ void test_autopause()
test_loop_equal((void *)queue_at(history_q, 0), test_loop_equal((void *)queue_at(history_q, 0),
(void *)audio_cur_track(), i); (void *)audio_cur_track(), i);
} test_loop_passed(); } test_loop_passed();
test_equal(state_count, 5);
audio_eos(); audio_eos();
test_equal(pause_count, -1); test_equal(pause_count, -1);