banshee r3687 - in trunk/banshee: . libbanshee src/Backends/Banshee.GStreamer src/Backends/Banshee.GStreamer/Banshee.GStreamer src/Core/Banshee.Services/Banshee.MediaEngine src/Extensions/Banshee.AudioCd/Banshee.AudioCd



Author: abock
Date: Sun Apr  6 07:21:35 2008
New Revision: 3687
URL: http://svn.gnome.org/viewvc/banshee?rev=3687&view=rev

Log:
2008-04-06  Aaron Bockover  <abock gnome org>

    * libbanshee/banshee-ripper.c: More cleanup and refactoring, it's mostly
    working but tags are not yet saved since I changed the way we do tagging
    and I'm not done

    * libbanshee/banshee-tagger.c: Basically this API provides a 1:1 with
    the GstTagList API and exists to make managed interop easier

    * src/Backends/Banshee.GStreamer/Banshee.GStreamer/TagList.cs: A wrapper
    and utility class around GstTagList that converts TrackInfo objects
    into GstTagList objects that can be passed directly to a GStreamer
    element that supports tagging

    * src/Backends/Banshee.GStreamer/Banshee.GStreamer/AudioCdRipper.cs:
    Wrote most of the ripper stuff - it works, but there are quirks not
    yet solved - it's not completely done

    * src/Core/Banshee.Services/Banshee.MediaEngine/IAudioCdRipper.cs:
    * src/Extensions/Banshee.AudioCd/Banshee.AudioCd/AudioCdRipper.cs:
    Updated some interface members



Added:
   trunk/banshee/libbanshee/banshee-tagger.c
   trunk/banshee/src/Backends/Banshee.GStreamer/Banshee.GStreamer/TagList.cs
Modified:
   trunk/banshee/ChangeLog
   trunk/banshee/libbanshee/Makefile.am
   trunk/banshee/libbanshee/banshee-ripper.c
   trunk/banshee/libbanshee/libbanshee.mdp
   trunk/banshee/src/Backends/Banshee.GStreamer/Banshee.GStreamer.mdp
   trunk/banshee/src/Backends/Banshee.GStreamer/Banshee.GStreamer/AudioCdRipper.cs
   trunk/banshee/src/Backends/Banshee.GStreamer/Banshee.GStreamer/PlayerEngine.cs
   trunk/banshee/src/Backends/Banshee.GStreamer/Makefile.am
   trunk/banshee/src/Core/Banshee.Services/Banshee.MediaEngine/IAudioCdRipper.cs
   trunk/banshee/src/Extensions/Banshee.AudioCd/Banshee.AudioCd/AudioCdRipper.cs

Modified: trunk/banshee/libbanshee/Makefile.am
==============================================================================
--- trunk/banshee/libbanshee/Makefile.am	(original)
+++ trunk/banshee/libbanshee/Makefile.am	Sun Apr  6 07:21:35 2008
@@ -20,6 +20,7 @@
 	banshee-player-pipeline.c \
 	banshee-player-video.c \
 	banshee-ripper.c \
+	banshee-tagger.c \
 	gst-misc-0.10.c \
 	gst-transcode-0.10.c
 

Modified: trunk/banshee/libbanshee/banshee-ripper.c
==============================================================================
--- trunk/banshee/libbanshee/banshee-ripper.c	(original)
+++ trunk/banshee/libbanshee/banshee-ripper.c	Sun Apr  6 07:21:35 2008
@@ -82,12 +82,6 @@
 }
 
 static gboolean
-br_gvfs_allow_overwrite_cb (GstElement *element, gpointer filename, gpointer user_data)
-{
-    return TRUE;
-}
-
-static gboolean
 br_iterate_timeout (BansheeRipper *ripper)
 {
     GstFormat format = GST_FORMAT_TIME;
@@ -240,34 +234,16 @@
     
     g_object_set (G_OBJECT (queue), "max-size-time", 120 * GST_SECOND, NULL);
     
-    ripper->filesink = gst_element_factory_make ("gnomevfssink", "gnomevfssink");
+    ripper->filesink = gst_element_factory_make ("filesink", "filesink");
     if (ripper->filesink == NULL) {
-        br_raise_error (ripper, _("Could not create GNOME VFS output plugin"), NULL);
+        br_raise_error (ripper, _("Could not create filesink plugin"), NULL);
         return FALSE;
     }
     
-    g_signal_connect (G_OBJECT (ripper->filesink), "allow-overwrite", G_CALLBACK (br_gvfs_allow_overwrite_cb), ripper);
-    
-    gst_bin_add_many (GST_BIN (ripper->pipeline),
-        ripper->cddasrc,
-        queue,
-        ripper->encoder,
-        ripper->filesink,
-        NULL);
+    gst_bin_add_many (GST_BIN (ripper->pipeline), ripper->cddasrc, queue, ripper->encoder, ripper->filesink, NULL);
         
-    if (!gst_element_link (ripper->cddasrc, queue)) {
-        br_raise_error (ripper, _("Could not link cddasrc to queue"), NULL);
-        return FALSE;
-    }
-    
-    if (!gst_element_link(queue, ripper->encoder)) {
-        br_raise_error (ripper, _("Could not link queue to encoder"), NULL);
-        return FALSE;
-    }
-        
-    if (!gst_element_link (ripper->encoder, ripper->filesink)) {
-        br_raise_error (ripper, _("Could not link encoder to gnomevfssink"), NULL);
-        return FALSE;
+    if (!gst_element_link_many (ripper->cddasrc, queue, ripper->encoder, ripper->filesink, NULL)) {
+        br_raise_error (ripper, _("Could not link pipeline elements"), NULL);
     }
     
     gst_bus_add_watch (gst_pipeline_get_bus (GST_PIPELINE (ripper->pipeline)), br_pipeline_bus_callback, ripper);
@@ -280,114 +256,91 @@
 // ---------------------------------------------------------------------------
 
 BansheeRipper *
-br_new(gchar *device, gint paranoia_mode, gchar *encoder_pipeline)
+br_new (gchar *device, gint paranoia_mode, gchar *encoder_pipeline)
 {
-    BansheeRipper *ripper = g_new0(BansheeRipper, 1);
+    BansheeRipper *ripper = g_new0 (BansheeRipper, 1);
     
-    if(ripper == NULL) {
+    if (ripper == NULL) {
         return NULL;
     }
         
-    ripper->device = g_strdup(device);
+    ripper->device = g_strdup (device);
     ripper->paranoia_mode = paranoia_mode;
-    ripper->encoder_pipeline = g_strdup(encoder_pipeline);
-    
-    ripper->pipeline = NULL;
-    ripper->cddasrc = NULL;
-    ripper->encoder = NULL;
-    ripper->filesink = NULL;
-    
-    ripper->track_format = 0;
-    
-    ripper->progress_cb = NULL;
-    ripper->error_cb = NULL;
-    ripper->finished_cb = NULL;
-    
+    ripper->encoder_pipeline = g_strdup (encoder_pipeline);
+
     return ripper;
 }
 
 void 
-br_cancel(BansheeRipper *ripper)
+br_cancel (BansheeRipper *ripper)
 {
-    g_return_if_fail(ripper != NULL);
+    g_return_if_fail (ripper != NULL);
     
-    br_stop_iterate_timeout(ripper);
+    br_stop_iterate_timeout (ripper);
     
-    if(ripper->pipeline != NULL && GST_IS_ELEMENT(ripper->pipeline)) {
-        gst_element_set_state(GST_ELEMENT(ripper->pipeline), GST_STATE_NULL);
-        gst_object_unref(GST_OBJECT(ripper->pipeline));
+    if (ripper->pipeline != NULL && GST_IS_ELEMENT (ripper->pipeline)) {
+        gst_element_set_state (GST_ELEMENT (ripper->pipeline), GST_STATE_NULL);
+        gst_object_unref (GST_OBJECT (ripper->pipeline));
         ripper->pipeline = NULL;
     }
     
-    g_remove(ripper->output_uri);
+    g_remove (ripper->output_uri);
 }
 
 void
-br_free(BansheeRipper *ripper)
+br_destroy (BansheeRipper *ripper)
 {
-    g_return_if_fail(ripper != NULL);
+    g_return_if_fail (ripper != NULL);
     
-    br_cancel(ripper);
+    br_cancel (ripper);
     
-    if(ripper->device != NULL) {
-        g_free(ripper->device);
+    if (ripper->device != NULL) {
+        g_free (ripper->device);
     }
     
-    if(ripper->encoder_pipeline != NULL) {
-        g_free(ripper->encoder_pipeline);
+    if (ripper->encoder_pipeline != NULL) {
+        g_free (ripper->encoder_pipeline);
     }
     
-    g_free(ripper);
+    g_free (ripper);
+    ripper = NULL;
 }
 
 gboolean
-br_rip_track(BansheeRipper *ripper, gchar *uri, gint track_number, 
-    gchar *md_artist, gchar *md_album, gchar *md_title, gchar *md_genre,
-    gint md_track_number, gint md_track_count, gpointer user_info)
+br_rip_track (BansheeRipper *ripper, gint track_number, gchar *output_path, 
+    GstTagList *tags, gboolean *tagging_supported)
 {
     GstIterator *bin_iterator;
     GstElement *bin_element;
     gboolean can_tag = FALSE;
     gboolean iterate_done = FALSE;
 
-    g_return_val_if_fail(ripper != NULL, FALSE);
+    g_return_val_if_fail (ripper != NULL, FALSE);
 
-    if(!br_pipeline_construct(ripper)) {
+    if (!br_pipeline_construct (ripper)) {
         return FALSE;
     }
     
     // initialize the pipeline, set the sink output location
-    gst_element_set_state(ripper->filesink, GST_STATE_NULL);
-    g_object_set(G_OBJECT(ripper->filesink), "location", uri, NULL);
+    gst_element_set_state (ripper->filesink, GST_STATE_NULL);
+    g_object_set (G_OBJECT (ripper->filesink), "location", output_path, NULL);
     
     // find an element to do the tagging and set tag data
-    bin_iterator = gst_bin_iterate_all_by_interface(GST_BIN(ripper->encoder), GST_TYPE_TAG_SETTER);
-    while(!iterate_done) {
-        switch(gst_iterator_next(bin_iterator, (gpointer)&bin_element)) {
+    bin_iterator = gst_bin_iterate_all_by_interface (GST_BIN (ripper->encoder), GST_TYPE_TAG_SETTER);
+    while (!iterate_done) {
+        switch (gst_iterator_next (bin_iterator, (gpointer)&bin_element)) {
             case GST_ITERATOR_OK:
-                gst_tag_setter_add_tags(GST_TAG_SETTER(bin_element),
-                    GST_TAG_MERGE_REPLACE_ALL,
-                    GST_TAG_TITLE,  md_title,
-                    GST_TAG_ARTIST, md_artist,
-                    GST_TAG_ALBUM,  md_album,
-                    GST_TAG_TRACK_NUMBER, md_track_number,
-                    GST_TAG_TRACK_COUNT,  md_track_count,
+                gst_tag_setter_add_tags (GST_TAG_SETTER (bin_element),
+                    GST_TAG_MERGE_APPEND,
                     GST_TAG_ENCODER, _("Banshee"),
                     GST_TAG_ENCODER_VERSION, VERSION,
                     NULL);
                     
-                if(md_genre && strlen(md_genre) == 0) {
-                    gst_tag_setter_add_tags(GST_TAG_SETTER(bin_element),
-                        GST_TAG_MERGE_APPEND,
-                        GST_TAG_GENRE, md_genre,
-                        NULL);
-                }
-        
                 can_tag = TRUE;    
-                gst_object_unref(bin_element);
+                gst_object_unref (bin_element);
                 break;
             case GST_ITERATOR_RESYNC:
-                gst_iterator_resync(bin_iterator);
+                gst_iterator_resync (bin_iterator);
                 break;
             default:
                 iterate_done = TRUE;
@@ -395,48 +348,43 @@
         }
     }
     
-    gst_iterator_free(bin_iterator);
+    gst_iterator_free (bin_iterator);
     
-    if(!can_tag) {
-        g_warning(_("Encoding element does not support tagging!"));
-    }
-    
-    // start the ripping
-    g_object_set(G_OBJECT(ripper->cddasrc), "track", track_number, NULL);
+    // We'll warn the user in the UI if we can't tag the encoded audio files
+    *tagging_supported = can_tag;
     
-    gst_element_set_state(ripper->pipeline, GST_STATE_PLAYING);
-    br_start_iterate_timeout(ripper);
+    // Begin the rip
+    g_object_set (G_OBJECT (ripper->cddasrc), "track", track_number, NULL);
+    gst_element_set_state (ripper->pipeline, GST_STATE_PLAYING);
+    br_start_iterate_timeout (ripper);
     
     return TRUE;
 }
 
 void
-br_set_progress_callback(BansheeRipper *ripper, 
-    BansheeRipperProgressCallback cb)
+br_set_progress_callback (BansheeRipper *ripper, BansheeRipperProgressCallback cb)
 {
-    g_return_if_fail(ripper != NULL);
+    g_return_if_fail (ripper != NULL);
     ripper->progress_cb = cb;
 }
 
 void
-br_set_finished_callback(BansheeRipper *ripper, 
-    BansheeRipperFinishedCallback cb)
+br_set_finished_callback (BansheeRipper *ripper, BansheeRipperFinishedCallback cb)
 {
-    g_return_if_fail(ripper != NULL);
+    g_return_if_fail (ripper != NULL);
     ripper->finished_cb = cb;
 }
 
 void
-br_set_error_callback(BansheeRipper *ripper, 
-    BansheeRipperErrorCallback cb)
+br_set_error_callback (BansheeRipper *ripper, BansheeRipperErrorCallback cb)
 {
-    g_return_if_fail(ripper != NULL);
+    g_return_if_fail (ripper != NULL);
     ripper->error_cb = cb;
 }
 
 gboolean
-br_get_is_ripping(BansheeRipper *ripper)
+br_get_is_ripping (BansheeRipper *ripper)
 {
-    g_return_val_if_fail(ripper != NULL, FALSE);
+    g_return_val_if_fail (ripper != NULL, FALSE);
     return ripper->is_ripping;
 }

Added: trunk/banshee/libbanshee/banshee-tagger.c
==============================================================================
--- (empty file)
+++ trunk/banshee/libbanshee/banshee-tagger.c	Sun Apr  6 07:21:35 2008
@@ -0,0 +1,56 @@
+//
+// banshee-tagger.c
+//
+// Author:
+//   Aaron Bockover <abockover novell com>
+//
+// Copyright (C) 2008 Novell, Inc.
+//
+// Permission is hereby granted, free of charge, to any person obtaining
+// a copy of this software and associated documentation files (the
+// "Software"), to deal in the Software without restriction, including
+// without limitation the rights to use, copy, modify, merge, publish,
+// distribute, sublicense, and/or sell copies of the Software, and to
+// permit persons to whom the Software is furnished to do so, subject to
+// the following conditions:
+//
+// The above copyright notice and this permission notice shall be
+// included in all copies or substantial portions of the Software.
+//
+// THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,
+// EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
+// MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND
+// NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE
+// LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION
+// OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION
+// WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
+//
+
+#ifdef HAVE_CONFIG_H
+#  include "config.h"
+#endif
+
+#include <gst/gst.h>
+#include <gst/tag/tag.h>
+
+// ---------------------------------------------------------------------------
+// Internal Functions
+// ---------------------------------------------------------------------------
+
+GstTagList *
+bt_tag_list_new ()
+{
+    return gst_tag_list_new ();
+}
+
+void
+bt_tag_list_free (GstTagList *list)
+{
+    gst_tag_list_free (list);
+}
+
+void
+bt_tag_list_add_value (GstTagList *list, const gchar *tag_name, const GValue *value)
+{
+    gst_tag_list_add_values (list, GST_TAG_MERGE_REPLACE_ALL, tag_name, value, NULL);
+}

Modified: trunk/banshee/libbanshee/libbanshee.mdp
==============================================================================
--- trunk/banshee/libbanshee/libbanshee.mdp	(original)
+++ trunk/banshee/libbanshee/libbanshee.mdp	Sun Apr  6 07:21:35 2008
@@ -14,7 +14,6 @@
     <File name="gst-transcode-0.10.c" subtype="Code" buildaction="Compile" />
     <File name="banshee-player-private.h" subtype="Code" buildaction="Nothing" />
     <File name="banshee-player-cdda.h" subtype="Code" buildaction="Nothing" />
-    <File name="gst-transcode.h" subtype="Code" buildaction="Nothing" />
     <File name="banshee-player-cdda.c" subtype="Code" buildaction="Compile" />
     <File name="banshee-player-missing-elements.c" subtype="Code" buildaction="Compile" />
     <File name="banshee-player-missing-elements.h" subtype="Code" buildaction="Nothing" />
@@ -23,6 +22,7 @@
     <File name="banshee-player-equalizer.c" subtype="Code" buildaction="Compile" />
     <File name="banshee-player-pipeline.c" subtype="Code" buildaction="Compile" />
     <File name="banshee-player-pipeline.h" subtype="Code" buildaction="Nothing" />
+    <File name="banshee-tagger.c" subtype="Code" buildaction="Compile" />
   </Contents>
   <compiler ctype="GccCompiler" />
   <MonoDevelop.Autotools.MakefileInfo IntegrationEnabled="True" RelativeMakefileName="Makefile.am">

Modified: trunk/banshee/src/Backends/Banshee.GStreamer/Banshee.GStreamer.mdp
==============================================================================
--- trunk/banshee/src/Backends/Banshee.GStreamer/Banshee.GStreamer.mdp	(original)
+++ trunk/banshee/src/Backends/Banshee.GStreamer/Banshee.GStreamer.mdp	Sun Apr  6 07:21:35 2008
@@ -1,4 +1,4 @@
-<Project name="Banshee.GStreamer" fileversion="2.0" UseParentDirectoryAsNamespace="True" language="C#" clr-version="Net_2_0" ctype="DotNetProject">
+<Project name="Banshee.GStreamer" fileversion="2.0" language="C#" clr-version="Net_2_0" UseParentDirectoryAsNamespace="True" ctype="DotNetProject">
   <Configurations active="Debug">
     <Configuration name="Debug" ctype="DotNetProjectConfiguration">
       <Output directory="../../../bin" assemblyKeyFile="." assembly="Banshee.MediaEngine.GStreamer" />
@@ -13,6 +13,7 @@
     <File name="Banshee.GStreamer/GstErrors.cs" subtype="Code" buildaction="Compile" />
     <File name="Banshee.GStreamer/Service.cs" subtype="Code" buildaction="Compile" />
     <File name="Banshee.GStreamer/AudioCdRipper.cs" subtype="Code" buildaction="Compile" />
+    <File name="Banshee.GStreamer/TagList.cs" subtype="Code" buildaction="Compile" />
   </Contents>
   <References>
     <ProjectReference type="Gac" localcopy="True" refto="Mono.Posix, Version=2.0.0.0, Culture=neutral, PublicKeyToken=0738eb9f132ed756" />

Modified: trunk/banshee/src/Backends/Banshee.GStreamer/Banshee.GStreamer/AudioCdRipper.cs
==============================================================================
--- trunk/banshee/src/Backends/Banshee.GStreamer/Banshee.GStreamer/AudioCdRipper.cs	(original)
+++ trunk/banshee/src/Backends/Banshee.GStreamer/Banshee.GStreamer/AudioCdRipper.cs	Sun Apr  6 07:21:35 2008
@@ -27,9 +27,12 @@
 //
 
 using System;
+using System.IO;
 using System.Threading;
+using System.Runtime.InteropServices;
 using Mono.Unix;
 
+using Hyena;
 using Banshee.Base;
 using Banshee.Collection;
 using Banshee.ServiceStack;
@@ -40,13 +43,21 @@
 {
     public class AudioCdRipper : IAudioCdRipper
     {
+        private HandleRef handle;
         private string encoder_pipeline;
+        private string output_extension;
+        private string output_path;
+        private TrackInfo current_track;
+        
+        private RipperProgressHandler progress_handler;
+        private RipperFinishedHandler finished_handler;
+        private RipperErrorHandler error_handler;
     
         public event AudioCdRipperProgressHandler Progress;
         public event AudioCdRipperTrackFinishedHandler TrackFinished;
         public event AudioCdRipperErrorHandler Error;
         
-        public void Begin ()
+        public void Begin (string device)
         {
             try {
                 Profile profile = ServiceManager.MediaProfileManager.GetConfiguredActiveProfile ("cd-importing");
@@ -63,10 +74,32 @@
             } catch (Exception e) {
                 throw new ApplicationException (Catalog.GetString ("Could not find an encoder for ripping."), e);
             }
+            
+            try {   
+                handle = new HandleRef (this, br_new (device, 0, encoder_pipeline));
+                
+                progress_handler = new RipperProgressHandler (OnNativeProgress);
+                br_set_progress_callback (handle, progress_handler);
+                
+                finished_handler = new RipperFinishedHandler (OnNativeFinished);
+                br_set_finished_callback (handle, finished_handler);
+                
+                error_handler = new RipperErrorHandler (OnNativeError);
+                br_set_error_callback (handle, error_handler);
+            } catch (Exception e) {
+                throw new ApplicationException (Catalog.GetString ("Could not create CD ripping driver."), e);
+            }
         }
         
         public void Finish ()
         {
+            TrackReset ();
+            
+            encoder_pipeline = null;
+            output_extension = null;
+            
+            br_destroy (handle);
+            handle = new HandleRef (this, IntPtr.Zero);
         }
         
         public void Cancel ()
@@ -74,30 +107,23 @@
             Finish ();
         }
         
-        public void RipTrack (TrackInfo track, SafeUri outputUri)
+        private void TrackReset ()
         {
-            ThreadPool.QueueUserWorkItem (delegate {
-                DateTime start_time = DateTime.Now;    
-                TimeSpan duration = TimeSpan.FromSeconds (5);
-                
-                while (true) {
-                    TimeSpan ellapsed = DateTime.Now - start_time;
-                    if (ellapsed >= duration) {
-                        break;
-                    }
-                    
-                    TimeSpan progress = TimeSpan.FromMilliseconds ((ellapsed.TotalMilliseconds 
-                        / duration.TotalMilliseconds) * track.Duration.TotalMilliseconds);
-                    
-                    OnProgress (track, progress);
-                    
-                    Thread.Sleep (50);
-                }
-                
-                OnTrackFinished (track, outputUri);
-            });
+            current_track = null;
+            output_path = null;
+        }
+        
+        public void RipTrack (int trackIndex, TrackInfo track, SafeUri outputUri, out bool taggingSupported)
+        {
+            TrackReset ();
+            current_track = track;
             
-            return;
+            using (TagList tags = new TagList (track)) {
+                output_path = Path.ChangeExtension (outputUri.LocalPath, output_extension); 
+                br_rip_track (handle, trackIndex + 1, output_path, tags.Handle, out taggingSupported);
+                
+                Log.DebugFormat ("GStreamer ripping track {0} to {1}", trackIndex, output_path);
+            }
         }
         
         protected virtual void OnProgress (TrackInfo track, TimeSpan ellapsedTime)
@@ -123,5 +149,52 @@
                 handler (this, new AudioCdRipperErrorArgs (track, message));
             }
         }
+        
+        private void OnNativeProgress (IntPtr ripper, int mseconds)
+        {
+            OnProgress (current_track, TimeSpan.FromMilliseconds (mseconds));
+        }
+        
+        private void OnNativeFinished (IntPtr ripper)
+        {
+            OnTrackFinished (current_track, new SafeUri (output_path));
+        }
+        
+        private void OnNativeError (IntPtr ripper, IntPtr error, IntPtr debug)
+        {
+            string error_message = GLib.Marshaller.Utf8PtrToString (error);
+            
+            if (debug != IntPtr.Zero) {
+                string debug_string = GLib.Marshaller.Utf8PtrToString (debug);
+                if (!String.IsNullOrEmpty (debug_string)) {
+                    error_message = String.Format ("{0}: {1}", error_message, debug_string);
+                }
+            }
+            
+            OnError (current_track, error_message);
+        }
+        
+        private delegate void RipperProgressHandler (IntPtr ripper, int mseconds);
+        private delegate void RipperFinishedHandler (IntPtr ripper);
+        private delegate void RipperErrorHandler (IntPtr ripper, IntPtr error, IntPtr debug);
+        
+        [DllImport ("libbanshee")]
+        private static extern IntPtr br_new (string device, int paranoia_mode, string encoder_pipeline);
+
+        [DllImport ("libbanshee")]
+        private static extern void br_destroy (HandleRef handle);
+        
+        [DllImport ("libbanshee")]
+        private static extern void br_rip_track (HandleRef handle, int track_number, string output_path, 
+            HandleRef tag_list, out bool tagging_supported);
+        
+        [DllImport ("libbanshee")]
+        private static extern void br_set_progress_callback (HandleRef handle, RipperProgressHandler callback);
+        
+        [DllImport ("libbanshee")]
+        private static extern void br_set_finished_callback (HandleRef handle, RipperFinishedHandler callback);
+        
+        [DllImport ("libbanshee")]
+        private static extern void br_set_error_callback (HandleRef handle, RipperErrorHandler callback);
     }
 }

Modified: trunk/banshee/src/Backends/Banshee.GStreamer/Banshee.GStreamer/PlayerEngine.cs
==============================================================================
--- trunk/banshee/src/Backends/Banshee.GStreamer/Banshee.GStreamer/PlayerEngine.cs	(original)
+++ trunk/banshee/src/Backends/Banshee.GStreamer/Banshee.GStreamer/PlayerEngine.cs	Sun Apr  6 07:21:35 2008
@@ -252,7 +252,7 @@
         
         private void OnTagFound (IntPtr player, string tagName, ref GLib.Value value)
         {
-            OnTagFound(ProcessNativeTagResult (tagName, ref value));
+            OnTagFound (ProcessNativeTagResult (tagName, ref value));
         }
             
         private static StreamTag ProcessNativeTagResult (string tagName, ref GLib.Value valueRaw)

Added: trunk/banshee/src/Backends/Banshee.GStreamer/Banshee.GStreamer/TagList.cs
==============================================================================
--- (empty file)
+++ trunk/banshee/src/Backends/Banshee.GStreamer/Banshee.GStreamer/TagList.cs	Sun Apr  6 07:21:35 2008
@@ -0,0 +1,110 @@
+// 
+// TagList.cs
+//
+// Author:
+//   Aaron Bockover <abockover novell com>
+//
+// Copyright (C) 2008 Novell, Inc.
+//
+// Permission is hereby granted, free of charge, to any person obtaining
+// a copy of this software and associated documentation files (the
+// "Software"), to deal in the Software without restriction, including
+// without limitation the rights to use, copy, modify, merge, publish,
+// distribute, sublicense, and/or sell copies of the Software, and to
+// permit persons to whom the Software is furnished to do so, subject to
+// the following conditions:
+//
+// The above copyright notice and this permission notice shall be
+// included in all copies or substantial portions of the Software.
+//
+// THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,
+// EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
+// MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND
+// NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE
+// LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION
+// OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION
+// WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
+//
+
+using System;
+using System.Runtime.InteropServices;
+
+using Banshee.Streaming;
+using Banshee.Collection;
+
+namespace Banshee.GStreamer
+{
+    public class TagList : IDisposable
+    {
+        private HandleRef handle;
+        
+        public TagList ()
+        {
+            handle = new HandleRef (this, bt_tag_list_new ());
+        }
+        
+        public TagList (TrackInfo track) : this ()
+        {
+            Merge (track);
+        }
+        
+        public void Merge (TrackInfo track)
+        {
+            AddTag (CommonTags.Artist, track.ArtistName);
+            AddTag (CommonTags.Album, track.AlbumTitle);
+            AddTag (CommonTags.Title, track.TrackTitle);
+            AddTag (CommonTags.Genre, track.Genre);
+            
+            AddTag (CommonTags.TrackNumber, (uint)track.TrackNumber);
+            AddTag (CommonTags.TrackCount, (uint)track.TrackCount);
+            AddTag (CommonTags.Disc, (uint)track.Disc);
+            
+            AddTag (CommonTags.Composer, track.Composer);
+            AddTag (CommonTags.Copyright, track.Copyright);
+            AddTag (CommonTags.Comment, track.Comment);
+        }
+        
+        public void AddTag (string tagName, string value)
+        {
+            if (!String.IsNullOrEmpty (value)) {
+                AddTag (tagName, (object)value);
+            }
+        }
+        
+        public void AddTag (string tagName, uint value)
+        {
+            if (value > 0) {
+                AddTag (tagName, (object)value);
+            }
+        }
+        
+        public void AddTag (string tagName, object value)
+        {
+            GLib.Value g_value = new GLib.Value (value);
+            bt_tag_list_add_value (Handle, tagName, ref g_value);
+        }
+        
+        public void Dispose ()
+        {
+            if (handle.Handle != IntPtr.Zero) {
+                bt_tag_list_free (handle);
+                handle = new HandleRef (this, IntPtr.Zero);
+                
+                GC.SuppressFinalize (this);
+            }
+        }
+        
+        public HandleRef Handle {
+            get { return handle; }
+        }
+                
+        [DllImport ("libbanshee")]
+        private static extern IntPtr bt_tag_list_new ();
+        
+        [DllImport ("libbanshee")]
+        private static extern void bt_tag_list_free (HandleRef tag_list);
+        
+        [DllImport ("libbanshee")]
+        private static extern void bt_tag_list_add_value (HandleRef tag_list, string tag_name, ref GLib.Value value);
+    }
+}

Modified: trunk/banshee/src/Backends/Banshee.GStreamer/Makefile.am
==============================================================================
--- trunk/banshee/src/Backends/Banshee.GStreamer/Makefile.am	(original)
+++ trunk/banshee/src/Backends/Banshee.GStreamer/Makefile.am	Sun Apr  6 07:21:35 2008
@@ -5,7 +5,8 @@
 	Banshee.GStreamer/AudioCdRipper.cs \
 	Banshee.GStreamer/GstErrors.cs \
 	Banshee.GStreamer/PlayerEngine.cs \
-	Banshee.GStreamer/Service.cs
+	Banshee.GStreamer/Service.cs \
+	Banshee.GStreamer/TagList.cs
 RESOURCES = Banshee.GStreamer.addin.xml
 INSTALL_DIR = $(BACKENDS_INSTALL_DIR)
 

Modified: trunk/banshee/src/Core/Banshee.Services/Banshee.MediaEngine/IAudioCdRipper.cs
==============================================================================
--- trunk/banshee/src/Core/Banshee.Services/Banshee.MediaEngine/IAudioCdRipper.cs	(original)
+++ trunk/banshee/src/Core/Banshee.Services/Banshee.MediaEngine/IAudioCdRipper.cs	Sun Apr  6 07:21:35 2008
@@ -43,11 +43,11 @@
         event AudioCdRipperTrackFinishedHandler TrackFinished;
         event AudioCdRipperErrorHandler Error;
         
-        void Begin ();
+        void Begin (string device);
         void Finish ();
         void Cancel ();
         
-        void RipTrack (TrackInfo track, SafeUri outputUri);
+        void RipTrack (int trackIndex, TrackInfo track, SafeUri outputUri, out bool taggingSupported);
     }
                              
     public sealed class AudioCdRipperProgressArgs : EventArgs

Modified: trunk/banshee/src/Extensions/Banshee.AudioCd/Banshee.AudioCd/AudioCdRipper.cs
==============================================================================
--- trunk/banshee/src/Extensions/Banshee.AudioCd/Banshee.AudioCd/AudioCdRipper.cs	(original)
+++ trunk/banshee/src/Extensions/Banshee.AudioCd/Banshee.AudioCd/AudioCdRipper.cs	Sun Apr  6 07:21:35 2008
@@ -127,7 +127,7 @@
                 }
             }
             
-            ripper.Begin ();
+            ripper.Begin (source.DiscModel.Volume.DeviceNode);
             
             RipNextTrack ();
         }
@@ -177,8 +177,9 @@
             status = String.Format("{0} - {1}", track.ArtistName, track.TrackTitle);
             user_job.Status = status;
             
-            SafeUri uri = new SafeUri (FileNamePattern.BuildFull (track, "mp3"));
-            ripper.RipTrack (track, uri);
+            SafeUri uri = new SafeUri (FileNamePattern.BuildFull (track, null));
+            bool tagging_supported;
+            ripper.RipTrack (track.IndexOnDisc, track, uri, out tagging_supported);
         }
 
 #region Ripper Event Handlers



[Date Prev][Date Next]   [Thread Prev][Thread Next]   [Thread Index] [Date Index] [Author Index]