Index: configure.in
===================================================================
RCS file: /cvs/gnome/muine/configure.in,v
retrieving revision 1.70
diff -u -u -r1.70 configure.in
--- configure.in 19 Jun 2004 14:26:55 -0000 1.70
+++ configure.in 18 Jul 2004 04:39:01 -0000
@@ -48,6 +48,7 @@
gdk-pixbuf-2.0 \
gnome-vfs-2.0 \
gtk+-2.0 \
+ libnautilus-burn \
libgnome-2.0 \
$audio_pkgconfig)
AC_SUBST(MUINE_CFLAGS)
Index: data/glade/Makefile.am
===================================================================
RCS file: /cvs/gnome/muine/data/glade/Makefile.am,v
retrieving revision 1.9
diff -u -u -r1.9 Makefile.am
--- data/glade/Makefile.am 15 Apr 2004 19:31:31 -0000 1.9
+++ data/glade/Makefile.am 18 Jul 2004 04:39:01 -0000
@@ -8,6 +8,8 @@
ProgressWindow.glade \
InfoWindow.glade \
PlaylistFilling.glade \
- GroupEditor.glade
+ GroupEditor.glade \
+ BurnPrefs.glade \
+ BurnProgressWindow.glade
EXTRA_DIST = $(noinst_DATA)
Index: data/glade/PlaylistWindow.glade
===================================================================
RCS file: /cvs/gnome/muine/data/glade/PlaylistWindow.glade,v
retrieving revision 1.27
diff -u -u -r1.27 PlaylistWindow.glade
--- data/glade/PlaylistWindow.glade 9 May 2004 13:17:47 -0000 1.27
+++ data/glade/PlaylistWindow.glade 18 Jul 2004 04:39:05 -0000
@@ -108,6 +108,29 @@
+
+
+
+
+
Index: libmuine/Makefile.am
===================================================================
RCS file: /cvs/gnome/muine/libmuine/Makefile.am,v
retrieving revision 1.10
diff -u -u -r1.10 Makefile.am
--- libmuine/Makefile.am 2 Apr 2004 18:05:49 -0000 1.10
+++ libmuine/Makefile.am 18 Jul 2004 04:39:07 -0000
@@ -20,18 +20,29 @@
muinelibdir = $(prefix)/lib/muine
muinelib_LTLIBRARIES = libmuine.la
+EXTRA_DIST = recorder-marshal.list
+
if HAVE_XINE
xine_sources = player-xine.c
endif
+
if HAVE_GST
-gst_sources = player-gst.c
+RMARSHALFILES = recorder-marshal.h recorder-marshal.c
+recorder-marshal.h: recorder-marshal.list
+ ( $(GLIB_GENMARSHAL) --prefix=recorder_marshal ./recorder-marshal.list --header > recorder-marshal.h )
+recorder-marshal.c: recorder-marshal.h
+ ( $(GLIB_GENMARSHAL) --prefix=recorder_marshal ./recorder-marshal.list --body --header > recorder-marshal.c )
+gst_sources = player-gst.c $(RMARSHALFILES) recorder-gst.c
+CLEANFILES = $(RMARSHALFILES)
+
endif
libmuine_la_SOURCES = \
$(xine_sources) \
$(gst_sources) \
player.h \
+ recorder.h \
metadata.c \
metadata.h \
ogg-helper.c \
Index: libmuine/metadata.c
===================================================================
RCS file: /cvs/gnome/muine/libmuine/metadata.c,v
retrieving revision 1.13
diff -u -u -r1.13 metadata.c
--- libmuine/metadata.c 27 Feb 2004 21:11:01 -0000 1.13
+++ libmuine/metadata.c 18 Jul 2004 04:39:09 -0000
@@ -669,8 +669,10 @@
gnome_vfs_get_file_info (escaped, info,
GNOME_VFS_FILE_INFO_GET_MIME_TYPE | GNOME_VFS_FILE_INFO_FOLLOW_LINKS);
- if (!strcmp (info->mime_type, "audio/x-mp3") ||
- !strcmp (info->mime_type, "audio/mpeg"))
+ if (info->mime_type == NULL) {
+ *error_message_return = g_strdup ("Unknown format");
+ } else if (!strcmp (info->mime_type, "audio/x-mp3") ||
+ !strcmp (info->mime_type, "audio/mpeg"))
m = assign_metadata_mp3 (escaped, info, error_message_return);
else if (!strcmp (info->mime_type, "application/x-ogg") ||
!strcmp (info->mime_type, "application/ogg"))
Index: src/Album.cs
===================================================================
RCS file: /cvs/gnome/muine/src/Album.cs,v
retrieving revision 1.25
diff -u -u -r1.25 Album.cs
--- src/Album.cs 20 Jun 2004 18:53:26 -0000 1.25
+++ src/Album.cs 18 Jul 2004 04:39:12 -0000
@@ -19,6 +19,11 @@
using System;
using System.Collections;
+using System.IO;
+using System.Net;
+using System.Threading;
+using System.Runtime.InteropServices;
+
public class Album
{
Index: src/Makefile.am
===================================================================
RCS file: /cvs/gnome/muine/src/Makefile.am,v
retrieving revision 1.36
diff -u -u -r1.36 Makefile.am
--- src/Makefile.am 10 May 2004 13:30:57 -0000 1.36
+++ src/Makefile.am 18 Jul 2004 04:39:12 -0000
@@ -13,6 +13,7 @@
$(srcdir)/About.cs \
$(srcdir)/Metadata.cs \
$(srcdir)/Player.cs \
+ $(srcdir)/Recorder.cs \
$(srcdir)/FileSelector.cs \
$(srcdir)/StringUtils.cs \
$(srcdir)/KeyUtils.cs \
@@ -35,7 +36,10 @@
$(srcdir)/CoverImage.cs \
$(srcdir)/MmKeys.cs \
$(srcdir)/GettextCatalog.cs \
- $(srcdir)/FileUtils.cs
+ $(srcdir)/FileUtils.cs \
+ $(srcdir)/CdUnit.cs \
+ $(srcdir)/BurnPrefs.cs \
+ $(srcdir)/BurnProgressWindow.cs
ASSEMBLIES = \
/r:AmazonSearchService.dll \
@@ -50,6 +54,8 @@
/resource:$(top_srcdir)/data/glade/AddWindow.glade,AddWindow.glade \
/resource:$(top_srcdir)/data/glade/ProgressWindow.glade,ProgressWindow.glade \
/resource:$(top_srcdir)/data/glade/InfoWindow.glade,InfoWindow.glade \
+ /resource:$(top_srcdir)/data/glade/BurnPrefs.glade,BurnPrefs.glade \
+ /resource:$(top_srcdir)/data/glade/BurnProgressWindow.glade,BurnProgressWindow.glade \
/resource:$(top_srcdir)/data/images/muine-previous.png,muine-previous.png \
/resource:$(top_srcdir)/data/images/muine-previous-16.png,muine-previous-16.png \
/resource:$(top_srcdir)/data/images/muine-play.png,muine-play.png \
Index: src/NotificationAreaIcon.cs
===================================================================
RCS file: /cvs/gnome/muine/src/NotificationAreaIcon.cs,v
retrieving revision 1.22
diff -u -u -r1.22 NotificationAreaIcon.cs
--- src/NotificationAreaIcon.cs 18 Jun 2004 19:33:16 -0000 1.22
+++ src/NotificationAreaIcon.cs 18 Jul 2004 04:39:13 -0000
@@ -43,6 +43,7 @@
public ImageMenuItem play_song_menu_item;
public ImageMenuItem play_album_menu_item;
public MenuItem show_window_menu_item;
+ public ImageMenuItem quit_menu_item;
private bool button_down = false;
@@ -105,6 +106,13 @@
show_window_menu_item = new MenuItem (Muine.Catalog.GetString ("Show _Window"));
menu.Append (show_window_menu_item);
+
+ sep = new SeparatorMenuItem ();
+ menu.Append (sep);
+
+ quit_menu_item = new ImageMenuItem (Muine.Catalog.GetString ("_Quit"));
+ quit_menu_item.Image = new Gtk.Image (Stock.Quit, IconSize.Menu);
+ menu.Append (quit_menu_item);
menu.ShowAll ();
}
Index: src/Player.cs
===================================================================
RCS file: /cvs/gnome/muine/src/Player.cs,v
retrieving revision 1.16
diff -u -u -r1.16 Player.cs
--- src/Player.cs 5 Jun 2004 14:17:22 -0000 1.16
+++ src/Player.cs 18 Jul 2004 04:39:14 -0000
@@ -27,6 +27,11 @@
string filename,
out IntPtr error_ptr);
[DllImport ("libmuine")]
+ private static extern bool player_set_output_file (IntPtr player,
+ string filename,
+ out IntPtr error_ptr);
+
+ [DllImport ("libmuine")]
private static extern void player_set_replaygain (IntPtr player,
double gain,
double peak);
Index: src/PlaylistWindow.cs
===================================================================
RCS file: /cvs/gnome/muine/src/PlaylistWindow.cs,v
retrieving revision 1.126
diff -u -u -r1.126 PlaylistWindow.cs
--- src/PlaylistWindow.cs 20 Jun 2004 18:59:39 -0000 1.126
+++ src/PlaylistWindow.cs 18 Jul 2004 04:39:23 -0000
@@ -21,6 +21,7 @@
using System.Collections;
using System.IO;
using System.Text.RegularExpressions;
+using System.Runtime.InteropServices;
using Gtk;
using GLib;
@@ -84,6 +85,9 @@
/* the player object */
private Player player;
+ /* the recorder object */
+ private Recorder recorder;
+
/* the playlist filename */
private string playlist_filename;
@@ -403,6 +407,7 @@
icon.play_song_menu_item.Activated += new EventHandler (HandleAddSongCommand);
icon.play_album_menu_item.Activated += new EventHandler (HandleAddAlbumCommand);
icon.show_window_menu_item.Activated += new EventHandler (HandleToggleWindowVisibilityCommand);
+ icon.quit_menu_item.Activated += new EventHandler (HandleQuitCommand);
}
private Gdk.Pixbuf empty_pixbuf;
@@ -1391,6 +1396,168 @@
OpenPlaylist (fn);
}
+ private bool HandleInsertCdEvent (bool is_reload, bool can_rewrite, bool busy_cd)
+ {
+ String msg;
+ String title;
+ if (busy_cd) {
+ msg = Muine.Catalog.GetString ("Please make sure another application is not using the disc.");
+ title = Muine.Catalog.GetString ("Disc is busy");
+ } else if (is_reload && can_rewrite) {
+ msg = Muine.Catalog.GetString ("Please insert a rewritable or blank media in the drive tray.");
+ title = Muine.Catalog.GetString ("Insert rewritable or blank media");
+ } else if (is_reload && !can_rewrite) {
+ msg = Muine.Catalog.GetString ("Please insert a blank media in the drive tray.");
+ title = Muine.Catalog.GetString ("Insert blank media");
+ } else if (can_rewrite) {
+ msg = Muine.Catalog.GetString ("Please replace the in-drive media by a rewritable or blank media.");
+ title = Muine.Catalog.GetString ("Reload rewritable or blank media");
+ } else {
+ msg = Muine.Catalog.GetString ("Please replace the in-drive media by a blank media.");
+ title = Muine.Catalog.GetString ("Reload blank media");
+ }
+
+ Dialog dialog = new Dialog (title, this, DialogFlags.Modal);
+ dialog.AddButton (Stock.Ok, ResponseType.Ok);
+ dialog.AddButton (Stock.Cancel, ResponseType.Cancel);
+ Label label = new Label (msg);
+ label.Visible = true;
+ dialog.VBox.PackStart (label);
+ if (dialog.Run () == (int) ResponseType.Cancel) {
+ dialog.Destroy ();
+ return false;
+ }
+
+ dialog.Destroy ();
+ return true;
+ }
+
+
+
+ [DllImport ("libmuine")]
+ private static extern long get_dir_free_space (string path);
+
+ private String GetBurnTempDir ()
+ {
+ String temp_dir;
+
+ try {
+ temp_dir = (String) Muine.GConfClient.Get ("/apps/muine/burn/temp");
+ } catch {
+ temp_dir = null;
+ }
+
+ long estimated_size = recorder.EstimateWavSize ();
+
+ while (temp_dir == null || estimated_size > get_dir_free_space (temp_dir)) {
+ Label label;
+ Dialog dialog = new Dialog ("Temp dir selection", this, Gtk.DialogFlags.DestroyWithParent);
+ dialog.Modal = true;
+ dialog.AddButton (Stock.Ok, ResponseType.Ok);
+
+ FileSelection sel = new FileSelection (Muine.Catalog.GetString ("Select a temporal directory"));
+
+ if (temp_dir == null)
+ label = new Label (Muine.Catalog.GetString ("You need to select a directory for temporal files"));
+ else {
+ label = new Label (String.Format (Muine.Catalog.GetString ("{0} has only {1} MiBs free. Please select another" +
+ " one with at least {2} MiBs free"),
+ temp_dir,
+ get_dir_free_space (temp_dir) / 1024,
+ estimated_size / 1048576));
+ sel.Filename = temp_dir;
+ }
+
+ label.Visible = true;
+ dialog.VBox.PackStart (label);
+ dialog.Run ();
+ dialog.Destroy ();
+
+ sel.HideFileopButtons ();
+ sel.HistoryPulldown.Visible = false;
+ sel.FileList.Parent.Visible = false;
+ sel.SetDefaultSize (350, 250);
+
+ if (sel.Run () != (int) ResponseType.Ok) {
+ sel.Destroy ();
+ return null;
+ }
+ temp_dir = sel.Filename;
+ if (temp_dir.EndsWith ("/") == false)
+ temp_dir += "/";
+ Muine.GConfClient.Set ("/apps/muine/burn/temp", temp_dir);
+ sel.Destroy ();
+ }
+ return temp_dir;
+ }
+
+ private String GetBurnDrivePath ()
+ {
+ String drive_path;
+
+ try {
+ drive_path = (String) Muine.GConfClient.Get ("/apps/muine/burn/drive");
+ } catch {
+ drive_path = null;
+ }
+ if (drive_path != null) {
+ if (recorder.SetDrive (drive_path) == false)
+ drive_path = null;
+ }
+
+ ArrayList devices = recorder.GetValidDevices ();
+ if (devices.Count == 0) {
+ new ErrorDialog (String.Format (Muine.Catalog.GetString ("You don't have any recognized CD Recorder")));
+ return null;
+ }
+
+ if (drive_path == null && devices.Count == 1) {
+ CdUnit unit = (CdUnit) devices[0];
+ recorder.SetDrive (unit.Path);
+ }
+
+ if (drive_path == null || devices.Count > 1) {
+ BurnPrefs bp = new BurnPrefs (devices);
+ if (bp.GetDrivePath (out drive_path) == false)
+ return null;
+ if (recorder.SetDrive (drive_path) == false)
+ return null;
+ }
+ return drive_path;
+ }
+
+ private void HandleBurnPlaylistCommand (object o, EventArgs args)
+ {
+ String temp_dir;
+ String drive_path;
+ long estimated_size, free_space;
+
+ try {
+ recorder = new Recorder ();
+ } catch (Exception e) {
+ new ErrorDialog (String.Format (Muine.Catalog.GetString ("Failed to initialize the recorder backend:\n{0}\n\nExiting..."), e.Message));
+ Muine.Exit ();
+ }
+
+ foreach (int i in playlist.Contents) {
+ IntPtr handle = new IntPtr (i);
+ Song song = Song.FromHandle (handle);
+ recorder.AddSong (song);
+ }
+
+ temp_dir = GetBurnTempDir ();
+ if (temp_dir == null)
+ return;
+
+ drive_path = GetBurnDrivePath ();
+ if (drive_path == null)
+ return;
+
+ recorder.InsertCdEvent += new Recorder.InsertCdHandler (HandleInsertCdEvent);
+
+ recorder.WriteFiles (temp_dir);
+
+ }
private void HandleSavePlaylistAsCommand (object o, EventArgs args)
{
FileSelector sel = new FileSelector (Muine.Catalog.GetString ("Save Playlist"),
--- /dev/null 2004-02-23 22:02:56.000000000 +0100
+++ data/glade/BurnPrefs.glade 2004-07-17 08:39:15.000000000 +0200
@@ -0,0 +1,119 @@
+
+
+
+
+
+
+
+ 7
+
+ GTK_WINDOW_TOPLEVEL
+ GTK_WIN_POS_NONE
+ False
+ True
+ False
+ True
+ False
+ False
+ GDK_WINDOW_TYPE_HINT_NORMAL
+ GDK_GRAVITY_NORTH_WEST
+ False
+
+
+
+ True
+ False
+ 6
+
+
+
+ True
+ GTK_BUTTONBOX_END
+
+
+
+ True
+ True
+ True
+ True
+ gtk-cancel
+ True
+ GTK_RELIEF_NORMAL
+ True
+ -6
+
+
+
+
+
+
+ True
+ True
+ True
+ _Burn
+ True
+ GTK_RELIEF_NORMAL
+ True
+ -5
+
+
+
+
+ 0
+ False
+ True
+ GTK_PACK_END
+
+
+
+
+
+ True
+ False
+ 6
+
+
+
+ True
+ Select CD Drive:
+ False
+ False
+ GTK_JUSTIFY_LEFT
+ False
+ False
+ 0.5
+ 0.5
+ 0
+ 0
+
+
+ 0
+ False
+ False
+
+
+
+
+
+
+ 0
+ False
+ False
+
+
+
+
+ 0
+ True
+ True
+
+
+
+
+
+
+
--- /dev/null 2004-02-23 22:02:56.000000000 +0100
+++ data/glade/BurnProgressWindow.glade 2004-07-13 06:56:11.000000000 +0200
@@ -0,0 +1,157 @@
+
+
+
+
+
+
+
+ 7
+
+ GTK_WINDOW_TOPLEVEL
+ GTK_WIN_POS_NONE
+ False
+ True
+ False
+ True
+ False
+ False
+ GDK_WINDOW_TYPE_HINT_NORMAL
+ GDK_GRAVITY_NORTH_WEST
+ False
+
+
+
+
+
+ True
+ False
+ 6
+
+
+
+ True
+ GTK_BUTTONBOX_END
+
+
+
+ True
+ True
+ True
+ True
+ gtk-cancel
+ True
+ GTK_RELIEF_NORMAL
+ True
+ -6
+
+
+
+
+
+ 0
+ False
+ True
+ GTK_PACK_END
+
+
+
+
+
+ 5
+ True
+ False
+ 6
+
+
+
+ True
+ gtk-dialog-info
+ 6
+ 0.5
+ 0.5
+ 0
+ 0
+
+
+ 0
+ False
+ True
+
+
+
+
+
+ True
+ False
+ 6
+
+
+
+ True
+ Writing temp files:
+ False
+ False
+ GTK_JUSTIFY_LEFT
+ False
+ False
+ 0
+ 0.5
+ 0
+ 0
+
+
+ 0
+ False
+ False
+
+
+
+
+
+ True
+ False
+ 0
+
+
+
+
+
+
+ 0
+ False
+ False
+
+
+
+
+ 0
+ True
+ True
+
+
+
+
+ 0
+ True
+ True
+
+
+
+
+
+ True
+ GTK_PROGRESS_LEFT_TO_RIGHT
+ 0
+ 0.1
+
+
+ 0
+ False
+ False
+
+
+
+
+
+
+
--- /dev/null 2004-02-23 22:02:56.000000000 +0100
+++ libmuine/recorder-gst.c 2004-07-17 09:17:22.000000000 +0200
@@ -0,0 +1,505 @@
+/* -*- mode: C; c-file-style: "gnu" -*- */
+/*
+ * Copyright (C) 2004 Fernando Herrera
+ *
+ * This program is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU General Public License as
+ * published by the Free Software Foundation; either version 2 of the
+ * License, or (at your option) any later version.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+ * General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public
+ * License along with this program; if not, write to the
+ * Free Software Foundation, Inc., 59 Temple Place - Suite 330,
+ * Boston, MA 02111-1307, USA.
+ */
+
+#include
+#include
+#include
+#include
+#include
+#include
+#include
+#include
+#include
+
+#include "recorder.h"
+#include "recorder-marshal.h"
+
+static void recorder_class_init (RecorderClass *klass);
+static void recorder_init (Recorder *recorder);
+static void recorder_finalize (GObject *object);
+static void eos_cb (GstElement *sink,
+ Recorder *recorder);
+static void error_cb (GObject *object,
+ GstObject *origin,
+ char *error,
+ Recorder *recorder);
+
+static void recorder_cd_progress_cb (CDRecorder *cdrecorder,
+ gdouble fraction,
+ gpointer data);
+
+static gboolean recorder_insert_cd_request_cb (CDRecorder *cdrecorder,
+ gboolean is_reload,
+ gboolean can_rewrite,
+ gboolean busy_cd,
+ gpointer data);
+
+
+
+enum {
+ END_OF_STREAM,
+ CD_BURN_PROGRESS,
+ CD_BURN_INSERT_CD,
+ ERROR,
+ LAST_SIGNAL
+};
+
+struct _RecorderPriv {
+ GstElement *pipeline;
+ GstElement *source;
+ GstElement *decoder;
+ GstElement *writer;
+ GstElement *converter;
+ GstElement *encoder;
+ GstElement *sink;
+
+ guint eos_idle_id;
+
+ gint64 pos;
+
+ GList *tracks;
+ CDDrive *drive;
+};
+
+static GObjectClass *parent_class;
+static guint signals[LAST_SIGNAL];
+
+GType
+recorder_get_type (void)
+{
+ static GType type = 0;
+
+ if (!type) {
+ static const GTypeInfo info = {
+ sizeof (RecorderClass),
+ NULL, /* base_init */
+ NULL, /* base_finalize */
+ (GClassInitFunc) recorder_class_init,
+ NULL, /* class_finalize */
+ NULL, /* class_data */
+ sizeof (Recorder),
+ 0,
+ (GInstanceInitFunc) recorder_init,
+ };
+
+ type = g_type_register_static (G_TYPE_OBJECT,
+ "Recorder",
+ &info, 0);
+ }
+
+ return type;
+}
+
+static void
+recorder_class_init (RecorderClass *klass)
+{
+ GObjectClass *object_class;
+
+ parent_class = g_type_class_peek_parent (klass);
+ object_class = (GObjectClass *) klass;
+
+ object_class->finalize = recorder_finalize;
+
+ signals[END_OF_STREAM] =
+ g_signal_new ("end_of_stream",
+ G_TYPE_FROM_CLASS (klass),
+ G_SIGNAL_RUN_LAST,
+ 0,
+ NULL, NULL,
+ g_cclosure_marshal_VOID__VOID,
+ G_TYPE_NONE, 0);
+ signals[CD_BURN_PROGRESS] =
+ g_signal_new ("cd_burn_progress",
+ G_TYPE_FROM_CLASS (klass),
+ G_SIGNAL_RUN_LAST,
+ 0,
+ NULL, NULL,
+ g_cclosure_marshal_VOID__DOUBLE,
+ G_TYPE_NONE, 1, G_TYPE_DOUBLE);
+ signals[CD_BURN_INSERT_CD] =
+ g_signal_new ("cd_burn_insert_cd",
+ G_TYPE_FROM_CLASS (klass),
+ G_SIGNAL_RUN_LAST,
+ 0,
+ NULL, NULL,
+ recorder_marshal_BOOLEAN__BOOLEAN_BOOLEAN_BOOLEAN,
+ G_TYPE_BOOLEAN, 3, G_TYPE_BOOLEAN,
+ G_TYPE_BOOLEAN, G_TYPE_BOOLEAN);
+ signals[ERROR] =
+ g_signal_new ("error",
+ G_TYPE_FROM_CLASS (klass),
+ G_SIGNAL_RUN_LAST,
+ 0,
+ NULL, NULL,
+ g_cclosure_marshal_VOID__STRING,
+ G_TYPE_NONE, 1, G_TYPE_STRING);
+}
+
+static void
+recorder_init (Recorder *recorder)
+{
+}
+
+static void
+recorder_construct (Recorder *recorder, char **error)
+{
+ RecorderPriv *priv;
+
+ gst_init (NULL, NULL);
+
+ priv = g_new0 (RecorderPriv, 1);
+ recorder->priv = priv;
+
+ priv->eos_idle_id = 0;
+
+ priv->pipeline = gst_pipeline_new ("pipeline");
+
+ priv->source = gst_element_factory_make ("gnomevfssrc", "source");
+ if (!priv->source) {
+ *error = g_strdup (_("Failed to create the required gnomevfssrc GStreamer element"));
+
+ return;
+ }
+
+ priv->decoder = gst_element_factory_make ("mad", "decoder");
+ if (!priv->decoder) {
+ *error = g_strdup (_("Could not render GStreamer mad decoder"));
+
+ return;
+ }
+
+ priv->converter = gst_element_factory_make ("audioconvert", "converter");
+
+ priv->encoder = gst_element_factory_make ("wavenc", "encoder");
+
+ priv->sink = gst_element_factory_make ("filesink", "sink");
+
+ gst_bin_add_many (GST_BIN (priv->pipeline), priv->source, priv->decoder, priv->converter, priv->encoder, priv->sink, NULL);
+ gst_element_link_many (priv->source, priv->decoder, priv->converter, priv->encoder, priv->sink, NULL);
+
+ g_signal_connect (priv->pipeline, "error", G_CALLBACK (error_cb), recorder);
+ g_signal_connect (priv->pipeline, "eos", G_CALLBACK (eos_cb), recorder);
+
+ priv->tracks = NULL;
+ priv->drive = NULL;
+}
+
+static void
+recorder_finalize (GObject *object)
+{
+ Recorder *recorder = RECORDER (object);
+
+ recorder_write_file_cancel (recorder);
+
+ g_free (recorder->priv);
+
+ if (G_OBJECT_CLASS (parent_class)->finalize)
+ (* G_OBJECT_CLASS (parent_class)->finalize) (object);
+}
+
+Recorder *
+recorder_new (char **error)
+{
+ Recorder *recorder;
+
+ recorder = g_object_new (TYPE_RECORDER, NULL);
+
+ *error = NULL;
+
+ recorder_construct (recorder, error);
+
+ return recorder;
+}
+
+static void
+eos_cb (GstElement *sink, Recorder *recorder)
+{
+ recorder->priv->eos_idle_id = 0;
+ gst_element_set_state (GST_ELEMENT (recorder->priv->pipeline), GST_STATE_NULL);
+ g_signal_emit (recorder, signals[END_OF_STREAM], 0);
+}
+
+typedef struct {
+ Recorder *recorder;
+ char *error;
+} RecorderError;
+
+static void
+error_cb (GObject *object,
+ GstObject *origin,
+ char *error,
+ Recorder *recorder)
+{
+ RecorderError *data = g_new0 (RecorderError, 1);
+
+ data->recorder = recorder;
+ data->error = g_strdup (error);
+
+ g_signal_emit (data->recorder, signals[ERROR], 0, data->error);
+ g_free (data->error);
+ g_free (data);
+}
+
+gboolean
+recorder_set_orig (Recorder *recorder,
+ const char *file,
+ char **error)
+{
+ g_return_val_if_fail (IS_RECORDER (recorder), FALSE);
+
+ *error = NULL;
+
+ g_print ("File=%s\n", file);
+
+ if (recorder->priv->eos_idle_id > 0) {
+ g_source_remove (recorder->priv->eos_idle_id);
+ recorder->priv->eos_idle_id = 0;
+ }
+
+ g_object_set (G_OBJECT (recorder->priv->source), "location", file, NULL);
+
+ recorder->priv->pos = 0;
+
+ return TRUE;
+}
+
+gboolean
+recorder_set_dest (Recorder *recorder,
+ const char *file,
+ char **error)
+{
+ g_return_val_if_fail (IS_RECORDER (recorder), FALSE);
+
+ *error = NULL;
+
+ if (recorder->priv->eos_idle_id > 0) {
+ g_source_remove (recorder->priv->eos_idle_id);
+ recorder->priv->eos_idle_id = 0;
+ }
+
+ g_object_set (G_OBJECT (recorder->priv->sink), "location", file, NULL);
+
+ recorder->priv->pos = 0;
+
+ return TRUE;
+}
+
+
+void
+recorder_write_file (Recorder *recorder)
+{
+ g_return_if_fail (IS_RECORDER (recorder));
+
+ gst_element_set_state (GST_ELEMENT (recorder->priv->pipeline), GST_STATE_PLAYING);
+
+ recorder->priv->eos_idle_id = g_idle_add ((GSourceFunc) gst_bin_iterate, GST_BIN (recorder->priv->pipeline));
+
+}
+
+void
+recorder_write_file_cancel (Recorder *recorder)
+{
+ g_return_if_fail (IS_RECORDER (recorder));
+
+ recorder->priv->pos = 0;
+
+ gst_element_set_state (GST_ELEMENT (recorder->priv->pipeline), GST_STATE_READY);
+}
+
+void
+recorder_pause (Recorder *recorder)
+{
+ g_return_if_fail (IS_RECORDER (recorder));
+
+ gst_element_set_state (GST_ELEMENT (recorder->priv->pipeline), GST_STATE_PAUSED);
+}
+
+int
+recorder_tell (Recorder *recorder)
+{
+ g_return_val_if_fail (IS_RECORDER (recorder), -1);
+
+ return recorder->priv->pos / GST_SECOND;
+}
+
+gboolean
+recorder_add_track (Recorder *recorder,
+ const char *file,
+ char **error)
+{
+ Track *track;
+ g_return_val_if_fail (IS_RECORDER (recorder), FALSE);
+
+ *error = NULL;
+
+ track = g_new0 (Track, 1);
+
+ track->type = TRACK_TYPE_AUDIO;
+ track->contents.audio.filename = g_strdup (file);
+ track->contents.audio.cdtext = g_path_get_basename (file);
+
+
+ /* FIXME: check for existence */
+
+ recorder->priv->tracks = g_list_append (recorder->priv->tracks, track);
+
+ return TRUE;
+}
+
+gboolean
+recorder_has_many_devices ()
+{
+ GList *drives, *tmp;
+ int num_drives = 0;
+
+ drives = scan_for_cdroms (FALSE, FALSE);
+
+ for (tmp = drives; tmp != NULL; tmp = tmp->next) {
+ CDDrive *drive = (CDDrive*) tmp->data;
+
+ if (drive->type & (CDDRIVE_TYPE_CD_RECORDER | CDDRIVE_TYPE_CDRW_RECORDER |
+ CDDRIVE_TYPE_DVD_RAM_RECORDER | CDDRIVE_TYPE_DVD_RW_RECORDER |
+ CDDRIVE_TYPE_DVD_PLUS_R_RECORDER | CDDRIVE_TYPE_DVD_PLUS_RW_RECORDER))
+ num_drives++;
+
+ cd_drive_free (drive);
+ }
+ g_list_free (drives);
+
+ return num_drives > 1;
+}
+
+gchar*
+recorder_get_valid_devices (void)
+{
+ GList *drives, *tmp;
+ GString *buf;
+ gchar *str;
+
+ buf = g_string_new (NULL);
+
+ drives = scan_for_cdroms (FALSE, FALSE);
+
+ for (tmp = drives; tmp != NULL; tmp = tmp->next) {
+ CDDrive *drive = (CDDrive*) tmp->data;
+
+ if (drive->type & (CDDRIVE_TYPE_CD_RECORDER | CDDRIVE_TYPE_CDRW_RECORDER |
+ CDDRIVE_TYPE_DVD_RAM_RECORDER | CDDRIVE_TYPE_DVD_RW_RECORDER |
+ CDDRIVE_TYPE_DVD_PLUS_R_RECORDER | CDDRIVE_TYPE_DVD_PLUS_RW_RECORDER)) {
+ g_string_append (buf, drive->device);
+ g_string_append (buf, ":");
+ g_string_append (buf, drive->display_name);
+ g_string_append (buf, ";");
+ }
+ cd_drive_free (drive);
+ }
+ g_list_free (drives);
+
+ str = g_string_free (buf, FALSE);
+
+ return str;
+}
+
+gboolean
+recorder_select_drive (Recorder *recorder,
+ const char *device,
+ char **error)
+{
+ GList *drives, *tmp;
+ g_return_val_if_fail (IS_RECORDER (recorder), FALSE);
+
+ *error = NULL;
+
+ drives = scan_for_cdroms (FALSE, FALSE);
+
+ for (tmp = drives; tmp != NULL; tmp = tmp->next) {
+ CDDrive *drive = (CDDrive*) tmp->data;
+ if (strcmp (drive->device, device) == 0) {
+ recorder->priv->drive = drive;
+ break;
+ }
+ cd_drive_free (drive);
+ }
+ g_list_free (drives);
+
+ if (recorder->priv->drive == NULL) {
+ *error = g_strdup_printf (_("Cannot found drive %s"), device);
+ return FALSE;
+ }
+
+ if (!(recorder->priv->drive->type & (CDDRIVE_TYPE_CD_RECORDER | CDDRIVE_TYPE_CDRW_RECORDER |
+ CDDRIVE_TYPE_DVD_RAM_RECORDER | CDDRIVE_TYPE_DVD_RW_RECORDER |
+ CDDRIVE_TYPE_DVD_PLUS_R_RECORDER | CDDRIVE_TYPE_DVD_PLUS_RW_RECORDER))) {
+ *error = g_strdup_printf (_("Drive %s is cannot burn CDs"), device);
+ return FALSE;
+ }
+
+ return TRUE;
+}
+
+int
+recorder_burn_cd (Recorder *recorder)
+{
+ g_return_val_if_fail (IS_RECORDER (recorder), FALSE);
+ CDRecorder *cdrecorder;
+
+ cdrecorder = cd_recorder_new ();
+
+ g_signal_connect (G_OBJECT (cdrecorder), "progress-changed", G_CALLBACK (recorder_cd_progress_cb), recorder);
+ g_signal_connect (G_OBJECT (cdrecorder), "insert-cd-request", G_CALLBACK (recorder_insert_cd_request_cb), recorder);
+
+ return cd_recorder_write_tracks (cdrecorder, recorder->priv->drive, recorder->priv->tracks, 0,
+ CDRECORDER_DUMMY_WRITE | CDRECORDER_DISC_AT_ONCE | CDRECORDER_DEBUG);
+}
+
+static void
+recorder_cd_progress_cb (CDRecorder *cdrecorder, gdouble fraction, gpointer data)
+{
+ Recorder *recorder = (Recorder*) data;
+
+ g_signal_emit (recorder, signals[CD_BURN_PROGRESS], 0, fraction);
+}
+
+static gboolean
+recorder_insert_cd_request_cb (CDRecorder *cdrecorder, gboolean is_reload, gboolean can_rewrite, gboolean busy_cd, gpointer data)
+{
+
+ Recorder *recorder = (Recorder*) data;
+ gboolean res;
+
+ g_signal_emit (recorder, signals[CD_BURN_INSERT_CD], 0, is_reload, can_rewrite, busy_cd, &res);
+ return res;
+}
+
+
+
+
+long
+get_dir_free_space (char *path)
+{
+ struct statfs buf;
+
+ if (statfs (path, &buf) == 0) {
+ return buf.f_bfree * buf.f_bsize;
+ } else {
+ return 0;
+ }
+}
+
--- /dev/null 2004-02-23 22:02:56.000000000 +0100
+++ libmuine/recorder-marshal.list 2004-07-17 03:42:26.000000000 +0200
@@ -0,0 +1 @@
+BOOLEAN:BOOLEAN,BOOLEAN,BOOLEAN
--- /dev/null 2004-02-23 22:02:56.000000000 +0100
+++ libmuine/recorder.h 2004-07-17 06:14:03.000000000 +0200
@@ -0,0 +1,72 @@
+/* -*- mode: C; c-file-style: "gnu" -*- */
+/*
+ * Copyright (C) 2004 Fernando Herrera
+ *
+ * This program is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU General Public License as
+ * published by the Free Software Foundation; either version 2 of the
+ * License, or (at your option) any later version.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+ * General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public
+ * License along with this program; if not, write to the
+ * Free Software Foundation, Inc., 59 Temple Place - Suite 330,
+ * Boston, MA 02111-1307, USA.
+ */
+
+#ifndef __RECORDER_H__
+#define __RECORDER_H__
+
+#include
+
+#define TYPE_RECORDER (recorder_get_type ())
+#define RECORDER(obj) (G_TYPE_CHECK_INSTANCE_CAST ((obj), TYPE_RECORDER, Recorder))
+#define RECORDER_CLASS(klass) (G_TYPE_CHECK_CLASS_CAST ((klass), TYPE_RECORDER, RecorderClass))
+#define IS_RECORDER(obj) (G_TYPE_CHECK_INSTANCE_TYPE ((obj), TYPE_RECORDER))
+#define IS_RECORDER_CLASS(klass) (G_TYPE_CHECK_CLASS_TYPE ((klass), TYPE_RECORDER))
+#define RECORDER_GET_CLASS(obj) (G_TYPE_INSTANCE_GET_CLASS ((obj), TYPE_RECORDER, RecorderClass))
+
+typedef struct _Recorder Recorder;
+typedef struct _RecorderClass RecorderClass;
+typedef struct _RecorderPriv RecorderPriv;
+
+struct _Recorder
+{
+ GObject parent;
+ RecorderPriv *priv;
+};
+
+struct _RecorderClass
+{
+ GObjectClass parent_class;
+};
+
+
+GType recorder_get_type (void);
+Recorder * recorder_new (char **error);
+gboolean recorder_set_orig (Recorder *recorder,
+ const char *filename,
+ char **error);
+gboolean recorder_set_dest (Recorder *recorder,
+ const char *filename,
+ char **error);
+void recorder_write_file (Recorder *recorder);
+void recorder_write_file_cancel (Recorder *recorder);
+gboolean recorder_add_track (Recorder *recorder,
+ const char *filename,
+ char **error);
+gchar * recorder_get_valid_devices (void);
+gboolean recorder_has_many_devices (void);
+gboolean recorder_select_drive (Recorder *recorder,
+ const char *device,
+ char **error);
+int recorder_burn_cd (Recorder *recorder);
+void recorder_pause (Recorder *recorder);
+int recorder_tell (Recorder *recorder);
+long get_dir_free_space (char *path);
+
+#endif /* __RECORDER_H__ */
--- /dev/null 2004-02-23 22:02:56.000000000 +0100
+++ src/BurnPrefs.cs 2004-07-17 09:05:40.000000000 +0200
@@ -0,0 +1,82 @@
+/*
+ * Copyright (C) 2004 Fernando Herrera
+ *
+ * This program is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU General Public License as
+ * published by the Free Software Foundation; either version 2 of the
+ * License, or (at your option) any later version.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+ * General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public
+ * License along with this program; if not, write to the
+ * Free Software Foundation, Inc., 59 Temple Place - Suite 330,
+ * Boston, MA 02111-1307, USA.
+ */
+
+using System;
+using System.Collections;
+
+using Gtk;
+using GLib;
+
+public class BurnPrefs
+{
+ [Glade.Widget]
+ Window window;
+ [Glade.Widget]
+ OptionMenu drives_menu;
+
+ private ArrayList devices;
+
+
+ public BurnPrefs (ArrayList devices)
+ {
+ Glade.XML gxml = new Glade.XML (null, "BurnPrefs.glade", "window", null);
+ gxml.Autoconnect (this);
+
+ this.devices = (ArrayList) devices.Clone ();
+
+ window.Title = String.Format (Muine.Catalog.GetString ("Burn playlist"));
+
+ window.SetDefaultSize (400, -1);
+ Menu m = new Menu ();
+ foreach (CdUnit unit in devices) {
+ MenuItem item = new MenuItem (unit.Name);
+ m.Append (item);
+ }
+ drives_menu.Menu = m;
+ drives_menu.ShowAll ();
+ try {
+ String path = (String) Muine.GConfClient.Get ("/apps/muine/burn/drive");
+ for (int i = 0; i < devices.Count; i++) {
+ CdUnit unit = (CdUnit) devices[i];
+ if (unit.Path == path)
+ drives_menu.SetHistory ((uint) i);
+ }
+ } catch {
+ drives_menu.SetHistory (0);
+ }
+ }
+
+ public bool GetDrivePath (out String drive_path)
+ {
+ int res = ((Dialog) window).Run ();
+
+ if (res == (int) ResponseType.Ok) {
+ CdUnit unit = (CdUnit) devices[(int) drives_menu.History];
+ drive_path = unit.Path;
+ Muine.GConfClient.Set ("/apps/muine/burn/drive", drive_path);
+ window.Destroy ();
+ return true;
+ } else {
+ drive_path = null;
+ window.Destroy ();
+ return false;
+ }
+ }
+
+}
--- /dev/null 2004-02-23 22:02:56.000000000 +0100
+++ src/BurnProgressWindow.cs 2004-07-13 22:26:11.000000000 +0200
@@ -0,0 +1,131 @@
+/*
+ * Copyright (C) 2004 Jorn Baayen
+ *
+ * This program is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU General Public License as
+ * published by the Free Software Foundation; either version 2 of the
+ * License, or (at your option) any later version.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+ * General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public
+ * License along with this program; if not, write to the
+ * Free Software Foundation, Inc., 59 Temple Place - Suite 330,
+ * Boston, MA 02111-1307, USA.
+ */
+
+using System;
+
+using Gtk;
+using GLib;
+
+public class BurnProgressWindow
+{
+ [Glade.Widget]
+ Window window;
+ [Glade.Widget]
+ Label loading_label;
+ [Glade.Widget]
+ Container file_label_container;
+ [Glade.Widget]
+ ProgressBar progressbar;
+ private EllipsizingLabel file_label;
+ private int steps = 0;
+ private int current_step = 0;
+
+ bool canceled;
+
+ public BurnProgressWindow (Window parent, string title)
+ {
+ Glade.XML gxml = new Glade.XML (null, "BurnProgressWindow.glade", "window", null);
+ gxml.Autoconnect (this);
+
+ window.TransientFor = parent;
+ window.Title = String.Format (title);
+
+ window.SetDefaultSize (400, -1);
+
+ file_label = new EllipsizingLabel ("");
+ file_label.Xalign = 0.0f;
+ file_label.Visible = true;
+ file_label_container.Add (file_label);
+
+ MarkupUtils.LabelSetMarkup (loading_label, 0, StringUtils.GetByteLength (loading_label.Text),
+ false, true, false);
+
+ canceled = false;
+
+ file_label.Text = "...";
+ }
+
+ public bool ReportFile (string file)
+ {
+ if (canceled)
+ return false;
+
+ window.Visible = true;
+
+ file_label.Text = file;
+
+ return true;
+ }
+
+ public int TotalSteps {
+ set {
+ steps = value;
+ }
+ get {
+ return steps;
+ }
+ }
+
+ public double Fraction {
+ set {
+ progressbar.Fraction = value;
+ }
+ get {
+ return progressbar.Fraction;
+ }
+ }
+
+ public String Label {
+ set {
+ loading_label.Text = String.Format (value);
+ }
+ get {
+ return loading_label.Text;
+ }
+ }
+
+ public void Step ()
+ {
+ current_step += 1;
+ progressbar.Fraction = (double) current_step / steps;
+ }
+
+ public void Done ()
+ {
+ window.Destroy ();
+ }
+
+ private void HandleWindowResponse (object o, EventArgs a)
+ {
+ window.Visible = false;
+
+ canceled = true;
+ }
+
+ private void HandleWindowDeleteEvent (object o, EventArgs a)
+ {
+ window.Visible = false;
+
+ DeleteEventArgs args = (DeleteEventArgs) a;
+
+ args.RetVal = true;
+
+ canceled = true;
+ }
+}
--- /dev/null 2004-02-23 22:02:56.000000000 +0100
+++ src/CdUnit.cs 2004-07-17 08:26:39.000000000 +0200
@@ -0,0 +1,29 @@
+public class CdUnit {
+
+ private string name;
+ public string Name {
+ get {
+ return name;
+ }
+ set {
+ name = value;
+ }
+ }
+
+ private string path;
+ public string Path {
+ get {
+ return path;
+ }
+ set {
+ path = value;
+ }
+ }
+
+
+ public CdUnit (string path, string name)
+ {
+ Path = path;
+ Name = name;
+ }
+}
--- /dev/null 2004-02-23 22:02:56.000000000 +0100
+++ src/Recorder.cs 2004-07-17 09:02:59.000000000 +0200
@@ -0,0 +1,321 @@
+/*
+ * Copyright (C) 2004 Jorn Baayen
+ * Copyright (C) 2004 Fernando Herrera
+ *
+ * This program is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU General Public License as
+ * published by the Free Software Foundation; either version 2 of the
+ * License, or (at your option) any later version.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+ * General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public
+ * License along with this program; if not, write to the
+ * Free Software Foundation, Inc., 59 Temple Place - Suite 330,
+ * Boston, MA 02111-1307, USA.
+ */
+
+using System;
+using System.Runtime.InteropServices;
+using System.Collections;
+
+
+public class Recorder : GLib.Object
+{
+ [DllImport ("libmuine")]
+ private static extern bool recorder_set_orig (IntPtr recorder,
+ string filename,
+ out IntPtr error_ptr);
+
+ [DllImport ("libmuine")]
+ private static extern bool recorder_set_dest (IntPtr recorder,
+ string filename,
+ out IntPtr error_ptr);
+
+ [DllImport ("libmuine")]
+ private static extern bool recorder_add_track (IntPtr recorder,
+ string filename,
+ out IntPtr error_ptr);
+ [DllImport ("libmuine")]
+ private static extern bool recorder_has_many_devices ();
+
+ [DllImport ("libmuine")]
+ private static extern string recorder_get_valid_devices ();
+
+ [DllImport ("libmuine")]
+ private static extern bool recorder_select_drive (IntPtr recorder,
+ string device,
+ out IntPtr error_ptr);
+ [DllImport ("libmuine")]
+ private static extern int recorder_burn_cd (IntPtr recorder);
+
+ [DllImport ("libmuine")]
+ private static extern long get_dir_free_space (string path);
+
+ private bool writing = false;
+ private int num_songs = 0;
+ private string temp_dir = null;
+ BurnProgressWindow pw;
+
+ private Queue songs;
+
+ public void AddSong (Song song) {
+ songs.Enqueue (song);
+ }
+
+ public long EstimateWavSize ()
+ {
+ long size = 0;
+ Queue tmp = (Queue) songs.Clone();
+ while (tmp.Count > 0) {
+ Song song = (Song) tmp.Dequeue ();
+ size += song.Duration;
+ }
+ return size * (44100 * 2 * 2 + 271);
+ }
+
+ public long GetDirFreeSpace (string path)
+ {
+ return get_dir_free_space (path);
+ }
+
+ [DllImport ("libmuine")]
+ private static extern void recorder_write_file (IntPtr recorder);
+
+
+ [DllImport ("libmuine")]
+ private static extern void recorder_write_file_cancel (IntPtr recorder);
+
+ public void WriteFileCancel ()
+ {
+ recorder_write_file_cancel (Raw);
+ }
+
+ private void WriteFile ()
+ {
+ IntPtr error_ptr;
+ Song song;
+
+ if (songs.Count == 0)
+ return;
+
+ song = (Song) songs.Dequeue ();
+
+ if (pw.ReportFile (song.Title) == false)
+ return;
+
+ recorder_set_orig (Raw, song.Filename, out error_ptr);
+ if (error_ptr != IntPtr.Zero) {
+ string error = GLib.Marshaller.PtrToStringGFree (error_ptr);
+
+ new ErrorDialog (String.Format (Muine.Catalog.GetString ("Error opening {0}:\n{1}"),
+ song, error));
+ }
+
+ recorder_set_dest (Raw, temp_dir + System.IO.Path.GetFileNameWithoutExtension (song.Filename) + ".wav",
+ out error_ptr);
+ if (error_ptr != IntPtr.Zero) {
+ string error = GLib.Marshaller.PtrToStringGFree (error_ptr);
+
+ new ErrorDialog (String.Format (Muine.Catalog.GetString ("Error opening {0}{1}.wav:\n{2}"),
+ temp_dir,
+ System.IO.Path.GetFileNameWithoutExtension (song.Filename),
+ error));
+ }
+
+ recorder_write_file (Raw);
+ recorder_add_track (Raw, temp_dir + System.IO.Path.GetFileNameWithoutExtension (song.Filename) + ".wav",
+ out error_ptr);
+ if (error_ptr != IntPtr.Zero) {
+ string error = GLib.Marshaller.PtrToStringGFree (error_ptr);
+
+ new ErrorDialog (String.Format (Muine.Catalog.GetString ("Error opening {0}:\n{1}"),
+ System.IO.Path.GetFileNameWithoutExtension (song.Filename),
+ error));
+ }
+ }
+
+ public void WriteFiles (String path)
+ {
+ temp_dir = path;
+ num_songs = songs.Count;
+ if (num_songs >= 1) {
+ pw = new BurnProgressWindow (null, Muine.Catalog.GetString ("Burning CD"));
+ pw.TotalSteps = num_songs;
+ WriteFile ();
+ }
+ }
+
+ public ArrayList GetValidDevices ()
+ {
+ ArrayList res = new ArrayList();
+ string str = recorder_get_valid_devices ();
+
+ int pos = 0;
+ int end = str.IndexOf (';', pos);
+ Console.WriteLine (str);
+ while (end > 0) {
+ int p = str.IndexOf (':', pos);
+ CdUnit unit = new CdUnit (str.Substring (pos, p - pos),
+ str.Substring (p + 1, end - p - 1 ));
+ pos = end + 1;
+ res.Add (unit);
+ if (pos >= str.Length)
+ break;
+ end = str.IndexOf (';', pos);
+ }
+ return res;
+
+ }
+
+
+ public bool HasManyDevices ()
+ {
+ return recorder_has_many_devices ();
+ }
+
+ public bool SetDrive (String path)
+ {
+ IntPtr error_ptr;
+ recorder_select_drive (Raw, path, out error_ptr);
+ if (error_ptr != IntPtr.Zero) {
+ string error = GLib.Marshaller.PtrToStringGFree (error_ptr);
+
+ new ErrorDialog (String.Format (Muine.Catalog.GetString ("Error selection drive:\n{0}"),
+ error));
+ return false;
+ }
+
+ return true;
+ }
+
+ public void BurnCd ()
+ {
+ int res;
+
+ res = recorder_burn_cd (Raw);
+ pw.Done ();
+ }
+
+
+
+ public delegate bool InsertCdHandler (bool is_reload, bool can_rewrite, bool busy_cd);
+ public event InsertCdHandler InsertCdEvent;
+
+
+ [DllImport ("libmuine")]
+ private static extern IntPtr recorder_new (out IntPtr error_ptr);
+
+ private class Connect
+ {
+ [DllImport ("libgobject-2.0-0.dll")]
+ public static extern uint g_signal_connect_data (IntPtr obj, string name,
+ SignalDelegate cb, IntPtr data,
+ IntPtr p, int flags);
+ }
+
+ private class ConnectInt
+ {
+ [DllImport ("libgobject-2.0-0.dll")]
+ public static extern uint g_signal_connect_data (IntPtr obj, string name,
+ IntSignalDelegate cb, IntPtr data,
+ IntPtr p, int flags);
+ }
+
+ private class ConnectString
+ {
+ [DllImport ("libgobject-2.0-0.dll")]
+ public static extern uint g_signal_connect_data (IntPtr obj, string name,
+ StringSignalDelegate cb, IntPtr data,
+ IntPtr p, int flags);
+ }
+
+ private class ConnectDouble
+ {
+ [DllImport ("libgobject-2.0-0.dll")]
+ public static extern uint g_signal_connect_data (IntPtr obj, string name,
+ DoubleSignalDelegate cb, IntPtr data,
+ IntPtr p, int flags);
+ }
+
+ private class ConnectBoolBoolBool
+ {
+ [DllImport ("libgobject-2.0-0.dll")]
+ public static extern uint g_signal_connect_data (IntPtr obj, string name,
+ BoolBoolBoolSignalDelegate cb, IntPtr data,
+ IntPtr p, int flags);
+ }
+
+
+ public Recorder () : base (IntPtr.Zero)
+ {
+ IntPtr error_ptr;
+
+ songs = new Queue ();
+ Raw = recorder_new (out error_ptr);
+ if (error_ptr != IntPtr.Zero) {
+ string error = GLib.Marshaller.PtrToStringGFree (error_ptr);
+ throw new Exception (error);
+ }
+
+ Connect.g_signal_connect_data (Raw, "end_of_stream", new SignalDelegate (EosCallback),
+ IntPtr.Zero, IntPtr.Zero, 0);
+ ConnectString.g_signal_connect_data (Raw, "error", new StringSignalDelegate (ErrorCallback),
+ IntPtr.Zero, IntPtr.Zero, 0);
+ ConnectDouble.g_signal_connect_data (Raw, "cd_burn_progress", new DoubleSignalDelegate (CdProgressCallback),
+ IntPtr.Zero, IntPtr.Zero, 0);
+
+ ConnectBoolBoolBool.g_signal_connect_data (Raw, "cd_burn_insert_cd", new BoolBoolBoolSignalDelegate (CdInsertionCallback),
+ IntPtr.Zero, IntPtr.Zero, 0);
+
+
+
+ }
+
+ ~Recorder ()
+ {
+ Dispose ();
+ }
+
+ private delegate void SignalDelegate (IntPtr obj);
+ private delegate void IntSignalDelegate (IntPtr obj, int i);
+ private delegate void StringSignalDelegate (IntPtr obj, string s);
+ private delegate void DoubleSignalDelegate (IntPtr obj, double d);
+ private delegate bool BoolBoolBoolSignalDelegate (IntPtr obj, bool b1, bool b2, bool b3);
+
+ public delegate void EndOfStreamEventHandler ();
+ public event EndOfStreamEventHandler EndOfStreamEvent;
+
+ private void EosCallback (IntPtr obj)
+ {
+ if (EndOfStreamEvent != null)
+ EndOfStreamEvent ();
+ if (songs.Count > 0) {
+ pw.Step ();
+ WriteFile ();
+ } else {
+ pw.Label = Muine.Catalog.GetString ("Burning CD:");
+ pw.ReportFile (Muine.Catalog.GetString ("Initializing unit"));
+ BurnCd ();
+ }
+ }
+
+ private void ErrorCallback (IntPtr obj, string error)
+ {
+ new ErrorDialog (String.Format (Muine.Catalog.GetString ("Audio backend error:\n{0}"), error));
+ }
+ private void CdProgressCallback (IntPtr obj, double fraction)
+ {
+ pw.Fraction = fraction;
+ pw.ReportFile (Muine.Catalog.GetString ("Progress: " + (int) (fraction * 100) + "%"));
+ }
+ private bool CdInsertionCallback (IntPtr obj, bool is_reload, bool can_rewrite, bool busy_cd)
+ {
+ return InsertCdEvent (is_reload, can_rewrite, busy_cd);
+ }
+
+
+}