This is an automated email from the git hooks/post-receive script.

git pushed a commit to branch main
in repository eradio.

View the commit online.

commit de6d788a9f3d8497bf854463f34958d3e61449b0
Author: politebot <[email protected]>
AuthorDate: Wed Oct 22 16:39:10 2025 -0500

    Add GOOM visualizer
---
 src/Makefile.am    |   4 +-
 src/appdata.h      |   6 +++
 src/main.c         |   3 ++
 src/radio_player.c |  24 +++++++++
 src/ui.c           |   2 +
 src/visualizer.c   | 153 +++++++++++++++++++++++++++++++++++++++++++++++++++++
 src/visualizer.h   |  13 +++++
 7 files changed, 203 insertions(+), 2 deletions(-)

diff --git a/src/Makefile.am b/src/Makefile.am
index dd66cad..f8849b2 100644
--- a/src/Makefile.am
+++ b/src/Makefile.am
@@ -1,7 +1,7 @@
 bin_PROGRAMS = eradio
 
-eradio_SOURCES = main.c ui.c radio_player.c station_list.c http.c favorites.c \
-                 appdata.h ui.h radio_player.h station_list.h http.h favorites.h
+eradio_SOURCES = main.c ui.c radio_player.c station_list.c http.c favorites.c visualizer.c \
+                 appdata.h ui.h radio_player.h station_list.h http.h favorites.h visualizer.h
 
 eradio_CFLAGS = $(EFL_CFLAGS) $(LIBXML_CFLAGS)
 eradio_LDADD = $(EFL_LIBS) $(LIBXML_LIBS)
diff --git a/src/appdata.h b/src/appdata.h
index bcc4c48..c80bfbb 100644
--- a/src/appdata.h
+++ b/src/appdata.h
@@ -36,6 +36,7 @@ typedef struct _AppData
    Evas_Object *controls_toolbar;
    Elm_Object_Item *play_pause_item;
    Elm_Object_Item *stop_item;
+   Elm_Object_Item *visualizer_item;
    Evas_Object *separator;
    Evas_Object *statusbar;
    Evas_Object *volume_slider;
@@ -58,4 +59,9 @@ typedef struct _AppData
    ViewMode view_mode;
    int search_offset;
    int displayed_stations_count;
+
+   // Visualizer
+   Evas_Object *visualizer_win;
+   Evas_Object *visualizer_emotion;
+   Eina_Bool visualizer_active;
 } AppData;
diff --git a/src/main.c b/src/main.c
index 09de68f..c3eeeef 100644
--- a/src/main.c
+++ b/src/main.c
@@ -3,6 +3,7 @@
 #include "radio_player.h"
 #include "http.h"
 #include "favorites.h"
+#include "visualizer.h"
 
 EAPI_MAIN int
 elm_main(int argc, char **argv)
@@ -17,11 +18,13 @@ elm_main(int argc, char **argv)
    http_init(&ad);
    ui_update_server_list(&ad);
    radio_player_init(&ad);
+   visualizer_init(&ad);
 
    elm_run();
 
    http_shutdown();
    radio_player_shutdown();
+   visualizer_shutdown(&ad);
    favorites_shutdown(&ad);
 
    return 0;
diff --git a/src/radio_player.c b/src/radio_player.c
index 9f0022e..36a2d54 100644
--- a/src/radio_player.c
+++ b/src/radio_player.c
@@ -1,5 +1,6 @@
 #include "radio_player.h"
 #include "ui.h"
+#include "visualizer.h"
 
 static Ecore_Timer *stream_error_timer = NULL;
 static Ecore_Timer *audio_progress_timer = NULL;
@@ -149,6 +150,9 @@ radio_player_play(AppData *ad, const char *url, const char *station_name)
         emotion_object_file_set(ad->emotion, url);
         emotion_object_play_set(ad->emotion, EINA_TRUE);
         ad->playing = EINA_TRUE;
+
+        // Start visualizer playback if active
+        visualizer_play(ad);
         if (ad->play_pause_item)
           elm_toolbar_item_icon_set(ad->play_pause_item, "media-playback-pause");
 
@@ -156,6 +160,9 @@ radio_player_play(AppData *ad, const char *url, const char *station_name)
         if (current_station_name)
           elm_object_text_set(ad->statusbar, current_station_name);
 
+        // Update visualizer with new station
+        visualizer_set_station(ad, url);
+
         // Reset position tracking
         last_position = 0.0;
 
@@ -172,6 +179,9 @@ radio_player_stop(AppData *ad)
    emotion_object_position_set(ad->emotion, 0.0);
    ad->playing = EINA_FALSE;
 
+   // Stop visualizer if active
+   visualizer_stop(ad);
+
    // Cancel all timers
    if (stream_error_timer)
      {
@@ -202,6 +212,13 @@ radio_player_toggle_pause(AppData *ad)
 {
    ad->playing = !ad->playing;
    emotion_object_play_set(ad->emotion, ad->playing);
+
+   // Sync visualizer with playback state
+   if (ad->playing)
+     visualizer_play(ad);
+   else
+     visualizer_pause(ad);
+
    if (ad->play_pause_item)
      {
         if (ad->playing)
@@ -224,3 +241,10 @@ _stop_btn_clicked_cb(void *data, Evas_Object *obj, void *event_info)
    AppData *ad = data;
    radio_player_stop(ad);
 }
+
+void
+_visualizer_btn_clicked_cb(void *data, Evas_Object *obj, void *event_info)
+{
+   AppData *ad = data;
+   visualizer_toggle(ad);
+}
diff --git a/src/ui.c b/src/ui.c
index 0fab782..792b589 100644
--- a/src/ui.c
+++ b/src/ui.c
@@ -16,6 +16,7 @@ static void _tb_url_clicked_cb(void *data, Evas_Object *obj, void *event_info);
 // Forward declarations for callbacks
 void _play_pause_btn_clicked_cb(void *data, Evas_Object *obj, void *event_info);
 void _stop_btn_clicked_cb(void *data, Evas_Object *obj, void *event_info);
+void _visualizer_btn_clicked_cb(void *data, Evas_Object *obj, void *event_info);
 void _search_btn_clicked_cb(void *data, Evas_Object *obj, void *event_info);
 void _search_entry_activated_cb(void *data, Evas_Object *obj, void *event_info);
 void _list_item_selected_cb(void *data, Evas_Object *obj, void *event_info);
@@ -250,6 +251,7 @@ ui_create(AppData *ad)
 
    ad->play_pause_item = elm_toolbar_item_append(ad->controls_toolbar, "media-playback-start", "Play/Pause", _play_pause_btn_clicked_cb, ad);
    ad->stop_item = elm_toolbar_item_append(ad->controls_toolbar, "media-playback-stop", "Stop", _stop_btn_clicked_cb, ad);
+   ad->visualizer_item = elm_toolbar_item_append(ad->controls_toolbar, "media-video", "Visualizer", _visualizer_btn_clicked_cb, ad);
 
    evas_object_smart_callback_add(ad->search_btn, "clicked", _search_btn_clicked_cb, ad);
    evas_object_smart_callback_add(ad->search_entry, "activated", _search_entry_activated_cb, ad);
diff --git a/src/visualizer.c b/src/visualizer.c
new file mode 100644
index 0000000..c1cd736
--- /dev/null
+++ b/src/visualizer.c
@@ -0,0 +1,153 @@
+#include "visualizer.h"
+#include "ui.h"
+
+static void _visualizer_win_del_cb(void *data, Evas_Object *obj, void *event_info);
+static void _visualizer_title_changed_cb(void *data, Evas_Object *obj, void *event_info);
+
+void
+visualizer_init(AppData *ad)
+{
+   ad->visualizer_win = NULL;
+   ad->visualizer_emotion = NULL;
+   ad->visualizer_active = EINA_FALSE;
+}
+
+static void
+_visualizer_win_del_cb(void *data, Evas_Object *obj, void *event_info)
+{
+   AppData *ad = data;
+   visualizer_hide(ad);
+}
+
+static void
+_visualizer_title_changed_cb(void *data, Evas_Object *obj, void *event_info)
+{
+   AppData *ad = data;
+   const char *title = emotion_object_title_get(obj);
+
+   if (ad->visualizer_win && title && strlen(title) > 0)
+     {
+        char window_title[256];
+        snprintf(window_title, sizeof(window_title), "eradio Visualizer - %s", title);
+        elm_win_title_set(ad->visualizer_win, window_title);
+     }
+}
+
+void
+visualizer_show(AppData *ad)
+{
+   if (ad->visualizer_active)
+     return;
+
+   // Create visualizer window
+   ad->visualizer_win = elm_win_add(NULL, "eradio_visualizer", ELM_WIN_BASIC);
+   elm_win_title_set(ad->visualizer_win, "eradio Visualizer");
+   elm_win_autodel_set(ad->visualizer_win, EINA_TRUE);
+   evas_object_smart_callback_add(ad->visualizer_win, "delete,request", _visualizer_win_del_cb, ad);
+
+   // Set a reasonable default size
+   evas_object_resize(ad->visualizer_win, 640, 480);
+
+   // Create emotion object for visualization
+   ad->visualizer_emotion = emotion_object_add(ad->visualizer_win);
+
+   // Set GOOM visualization
+   emotion_object_vis_set(ad->visualizer_emotion, EMOTION_VIS_GOOM);
+
+   // Add title change callback for window title updates
+   evas_object_smart_callback_add(ad->visualizer_emotion, "title_change", _visualizer_title_changed_cb, ad);
+
+   // Make emotion object fill the window
+   evas_object_size_hint_weight_set(ad->visualizer_emotion, EVAS_HINT_EXPAND, EVAS_HINT_EXPAND);
+   evas_object_size_hint_align_set(ad->visualizer_emotion, EVAS_HINT_FILL, EVAS_HINT_FILL);
+   elm_win_resize_object_add(ad->visualizer_win, ad->visualizer_emotion);
+   evas_object_show(ad->visualizer_emotion);
+
+   // If there's already a station playing, connect the visualizer to it
+   if (ad->playing && ad->emotion)
+     {
+        const char *current_url = emotion_object_file_get(ad->emotion);
+        if (current_url)
+          {
+             emotion_object_file_set(ad->visualizer_emotion, current_url);
+             emotion_object_play_set(ad->visualizer_emotion, EINA_TRUE);
+          }
+     }
+
+   ad->visualizer_active = EINA_TRUE;
+   evas_object_show(ad->visualizer_win);
+}
+
+void
+visualizer_hide(AppData *ad)
+{
+   if (!ad->visualizer_active)
+     return;
+
+   if (ad->visualizer_emotion)
+     {
+        emotion_object_play_set(ad->visualizer_emotion, EINA_FALSE);
+        evas_object_del(ad->visualizer_emotion);
+        ad->visualizer_emotion = NULL;
+     }
+
+   if (ad->visualizer_win)
+     {
+        evas_object_del(ad->visualizer_win);
+        ad->visualizer_win = NULL;
+     }
+
+   ad->visualizer_active = EINA_FALSE;
+}
+
+void
+visualizer_toggle(AppData *ad)
+{
+   if (ad->visualizer_active)
+     visualizer_hide(ad);
+   else
+     visualizer_show(ad);
+}
+
+void
+visualizer_set_station(AppData *ad, const char *url)
+{
+   if (!ad->visualizer_active || !ad->visualizer_emotion || !url)
+     return;
+
+   emotion_object_file_set(ad->visualizer_emotion, url);
+}
+
+void
+visualizer_play(AppData *ad)
+{
+   if (!ad->visualizer_active || !ad->visualizer_emotion)
+     return;
+
+   emotion_object_play_set(ad->visualizer_emotion, EINA_TRUE);
+}
+
+void
+visualizer_pause(AppData *ad)
+{
+   if (!ad->visualizer_active || !ad->visualizer_emotion)
+     return;
+
+   emotion_object_play_set(ad->visualizer_emotion, EINA_FALSE);
+}
+
+void
+visualizer_stop(AppData *ad)
+{
+   if (!ad->visualizer_active || !ad->visualizer_emotion)
+     return;
+
+   emotion_object_play_set(ad->visualizer_emotion, EINA_FALSE);
+   emotion_object_position_set(ad->visualizer_emotion, 0.0);
+}
+
+void
+visualizer_shutdown(AppData *ad)
+{
+   visualizer_hide(ad);
+}
\ No newline at end of file
diff --git a/src/visualizer.h b/src/visualizer.h
new file mode 100644
index 0000000..9c44f7d
--- /dev/null
+++ b/src/visualizer.h
@@ -0,0 +1,13 @@
+#pragma once
+
+#include "appdata.h"
+
+void visualizer_init(AppData *ad);
+void visualizer_show(AppData *ad);
+void visualizer_hide(AppData *ad);
+void visualizer_toggle(AppData *ad);
+void visualizer_set_station(AppData *ad, const char *url);
+void visualizer_play(AppData *ad);
+void visualizer_pause(AppData *ad);
+void visualizer_stop(AppData *ad);
+void visualizer_shutdown(AppData *ad);
\ No newline at end of file

-- 
To stop receiving notification emails like this one, please contact
the administrator of this repository.

Reply via email to