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)
{
GstStateChangeReturn ret = GST_STATE_CHANGE_FAILURE;
if (audio_cur_state() != 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)
@ -42,8 +47,8 @@ static bool __audio_load(struct track *track, GstState state)
gst_element_set_state(audio_player, GST_STATE_NULL);
g_object_set(G_OBJECT(audio_player), "uri", uri, NULL);
audio_ops->on_load(track);
__audio_change_state(state);
audio_ops->on_load(track, state);
__audio_save();
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>");
}
static void on_pause()
{
o_play->show();
o_pause->hide();
}
static void on_load(struct track *track, GstState state)
static void on_load(struct track *track)
{
gchar *str = g_strdup_printf("From: %s", track->tr_album->al_name);
set_markup(o_album, "x-large", str);
@ -61,9 +55,17 @@ static void on_load(struct track *track, GstState state)
g_free(str);
plist :: track_loaded(track);
}
if (state != GST_STATE_PLAYING)
on_pause();
static void on_change_state(GstState state)
{
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)
@ -79,6 +81,7 @@ static void on_config_pause(int n)
struct audio_ops audio_ops = {
on_load,
on_change_state,
on_config_pause,
};
@ -116,25 +119,9 @@ static bool on_timeout()
void gst :: play()
{
if (audio_play()) {
o_play->hide();
o_pause->show();
}
}
void gst :: pause()
{
if (audio_pause()) {
on_pause();
}
}
void gst :: stop() {
if (audio_stop())
on_pause();
}
void gst :: play() { audio_play(); }
void gst :: pause() { audio_pause(); }
void gst :: stop() { audio_stop(); }
void gst :: next()
{

View File

@ -9,7 +9,10 @@
struct audio_ops {
/* 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. */
void (*on_config_pause)(int);

View File

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