Menu

bassix-radio-player

big-bass
Attachments
bassix-radio-player.png (12377 bytes)
radio2.cfg (6404 bytes)

BASSIX RADIO PLAYER

image

Example code:bassix-radio-player.bac

place radio2.cfg in your home directory
install dependencies

sudo apt-get install mpg123

tested on linux mint 20.1 64 bit xfce

'--- bigbass GTK3 with FIXED placement and some new macros
'--- for the lack of a name we can call it gtk3 bassix 
'--- a simple 'HUG' looking syntax idea but include only what you need as you go
'--- June 25 2020 --- UPDATED MAY 1 2021
'--- added dynamic combobox
'--- added songtrack automatically as a label
'--- added timeout and refresh July 12

OPTION PARSE FALSE
PRAGMA INCLUDE <gtk-3.0/gtk/gtk.h>
PRAGMA OPTIONS `pkg-config --cflags gtk+-3.0` 
PRAGMA LDFLAGS `pkg-config --libs gtk+-3.0` 
PRAGMA OPTIONS -Wno-deprecated-declarations

'--- new signal handlers to simplify the callbacks
DEF FN CONNECT( widget, event,cb) = g_signal_connect_data(widget,event,cb, 0, 0, 0)
DEF FN CONNECT_DATA( widget, event,cb,t) = g_signal_connect_data(G_OBJECT (widget),event,G_CALLBACK (cb),(gpointer) t, 0, 0)
DEF FN WINDOW_ADD() = gtk_window_new(GTK_WINDOW_TOPLEVEL)
DEF FN NEW(widget,...) = g_object_new(widget, __VA_ARGS__,NULL)
DEF FN PLACE( widget, name,wid,high) = gtk_fixed_put(GTK_FIXED(widget),  GTK_WIDGET(name),wid,high)
DEF FN ADD_FIXED( widget, name) = gtk_container_add(GTK_CONTAINER(widget), GTK_WIDGET(name))
DEF FN SET(widget, name, ...) = g_object_set(GTK_WIDGET(widget), name, __VA_ARGS__, NULL)
DEF FN GET( widget, name, ...) = g_object_get(widget, name, __VA_ARGS__, NULL)
DEF FN SHOW( widget) = gtk_widget_show_all(GTK_WIDGET(widget))
DEF FN HIDE( widget) = gtk_widget_hide(GTK_WIDGET(widget))
DEF FN INIT() = gtk_init(0,0)
DEF FN LABEL_ADD(t) = gtk_label_new(t)
DEF FN BUTTON_ADD(t) = gtk_button_new_with_label(t)
DEF FN TEXT_VIEW() = gtk_text_view_new ()
DEF FN FIXED() = gtk_fixed_new()  
DEF FN DISPLAY() = gtk_main() 
DEF FN ATTACH() = gtk_container_add()
DEF FN SCROLLED_WINDOW() = gtk_scrolled_window_new (NULL, NULL)

DEF FN STREAM(im) = g_memory_input_stream_new_from_data(im, -1, g_free)
DEF FN PIXBUF_MEM(stm) = gdk_pixbuf_new_from_stream(stm, NULL, NULL)
DEF FN PIXBUFF(p) = gtk_image_new_from_pixbuf (p )

DEF FN SET_IMAGE(widget,im) = gtk_button_set_image (GTK_BUTTON (widget), im)
DEF FN IMAGE_FILE(f) = gtk_image_new_from_file(f)

DEF FN  COMBO() = gtk_combo_box_text_new ()
DEF FN  COMBO_GET(c) = gtk_combo_box_text_get_active_text (GTK_COMBO_BOX_TEXT(c))
DEF FN  COMBO_ACTIVE(c) = gtk_combo_box_get_active (GTK_COMBO_BOX(c))
DEF FN  COMBO_ADD(widget,arr) = gtk_combo_box_text_append_text (GTK_COMBO_BOX_TEXT (widget), arr)

DEF FN VOLUME_GET(widget) = gtk_scale_button_get_value(GTK_SCALE_BUTTON(widget)) 
DEF FN VOLUME() = gtk_volume_button_new()

DEF FN TIMEOUT_ADD(n,cb) = g_timeout_add(n,(GSourceFunc) cb, NULL)
DEF FN REMOVE_TIMEOUT(id) = g_source_remove(id)


ALIAS GTK_TYPE_WINDOW TO WINDOW
ALIAS GTK_TYPE_BUTTON TO BUTTON
ALIAS GTK_WIDGET TO WIDGET
ALIAS GTK_CONTAINER TO CONTAINER
ALIAS g_free TO FREE

DECLARE window, scrolled_win ,exit_btn ,image ,label2 TYPE GtkWidget*
DECLARE fixed TYPE GtkWidget*
DECLARE image2 TYPE GtkWidget*
DECLARE VOLUME2 TYPE GtkWidget*

DECLARE combo_box TYPE  GtkWidget*
'=====================
SUB exit_prog
'=====================
    CLEAR 
    SYSTEM(" killall mpg123 ")
    SLEEP 100
    DELETE FILE "/tmp/MPG123_file.txt"

    END
END SUB



'===================== 
SUB exit_clicked ()
'=====================  
    CLEAR 
    SYSTEM(" killall mpg123 ")
    SLEEP 100
    DELETE FILE "/tmp/MPG123_file.txt"

    END
END SUB


SUB song_title_cb

        HIDE(label2)
        count = 0
        REPEAT
            SLEEP 200
            LIVE_DATA$ = EXEC$("tail -n 1   /tmp/MPG123_file.txt &")
            '---now we will use bacon to parse for StreamTitle
            track$ = INBETWEEN$(LIVE_DATA$ , "StreamTitle='", "';")
            INCR count
        UNTIL LEN(track$) !=0 OR count > 35
        'PRINT "live data test:",LIVE_DATA$
        '---if no track is found in 3.5 seconds give up on the title
        '--- offer a visual aid if found +  not found - as the icon

        IF LEN(track$) !=0 THEN

            SET(window, "icon-name","gtk-add")
            IF LEN(track$) > 70 THEN
                 track$ = ALIGN$(track$, 70, 0)
            END IF  
            'SET(label2, "label", track$)
            label2 = LABEL_ADD(track$)
            PLACE(fixed ,label2,5,45) 
            SHOW(label2)
        ELSE
            SET(window, "icon-name","gtk-remove")
        END IF 

END SUB







'======================================================
SUB on_changed (GtkComboBox *widget, void*   user_data)
'======================================================           

IF FILEEXISTS( "/tmp/MPG123_file.txt") THEN
    DELETE FILE "/tmp/MPG123_file.txt"
END IF


'LOCAL combo_box TYPE GtkComboBox*
'combo_box = widget

CLEAR 
'--- we dont want more than one station playing at a time
SYSTEM(" killall mpg123 & ")



LOCAL distro TYPE  STRING

        '---get matching url is the  index_num
        index_num = COMBO_ACTIVE(combo_box)
        distro = COMBO_GET(combo_box) 


        HIDE(label2)
        PRINT distro FORMAT "%s\n"

        PRINT url$[index_num] FORMAT "%s\n"

        SETENVIRON "result_selected",url$[index_num]
        SYSTEM("mpg123 $result_selected 2> /tmp/MPG123_file.txt&")

TIMEOUT_ADD(500,song_title_cb)

END SUB



' ==============================
SUB VOLUME2_CB(long widget, void*  user_data)
' ==============================
    PRINT "VOLUME2_CB"
    '---we use strings to set env 
    LOCAL audio_level_bacon$ TYPE STRING
    LOCAL audio_level_bacon TYPE double 

    PRINT VOLUME_GET(VOLUME2) FORMAT "%.1f\n"
    audio_level_bacon = VOLUME_GET(VOLUME2)

    '---a hack to get scale 1-100
    audio_level_bacon = audio_level_bacon * 100
    audio_level_bacon$= STR$(audio_level_bacon)

    SETENVIRON "audio_level_bacon",audio_level_bacon$

    '---debug whats happenning in the low level 
    sys_vol$ = EXEC$("echo $audio_level_bacon") 
    PRINT "sys volume: ",sys_vol$ 
    SYSTEM "amixer -D pulse sset Master $audio_level_bacon% &"



END SUB




'---main code
INIT

'--- you could place all properties in the NEW() or use SET 
'--- and add what you need as you go 

window = WINDOW_ADD()
'--- widget ,property , value or string
SET(window, "icon-name", "media-record")
SET(window, "title", "Internet Radio auto title Bassix ")
SET(window, "resizable", TRUE)
SET(window,  "border-width", 10, "default-width", 590)
SET(window,  "default-height", 30)

'--- place window into the fixed container
fixed = FIXED()
ADD_FIXED(window, fixed)

'---new button and label
exit_btn = BUTTON_ADD ("Exit")




SET(exit_btn, "width_request", 80  ,"height_request",30)
SET(exit_btn, "tooltip-text", "EXIT")

'---make sure the image is visible
SET(exit_btn, "always_show_image",TRUE) 
SET(exit_btn, "label","gtk-quit","use_stock",TRUE)

'---placement inside fixed,widget,X,Y
PLACE (fixed, exit_btn, 550, 5)

SET(exit_btn, "width_request", 80  ,"height_request",30)
SET(exit_btn, "tooltip-text", "refresh")

refresh_btn = BUTTON_ADD ("Refresh")
'---make sure the image is visible
SET(refresh_btn, "always_show_image",TRUE) 
SET(refresh_btn, "label","gtk-refresh","use_stock",TRUE)

'---placement inside fixed,widget,X,Y
PLACE (fixed, refresh_btn, 390, 5)

'---volume button , settings and placement
VOLUME2 = VOLUME()
SET(VOLUME2, "size", GTK_ICON_SIZE_DND)
PLACE (fixed, VOLUME2, 500, 5)


'--- handle callbacks  widget,event,sub or function
CONNECT(window, "delete-event", exit_prog)
CONNECT(exit_btn, "clicked" ,exit_clicked )


'---DYNAMIC COMBO BOX read in a file

LOCAL i TYPE int
LOCAL view TYPE   GtkWidget*


'--- Create the combo box and append your string values to it. 
combo_box = COMBO()
SET(combo_box,  "height_request",10)
SET(combo_box, "width_request", 80)



'--- make a dynamic combobox read in any type of file 
'--- get names of station  left side of pipe
result_input$ = CHOP$(EXEC$("cat ~/radio2.cfg | cut -d'|' -f1"))

'--- get urls right side of pipe
result_input2$ = CHOP$(EXEC$("cat ~/radio2.cfg | cut -d'|' -f2"))

    SPLIT result_input$ BY NL$ TO words$ SIZE dim

        FOR i = 0 TO dim - 1
            COMBO_ADD(combo_box,words$[i])
        NEXT



    '--- a 2D array split in two parts station and url
    SPLIT result_input2$ BY NL$ TO url$ SIZE dim2

    '---second url 
    FOR i = 0  TO dim2 -1

        IF NOT(INSTR(url$[i],"cannot access")) THEN
            PRINT url$[i] TO  SIZE 8098
            CLEAR
            '--- going to save the url part  in memory

        ENDIF   
    NEXT

'--- Choose to set the first option as the active one by default
SET(combo_box, "active",0) 
CONNECT_DATA(combo_box, "changed",on_changed,NULL)

CONNECT_DATA(VOLUME2, "value-changed",VOLUME2_CB ,NULL)
CONNECT_DATA(refresh_btn, "clicked",song_title_cb ,NULL)
label2 = LABEL_ADD("")
PLACE (fixed, combo_box, 5, 5)


SHOW(window)
HIDE(label2)
'---got the g_timeout working for bassix

DISPLAY