diff -ru last-exit-0.2/data/glade/PlayerWindow.glade last-exit-0.2-mod/data/glade/PlayerWindow.glade --- last-exit-0.2/data/glade/PlayerWindow.glade 2006-02-12 03:06:01.000000000 +0100 +++ last-exit-0.2-mod/data/glade/PlayerWindow.glade 2006-03-01 03:39:36.000000000 +0100 @@ -557,7 +557,32 @@ 0 False True - GTK_PACK_END + + + + + + True + True + GTK_RELIEF_NORMAL + True + + + + True + gtk-save-as + 4 + 0.5 + 0.5 + 0 + 0 + + + + + 0 + False + False Only in last-exit-0.2-mod/data/glade: PlayerWindow.glade.bak Only in last-exit-0.2-mod/data/glade: PlayerWindow.gladep Only in last-exit-0.2-mod/data/glade: PlayerWindow.gladep.bak Only in last-exit-0.2-mod/liblast-exit: player-0.1-mod.c Only in last-exit-0.2-mod/liblast-exit: player-0.2-mod.c diff -ru last-exit-0.2/liblast-exit/player.c last-exit-0.2-mod/liblast-exit/player.c --- last-exit-0.2/liblast-exit/player.c 2006-02-15 00:56:29.000000000 +0100 +++ last-exit-0.2-mod/liblast-exit/player.c 2006-03-01 04:53:39.000000000 +0100 @@ -21,15 +21,14 @@ #include #include #include - +#include +#include +#include +#include #include -/*#include "last-fm.h"*/ #include "player.h" -/* #define USE_NEON 1 */ -/* #define USE_LAST_FM 1 */ - enum { NEW_SONG, ERROR, @@ -38,6 +37,11 @@ struct _PlayerPrivate { GstElement *play; + GstElement *multisink; + GstElement *src; + GstElement *volume; + + gchar *save_location; }; static GObjectClass *parent_class; @@ -81,6 +85,8 @@ NULL, NULL, g_cclosure_marshal_VOID__STRING, G_TYPE_NONE, 1, G_TYPE_STRING); + + gst_init (NULL, NULL); } static void @@ -124,6 +130,43 @@ } static void +change_dump_file (Player *player, gboolean create_new_file) +{ + gint fd; + gchar *temp_file_location = g_build_filename (g_get_home_dir (), ".lastfm.mp3", NULL); + + g_signal_emit_by_name (player->priv->multisink, "clear", fd); + if (player->priv->save_location != NULL) + { + /* We wanted to save the file */ + fd = rename (temp_file_location, player->priv->save_location); + if (fd == -1) + { + perror("Error Occured while moving dump file to destination:"); + } + g_free (player->priv->save_location); + player->priv->save_location = NULL; + } + + if (create_new_file) + { + fd = open (temp_file_location, O_WRONLY|O_CREAT|O_TRUNC, 0644); + if (fd == -1) + { + perror("Error Occured while opening the file:"); + } + + g_signal_emit_by_name (player->priv->multisink, "add", fd); + } + else + { + unlink (temp_file_location); + } + + g_free (temp_file_location); +} + +static void post_new_song_message (Player *player) { GstMessage *msg; @@ -135,12 +178,23 @@ bus = gst_pipeline_get_bus (GST_PIPELINE (player->priv->play)); gst_bus_post (bus, msg); + + change_dump_file (player, TRUE); } -static gboolean -have_data_cb (GstPad *pad, - GstBuffer *buffer, - Player *player) +static void +client_removed (GstElement* multisink, + gint fd, + guint status, + gpointer user_data) +{ + close(fd); +} + +static void +identity_handoff (GstElement *id, + GstBuffer *buffer, + Player *player) { char *data = GST_BUFFER_DATA (buffer); char *s; @@ -154,51 +208,7 @@ s = memmem (data, GST_BUFFER_SIZE (buffer), sync, 4); if (s != NULL) { post_new_song_message (player); - } -#if 0 - else if (req > 0) { - if (strncmp (data, sync + (4 - req), req) == 0) { - post_new_song_message (player); - } - - // Reset req - req = 0; - } else { - guint len = GST_BUFFER_SIZE (buffer); - char *e = data + (len - 3); - - // Is it even possible for the SYNC to get split over two - // different buffers? - - // Check if there is any of SYN in the last three chars - if (*(e + 2) == 'S') { - req = 3; - } else if ((*(e + 2) == 'Y') && (*(e + 1) == 'S')) { - req = 2; - } else if ((*(e + 2) == 'N') && (*(e + 1) == 'Y') && (*e == 'S')) { - req = 1; - } else { - req = 0; - } } -#endif - - return TRUE; -} - -static src_setup (GObject *object, - GParamSpec *pspec, - Player *player) -{ - GstElement *src; - GstPad *pad; - - g_object_get (G_OBJECT (object), - "source", &src, - NULL); - - pad = gst_element_get_pad (src, "src"); - gst_pad_add_buffer_probe (pad, G_CALLBACK (have_data_cb), player); } static void @@ -206,13 +216,27 @@ char **error) { PlayerPrivate *priv = player->priv; - - gst_init (NULL, NULL); - - priv->play = gst_element_factory_make ("playbin", "last-fm-player"); - g_signal_connect (G_OBJECT (priv->play), "notify::source", - G_CALLBACK (src_setup), player); - + GstElement *bin; + GstElement *last_fm; + + priv->play = gst_pipeline_new ("last-fm-pipeline"); + bin = gst_parse_bin_from_description ( + "gnomevfssrc name=src ! identity name=last-fm ! tee name=t " + "t. ! queue ! mad ! audioconvert ! volume name=volume ! alsasink " + "t. ! queue ! multifdsink name=file sync-method=2", + TRUE, + NULL); + + last_fm = gst_bin_get_by_name (GST_BIN (bin), "last-fm"); + g_signal_connect (G_OBJECT (last_fm), "handoff", + G_CALLBACK (identity_handoff), player); + + priv->src = gst_bin_get_by_name (GST_BIN (bin), "src"); + priv->volume = gst_bin_get_by_name (GST_BIN (bin), "volume"); + priv->multisink = gst_bin_get_by_name (GST_BIN (bin), "file"); + g_signal_connect(priv->multisink, "client-removed", G_CALLBACK (client_removed), NULL); + + gst_bin_add (GST_BIN (priv->play), bin); gst_bus_add_watch (gst_pipeline_get_bus (GST_PIPELINE (priv->play)), bus_message_cb, player); } @@ -255,14 +279,20 @@ { player_stop (player); - g_object_set (G_OBJECT (player->priv->play), - "uri", location, - NULL); + g_object_set (G_OBJECT (player->priv->src), + "location", location, NULL); return TRUE; } void +player_set_save_location (Player *player, + const char *location) +{ + player->priv->save_location = g_strdup (location); +} + +void player_play (Player *player) { gst_element_set_state (GST_ELEMENT (player->priv->play), GST_STATE_PLAYING); @@ -272,6 +302,7 @@ player_stop (Player *player) { gst_element_set_state (GST_ELEMENT (player->priv->play), GST_STATE_READY); + change_dump_file (player, FALSE); } void @@ -282,7 +313,7 @@ vol = CLAMP (volume, 0, 100) / 100.0; - g_object_set (G_OBJECT (player->priv->play), + g_object_set (G_OBJECT (player->priv->volume), "volume", vol, NULL); } diff -ru last-exit-0.2/liblast-exit/player.h last-exit-0.2-mod/liblast-exit/player.h --- last-exit-0.2/liblast-exit/player.h 2006-01-20 23:10:17.000000000 +0100 +++ last-exit-0.2-mod/liblast-exit/player.h 2006-03-01 03:01:22.000000000 +0100 @@ -46,6 +46,8 @@ Player *player_new (void); gboolean player_set_location (Player *player, const char *location); +void player_set_save_location (Player *player, + const char *location); void player_play (Player *player); void player_stop (Player *player); diff -ru last-exit-0.2/src/Driver.cs last-exit-0.2-mod/src/Driver.cs --- last-exit-0.2/src/Driver.cs 2006-02-10 02:00:37.000000000 +0100 +++ last-exit-0.2-mod/src/Driver.cs 2006-03-01 04:46:26.000000000 +0100 @@ -105,7 +105,8 @@ } public static void Exit () { - Environment.Exit (0); + player.Stop(); + Application.Quit (); } [DllImport ("libc")] diff -ru last-exit-0.2/src/Player.cs last-exit-0.2-mod/src/Player.cs --- last-exit-0.2/src/Player.cs 2006-02-12 02:25:44.000000000 +0100 +++ last-exit-0.2-mod/src/Player.cs 2006-03-01 03:01:44.000000000 +0100 @@ -61,6 +61,15 @@ player_set_location (Raw, value); } } + + [DllImport ("liblastexit")] + private static extern void player_set_save_location (IntPtr player, + string filename); + public string SaveLocation { + set { + player_set_save_location (Raw, value); + } + } [DllImport ("liblastexit")] private static extern void player_play (IntPtr player); diff -ru last-exit-0.2/src/PlayerWindow.cs last-exit-0.2-mod/src/PlayerWindow.cs --- last-exit-0.2/src/PlayerWindow.cs 2006-02-16 01:23:16.000000000 +0100 +++ last-exit-0.2-mod/src/PlayerWindow.cs 2006-03-01 04:56:00.000000000 +0100 @@ -49,6 +49,7 @@ private UrlLabel song_label; [Glade.Widget] private Button info_button; + [Glade.Widget] private Button save_button; [Glade.Widget] private ComboBox station_combo; private StationStore stations; @@ -132,7 +133,8 @@ tag_button.Clicked += new EventHandler (OnTagButtonClicked); journal_button.Clicked += new EventHandler (OnJournalButtonClicked); info_button.Clicked += new EventHandler (OnInfoButtonClicked); - + save_button.Clicked += new EventHandler (OnSaveButtonClicked); + // Volume volume_button = new VolumeButton (); volume_button_container.Add (volume_button); @@ -421,7 +423,26 @@ i_window.Visible = true; i_window.Response += new ResponseHandler (OnInfoWindowResponse); } - + + private void OnSaveButtonClicked (object o, EventArgs args) + { + FileChooserDialog filechooser = new FileChooserDialog("Choose Song directory", this, FileChooserAction.SelectFolder, + Stock.Cancel, ResponseType.Cancel, + Stock.Save, ResponseType.Accept); + + int response = filechooser.Run(); + if ((ResponseType) response == ResponseType.Accept && current_song != null) + { + string artist = current_song.Artist.Replace("/","-"); + string album = current_song.Album.Replace("/","-"); + string track = current_song.Track.Replace("/","-"); + string filename = String.Format("{0}/{1} - {2} - {3}.mp3", filechooser.CurrentFolder, artist, album, track); + Console.WriteLine("Setting up to save song at: {0}", filename); + Driver.player.SaveLocation = filename; + } + filechooser.Destroy(); + } + private void OnVolumeChanged (int vol) { Driver.player.Volume = vol; @@ -449,6 +470,7 @@ private void OnNewSong () { Driver.connection.GetMetadata (); + } private void OnCoverLoaded (Gdk.Pixbuf cover_pb)