Project Railway Documentation
Background
In recent days I was debugging some strange crashes of Project Railway. The railway
process sometimes receives signal SIGSEGV when calling gst_player_new
or gst_player_play
. After switching to calling the mpg123
program by fork-exec as music playing backend, currently there are no crashes. Maybe I should write some documentation to explain the program.
RailwayMusic
RailwayMusic does the actual work by calling mpg123
, using its remote control mode.
void init_music()
: Constructor function; launch mpg123 and create read/write file pointers that sends to mpg123; launch music_wait
thread.void destroy_music()
: Destructor function; cancel and wait for the thread; tells mpg123 to quit and wait for it.void music_play(song_type*)
: Ask mpg123 to stop and load this song.void music_volume(double)
: Pass volume to mpg123.void music_pause_trigger()
: Pass pause to mpg123.bool music_is_playing()
: Get the play state boolean.void* music_wait(void*)
: Thread that continuously read output of mpg123.int music_update(void*)
: Update function that run every 1 sec in the main thread to update progress bar and switch to next song if necessary.
RailwayPlaylist
RailwayPlaylist is a simple part to maintain current playlist. It contains the current track index in playlist_ptr
.
void init_playlist()
: Constructor function; init vars.void destroy_playlist()
: Destructor function; cleanup playlist_array
if necessary; reset vars.void generate_playlist(song_type*)
: Generate playlist array by cloning the current song_array
.void playlist_next()
: Modify playlist_ptr
; calls play_song
to do actual music playing.void playlist_prev()
: Similar to playlist_next
.void playlist_play(song_type*)
: To play a new song that changes the playlist. First destroy and regenerate the playlist, and call play_song
.void playlist_set_shuffle(bool)
: Set shuffle status.void playlist_set_repeat(bool)
: Set repeat status.
RailwayLib
RailwayLib manages the library of albums and songs, configuration file, and gets music tags to sort songs by track id.
void init_library()
: Constructor function; get configuration values; init the gst_discoverer
to get tags.void destroy_library()
: Destructor function; cleanup resources.void generate_album_list()
: To generate album_array
; iterate over library directories and artist directories to generate a linked list of albums and convert to array (to find out number of albums and malloc accordingly).void generate_song_list(const album_type*)
: To generate song_array
; iterate over each (regular) song file in a given album directory; create linked list and song array.void destroy_album_list()
: Cleanup album array.void destroy_song_list()
: Cleanup song array.void generate_album_button_image(GTask*, void*, album_type*, void*)
: Function for GTask thread to generate album cover picture; Get any song in the album; check if existing picture exist, and if not exist generate one using ffmpeg -n -i <song filename> <image filename>
.
Railway
Railway controls all GUI elements and sets their handlers.
void music_position_update_cb(int, int)
: Update the song progress bar; called from update function in railwaymusic.void music_pause_button_trigger_cb(GtkWidget*, void*)
: Update the icon of the play/pause trigger button; call railwaymusic to trigger pause.void play_song(song_type*)
: Setting labels and images in the interface and pass to music_play
; called from railwayplaylist.void init_albums()
: Create album button grid.void destroy_albums()
: Cleanup album button array.void init_window()
&& void init_control()
: Set signal handlers.bool substring_test(const char*, const char*)
: Substring test (case insensitive).bool search_judge(album_type*, const char*)
: Test if an album contains the given search term.