[Muine] m4a support (try #2)



Hey all,

ok, here's a reworking of the patch using the GPled faad and mp4ff
libraries. Anybody who's more C proficient, checking to make sure I
don't leak memory like a sieve would be nice.

Again, basic metadata support is there, but finding the peak, or trying
to pull the cover art metadata is not yet supported. I don't yet know if
any of the m4a files i have even *has* cover art metadata, but at some
point i'll fiddle and see if I can get it working. Anyone who has a file
with such metadata who can send it my way, it would be much appreciated.

Feedback?

-pete

-- 
Peter Johanson
<latexer gentoo org>
Index: configure.in
===================================================================
RCS file: /cvs/gnome/muine/configure.in,v
retrieving revision 1.102
diff -a -u -r1.102 configure.in
--- configure.in	10 Jan 2005 17:59:26 -0000	1.102
+++ configure.in	17 Jan 2005 03:17:02 -0000
@@ -97,6 +97,19 @@
 AC_CHECK_HEADER(FLAC/all.h, FLAC_LIBS="-lFLAC", AC_MSG_ERROR(You need FLAC))
 AC_SUBST(FLAC_LIBS)
 
+dnl Check for FAAD 
+AC_ARG_ENABLE(faad2, [  --disable-faad2   Disable faad2 library support],,have_faad2=yes)
+
+if test x$have_faad2 = xyes; then
+	AC_CHECK_HEADER(mp4ff.h, FAAD_LIBS="-lmp4ff -lfaad", AC_MSG_ERROR(faad2 library not found))
+	AC_DEFINE(HAVE_FAAD, 1, faad2 support)
+else
+	AC_DEFINE(HAVE_FAAD, 0, faad2 support)
+fi
+
+AM_CONDITIONAL(HAVE_FAAD, test "x$have_faad2" = "xyes")
+AC_SUBST(FAAD_LIBS)
+
 dnl Check for Mono
 AC_PATH_PROG(MCS, mcs)
 AC_PATH_PROG(MONO, mono)
Index: libmuine/Makefile.am
===================================================================
RCS file: /cvs/gnome/muine/libmuine/Makefile.am,v
retrieving revision 1.16
diff -a -u -r1.16 Makefile.am
--- libmuine/Makefile.am	14 Jan 2005 23:33:45 -0000	1.16
+++ libmuine/Makefile.am	17 Jan 2005 03:17:02 -0000
@@ -52,4 +52,4 @@
 	mm-keys.c			\
 	mm-keys.h
 	
-libmuine_la_LIBADD = id3-vfs/libid3-vfs.la egg/libegg.la $(MUINE_LIBS) $(OGG_LIBS) $(VORBIS_LIBS) $(VORBISFILE_LIBS) $(GDBM_LIBS) $(ID3TAG_LIBS) $(FLAC_LIBS)
+libmuine_la_LIBADD = id3-vfs/libid3-vfs.la egg/libegg.la $(MUINE_LIBS) $(OGG_LIBS) $(VORBIS_LIBS) $(VORBISFILE_LIBS) $(GDBM_LIBS) $(ID3TAG_LIBS) $(FLAC_LIBS) $(FAAD_LIBS)
Index: libmuine/metadata.c
===================================================================
RCS file: /cvs/gnome/muine/libmuine/metadata.c,v
retrieving revision 1.14
diff -a -u -r1.14 metadata.c
--- libmuine/metadata.c	26 Dec 2004 11:00:28 -0000	1.14
+++ libmuine/metadata.c	17 Jan 2005 03:17:03 -0000
@@ -26,11 +26,17 @@
 #include <stdlib.h>
 #include <string.h>
 #include <math.h>
+#include <config.h>
 
 #include "id3-vfs/id3-vfs.h"
 #include "ogg-helper.h"
 #include "metadata.h"
 
+#if HAVE_FAAD
+#include <faad.h>
+#include <mp4ff.h>
+#endif /* HAVE_FAAD */
+
 struct _Metadata {
 	char *title;
 
@@ -373,6 +379,125 @@
 	return metadata;
 }
 
+#if HAVE_FAAD
+
+uint32_t mp4_read_callback(void *user_data, void *buffer, uint32_t length);
+uint32_t mp4_seek_callback(void *user_data, uint64_t position);
+
+uint32_t mp4_read_callback(void *user_data, void *buffer, uint32_t length) {
+	GnomeVFSFileSize read;
+	gnome_vfs_read((GnomeVFSHandle*)user_data, (gpointer *)buffer,  length, &read);
+	return (uint32_t)read;
+}
+
+uint32_t mp4_seek_callback(void *user_data, uint64_t position) {
+	return (uint32_t) gnome_vfs_seek ((GnomeVFSHandle*) user_data, GNOME_VFS_SEEK_START, position);
+}
+
+static Metadata *
+assign_metadata_mp4 (const char *filename,
+		      char **error_message_return)
+{
+	Metadata *m = NULL;
+	GnomeVFSHandle *fh;
+	mp4ff_t *mp4f;
+	mp4ff_callback_t *mp4cb = (mp4ff_callback_t*) malloc (sizeof(mp4ff_callback_t));
+	gchar *value;
+	unsigned char *buff = NULL;
+        int buff_size = 0;
+	mp4AudioSpecificConfig mp4ASC;
+	long samples;
+	float f = 1024.0;
+
+	if (gnome_vfs_open (&fh, filename, GNOME_VFS_OPEN_READ) != GNOME_VFS_OK) {                                              
+                *error_message_return = g_strdup ("Failed to open file for reading");                                                                           
+                return NULL;                                                    
+        }
+
+	mp4cb->read = mp4_read_callback;
+	mp4cb->seek = mp4_seek_callback;
+	mp4cb->user_data = fh;
+
+	mp4f = mp4ff_open_read (mp4cb);
+
+	if (!mp4f)
+	{
+		*error_message_return = g_strdup ("Unable to open the AAC file");
+		return NULL;
+	}
+
+	if (mp4ff_total_tracks (mp4f) > 1)
+	{
+		 *error_message_return = g_strdup("Multi-track AAC files not supported");
+		 return NULL;
+	}
+
+	m = g_new0 (Metadata, 1);
+
+	if (mp4ff_meta_get_artist (mp4f, &value) && value != NULL)
+	{
+		if(g_utf8_validate (value, -1, NULL))
+		{
+			m->artists = g_new (char *, 2);
+			m->artists[0] = g_strdup (value);
+			m->artists[1] = NULL;
+			m->artists_count = 1;
+		}
+		g_free(value);
+	}
+	if (mp4ff_meta_get_title (mp4f, &value) && value != NULL)
+	{
+		if(g_utf8_validate (value, -1, NULL))
+			m->title = g_strdup (value);
+		g_free(value);
+	}
+	if (mp4ff_meta_get_album (mp4f, &value) && value != NULL)
+	{
+		if(g_utf8_validate (value, -1, NULL))
+			m->album = g_strdup (value);
+		g_free(value);
+	}
+	if (mp4ff_meta_get_track (mp4f, &value) && value != NULL)
+	{
+		m->track_number = atoi (value);
+		g_free (value);
+	}
+	if (mp4ff_meta_get_disc (mp4f, &value) && value != NULL)
+	{
+		m->disc_number = atoi (value);
+		g_free (value);
+	}
+
+	/*
+	 * duration code shameless based on code from frontend/main.c in faad2
+	 */
+
+	samples = mp4ff_num_samples (mp4f, 0);
+	mp4ff_get_decoder_config (mp4f, 0, &buff, &buff_size);
+
+	if (buff)
+	{
+		if (AudioSpecificConfig (buff, buff_size, &mp4ASC) >= 0)
+		{
+			free (buff);
+		        if (mp4ASC.sbr_present_flag == 1)
+		        {   
+		            f = f * 2.0;
+		        }	
+
+			m->duration = (float) samples * (float) (f-1.0)/(float) mp4ASC.samplingFrequency;
+		}
+	}
+
+	mp4ff_close (mp4f);
+	free (mp4cb);
+	gnome_vfs_close (fh);
+
+	return m;
+}
+
+#endif /* HAVE_FAAD */
+
 static ov_callbacks file_info_callbacks =
 {
         ogg_helper_read,
@@ -693,6 +818,11 @@
 	else if (!strcmp (info->mime_type, "application/x-flac") ||
 		 !strcmp (info->mime_type, "audio/x-flac"))
 		m = assign_metadata_flac (escaped, error_message_return);
+#if HAVE_FAAD
+	else if (!strcmp (info->mime_type, "application/x-m4a") ||
+		 !strcmp (info->mime_type, "audio/x-m4a"))
+		m = assign_metadata_mp4 (filename, error_message_return);
+#endif /* HAVE_FAAD */
 	else
 		*error_message_return = g_strdup ("Unknown format");
 


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