~ft/aacdec

3254623f0745837118e0d5d739fa6c402fd5b9d3 — menno 18 years ago 728303a
Updated XMMS plugins
Updated Linux installation process
M Makefile.am => Makefile.am +1 -1
@@ 1,1 1,1 @@
SUBDIRS = libfaad common frontend
SUBDIRS = libfaad common frontend plugins

M configure.in => configure.in +4 -2
@@ 60,6 60,8 @@ MY_CHECK_TYPEDEF_FROM_INCLUDE([fpos_t foo; foo.__pos = 0;],

AC_OUTPUT_COMMANDS(,[cd common/mp4v2; aclocal -I .; autoheader; libtoolize --automake; automake --add-missing; autoconf; cd -])

AC_CONFIG_SUBDIRS(common/mp4v2)
AC_OUTPUT_COMMANDS(,[cd plugins/xmms; libtoolize; aclocal; autoconf; automake --add-missing; cd -])

AC_OUTPUT(libfaad/Makefile common/Makefile  frontend/Makefile Makefile)
AC_CONFIG_SUBDIRS(common/mp4v2 plugins/xmms)

AC_OUTPUT(libfaad/Makefile common/Makefile  frontend/Makefile Makefile plugins/Makefile)

A plugins/Makefile.am => plugins/Makefile.am +1 -0
@@ 0,0 1,1 @@
SUBDIRS = xmms

M plugins/xmms/ChangeLog => plugins/xmms/ChangeLog +25 -1
@@ 1,3 1,26 @@
4 juillet 2003:
	* package the plugin for faad2
	* upgrade code to libfaad2-2.0 API
	* version 0.5

15 juin 2003:
	* better configuration code
	  (choose automaticaly at compile time)
	* installation must be set by root
	* version 0.4

15 mai 2003:
	* update configure script to be better
	* version 0.3

01 Novembre 2002:
	* check automake/autoconf/libtool for plugin, now 'make install' work
	* handle seeking
	* configuration box created (thanks glade !)
	* handle aac informations
	* modification to a better infobox (thanks angain glade !)
	* version 0.2 ready to public :)

25 Aout 2002:
	* gtk-1.2.x info file with some 'static' useful ID3 info
	* title show in xmms correctly


@@ 8,5 31,6 @@
	* work with faad2lib-1.1, id3lib-3.8.0 (glibc-2.2.5, gcc-2.95.3)
	  i think the minimum required but need testing...
	* playlist working
	* handle id3tag
	* handle id3tag, the plugin work :)
	* new maintener : ciberfred
	

A plugins/xmms/INSTALL => plugins/xmms/INSTALL +1 -0
@@ 0,0 1,1 @@
see README file

M plugins/xmms/NEWS => plugins/xmms/NEWS +4 -0
@@ 1,3 1,7 @@
4 Juillet 2003
--------------
integration du plugin xmms-aac dans le projet faad2 version 2.x

15 aout 2002
------------


M plugins/xmms/README => plugins/xmms/README +19 -63
@@ 1,94 1,50 @@
       this is an AAC InputPlugin source written from scratch for Xmms 1.2.7
                          by ciberfred from France :)
				version 0.1
                            by ciberfred from France
                    version 0.5 (build of 4 july 2003)

				-------------
this plugin is not finished yet wait and see...
				------------

1 -- Introduction.
2 -- Warning
3 -- How to build the plugin

Hey, nice to see that i could realise a plugin for xmms .. :), so what about
this plugin. This is a plugin to play AAC files (.aac) encoded with FAAC or
the windows program psytel aacenc.exe
the M$ windows program psytel aacenc.exe

The plugin read aac files with and without ID3tag(version 2.x), AAC files
are MPEG2 or MPEG4 files that could be found in MPEG4 audio files (.mp4).
MPEG4 files with aac inside could be reads by RealPlayer or Quicktime.
MPEG4 files with aac inside could be read by RealPlayer or Quicktime and with
my mp4 audio only xmms plugin. Also you could check the lamip project on
sourceforge.

For any informations about this plugin contact me at :

mail : frederic.fondriest@laposte.net
ICQ  : 17293220
aac plugin homepage (and more) : http://fondriest.frederic.free.fr/realisations/
IRC  : irc.eu.freenode.net (#lamip)

	-------------------------------------------------------------

			!!!!!!!!!! WARNING !!!!!!!!!!!!
if at the end of some song there is a segfault (xmms going out!),
this is probably you have an old aac song encoded with an old psytel
encoder (maybe a 1.x).
To avoide this error use psystrip.exe windows program on the file. This maybe
This error is comming from faad2
To remove this error use psystrip.exe windows program on the file. This maybe
resolve this problem.

this plugin was tested with the psytel encoder 2.15 (MPEG4 version for all
profile)

tested on a linux LFS 3.3 with :
Glibc-2.2.5
gcc-2.95.3
gtk+-1.2.10
glib-1.2.10
xmms-1.2.7
id3lib-3.8.0
wine
faad2 1.1

I don't test it for more than 2 channels file, i don't have such files...
if you wana test and give feedback could be great :)

Also note that if you have old aac files encoded with psytel 2.15 you should
use the 0.4 version of this plugin. (see my home page). This version
handle the new AAC files with new ADTS header size.
	-------------------------------------------------------------

HOWTO Build the plugin.
-----------------------

check that xmms-config could be run from a terminal.

before, you should take the faad2 1.1 package from
www.audiocoding.com
go into the faad2 directory with a user account :
install the libsnd you found into the common/libsnd directoy
then run in the faad2 top directory :

	- sh bootstrap
	- ./configure
	- make (this build libfaad and libmp4v2)
	- make install (with the root account)

then now you should run a ldconfig or add a line
into your /etc/ld.so.conf (and run a ldconfig again)

To build this plugin just run and install the faad2 package
also check that you have :
id3lib-3.8.x (http://www.id3.org), the lastiest version is better
xmms-1.2.7 (http://www.xmms.org)

so now you have the libfaad installed you could
install the id3lib, with the common configure && make && make install.
take the library from the net not from the common/id3lib directory

so now you have libffad and libid3 you could build the xmms plugin
run these command to build the xmms-acc plugin :

	- sh bootstrap
	- ./configure ID3_LIB=<path to the id3lib install>
		FAAD2_DIR=<path to the faad2 install>
	- make

then you should find the libaac.so file into the src directory.
copy this file into your ${HOME}/.xmms/Plugin/ or in the
common plugin directory of xmms...


NB: sorry i not a pro of automake or autoconf i prefere to build a Makefile
that a user could change to adapte to his computer. You should find the
original Makefile into the src directory. his name is Makefile.save :)

	-------------------------------------------------------------
-- 
Fr�d�ric Fondriest from France

D plugins/xmms/bootstrap => plugins/xmms/bootstrap +0 -15
@@ 1,15 0,0 @@
#!/bin/bash

echo ""
echo "----running setup for xmms-aac plugin----"
echo "don't forget to install libfaad before !!"
echo "check http://www.audiocoding.com"
echo ""

aclocal -I .
libtoolize --automake
automake --add-missing
autoconf
echo "******"
echo "ready to run ./configure (check '--help' for options)"
echo "******"

M plugins/xmms/configure.in => plugins/xmms/configure.in +40 -35
@@ 1,41 1,46 @@
dnl
dnl configure.in for faad2-2.0 package

AC_INIT(src/libaac.c)
AM_INIT_AUTOMAKE(libaac, 0.0.1)
AM_INIT_AUTOMAKE(libaac, 0.5)

dnl save CFLAGS since AC_PROG_CC insert "-g -O2" if CFLAGS is empty
cflags_save="$CFLAGS"

AC_DISABLE_STATIC
AM_DISABLE_STATIC

AC_PROG_CC
AC_PROG_CXX
AC_PROG_INSTALL

dnl AM_DISABLE_STATIC
dnl AM_PROG_LIBTOOL

AC_CHECK_HEADER(pthread.h,,AC_MSG_ERROR([thread support not installed or not found]))
dnl AM_PATH_GLIB(1.2.2,,AC_MSG_ERROR([ GLIB >=1.2.2 not installed or not found]))
dnl AM_PATH_GTK(1.2.2,,AC_MSG_ERROR([ GTK+ >=1.2.2 not installed or not found]),gthread)
AC_PATH_PROG(XMMS_PATH,xmms,no)
LIBS="$LIBS $GTK_LIBS"
CFLAGS="$CFLAGS $GTK_CFLAGS"
PTHREAD_LIBS="-lpthread"
AC_SUBST(PTHREAD_LIBS)
CPPFLAGS="$GTK_CFLAGS $CPPFLAGS"
AC_SUBST(CPPFLAGS)
if test "$FAAD2_DIR" = ""; then
 AC_MSG_ERROR([add FAAD2_DIR=<path to faad2 install dir> (ex:/usr/local/faad2)])
fi
if test "$ID3_DIR" = "";then
 AC_MSG_ERROR([ add ID3_DIR=<path to id3 install dir> (ex:/usr/local/id3lib)])
AC_PROG_LIBTOOL


AC_CHECK_PROGS(XMMS_CONFIG, xmms-config,"no_found")
if test "$XMMS_CONFIG" = "no_found"; then
 AC_MSG_ERROR("*** xmms-config not found check PATH or install xmms")
fi
AC_SUBST(FAAD2_DIR)
AC_SUBST(ID3_DIR)

CFLAGS="$cflags_save `xmms-config --cflags` -Wall"
CPPFLAGS="$CPPFLAGS $CFLAGS"
AC_SUBST(CFLAGS)
AC_OUTPUT(Makefile src/Makefile)

echo "*****configuration xmms-aac plugin done****"
echo ""
echo "pthread flag :	$PTHREAD_LIBS"
echo "id3 dir :		$ID3_DIR"
echo "faad2 dir :	$FAAD2_DIR"
echo "xmms dir :	$XMMS_PATH"
echo ""
echo " !!!!!!!!!!!!!!!!! WARNING !!!!!!!!!!!!!!!!!!!!!!!!!!!"
echo "note that id3 and faad2 directoies MUST not be empty !!"

AC_CHECK_HEADER(pthread.h,,
	AC_MSG_ERROR(*** pthread headers support not installed or not found))
AC_CHECK_HEADER(id3.h,,
	AC_MSG_ERROR(*** id3lib headers support not installed or not found))

dnl *** check for presence of libfaad2 in the system
dnl *** it's maybe a new version than provided here (faad2-1.1)
dnl ***
dnl ***
have_libfaad2=yes
AC_CHECK_HEADER(faad.h,,
	[echo "*** use libfaad2-2.0 in static mode"
	have_libfaad2=no])
AM_CONDITIONAL(USE_STATIC_FAAD2, test $have_libfaad2 = no)

AC_OUTPUT(Makefile src/Makefile )
echo "***"
echo "*** configuration xmms-aac plugin done (version 0.5)"
echo "***"
echo "*** note that if you can't decode aac files you need"
echo "*** the old libfaad2-1.1, typicaly for files encoded with psytel-2.15"

M plugins/xmms/src/Makefile.am => plugins/xmms/src/Makefile.am +10 -5
@@ 1,7 1,12 @@
CFLAGS = @CFLAGS@ -Wall
bin_PROGRAMS = libaac.so
libdir = `xmms-config --input-plugin-dir`

INCLUDES = `xmms-config --cflags` -I@FAAD2_DIR@/include -I@ID3_DIR@/include
libaac_so_LDFLAGS = -shared -L@FAAD2_DIR@/lib -L@ID3_DIR@/lib `xmms-config --libs` -lpthread -lfaad -lz
lib_LTLIBRARIES = libaac.la

libaac_so_SOURCES = libaac.c id3.cpp
if USE_STATIC_FAAD2
INCLUDES = -I../../$(top_srcdir)/include
libaac_la_LDFLAGS = -module -avoid-version `xmms-config --libs` -lpthread -lid3 -lstdc++ -lz
libaac_la_LIBADD = ../../$(top_srcdir)/libfaad/libfaad.la
else
libaac_la_LDFLAGS = -module -avoid-version `xmms-config --libs` -lpthread -lfaad -lz -lid3 -lstdc++
endif
libaac_la_SOURCES = libaac.c id3.cpp dialog_gtk1.c aac_utils.c

D plugins/xmms/src/Makefile.save => plugins/xmms/src/Makefile.save +0 -22
@@ 1,22 0,0 @@

CC = gcc
CPP = g++
LDFLAGS = -lpthread -lfaad -L/usr/local/faad2/lib -lid3 -lz
CFLAGS = -O2 -Wall
INCLUDE = -I/usr/local/faad2/include `xmms-config --cflags`
OBJS = libaac.o id3.o dialog_gtk1.o

.SUFFIXES: .c .o

.c.o:
	$(CC) -c $(CFLAGS) $(INCLUDE) -o $@ $<

.cpp.o:
	$(CPP) -c $(CFLAGS) $(INCLUDE) -o $@ $<

all: $(OBJS)
	$(CPP) -shared -o libaac.so $(OBJS) `xmms-config --libs` $(INCLUDE) $(CFLAGS) $(LDFLAGS)
	strip --strip-debug libaac.so

install:
	mv libaac.so $(HOME)/.xmms/Plugins/

A plugins/xmms/src/aac_utils.c => plugins/xmms/src/aac_utils.c +97 -0
@@ 0,0 1,97 @@
/*
** utils for AAC informations
*/
#include <glib.h>
#include <stdio.h>
#include <stdlib.h>
#include "aac_utils.h"


// Read ADTS header, the file descriptor must be at
// the begining of the aac frame not at the id3tag

int	getAacInfo(FILE *fd)
{
  unsigned char	header[ADTS_HEADER_SIZE];
  unsigned int	id;
  unsigned long	originPosition;
  
  originPosition = ftell(fd);
  if(fread(header, 1, ADTS_HEADER_SIZE, fd) != ADTS_HEADER_SIZE){
    fseek(fd, originPosition, SEEK_SET);
    return(-1);
  }
  if(!((header[0]==0xFF)&&((header[1]& 0xF6)==0xF0))){
    printf("Bad header\n");
    return(-1);
  }
  id = header[1]&0x08;
  if(id==0){//MPEG-4 AAC
    fseek(fd, originPosition, SEEK_SET);
    return(MPEG4_TYPE);
  }else{
    fseek(fd, originPosition, SEEK_SET);
    return(MPEG2_TYPE);
  }
  fseek(fd, originPosition, SEEK_SET);
  return(-1);
}

// as AAC is VBR we need to check all ADTS header
// to enable seeking...
// there is no other solution
void	checkADTSForSeeking(FILE *fd,
			    unsigned long **seekTable,
			    unsigned long *seekTableLength)
{
  unsigned long	originPosition;
  unsigned long	position;
  unsigned char	header[ADTS_HEADER_SIZE];
  unsigned int	frameCount, frameLength, frameInsec;
  unsigned int	id=0, seconds=0;

  originPosition = ftell(fd);

  for(frameCount=0,frameInsec=0;; frameCount++,frameInsec++){
    position = ftell(fd);
    if(fread(header, 1, ADTS_HEADER_SIZE, fd)!=ADTS_HEADER_SIZE){
      break;
    }
    if(!strncmp(header, "ID3", 3)){
      break;
    }
    if(!((header[0]==0xFF)&&((header[1]& 0xF6)==0xF0))){
      printf("error : Bad 1st header, file may be corrupt !\n");
      break;
    }
    if(!frameCount){
      id=header[1]&0x08;
      if(((*seekTable) = malloc(SEEK_TABLE_CHUNK * sizeof(unsigned long)))==0){
	printf("malloc error\n");
	return;
      }
      (*seekTableLength) = SEEK_TABLE_CHUNK;
    }
    if(id==0){//MPEG-4
      frameLength = ((unsigned int)header[4]<<5)|((unsigned int)header[5]>>3);
    }else{//MPEG-2
      frameLength = (((unsigned int)header[3]&0x3)<<11)|((unsigned int)header[4]<<3)|(header[5]>>5);
    }
    if(frameInsec==43){//???
      frameInsec=0;
    }
    if(frameInsec==0){
      if(seconds == (*seekTableLength)){
	(*seekTable) = realloc((*seekTable), (seconds+SEEK_TABLE_CHUNK)*sizeof(unsigned long));
	(*seekTableLength) = seconds+SEEK_TABLE_CHUNK;
      }
      (*seekTable)[seconds] = position;
      seconds++;
    }
    if(fseek(fd, frameLength-ADTS_HEADER_SIZE, SEEK_CUR)==-1){
      break;
    } 
  }
  (*seekTableLength) = seconds;
  fseek(fd, originPosition, SEEK_SET);
}

A plugins/xmms/src/aac_utils.h => plugins/xmms/src/aac_utils.h +11 -0
@@ 0,0 1,11 @@
#ifndef __AACUTILS_H__
#define __AACUTILS_H__

#define ADTS_HEADER_SIZE	8
#define SEEK_TABLE_CHUNK	60
#define MPEG4_TYPE		0
#define MPEG2_TYPE		1

int	getAacInfo(FILE *);
void	checkADTSForSeeking(FILE *, unsigned long **, unsigned long *);
#endif

M plugins/xmms/src/dialog_gtk1.c => plugins/xmms/src/dialog_gtk1.c +266 -314
@@ 1,62 1,59 @@
/*
** Dialog info file 
** use gtk 1.2.x
** with the help of wGlade
*/

#include <gdk/gdkkeysyms.h>
#include <gtk/gtk.h>

void updateWindowDatas(void);

char *title=0;
char *artist=0;
char *album=0;
char *year=0;
char *track=0;
char *genre=0;
char *comment=0;
char *composer=0;
char *url=0;
char *originalArtist=0;
char *encodedby=0;

GtkWidget *createDialogInfo(void);
char *title=0, *artist=0, *album=0, *year=0, *track=0, *genre=0, *comment=0,
	*composer=0, *url=0, *originalArtist=0, *encodedby=0;
void updateWindowDatas(void);
GtkWidget* createDialogInfo(void);

GtkWidget* createDialogInfo(void)

{
  GtkWidget *window1;
  GtkWidget *fixed1;
  GtkWidget *button2;
  GtkWidget *frame2;
  GtkWidget *fixed3;
  GtkWidget *Track;
  GtkWidget *Artist;
  GtkWidget *Title;
  GtkWidget *Album;
  GtkWidget *Year;
  GtkWidget *Encoded;
  GtkWidget *entry1;
  GtkWidget *labelYear;
  GtkWidget *labelEncoded;
  GtkWidget *text1;
  GtkWidget *entry2;
  GtkWidget *labelAlbum;
  GtkWidget *entry3;
  GtkWidget *labelTrack;
  GtkWidget *labelComposer;
  GtkWidget *label15;
  GtkWidget *hseparator1;
  GtkWidget *labelArtist;
  GtkWidget *labelTitle;
  GtkWidget *label17;
  GtkWidget *entry4;
  GtkWidget *label18;
  GtkWidget *labelGenre;
  GtkWidget *button1;
  GtkWidget *AACTypeentry;
  GtkWidget *HeaderTypeentry;
  GtkWidget *frame1;
  GtkWidget *fixed2;
  GtkWidget *labelaacType;
  GtkWidget *label13;
  GtkWidget *Titleentry;
  GtkWidget *Artistentry;
  GtkWidget *Trackentry;
  GtkWidget *Albumentry;
  GtkWidget *Yearentry;
  GtkWidget *CommentText;
  GtkWidget *Composerentry;
  GtkWidget *label9;
  GtkWidget *label8;
  GtkWidget *label3;
  GtkWidget *label4;
  GtkWidget *label6;
  GtkWidget *label7;
  GtkWidget *label5;
  GtkWidget *OrArtistentry;
  GtkWidget *label10;
  GtkWidget *Encodedentry;
  GtkWidget *label11;
  GtkWidget *label1;
  GtkWidget *label2;
  GtkTooltips *tooltips;

  tooltips = gtk_tooltips_new ();
  updateWindowDatas();
  tooltips = gtk_tooltips_new ();

  window1 = gtk_window_new (GTK_WINDOW_DIALOG);
  gtk_object_set_data (GTK_OBJECT (window1), "window1", window1);
  gtk_window_set_title (GTK_WINDOW (window1), "Infos / AAC / ID3tag");
  gtk_window_set_modal (GTK_WINDOW (window1), TRUE);
  gtk_window_set_default_size (GTK_WINDOW (window1), 400, 350);
  gtk_window_set_title (GTK_WINDOW (window1), "AAC info");

  fixed1 = gtk_fixed_new ();
  gtk_widget_ref (fixed1);


@@ 65,303 62,258 @@ GtkWidget* createDialogInfo(void)
  gtk_widget_show (fixed1);
  gtk_container_add (GTK_CONTAINER (window1), fixed1);

  button2 = gtk_button_new_with_label ("Close");
  gtk_widget_ref (button2);
  gtk_object_set_data_full (GTK_OBJECT (window1), "button2", button2,
  button1 = gtk_button_new_with_label ("Close");
  gtk_widget_ref (button1);
  gtk_object_set_data_full (GTK_OBJECT (window1), "button1", button1,
                            (GtkDestroyNotify) gtk_widget_unref);
  gtk_signal_connect_object(GTK_OBJECT(button2), "clicked", GTK_SIGNAL_FUNC(gtk_widget_destroy), GTK_OBJECT(window1));
  gtk_widget_show (button2);
  gtk_fixed_put (GTK_FIXED (fixed1), button2, 451, 39);
  gtk_widget_set_uposition (button2, 451, 39);
  gtk_widget_set_usize (button2, 49, 24);

  frame2 = gtk_frame_new ("ID3 Tag");
  gtk_widget_ref (frame2);
  gtk_object_set_data_full (GTK_OBJECT (window1), "frame2", frame2,
  gtk_signal_connect_object(GTK_OBJECT(button1), "clicked", GTK_SIGNAL_FUNC(gtk_widget_destroy), GTK_OBJECT(window1));
  gtk_widget_show (button1);
  gtk_fixed_put (GTK_FIXED (fixed1), button1, 408, 16);
  gtk_widget_set_uposition (button1, 408, 16);
  gtk_widget_set_usize (button1, 47, 22);

  AACTypeentry = gtk_entry_new ();
  gtk_widget_ref (AACTypeentry);
  gtk_object_set_data_full (GTK_OBJECT (window1), "AACTypeentry", AACTypeentry,
                            (GtkDestroyNotify) gtk_widget_unref);
  gtk_widget_show (frame2);
  gtk_fixed_put (GTK_FIXED (fixed1), frame2, 2, 99);
  gtk_widget_set_uposition (frame2, 2, 99);
  gtk_widget_set_usize (frame2, 504, 326);

  fixed3 = gtk_fixed_new ();
  gtk_widget_ref (fixed3);
  gtk_object_set_data_full (GTK_OBJECT (window1), "fixed3", fixed3,
  gtk_widget_show (AACTypeentry);
  gtk_fixed_put (GTK_FIXED (fixed1), AACTypeentry, 128, 8);
  gtk_widget_set_uposition (AACTypeentry, 128, 8);
  gtk_widget_set_usize (AACTypeentry, 96, 16);
  gtk_entry_set_editable (GTK_ENTRY (AACTypeentry), FALSE);

  HeaderTypeentry = gtk_entry_new ();
  gtk_widget_ref (HeaderTypeentry);
  gtk_object_set_data_full (GTK_OBJECT (window1), "HeaderTypeentry", HeaderTypeentry,
                            (GtkDestroyNotify) gtk_widget_unref);
  gtk_widget_show (fixed3);
  gtk_container_add (GTK_CONTAINER (frame2), fixed3);
  gtk_widget_show (HeaderTypeentry);
  gtk_fixed_put (GTK_FIXED (fixed1), HeaderTypeentry, 128, 32);
  gtk_widget_set_uposition (HeaderTypeentry, 128, 32);
  gtk_widget_set_usize (HeaderTypeentry, 96, 16);
  gtk_entry_set_editable (GTK_ENTRY (HeaderTypeentry), FALSE);

  Track = gtk_entry_new ();
  gtk_widget_ref (Track);
  gtk_object_set_data_full (GTK_OBJECT (window1), "Track", Track,
                            (GtkDestroyNotify) gtk_widget_unref);
  gtk_widget_show (Track);
  gtk_fixed_put (GTK_FIXED (fixed3), Track, 424, 0);
  gtk_widget_set_uposition (Track, 424, 0);
  gtk_widget_set_usize (Track, 60, 20);
  gtk_tooltips_set_tip (tooltips, Track, "number on the album", NULL);
  gtk_entry_set_editable (GTK_ENTRY (Track), FALSE);
  gtk_entry_set_text (GTK_ENTRY (Track), track);

  Artist = gtk_entry_new ();
  gtk_widget_ref (Artist);
  gtk_object_set_data_full (GTK_OBJECT (window1), "Artist", Artist,
                            (GtkDestroyNotify) gtk_widget_unref);
  gtk_widget_show (Artist);
  gtk_fixed_put (GTK_FIXED (fixed3), Artist, 112, 0);
  gtk_widget_set_uposition (Artist, 112, 0);
  gtk_widget_set_usize (Artist, 240, 20);
  gtk_tooltips_set_tip (tooltips, Artist, "artist or group singer", NULL);
  gtk_entry_set_editable (GTK_ENTRY (Artist), FALSE);
  gtk_entry_set_text (GTK_ENTRY (Artist), artist);

  Title = gtk_entry_new ();
  gtk_widget_ref (Title);
  gtk_object_set_data_full (GTK_OBJECT (window1), "Title", Title,
                            (GtkDestroyNotify) gtk_widget_unref);
  gtk_widget_show (Title);
  gtk_fixed_put (GTK_FIXED (fixed3), Title, 112, 32);
  gtk_widget_set_uposition (Title, 112, 32);
  gtk_widget_set_usize (Title, 370, 20);
  gtk_tooltips_set_tip (tooltips, Title, "title of the song", NULL);
  gtk_entry_set_editable (GTK_ENTRY (Title), FALSE);
  gtk_entry_set_text (GTK_ENTRY (Title), title);

  Album = gtk_entry_new ();
  gtk_widget_ref (Album);
  gtk_object_set_data_full (GTK_OBJECT (window1), "Album", Album,
                            (GtkDestroyNotify) gtk_widget_unref);
  gtk_widget_show (Album);
  gtk_fixed_put (GTK_FIXED (fixed3), Album, 112, 64);
  gtk_widget_set_uposition (Album, 112, 64);
  gtk_widget_set_usize (Album, 240, 20);
  gtk_tooltips_set_tip (tooltips, Album, "from album...", NULL);
  gtk_entry_set_editable (GTK_ENTRY (Album), FALSE);
  gtk_entry_set_text (GTK_ENTRY (Album), album);

  Year = gtk_entry_new_with_max_length (4);
  gtk_widget_ref (Year);
  gtk_object_set_data_full (GTK_OBJECT (window1), "Year", Year,
                            (GtkDestroyNotify) gtk_widget_unref);
  gtk_widget_show (Year);
  gtk_fixed_put (GTK_FIXED (fixed3), Year, 424, 64);
  gtk_widget_set_uposition (Year, 424, 64);
  gtk_widget_set_usize (Year, 60, 20);
  gtk_tooltips_set_tip (tooltips, Year, "sell in ...", NULL);
  gtk_entry_set_editable (GTK_ENTRY (Year), FALSE);
  gtk_entry_set_text (GTK_ENTRY (Year), year);

  Encoded = gtk_entry_new ();
  gtk_widget_ref (Encoded);
  gtk_object_set_data_full (GTK_OBJECT (window1), "Encoded", Encoded,
  frame1 = gtk_frame_new ("ID3v2 Tag");
  gtk_widget_ref (frame1);
  gtk_object_set_data_full (GTK_OBJECT (window1), "frame1", frame1,
                            (GtkDestroyNotify) gtk_widget_unref);
  gtk_widget_show (Encoded);
  gtk_fixed_put (GTK_FIXED (fixed3), Encoded, 336, 272);
  gtk_widget_set_uposition (Encoded, 336, 272);
  gtk_widget_set_usize (Encoded, 158, 20);
  gtk_tooltips_set_tip (tooltips, Encoded, "the name of the encoder...", NULL);
  gtk_entry_set_editable (GTK_ENTRY (Encoded), FALSE);
  gtk_entry_set_text (GTK_ENTRY (Encoded), encodedby);

  entry1 = gtk_entry_new ();
  gtk_widget_ref (entry1);
  gtk_object_set_data_full (GTK_OBJECT (window1), "entry1", entry1,
  gtk_widget_show (frame1);
  gtk_fixed_put (GTK_FIXED (fixed1), frame1, 8, 64);
  gtk_widget_set_uposition (frame1, 8, 64);
  gtk_widget_set_usize (frame1, 464, 192);

  fixed2 = gtk_fixed_new ();
  gtk_widget_ref (fixed2);
  gtk_object_set_data_full (GTK_OBJECT (window1), "fixed2", fixed2,
                            (GtkDestroyNotify) gtk_widget_unref);
  gtk_widget_show (entry1);
  gtk_fixed_put (GTK_FIXED (fixed3), entry1, 328, 96);
  gtk_widget_set_uposition (entry1, 328, 96);
  gtk_widget_set_usize (entry1, 160, 20);
  gtk_tooltips_set_tip (tooltips, entry1, "what king of music...", NULL);
  gtk_entry_set_editable (GTK_ENTRY (entry1), FALSE);
  gtk_entry_set_text (GTK_ENTRY (entry1), genre);

  labelYear = gtk_label_new ("Year :");
  gtk_widget_ref (labelYear);
  gtk_object_set_data_full (GTK_OBJECT (window1), "labelYear", labelYear,
  gtk_widget_show (fixed2);
  gtk_container_add (GTK_CONTAINER (frame1), fixed2);

  Titleentry = gtk_entry_new ();
  gtk_widget_ref (Titleentry);
  gtk_object_set_data_full (GTK_OBJECT (window1), "Titleentry", Titleentry,
                            (GtkDestroyNotify) gtk_widget_unref);
  gtk_widget_show (labelYear);
  gtk_fixed_put (GTK_FIXED (fixed3), labelYear, 376, 64);
  gtk_widget_set_uposition (labelYear, 376, 64);
  gtk_widget_set_usize (labelYear, 41, 18);

  labelEncoded = gtk_label_new ("Encoded by :");
  gtk_widget_ref (labelEncoded);
  gtk_object_set_data_full (GTK_OBJECT (window1), "labelEncoded", labelEncoded,
  gtk_widget_show (Titleentry);
  gtk_fixed_put (GTK_FIXED (fixed2), Titleentry, 80, 0);
  gtk_widget_set_uposition (Titleentry, 80, 0);
  gtk_widget_set_usize (Titleentry, 232, 16);
  gtk_entry_set_editable (GTK_ENTRY (Titleentry), FALSE);
  gtk_entry_set_text (GTK_ENTRY (Titleentry), title);

  Artistentry = gtk_entry_new ();
  gtk_widget_ref (Artistentry);
  gtk_object_set_data_full (GTK_OBJECT (window1), "Artistentry", Artistentry,
                            (GtkDestroyNotify) gtk_widget_unref);
  gtk_widget_show (labelEncoded);
  gtk_fixed_put (GTK_FIXED (fixed3), labelEncoded, 248, 272);
  gtk_widget_set_uposition (labelEncoded, 248, 272);
  gtk_widget_set_usize (labelEncoded, 83, 18);

  text1 = gtk_text_new (NULL, NULL);
  gtk_widget_ref (text1);
  gtk_object_set_data_full (GTK_OBJECT (window1), "text1", text1,
  gtk_widget_show (Artistentry);
  gtk_fixed_put (GTK_FIXED (fixed2), Artistentry, 80, 16);
  gtk_widget_set_uposition (Artistentry, 80, 16);
  gtk_widget_set_usize (Artistentry, 232, 16);
  gtk_entry_set_editable (GTK_ENTRY (Artistentry), FALSE);
  gtk_entry_set_text (GTK_ENTRY (Artistentry), artist);

  Trackentry = gtk_entry_new ();
  gtk_widget_ref (Trackentry);
  gtk_object_set_data_full (GTK_OBJECT (window1), "Trackentry", Trackentry,
                            (GtkDestroyNotify) gtk_widget_unref);
  gtk_widget_show (text1);
  gtk_fixed_put (GTK_FIXED (fixed3), text1, 112, 152);
  gtk_widget_set_uposition (text1, 112, 152);
  gtk_widget_set_usize (text1, 376, 72);

  entry2 = gtk_entry_new ();
  gtk_widget_ref (entry2);
  gtk_object_set_data_full (GTK_OBJECT (window1), "entry2", entry2,
  gtk_widget_show (Trackentry);
  gtk_fixed_put (GTK_FIXED (fixed2), Trackentry, 400, 32);
  gtk_widget_set_uposition (Trackentry, 400, 32);
  gtk_widget_set_usize (Trackentry, 56, 16);
  gtk_entry_set_editable (GTK_ENTRY (Trackentry), FALSE);
  gtk_entry_set_text (GTK_ENTRY (Trackentry), track);

  Albumentry = gtk_entry_new ();
  gtk_widget_ref (Albumentry);
  gtk_object_set_data_full (GTK_OBJECT (window1), "Albumentry", Albumentry,
                            (GtkDestroyNotify) gtk_widget_unref);
  gtk_widget_show (entry2);
  gtk_fixed_put (GTK_FIXED (fixed3), entry2, 248, 232);
  gtk_widget_set_uposition (entry2, 248, 232);
  gtk_widget_set_usize (entry2, 240, 20);
  gtk_tooltips_set_tip (tooltips, entry2, "Composer of the song", NULL);
  gtk_entry_set_editable (GTK_ENTRY (entry2), FALSE);
  gtk_entry_set_text (GTK_ENTRY (entry2), composer);

  labelAlbum = gtk_label_new ("Album :");
  gtk_widget_ref (labelAlbum);
  gtk_object_set_data_full (GTK_OBJECT (window1), "labelAlbum", labelAlbum,
  gtk_widget_show (Albumentry);
  gtk_fixed_put (GTK_FIXED (fixed2), Albumentry, 80, 32);
  gtk_widget_set_uposition (Albumentry, 80, 32);
  gtk_widget_set_usize (Albumentry, 232, 16);
  gtk_entry_set_editable (GTK_ENTRY (Albumentry), FALSE);
  gtk_entry_set_text (GTK_ENTRY (Albumentry), album);

  Yearentry = gtk_entry_new ();
  gtk_widget_ref (Yearentry);
  gtk_object_set_data_full (GTK_OBJECT (window1), "Yearentry", Yearentry,
                            (GtkDestroyNotify) gtk_widget_unref);
  gtk_widget_show (labelAlbum);
  gtk_fixed_put (GTK_FIXED (fixed3), labelAlbum, 48, 64);
  gtk_widget_set_uposition (labelAlbum, 48, 64);
  gtk_widget_set_usize (labelAlbum, 55, 18);
  gtk_label_set_justify (GTK_LABEL (labelAlbum), GTK_JUSTIFY_RIGHT);

  entry3 = gtk_entry_new ();
  gtk_widget_ref (entry3);
  gtk_object_set_data_full (GTK_OBJECT (window1), "entry3", entry3,
  gtk_widget_show (Yearentry);
  gtk_fixed_put (GTK_FIXED (fixed2), Yearentry, 384, 0);
  gtk_widget_set_uposition (Yearentry, 384, 0);
  gtk_widget_set_usize (Yearentry, 72, 16);
  gtk_entry_set_editable (GTK_ENTRY (Yearentry), FALSE);
  gtk_entry_set_text (GTK_ENTRY (Yearentry), year);

  CommentText = gtk_text_new (NULL, NULL);
  gtk_widget_ref (CommentText);
  gtk_object_set_data_full (GTK_OBJECT (window1), "CommentText", CommentText,
                            (GtkDestroyNotify) gtk_widget_unref);
  gtk_widget_show (entry3);
  gtk_fixed_put (GTK_FIXED (fixed3), entry3, 96, 272);
  gtk_widget_set_uposition (entry3, 96, 272);
  gtk_widget_set_usize (entry3, 145, 20);
  gtk_tooltips_set_tip (tooltips, entry3, "if a remix who's the original artist...", NULL);
  gtk_entry_set_editable (GTK_ENTRY (entry3), FALSE);
  gtk_entry_set_text (GTK_ENTRY (entry3), originalArtist);

  labelTrack = gtk_label_new ("Track :");
  gtk_widget_ref (labelTrack);
  gtk_object_set_data_full (GTK_OBJECT (window1), "labelTrack", labelTrack,
  gtk_widget_show (CommentText);
  gtk_fixed_put (GTK_FIXED (fixed2), CommentText, 80, 56);
  gtk_widget_set_uposition (CommentText, 80, 56);
  gtk_widget_set_usize (CommentText, 376, 48);

  Composerentry = gtk_entry_new ();
  gtk_widget_ref (Composerentry);
  gtk_object_set_data_full (GTK_OBJECT (window1), "Composerentry", Composerentry,
                            (GtkDestroyNotify) gtk_widget_unref);
  gtk_widget_show (labelTrack);
  gtk_fixed_put (GTK_FIXED (fixed3), labelTrack, 368, 0);
  gtk_widget_set_uposition (labelTrack, 368, 0);
  gtk_widget_set_usize (labelTrack, 47, 18);

  labelComposer = gtk_label_new ("Composer :");
  gtk_widget_ref (labelComposer);
  gtk_object_set_data_full (GTK_OBJECT (window1), "labelComposer", labelComposer,
  gtk_widget_show (Composerentry);
  gtk_fixed_put (GTK_FIXED (fixed2), Composerentry, 80, 112);
  gtk_widget_set_uposition (Composerentry, 80, 112);
  gtk_widget_set_usize (Composerentry, 232, 16);
  gtk_entry_set_editable (GTK_ENTRY (Composerentry), FALSE);
  gtk_entry_set_text (GTK_ENTRY (Composerentry), composer);

  label9 = gtk_label_new ("Composer :");
  gtk_widget_ref (label9);
  gtk_object_set_data_full (GTK_OBJECT (window1), "label9", label9,
                            (GtkDestroyNotify) gtk_widget_unref);
  gtk_widget_show (labelComposer);
  gtk_fixed_put (GTK_FIXED (fixed3), labelComposer, 160, 232);
  gtk_widget_set_uposition (labelComposer, 160, 232);
  gtk_widget_set_usize (labelComposer, 78, 18);

  label15 = gtk_label_new ("Comment :");
  gtk_widget_ref (label15);
  gtk_object_set_data_full (GTK_OBJECT (window1), "label15", label15,
  gtk_widget_show (label9);
  gtk_fixed_put (GTK_FIXED (fixed2), label9, 0, 112);
  gtk_widget_set_uposition (label9, 0, 112);
  gtk_widget_set_usize (label9, 80, 16);
  gtk_label_set_justify (GTK_LABEL (label9), GTK_JUSTIFY_RIGHT);

  label8 = gtk_label_new ("Comment :");
  gtk_widget_ref (label8);
  gtk_object_set_data_full (GTK_OBJECT (window1), "label8", label8,
                            (GtkDestroyNotify) gtk_widget_unref);
  gtk_widget_show (label15);
  gtk_fixed_put (GTK_FIXED (fixed3), label15, 32, 160);
  gtk_widget_set_uposition (label15, 32, 160);
  gtk_widget_set_usize (label15, 72, 18);

  hseparator1 = gtk_hseparator_new ();
  gtk_widget_ref (hseparator1);
  gtk_object_set_data_full (GTK_OBJECT (window1), "hseparator1", hseparator1,
  gtk_widget_show (label8);
  gtk_fixed_put (GTK_FIXED (fixed2), label8, 0, 72);
  gtk_widget_set_uposition (label8, 0, 72);
  gtk_widget_set_usize (label8, 72, 16);
  gtk_label_set_justify (GTK_LABEL (label8), GTK_JUSTIFY_RIGHT);

  label3 = gtk_label_new ("Title :");
  gtk_widget_ref (label3);
  gtk_object_set_data_full (GTK_OBJECT (window1), "label3", label3,
                            (GtkDestroyNotify) gtk_widget_unref);
  gtk_widget_show (hseparator1);
  gtk_fixed_put (GTK_FIXED (fixed3), hseparator1, 144, 120);
  gtk_widget_set_uposition (hseparator1, 144, 120);
  gtk_widget_set_usize (hseparator1, 278, 16);

  labelArtist = gtk_label_new ("Artist / Group :");
  gtk_widget_ref (labelArtist);
  gtk_object_set_data_full (GTK_OBJECT (window1), "labelArtist", labelArtist,
  gtk_widget_show (label3);
  gtk_fixed_put (GTK_FIXED (fixed2), label3, 8, 0);
  gtk_widget_set_uposition (label3, 8, 0);
  gtk_widget_set_usize (label3, 56, 16);
  gtk_label_set_justify (GTK_LABEL (label3), GTK_JUSTIFY_RIGHT);

  label4 = gtk_label_new ("Artist :");
  gtk_widget_ref (label4);
  gtk_object_set_data_full (GTK_OBJECT (window1), "label4", label4,
                            (GtkDestroyNotify) gtk_widget_unref);
  gtk_widget_show (labelArtist);
  gtk_fixed_put (GTK_FIXED (fixed3), labelArtist, 0, 0);
  gtk_widget_set_uposition (labelArtist, 0, 0);
  gtk_widget_set_usize (labelArtist, 106, 18);
  gtk_label_set_justify (GTK_LABEL (labelArtist), GTK_JUSTIFY_RIGHT);

  labelTitle = gtk_label_new ("Title :");
  gtk_widget_ref (labelTitle);
  gtk_object_set_data_full (GTK_OBJECT (window1), "labelTitle", labelTitle,
  gtk_widget_show (label4);
  gtk_fixed_put (GTK_FIXED (fixed2), label4, 8, 16);
  gtk_widget_set_uposition (label4, 8, 16);
  gtk_widget_set_usize (label4, 56, 16);
  gtk_label_set_justify (GTK_LABEL (label4), GTK_JUSTIFY_RIGHT);

  label6 = gtk_label_new ("Album :");
  gtk_widget_ref (label6);
  gtk_object_set_data_full (GTK_OBJECT (window1), "label6", label6,
                            (GtkDestroyNotify) gtk_widget_unref);
  gtk_widget_show (labelTitle);
  gtk_fixed_put (GTK_FIXED (fixed3), labelTitle, 62, 36);
  gtk_widget_set_uposition (labelTitle, 62, 36);
  gtk_widget_set_usize (labelTitle, 39, 18);

  label17 = gtk_label_new ("Original Artist :");
  gtk_widget_ref (label17);
  gtk_object_set_data_full (GTK_OBJECT (window1), "label17", label17,
  gtk_widget_show (label6);
  gtk_fixed_put (GTK_FIXED (fixed2), label6, 8, 32);
  gtk_widget_set_uposition (label6, 8, 32);
  gtk_widget_set_usize (label6, 48, 16);
  gtk_label_set_justify (GTK_LABEL (label6), GTK_JUSTIFY_RIGHT);

  label7 = gtk_label_new ("Year :");
  gtk_widget_ref (label7);
  gtk_object_set_data_full (GTK_OBJECT (window1), "label7", label7,
                            (GtkDestroyNotify) gtk_widget_unref);
  gtk_widget_show (label17);
  gtk_fixed_put (GTK_FIXED (fixed3), label17, 0, 272);
  gtk_widget_set_uposition (label17, 0, 272);
  gtk_widget_set_usize (label17, 95, 18);

  entry4 = gtk_entry_new ();
  gtk_widget_ref (entry4);
  gtk_object_set_data_full (GTK_OBJECT (window1), "entry4", entry4,
  gtk_widget_show (label7);
  gtk_fixed_put (GTK_FIXED (fixed2), label7, 328, 0);
  gtk_widget_set_uposition (label7, 328, 0);
  gtk_widget_set_usize (label7, 64, 16);
  gtk_label_set_justify (GTK_LABEL (label7), GTK_JUSTIFY_RIGHT);

  label5 = gtk_label_new ("Track N\260 :");
  gtk_widget_ref (label5);
  gtk_object_set_data_full (GTK_OBJECT (window1), "label5", label5,
                            (GtkDestroyNotify) gtk_widget_unref);
  gtk_widget_show (entry4);
  gtk_fixed_put (GTK_FIXED (fixed3), entry4, 96, 96);
  gtk_widget_set_uposition (entry4, 96, 96);
  gtk_widget_set_usize (entry4, 158, 20);
  gtk_tooltips_set_tip (tooltips, entry4, "Artist Web site", NULL);
  gtk_entry_set_text (GTK_ENTRY (entry4), url);

  label18 = gtk_label_new ("Web site :");
  gtk_widget_ref (label18);
  gtk_object_set_data_full (GTK_OBJECT (window1), "label18", label18,
  gtk_widget_show (label5);
  gtk_fixed_put (GTK_FIXED (fixed2), label5, 328, 32);
  gtk_widget_set_uposition (label5, 328, 32);
  gtk_widget_set_usize (label5, 64, 16);
  gtk_label_set_justify (GTK_LABEL (label5), GTK_JUSTIFY_RIGHT);

  OrArtistentry = gtk_entry_new ();
  gtk_widget_ref (OrArtistentry);
  gtk_object_set_data_full (GTK_OBJECT (window1), "OrArtistentry", OrArtistentry,
                            (GtkDestroyNotify) gtk_widget_unref);
  gtk_widget_show (label18);
  gtk_fixed_put (GTK_FIXED (fixed3), label18, 24, 96);
  gtk_widget_set_uposition (label18, 24, 96);
  gtk_widget_set_usize (label18, 67, 18);

  labelGenre = gtk_label_new ("Genre :");
  gtk_widget_ref (labelGenre);
  gtk_object_set_data_full (GTK_OBJECT (window1), "labelGenre", labelGenre,
  gtk_widget_show (OrArtistentry);
  gtk_fixed_put (GTK_FIXED (fixed2), OrArtistentry, 80, 128);
  gtk_widget_set_uposition (OrArtistentry, 80, 128);
  gtk_widget_set_usize (OrArtistentry, 232, 16);
  gtk_tooltips_set_tip (tooltips, OrArtistentry, "Original Artist", NULL);
  gtk_entry_set_editable (GTK_ENTRY (OrArtistentry), FALSE);
  gtk_entry_set_text (GTK_ENTRY (OrArtistentry), originalArtist);

  label10 = gtk_label_new ("Or. Artist :");
  gtk_widget_ref (label10);
  gtk_object_set_data_full (GTK_OBJECT (window1), "label10", label10,
                            (GtkDestroyNotify) gtk_widget_unref);
  gtk_widget_show (labelGenre);
  gtk_fixed_put (GTK_FIXED (fixed3), labelGenre, 272, 96);
  gtk_widget_set_uposition (labelGenre, 272, 96);
  gtk_widget_set_usize (labelGenre, 46, 18);

  frame1 = gtk_frame_new ("Infos");
  gtk_widget_ref (frame1);
  gtk_object_set_data_full (GTK_OBJECT (window1), "frame1", frame1,
  gtk_widget_show (label10);
  gtk_fixed_put (GTK_FIXED (fixed2), label10, 0, 128);
  gtk_widget_set_uposition (label10, 0, 128);
  gtk_widget_set_usize (label10, 72, 16);

  Encodedentry = gtk_entry_new ();
  gtk_widget_ref (Encodedentry);
  gtk_object_set_data_full (GTK_OBJECT (window1), "Encodedentry", Encodedentry,
                            (GtkDestroyNotify) gtk_widget_unref);
  gtk_widget_show (frame1);
  gtk_fixed_put (GTK_FIXED (fixed1), frame1, 5, 2);
  gtk_widget_set_uposition (frame1, 5, 2);
  gtk_widget_set_usize (frame1, 436, 96);

  fixed2 = gtk_fixed_new ();
  gtk_widget_ref (fixed2);
  gtk_object_set_data_full (GTK_OBJECT (window1), "fixed2", fixed2,
  gtk_widget_show (Encodedentry);
  gtk_fixed_put (GTK_FIXED (fixed2), Encodedentry, 112, 144);
  gtk_widget_set_uposition (Encodedentry, 112, 144);
  gtk_widget_set_usize (Encodedentry, 200, 16);
  gtk_entry_set_editable (GTK_ENTRY (Encodedentry), FALSE);
  gtk_entry_set_text (GTK_ENTRY (Encodedentry), encodedby);

  label11 = gtk_label_new ("Encoded by :");
  gtk_widget_ref (label11);
  gtk_object_set_data_full (GTK_OBJECT (window1), "label11", label11,
                            (GtkDestroyNotify) gtk_widget_unref);
  gtk_widget_show (fixed2);
  gtk_container_add (GTK_CONTAINER (frame1), fixed2);

  labelaacType = gtk_label_new ("MPEG Type :");
  gtk_widget_ref (labelaacType);
  gtk_object_set_data_full (GTK_OBJECT (window1), "labelaacType", labelaacType,
  gtk_widget_show (label11);
  gtk_fixed_put (GTK_FIXED (fixed2), label11, 0, 144);
  gtk_widget_set_uposition (label11, 0, 144);
  gtk_widget_set_usize (label11, 104, 16);
  gtk_label_set_justify (GTK_LABEL (label11), GTK_JUSTIFY_RIGHT);

  label1 = gtk_label_new ("AAC Type :");
  gtk_widget_ref (label1);
  gtk_object_set_data_full (GTK_OBJECT (window1), "label1", label1,
                            (GtkDestroyNotify) gtk_widget_unref);
  gtk_widget_show (labelaacType);
  gtk_fixed_put (GTK_FIXED (fixed2), labelaacType, 32, 16);
  gtk_widget_set_uposition (labelaacType, 32, 16);
  gtk_widget_set_usize (labelaacType, 85, 18);

  label13 = gtk_label_new ("Frame Type :");
  gtk_widget_ref (label13);
  gtk_object_set_data_full (GTK_OBJECT (window1), "label13", label13,
  gtk_widget_show (label1);
  gtk_fixed_put (GTK_FIXED (fixed1), label1, 8, 8);
  gtk_widget_set_uposition (label1, 8, 8);
  gtk_widget_set_usize (label1, 112, 16);
  gtk_label_set_justify (GTK_LABEL (label1), GTK_JUSTIFY_RIGHT);

  label2 = gtk_label_new ("Header Type :");
  gtk_widget_ref (label2);
  gtk_object_set_data_full (GTK_OBJECT (window1), "label2", label2,
                            (GtkDestroyNotify) gtk_widget_unref);
  gtk_widget_show (label13);
  gtk_fixed_put (GTK_FIXED (fixed2), label13, 32, 40);
  gtk_widget_set_uposition (label13, 32, 40);
  gtk_widget_set_usize (label13, 85, 18);
  gtk_widget_show (label2);
  gtk_fixed_put (GTK_FIXED (fixed1), label2, 8, 32);
  gtk_widget_set_uposition (label2, 8, 32);
  gtk_widget_set_usize (label2, 112, 16);
  gtk_label_set_justify (GTK_LABEL (label2), GTK_JUSTIFY_RIGHT);

  gtk_object_set_data (GTK_OBJECT (window1), "tooltips", tooltips);


M plugins/xmms/src/id3.cpp => plugins/xmms/src/id3.cpp +117 -109
@@ 13,11 13,19 @@
extern "C" {
#endif

void readID3tag(char*);
void clearWindowDatas(void);
extern char *title, *artist, *album, *year, *track, *genre, *comment,
	*composer, *url, *originalArtist, *encodedby;

void	readID3tag(char*);
void	clearWindowDatas(void);
extern char	*title;
extern char	*artist;
extern char	*album;
extern char	*year;
extern char	*track;
extern char	*genre;
extern char	*comment;
extern char	*composer;
extern char	*url;
extern char	*originalArtist;
extern char	*encodedby;

#ifdef __cplusplus
}


@@ 27,123 35,123 @@ extern char *title, *artist, *album, *year, *track, *genre, *comment,
void readID3tag(char *filename)
{
  ID3_Tag tag;
   tag.Link(filename, ID3TT_ALL);
   ID3_Tag::Iterator	*iter = tag.CreateIterator();
   ID3_Frame		*frame = NULL;

   while((frame = iter->GetNext()) != NULL){
	ID3_FrameID FrameID = frame->GetID();
	switch (FrameID)
  tag.Link(filename, ID3TT_ALL);
  ID3_Tag::Iterator	*iter = tag.CreateIterator();
  ID3_Frame		*frame = NULL;

  while((frame = iter->GetNext()) != NULL){
    ID3_FrameID FrameID = frame->GetID();
    switch (FrameID)
      {
      case ID3FID_TITLE:
	{
	case ID3FID_TITLE:
		{
		title = ID3_GetString(frame, ID3FN_TEXT);
		break;
		}
	case ID3FID_LEADARTIST:
		{
		artist = ID3_GetString(frame, ID3FN_TEXT);
		break;
		}
	case ID3FID_ALBUM:
		{
		album = ID3_GetString(frame, ID3FN_TEXT);
		break;
		}
	case ID3FID_YEAR:
		{
		year = ID3_GetString(frame, ID3FN_TEXT);
		break;
		}
	case ID3FID_TRACKNUM:
		{
		track = ID3_GetString(frame, ID3FN_TEXT);
		break;
		}
	case ID3FID_CONTENTTYPE:
		{
		genre = ID3_GetString(frame, ID3FN_TEXT);
		break;
		}
	case ID3FID_COMMENT:
		{
		comment = ID3_GetString(frame, ID3FN_TEXT);
		break;
		}
	case ID3FID_COMPOSER:
		{
		composer = ID3_GetString(frame, ID3FN_TEXT);
		break;
		}
	case ID3FID_WWWARTIST:
		{
		url = ID3_GetString(frame, ID3FN_URL);
		break;
		}
	case ID3FID_ORIGARTIST:
		{
		originalArtist = ID3_GetString(frame, ID3FN_TEXT);
		break;
		}
	case ID3FID_ENCODEDBY:
		{
		encodedby = ID3_GetString(frame, ID3FN_TEXT);
	  title = ID3_GetString(frame, ID3FN_TEXT);
	  break;
	}
      case ID3FID_LEADARTIST:
	{
	  artist = ID3_GetString(frame, ID3FN_TEXT);
	  break;
	}
      case ID3FID_ALBUM:
	{
	  album = ID3_GetString(frame, ID3FN_TEXT);
	  break;
	}
      case ID3FID_YEAR:
	{
	  year = ID3_GetString(frame, ID3FN_TEXT);
	  break;
	}
      case ID3FID_TRACKNUM:
	{
	  track = ID3_GetString(frame, ID3FN_TEXT);
	  break;
	}
      case ID3FID_CONTENTTYPE:
	{
	  genre = ID3_GetString(frame, ID3FN_TEXT);
	  break;
	}
      case ID3FID_COMMENT:
	{
	  comment = ID3_GetString(frame, ID3FN_TEXT);
	  break;
	}
      case ID3FID_COMPOSER:
	{
	  composer = ID3_GetString(frame, ID3FN_TEXT);
	  break;
	}
      case ID3FID_WWWARTIST:
	{
	  url = ID3_GetString(frame, ID3FN_URL);
		break;
	}
      case ID3FID_ORIGARTIST:
	{
	  originalArtist = ID3_GetString(frame, ID3FN_TEXT);
	  break;
		}
	default:
		break;
      case ID3FID_ENCODEDBY:
	{
	  encodedby = ID3_GetString(frame, ID3FN_TEXT);
	  break;
	}
   }
   delete iter;
   return;
      default:
	break;
	}
  }
  delete iter;
  return;
}

void clearWindowDatas(void)
{
 if(title)
  if(strcmp(title,"")!=0){
     delete [] title;
 }
 if(artist)
  if(strcmp(artist,"")!=0){
        delete [] artist;
 }
 if(album)
  if(strcmp(album,"")!=0){
        delete [] album;
 }
 if(year)
  if(title)
    if(strcmp(title,"")!=0){
      delete [] title;
    }
  if(artist)
    if(strcmp(artist,"")!=0){
      delete [] artist;
    }
  if(album)
    if(strcmp(album,"")!=0){
      delete [] album;
    }
  if(year)
  if(strcmp(year,"")!=0){
        delete [] year;
 }
 if(track)
  if(strcmp(track,"")!=0){
        delete [] track;
 }
 if(genre)
  if(strcmp(genre,"")!=0){
        delete [] genre;
    delete [] year;
  }
  if(track)
    if(strcmp(track,"")!=0){
      delete [] track;
    }
  if(genre)
    if(strcmp(genre,"")!=0){
      delete [] genre;
 }
 if(comment)
  if(strcmp(comment,"")!=0){
        delete [] comment;
 }
 if(composer)
  if(comment)
    if(strcmp(comment,"")!=0){
      delete [] comment;
    }
  if(composer)
  if(strcmp(composer,"")!=0){
        delete [] composer;
 }
 if(url)
  if(strcmp(url,"")!=0){
        delete [] url;
    delete [] composer;
 }
 if(originalArtist)
  if(strcmp(originalArtist,"")!=0){
        delete [] originalArtist;
  if(url)
    if(strcmp(url,"")!=0){
      delete [] url;
    }
  if(originalArtist)
    if(strcmp(originalArtist,"")!=0){
      delete [] originalArtist;
 }
 if(encodedby)
  if(encodedby)
  if(strcmp(encodedby,"")!=0){
        delete [] encodedby;
 }
 title=artist=album=year=track=genre=comment=composer=url=originalArtist=
        encodedby=0;
    delete [] encodedby;
  }
  title=artist=album=year=track=genre=comment=composer=url=originalArtist=encodedby=0;
}

M plugins/xmms/src/libaac.c => plugins/xmms/src/libaac.c +349 -225
@@ 1,14 1,10 @@
/*
**            AAC plugin for XMMS 1.2.7
**              by ciberfred
**      ------------------------------------------------
** The version of the plugin match the version of XMMS
** for identifie different version use the date :)
**			  AAC plugin for XMMS 1.2.7
**				by ciberfred
**		------------------------------------------------
**
**          version 1.2.7 (23 august 2002)
**
**
**         need faad2 package from http://www.audiocoding.com
** need libfaad2-2.0  package from http://www.audiocoding.com
** and id3lib-3.8.x   package from http://www.id3lib.org
**
*/



@@ 24,288 20,416 @@
#include "xmms/util.h"
#include "xmms/configfile.h"
#include "xmms/titlestring.h"
#include "aac_utils.h"

#define AAC_DESCRIPTION	"MPEG2/4 AAC player - 1.2.7"
#define AAC_VERSION	"AAC player - 5 July 2003 (v0.4.1)"
#define AAC_ABOUT	"Writen from scratch by ciberfred from France\n"
#define PATH2CONFIGFILE "/.xmms/Plugins/aacConfig.txt"
#define BUFFER_SIZE	FAAD_MIN_STREAMSIZE*64

static void	aac_init(void);
static void	aac_play(char*);
static void	aac_stop(void);
static void	aac_pause(short);
static int	aac_getTime(void);
static void	aac_seek(int);
static void	aac_cleanup(void);
static void	aac_about(void);
static void	aac_configuration(void);
static void	*aac_decode(void*);

static void	aac_getSongInfo(char*);
static int	aac_isFile(char*);

#define AAC_DESCRIPTION "MPEG2/4 AAC player - 1.2.7"
#define AAC_VERSION "AAC player - 23 Agust 2002"
#define AAC_ABOUT   "Writen from scratch by ciberfred from France"
#define BUFFER_SIZE FAAD_MIN_STREAMSIZE*64

static void aac_init(void);
static void aac_play(char*);
static void aac_stop(void);
static void aac_pause(short);
static int  aac_getTime(void);
static void aac_seek(int);
static void aac_cleanup(void);
static void aac_about(void);
static void *aac_decode(void*);

static void aac_getSongInfo(char*);
static int  aac_isFile(char*);

extern void readID3tag(char*);
extern void	readID3tag(char*);
extern GtkWidget *createDialogInfo(void);
extern void	clearWindowDatas(void);

static GtkWidget *infoBoxWindow = NULL;
extern char *title, *artist, *album, *track, *genre;
extern void clearWindowDatas(void);
/******************************************************************************/


/*****************************************************************************/
/*
** struct need by xmms for Library Interface
*/

InputPlugin aac_ip =
{
    0,      // handle
    0,      // filename
  {
    0,		// handle
    0,		// filename
    AAC_DESCRIPTION,// description
    aac_init,   // init_func
    aac_about,  // aboutbox
    0,      // configuration
    aac_isFile, // ???
    0,      // scan dir
    aac_play,   // when play button
    aac_stop,   // when stop
    aac_pause,  // when pause
    aac_seek,   // when seek
    0,      // set equalizer
    aac_getTime,    // ???
    0,      // get volume
    0,      // set volume
    aac_cleanup,    // the cleanup function :)
    0,      // obsolete (???)
    0,      // send visualisation data
    0,      // set player window info
    0,      // set song title text
    0,  // get song title text to show on Playlist
    aac_init,	// init_func
    aac_about,	// aboutbox
    aac_configuration,		// configuration
    aac_isFile,	// ???
    0,		// scan dir
    aac_play,	// when play button
    aac_stop,	// when stop
    aac_pause,	// when pause
    aac_seek,	// when seek
    0,		// set equalizer
    aac_getTime,	// ???
    0,		// get volume
    0,		// set volume
    aac_cleanup,	// the cleanup function :)
    0,		// obsolete (???)
    0,		// send visualisation data
    0,		// set player window info
    0,		// set song title text
    0,	// get song title text to show on Playlist
    aac_getSongInfo,// file info box
    0       // pointer to outputPlugin
};
static gboolean     bPlaying = FALSE;
static gboolean bOutputOpen = FALSE;
static pthread_t    decodeThread;
static gint     seek_pos = -1; // the track position
static pthread_mutex_t  mutex = PTHREAD_MUTEX_INITIALIZER;

/******************************************************************************/
    0		// pointer to outputPlugin
  };
static gboolean 	bPlaying = FALSE;
static gboolean		bOutputOpen = FALSE;
static pthread_t	decodeThread;
static gboolean		bSeek = FALSE;
static gint		seekPosition = -1; // track position
static pthread_mutex_t	mutex = PTHREAD_MUTEX_INITIALIZER;
static unsigned long	*positionTable = 0;
int			aacType;
/*****************************************************************************/

InputPlugin *get_iplugin_info(void)
{
    return (&aac_ip);
  return (&aac_ip);
}


static void aac_init(void)
{
    memset(&decodeThread, 0, sizeof(pthread_t));
  ConfigFile*	cfg;

  memset(&decodeThread, 0, sizeof(pthread_t));
  cfg = xmms_cfg_open_default_file();
  xmms_cfg_read_boolean(cfg, "AAC", "seeking", &bSeek);
  xmms_cfg_free(cfg);
}

static void aac_cleanup(void)
{
  memset(&decodeThread, 0, sizeof(pthread_t));
  if(positionTable){
    free(positionTable);
  }

}

static void aac_play(char *filename)
{
    printf("play\n");
    bPlaying = TRUE;
    pthread_create(&decodeThread, 0, aac_decode, g_strdup(filename));
    return;
  bPlaying = TRUE;
  if(pthread_create(&decodeThread, 0, aac_decode, g_strdup(filename))!=0){
    printf("Error creating pthread, can't play file\n");
  }

  return;
}

static void aac_stop(void)
{
    printf("stop\n");
    if (bPlaying){
        bPlaying = FALSE;
        pthread_join(decodeThread, NULL);
        memset(&decodeThread, 0, sizeof(pthread_t));
        aac_ip.output->close_audio();
        clearWindowDatas();
    }
  if (bPlaying){
    bPlaying = FALSE;
    pthread_join(decodeThread, NULL);
    memset(&decodeThread, 0, sizeof(pthread_t));
    aac_ip.output->close_audio();
    clearWindowDatas();
  }
}

static void aac_pause(short paused)
{
    printf("pause\n");
    if(bOutputOpen){
        aac_ip.output->pause(paused);
    }
  if(bOutputOpen){
    aac_ip.output->pause(paused);
  }
}

static int aac_getTime(void)
{
    if (!bPlaying){
        return (-1);
    }
    else{
        return (aac_ip.output->output_time());
    }
  if (!bPlaying){
    return (-1);
  }
  else{
    return (aac_ip.output->output_time());
  }
}


static void aac_seek(int time)
{
    printf("seek\n");
  seekPosition=time;
  while(bPlaying && seekPosition!=-1) xmms_usleep(10000);
}

static void aac_getSongInfo(char *filename)
{
    infoBoxWindow = createDialogInfo();
    gtk_widget_show(infoBoxWindow);
  infoBoxWindow = createDialogInfo();
  gtk_widget_show(infoBoxWindow);
}

static void *aac_decode(void *args)
{
    char            *filename = args;
    char            *xmmstitle=NULL;
    FILE            *file = NULL;
    faacDecHandle       decoder = 0;
    unsigned char       *buffer = 0;
    unsigned long       bufferconsumed = 0;
    unsigned long       samplerate = 0;
    unsigned char       channels;
    unsigned long       buffervalid = 0;
    TitleInput      *input;
    char            *temp = g_strdup(filename);
    char            *ext  = strrchr(temp, '.');

    printf("decoding...\n");
    pthread_mutex_lock(&mutex);
    clearWindowDatas();
    if ((file = fopen(filename, "rb")) == 0){
        printf("can't find file %s\n", filename);
        pthread_mutex_unlock(&mutex);
        pthread_exit(NULL);
    }
    if ((decoder = faacDecOpen()) == NULL){
        printf("Open Decoder Error\n");
        fclose(file);
        pthread_mutex_unlock(&mutex);
        pthread_exit(NULL);
  char 			*filename = args;
  char			*xmmstitle=NULL;
  FILE 			*file = NULL;
  faacDecHandle		decoder = 0;
  unsigned char		*buffer = 0;
  unsigned long		bufferconsumed = 0;
  unsigned long		samplerate = 0;
  unsigned long		lenght=0;
  char			channels;
  unsigned long		buffervalid = 0;
  TitleInput		*input;
  char 			*temp = g_strdup(filename);
  char			*ext  = strrchr(temp, '.');

  pthread_mutex_lock(&mutex);
  seekPosition=-1;
  clearWindowDatas();
  if((file = fopen(filename, "rb")) == 0){
    printf("can't find file %s\n", filename);
    pthread_mutex_unlock(&mutex);
    pthread_exit(NULL);
  }
  if(bSeek){
    checkADTSForSeeking(file, &positionTable, &lenght);
    if((aacType = getAacInfo(file)) ==-1){
      g_print("erreur getAAC\n");
      fclose(file);
      if(positionTable){
	free(positionTable); positionTable=0;
      }
      pthread_mutex_unlock(&mutex);
      pthread_exit(NULL);
    }
    if ((buffer = g_malloc(BUFFER_SIZE)) == NULL)
        printf("error g_malloc\n");
    buffervalid = fread(buffer, 1, BUFFER_SIZE, file);
// check for ID3 tag
        XMMS_NEW_TITLEINPUT(input);
        input->file_name = g_basename(temp);
        input->file_ext = ext ? ext+1 : NULL;
        input->file_path = temp;
    if (!strncmp(buffer, "ID3", 3)){
        int size = 0;

        printf("Song with a ID3Tagv2\n");
        readID3tag(filename);
        if(title)
        input->track_name = g_strdup(title);
        if(artist)
        input->performer = g_strdup(artist);
        if(genre)
        input->genre = g_strdup(genre);
        if(track)
        input->track_number = atoi(track);
        fseek(file, 0, SEEK_SET);
  }
  if((decoder = faacDecOpen()) == NULL){
    printf("Open Decoder Error\n");
    fclose(file);
    pthread_mutex_unlock(&mutex);
    pthread_exit(NULL);
  }
  if((buffer = g_malloc(BUFFER_SIZE)) == NULL){
    printf("error g_malloc\n");
    fclose(file);
    pthread_mutex_unlock(&mutex);
    pthread_exit(NULL);
  }

  if((buffervalid = fread(buffer, 1, BUFFER_SIZE, file))==0){
    printf("Error file NULL\n");
    g_free(buffer);
    fclose(file);
    pthread_mutex_unlock(&mutex);
    pthread_exit(NULL);
  }
  XMMS_NEW_TITLEINPUT(input);
  input->file_name = g_basename(temp);
  input->file_ext = ext ? ext+1 : NULL;
  input->file_path = temp;
  if(!strncmp(buffer, "ID3", 3)){
    int size = 0;

    readID3tag(filename);
    if(title)
      input->track_name = g_strdup(title);
    if(artist)
      input->performer = g_strdup(artist);
    if(genre)
      input->genre = g_strdup(genre);
    if(track)
      input->track_number = atoi(track);
    fseek(file, 0, SEEK_SET);
/*
** hum .. horrible hack taken from the winamp plugin to jump
** the tag, is there any id3 function to do this ???? hum... seems not :(
*/
        size = (buffer[6]<<21) | (buffer[7]<<14) | (buffer[8]<<7) | buffer[9];
        size+=10;
        fread(buffer, 1, size, file);
        buffervalid = fread(buffer, 1, BUFFER_SIZE, file);
    }
    xmmstitle = xmms_get_titlestring(xmms_get_gentitle_format(), input);
    if(xmmstitle == NULL)
        xmmstitle = g_strdup(input->file_name);
    g_free(temp);
    g_free(input->performer);
    g_free(input->album_name);
    g_free(input->track_name);
    g_free(input->genre);
    g_free(input);
    bufferconsumed = faacDecInit(decoder, buffer, buffervalid, &samplerate, &channels);
//  printf("song with %d channels at %d Hz\n", channels, samplerate);
    if((bOutputOpen = aac_ip.output->open_audio(FMT_S16_NE, samplerate, channels)) == FALSE){
        printf("Output Error\n");
        g_free(buffer);
        buffer=0;
        faacDecClose(decoder);
        fclose(file);
        aac_ip.output->close_audio();
        pthread_mutex_unlock(&mutex);
        pthread_exit(NULL);
    }
    aac_ip.set_info(xmmstitle, -1, -1, samplerate, channels);
    aac_ip.output->flush(0);

    while(bPlaying && buffervalid > 0){
        faacDecFrameInfo    finfo;
        unsigned long       samplesdecoded;
        char            *sample_buffer = NULL;

        if(bufferconsumed > 0){
        memmove(buffer, &buffer[bufferconsumed], buffervalid-bufferconsumed);
            buffervalid -= bufferconsumed;
            buffervalid += fread(&buffer[buffervalid], 1, BUFFER_SIZE-buffervalid, file);
            bufferconsumed = 0;
        }
        sample_buffer = faacDecDecode(decoder, &finfo, buffer, buffervalid);
        if(finfo.error){
            buffervalid = 0;
            printf("FAAD2 Error %s\n", faacDecGetErrorMessage(finfo.error));
            printf("---Use Psystrip.exe on the file to avoid the ADTS error---\n");
        }
        bufferconsumed += finfo.bytesconsumed;
        samplesdecoded = finfo.samples;
        if((samplesdecoded<=0) && !sample_buffer){
            printf("error\n");
        }
        while(bPlaying && aac_ip.output->buffer_free() < (samplesdecoded<<1)){
            xmms_usleep(10000);
        }
        aac_ip.add_vis_pcm(aac_ip.output->written_time(), FMT_S16_LE, channels, samplesdecoded<<1, sample_buffer);
        aac_ip.output->write_audio(sample_buffer, samplesdecoded<<1);
    }
    while(bPlaying && aac_ip.output->buffer_playing()){
        xmms_usleep(10000);
    size = (buffer[6]<<21) | (buffer[7]<<14) | (buffer[8]<<7) | buffer[9];
    size+=10;
    fread(buffer, 1, size, file);
    if(bSeek){
      checkADTSForSeeking(file, &positionTable, &lenght);
      if((aacType = getAacInfo(file)) ==-1){
	printf("erreur getAAC\n");
	g_free(buffer); buffer=0;
	faacDecClose(decoder);
	fclose(file);
	aac_ip.output->close_audio();
	if(positionTable){
	  free(positionTable); positionTable=0;
	}
	pthread_mutex_unlock(&mutex);
	pthread_exit(NULL);
      }
      printf("AAC-%s Type\n", aacType?"MPEG2":"MPEG4");
    }
//  aac_ip.output->flush(0);
    aac_ip.output->buffer_free();
    aac_ip.output->close_audio();
    bPlaying = FALSE;
    bOutputOpen = FALSE;
    g_free(buffer);
    buffervalid = fread(buffer, 1, BUFFER_SIZE, file);
  }
  xmmstitle = xmms_get_titlestring(xmms_get_gentitle_format(), input);
  if(xmmstitle == NULL)
    xmmstitle = g_strdup(input->file_name);
  g_free(temp);
  g_free(input->performer);
  g_free(input->album_name);
  g_free(input->track_name);
  g_free(input->genre);
  g_free(input);

  bufferconsumed = faacDecInit(decoder, buffer, BUFFER_SIZE, &samplerate, &channels);
  if((bOutputOpen = aac_ip.output->open_audio(FMT_S16_NE, samplerate, channels)) == FALSE){
    printf("Output Error\n");
    g_free(buffer); buffer=0;
    faacDecClose(decoder);
    g_free(xmmstitle);
    fclose(file);
    printf("...ended\n");
    seek_pos = -1;
    aac_ip.output->close_audio();
    if(positionTable){
      free(positionTable); positionTable=0;
    }
    pthread_mutex_unlock(&mutex);
    pthread_exit(NULL);
  }
  if(bSeek){
    aac_ip.set_info(xmmstitle, lenght*1000, -1, samplerate, channels);
  }else{
    aac_ip.set_info(xmmstitle, -1, -1, samplerate, channels);
  }
  aac_ip.output->flush(0);  
  while(bPlaying && buffervalid > 0){
    faacDecFrameInfo	finfo;
    unsigned long		samplesdecoded;
    char			*sample_buffer = NULL;

    if(bSeek && seekPosition!=-1){
      fseek(file, positionTable[seekPosition], SEEK_SET);
      bufferconsumed=0;
      buffervalid = fread(buffer, 1, BUFFER_SIZE, file);
      aac_ip.output->flush(seekPosition*1000);
      seekPosition=-1;
    }
    if(bufferconsumed > 0){
      memmove(buffer, &buffer[bufferconsumed], buffervalid-bufferconsumed);
      buffervalid -= bufferconsumed;
      buffervalid += fread(&buffer[buffervalid], 1, BUFFER_SIZE-buffervalid, file);
      bufferconsumed = 0;
    }
    sample_buffer = faacDecDecode(decoder, &finfo, buffer, buffervalid);
    if(finfo.error){
      buffervalid = 0;
      printf("FAAD2 Error %s\n", faacDecGetErrorMessage(finfo.error));
      printf("---Use Psystrip.exe on the file to avoid the ADTS error---\n");
    }
    bufferconsumed += finfo.bytesconsumed;
    samplesdecoded = finfo.samples;
    if((samplesdecoded<=0) && !sample_buffer){
      printf("error\n");
    }
    while(bPlaying && aac_ip.output->buffer_free() < (samplesdecoded<<1)){
      xmms_usleep(10000);
    }
    aac_ip.add_vis_pcm(aac_ip.output->written_time(), FMT_S16_LE, channels, samplesdecoded<<1, sample_buffer);
    aac_ip.output->write_audio(sample_buffer, samplesdecoded<<1);
  }
  while(bPlaying && aac_ip.output->buffer_playing()){
    xmms_usleep(10000);
  }
  aac_ip.output->buffer_free();
  aac_ip.output->close_audio();
  bPlaying = FALSE;
  bOutputOpen = FALSE;
  g_free(buffer);
  faacDecClose(decoder);
  g_free(xmmstitle);
  fclose(file);
  seekPosition = -1;
  if(positionTable){
    free(positionTable); positionTable=0;
  }
  pthread_mutex_unlock(&mutex);
  pthread_exit(NULL);
}

static int aac_isFile(char *filename)
{
    char *extention = strrchr(filename, '.');
    if (extention && !strcasecmp(extention, ".aac")){
        return (1);
    }
    return(0);
  char *extention = strrchr(filename, '.');
  if (extention && !strcasecmp(extention, ".aac")){
    return (1);
  }
  return(0);
}

static void aac_about(void)
{
    GtkWidget *dialog, *button, *label, *label2;

    dialog = gtk_dialog_new();
    gtk_window_set_title(GTK_WINDOW(dialog), "About FAAD2 plugin");
    label = gtk_label_new(AAC_ABOUT);
    gtk_box_pack_start(GTK_BOX(GTK_DIALOG(dialog)->vbox), label, TRUE, TRUE, 0);
    gtk_widget_show(label);
    label2 = gtk_label_new(AAC_VERSION);
    gtk_box_pack_start(GTK_BOX(GTK_DIALOG(dialog)->vbox), label2, TRUE, TRUE, 0);
    gtk_widget_show(label2);
    button = gtk_button_new_with_label("close");
    gtk_signal_connect_object(GTK_OBJECT(button), "clicked", GTK_SIGNAL_FUNC(gtk_widget_destroy), GTK_OBJECT(dialog));
    gtk_box_pack_start(GTK_BOX(GTK_DIALOG(dialog)->action_area), button, FALSE, FALSE, 0);
    gtk_widget_show(button);
    gtk_widget_show(dialog);
  static GtkWidget	*aboutbox;

  if(aboutbox!=NULL)
    return;

  aboutbox = xmms_show_message(
		 "About MPEG2/4-AAC plugin",
		 "decoding engine : FAAD2 team\n"
		 "Plugin coder : ciberfred",
 	         "Ok", FALSE, NULL, NULL);
  gtk_signal_connect(GTK_OBJECT(aboutbox), "destroy",
		     GTK_SIGNAL_FUNC(gtk_widget_destroyed),
		     &aboutbox);
}


static  GtkWidget *checkbutton;
static  GtkWidget *window;
static void aac_configuration_save(GtkWidget *widget, gpointer data)
{
  ConfigFile	*cfg;
  bSeek = gtk_toggle_button_get_active(GTK_TOGGLE_BUTTON(checkbutton));
  cfg = xmms_cfg_open_default_file();
  xmms_cfg_write_boolean(cfg, "AAC", "seeking", bSeek);
  xmms_cfg_free(cfg);
  gtk_widget_destroy(window);
}

static void	aac_configuration(void)
{
  GtkWidget *vbox, *hbox;
  GtkWidget *NotaBene;
  GtkWidget *button2;

  window = gtk_window_new(GTK_WINDOW_DIALOG);
  gtk_signal_connect(GTK_OBJECT(window), "destroy",
		     GTK_SIGNAL_FUNC(gtk_widget_destroyed),
		     &window);
  gtk_window_set_title(GTK_WINDOW(window), "AAC Plugin Configuration");
  gtk_widget_set_usize(window, 220, 200);

  vbox = gtk_vbox_new(FALSE, 2);
  gtk_container_add(GTK_CONTAINER(window), vbox);

  NotaBene = gtk_text_new(NULL, NULL);
  GTK_WIDGET_UNSET_FLAGS (NotaBene, GTK_CAN_FOCUS);
  gtk_text_insert(GTK_TEXT(NotaBene), NULL, NULL, NULL,
                   "Remember that unable seeking"
		   " is not suitable for playing"
		   " file from network.\n"
		   "Seeking must read first all aac file before playing.",-1);
  gtk_box_pack_start(GTK_BOX(vbox), NotaBene, FALSE, FALSE, 0);

  checkbutton = gtk_check_button_new_with_label("Unable Seeking");
  gtk_toggle_button_set_active(GTK_TOGGLE_BUTTON(checkbutton), bSeek);
  gtk_box_pack_start(GTK_BOX(vbox), checkbutton, FALSE, FALSE, 0);

  hbox = gtk_hbutton_box_new();
  gtk_button_box_set_layout(GTK_BUTTON_BOX(hbox), GTK_BUTTONBOX_END);
  gtk_box_pack_start(GTK_BOX(vbox), hbox, FALSE, FALSE, 0);

  button2 = gtk_button_new_with_label ("Save");
  gtk_signal_connect_object(GTK_OBJECT(button2), "clicked",
			    GTK_SIGNAL_FUNC(aac_configuration_save),
			    GTK_OBJECT(window));
  gtk_box_pack_start(GTK_BOX(hbox), button2, FALSE, FALSE, 0);
  button2 = gtk_button_new_with_label ("Close");
  gtk_signal_connect_object(GTK_OBJECT(button2), "clicked",
			    GTK_SIGNAL_FUNC(gtk_widget_destroy),
			    GTK_OBJECT(window));
  gtk_box_pack_start(GTK_BOX(hbox), button2, FALSE, FALSE, 0);
  gtk_widget_show_all(window);
}