[Easytag-mailing] Re: [Patch] ... implement speex tag editing
- From: Pierre Marc Dumuid <pierre dumuid adelaide edu au>
- To: Pierre Marc Dumuid <pierre dumuid adelaide edu au>
- Cc: easytag gmail com, easytag-mailing lists sourceforge net
- Subject: [Easytag-mailing] Re: [Patch] ... implement speex tag editing
- Date: Sat Sep 3 15:22:48 2005
Oops, I forgot to attach the patch!!
Pierre Marc Dumuid wrote:
Hi Jerome Courderc,
Here's a patch to have speex editing working.. in easytag...
Cheers,
Pierre
P.S. I'm not on the mailing list so please CC any comments about this
patch to me...
diff -uar easytag-1.99.8/config.h.in easytag-1.99.8_comp/config.h.in
--- easytag-1.99.8/config.h.in 2005-08-26 06:12:19.000000000 +0930
+++ easytag-1.99.8_comp/config.h.in 2005-09-03 23:14:04.000000000 +0930
@@ -32,6 +32,9 @@
/* Define for Ogg Vorbis support */
#undef ENABLE_OGG
+/* Define for Speex support */
+#undef ENABLE_SPEEX
+
/* Package name for gettext */
#undef GETTEXT_PACKAGE
@@ -75,6 +78,9 @@
/* Define to 1 if you have the `ogg' library (-logg). */
#undef HAVE_LIBOGG
+/* Define to 1 if you have the `speex' library (-lspeex). */
+#undef HAVE_LIBSPEEX
+
/* Define to 1 if you have the `vorbis' library (-lvorbis). */
#undef HAVE_LIBVORBIS
diff -uar easytag-1.99.8/configure.in easytag-1.99.8_comp/configure.in
--- easytag-1.99.8/configure.in 2005-08-26 06:11:59.000000000 +0930
+++ easytag-1.99.8_comp/configure.in 2005-09-03 23:13:14.000000000 +0930
@@ -37,6 +37,10 @@
AC_HELP_STRING([--disable-ogg], [Disable support for Ogg Vorbis files (default=enabled)]),
, enable_ogg=yes)
+AC_ARG_ENABLE(speex,
+ AC_HELP_STRING([--disable-speex], [Disable support for Ogg Speex files (default=enabled)]),
+ , enable_speex=yes)
+
AC_ARG_ENABLE(flac,
AC_HELP_STRING([--disable-flac],[Disable support for FLAC files (default=enabled)]),
, enable_flac=yes)
@@ -89,6 +93,40 @@
echo "***"
fi
+dnl libSpeex library
+dnl check for system libspeex
+dnl Note that libvorbis is required for speex support, even if the user chooses --disable-speex
+if test "x$enable_speex" = "xyes"; then
+ dnl Library required for speex files, if not found 'enable_speex' is disabled
+ AC_CHECK_LIB(m, cos) dnl Patch from Christian Weisgerber
+ AC_CHECK_LIB(speex, speex_packet_to_header, , speex_available=yes)
+ if test "x$speex_available" = "xno"; then
+ AC_MSG_RESULT(no)
+ enable_flac="no"
+ echo "***"
+ echo "*** Warning: Speex file support disabled, speex missing"
+ echo "*** (Install speex, libogg and libvorbis libraries to enable it)"
+ echo "***"
+ elif test "x$ogg_available" = "xno"; then
+ AC_MSG_RESULT(no)
+ enable_flac="no"
+ echo "***"
+ echo "*** Warning: Speex file support disabled, libvorbis missing"
+ echo "*** (Install speex, libogg and libvorbis libraries to enable it)"
+ echo "***"
+ else
+ AC_MSG_RESULT(yes)
+ AC_DEFINE(ENABLE_SPEEX,1,[Define for Speex support])
+ fi
+else
+ AC_MSG_CHECKING(for Speex file support)
+ AC_MSG_RESULT(no)
+ echo "***"
+ echo "*** Speex file support disabled on commandline"
+ echo "*** (Install speex, libogg and libvorbis libraries, and use --enable-speex to enable it)"
+ echo "***"
+fi
+
dnl libFLAC library
dnl check for system libflac
dnl Note that libvorbis is required for flac support, even if the user chooses --disable-ogg
@@ -302,6 +340,7 @@
Id3lib version ..........: $ID3LIB_MAJOR.$ID3LIB_MINOR.$ID3LIB_PATCH
NLS/gettext .............: $USE_NLS
Ogg Vorbis file support .: $enable_ogg
+ Speex file support ......: $enable_speex
FLAC file support .......: $enable_flac $LIBFLAC_VERSION
MP4 file support ...... : $enable_mp4
Install path ............: $prefix
diff -uar easytag-1.99.8/src/et_core.h easytag-1.99.8_comp/src/et_core.h
--- easytag-1.99.8/src/et_core.h 2005-08-19 07:35:23.000000000 +0930
+++ easytag-1.99.8_comp/src/et_core.h 2005-09-03 23:24:24.000000000 +0930
@@ -115,10 +115,10 @@
MP3_FILE, // Mpeg audio Layer 3 : .mp3 (.mpg) (.mpga)
MP4_FILE, // Mpeg audio Layer 4 / AAC : .mp4 (.m4a) (.m4p)
OGG_FILE, // Ogg Vorbis audio : .ogg (.ogm)
+ SPEEX_FILE, // Speech audio files : .spx
FLAC_FILE, // FLAC (lossless) : .flac .fla
MPC_FILE, // MusePack : .mpc .mp+ .mpp
MAC_FILE, // Monkey's Audio (lossless) : .ape (.mac)
-// SPEEX_FILE, // Speech audio files : .spx
OFR_FILE, // OptimFROG (lossless) : .ofr .ofs
UNKNOWN_FILE
} ET_File_Type;
@@ -236,6 +236,9 @@
#ifdef ENABLE_OGG
{OGG_FILE, ".ogg", OGG_TAG},
#endif
+#ifdef ENABLE_SPEEX
+ {SPEEX_FILE, ".spx", OGG_TAG},
+#endif
#ifdef ENABLE_FLAC
{FLAC_FILE, ".flac", FLAC_TAG},
{FLAC_FILE, ".fla", FLAC_TAG},
@@ -253,7 +256,6 @@
{MP4_FILE, ".m4a", MP4_TAG}, // Implemented by Michael Ihde
{MP4_FILE, ".m4p", MP4_TAG}, // Implemented by Michael Ihde
#endif
-// {SPEEX_FILE, ".spx", OGG_TAG},
{UNKNOWN_FILE, "", UNKNOWN_TAG} /* This item must be placed to the end! */
};
diff -uar easytag-1.99.8/src/vcedit.c easytag-1.99.8_comp/src/vcedit.c
--- easytag-1.99.8/src/vcedit.c 2004-11-24 03:43:26.000000000 +1030
+++ easytag-1.99.8_comp/src/vcedit.c 2005-09-03 23:35:19.000000000 +0930
@@ -30,6 +30,7 @@
{
vcedit_state *state = malloc(sizeof(vcedit_state));
memset(state, 0, sizeof(vcedit_state));
+ state->oggtype = 0;
return state;
}
@@ -98,15 +99,20 @@
}
}
-static int _commentheader_out(vorbis_comment *vc, char *vendor, ogg_packet *op)
+static int _commentheader_out(vcedit_state *state, ogg_packet *op)
{
+ vorbis_comment *vc = state->vc;
+ char *vendor = state->vendor;
oggpack_buffer opb;
oggpack_writeinit(&opb);
- /* preamble */
- oggpack_write(&opb,0x03,8);
- _v_writestring(&opb,"vorbis", 6);
+ if (state->oggtype == VCEDIT_ISVORBIS)
+ {
+ /* preamble */
+ oggpack_write(&opb,0x03,8);
+ _v_writestring(&opb,"vorbis", 6);
+ }
/* vendor */
oggpack_write(&opb,strlen(vendor),32);
@@ -135,6 +141,10 @@
op->b_o_s=0;
op->e_o_s=0;
op->granulepos=0;
+ if (state->oggtype == VCEDIT_ISVORBIS)
+ {
+ op->packetno = 1;
+ }
oggpack_writeclear(&opb);
return 0;
@@ -191,6 +201,44 @@
}
}
+/* Next functions pulled straight from libvorbis,
+ */
+static void _v_readstring(oggpack_buffer *o,char *buf,int bytes){
+ while(bytes--){
+ *buf++=oggpack_read(o,8);
+ }
+}
+
+/* Next functions pulled straight from libvorbis, apart from one change
+ - disabled the EOP check
+ */
+static int _speex_unpack_comment(vorbis_comment *vc,oggpack_buffer *opb)
+{
+ int i;
+ int vendorlen=oggpack_read(opb,32);
+ if(vendorlen<0)goto err_out;
+
+ vc->vendor=_ogg_calloc(vendorlen+1,1);
+ _v_readstring(opb,vc->vendor,vendorlen);
+
+ vc->comments=oggpack_read(opb,32);
+ if(vc->comments<0)goto err_out;
+ vc->user_comments=_ogg_calloc(vc->comments+1,sizeof(*vc->user_comments));
+ vc->comment_lengths=_ogg_calloc(vc->comments+1, sizeof(*vc->comment_lengths));
+ for(i=0;i<vc->comments;i++){
+ int len=oggpack_read(opb,32);
+ if(len<0)goto err_out;
+ vc->comment_lengths[i]=len;
+ vc->user_comments[i]=_ogg_calloc(len+1,1);
+ _v_readstring(opb,vc->user_comments[i],len);
+ }
+// if(oggpack_read(opb,1)!=1)goto err_out; /* EOP check */
+ return(0);
+err_out:
+ vorbis_comment_clear(vc);
+ return(1);
+}
+
int vcedit_open(vcedit_state *state, FILE *in)
{
return vcedit_open_callbacks(state, (void *)in,
@@ -260,26 +308,52 @@
goto err;
}
- if(vorbis_synthesis_headerin(state->vi, state->vc, &header_main) < 0)
- {
- state->lasterror = _("Ogg bitstream does not contain vorbis data.");
- goto err;
- }
-
+ // We save the main header first, (it seems speex_packet_to_header munge's it??)
state->mainlen = header_main.bytes;
state->mainbuf = malloc(state->mainlen);
memcpy(state->mainbuf, header_main.packet, header_main.bytes);
- i = 0;
- header = &header_comments;
- while(i<2) {
- while(i<2) {
+ state->oggtype = 0;
+ int headerpackets = 0;
+#ifdef ENABLE_SPEEX
+ state->si = malloc(sizeof(SpeexHeader));
+ if((state->si = speex_packet_to_header((char*)(&header_main)->packet,(&header_main)->bytes)))
+ state->oggtype = VCEDIT_ISSPEEX;
+#endif
+ if(vorbis_synthesis_headerin(state->vi, state->vc, &header_main) == 0)
+ state->oggtype = VCEDIT_ISVORBIS;
+
+ if (!state->oggtype)
+ {
+ state->lasterror = _("Ogg bitstream contains neither speex or vorbis data.");
+ goto err;
+ }
+
+ switch (state->oggtype)
+ {
+ case VCEDIT_ISVORBIS:
+ header = &header_comments;
+ headerpackets = 3;
+ break;
+#ifdef ENABLE_SPEEX
+ case VCEDIT_ISSPEEX:
+ header = &header_comments;
+ headerpackets = 2 + state->si->extra_headers;
+ break;
+#endif
+ }
+ oggpack_buffer opb;
+ i = 1;
+ while(i<headerpackets)
+ {
+ while(i<headerpackets)
+ {
int result = ogg_sync_pageout(state->oy, &og);
if(result == 0) break; /* Too little data so far */
else if(result == 1)
{
ogg_stream_pagein(state->os, &og);
- while(i<2)
+ while(i< headerpackets)
{
result = ogg_stream_packetout(state->os, header);
if(result == 0) break;
@@ -288,16 +362,39 @@
state->lasterror = _("Corrupt secondary header.");
goto err;
}
- vorbis_synthesis_headerin(state->vi, state->vc, header);
- if(i==1)
+ switch (state->oggtype)
{
- state->booklen = header->bytes;
- state->bookbuf = malloc(state->booklen);
- memcpy(state->bookbuf, header->packet,
- header->bytes);
+ case VCEDIT_ISVORBIS:
+ vorbis_synthesis_headerin(state->vi, state->vc, header);
+ switch (i)
+ {
+ // 0 packet was the vorbis header
+ case 1:
+ header = &header_codebooks;
+ break;
+ case 2:
+ state->booklen = header->bytes;
+ state->bookbuf = malloc(state->booklen);
+ memcpy(state->bookbuf, header->packet,
+ header->bytes);
+ break;
+ }
+ break;
+ case VCEDIT_ISSPEEX:
+ switch (i)
+ {
+ // 0 packet was the speex header
+ case 1:
+ oggpack_readinit(&opb,header->packet,header->bytes);
+ _speex_unpack_comment(state->vc,&opb);
+ break;
+ default:
+ state->lasterror = _("Need to save extra headers - TODO!!");
+ goto err;
+ break;
+ }
}
i++;
- header = &header_codebooks;
}
}
}
@@ -356,7 +453,7 @@
ogg_stream_init(&streamout, state->serial);
- _commentheader_out(state->vc, state->vendor, &header_comments);
+ _commentheader_out(state, &header_comments);
/* 2002/10/22 - new code here for padded headers */
//header_comments.packet = realloc(header_comments.packet, header_comments.bytes + 1000);
@@ -365,7 +462,9 @@
ogg_stream_packetin(&streamout, &header_main);
ogg_stream_packetin(&streamout, &header_comments);
- ogg_stream_packetin(&streamout, &header_codebooks);
+
+ if (state->oggtype != VCEDIT_ISSPEEX)
+ ogg_stream_packetin(&streamout, &header_codebooks);
while((result = ogg_stream_flush(&streamout, &ogout)))
{
@@ -379,10 +478,6 @@
while(_fetch_next_packet(state, &op, &ogin))
{
- int size;
- size = _blocksize(state, &op);
- granpos += size;
-
if(needflush)
{
if(ogg_stream_flush(&streamout, &ogout))
@@ -409,27 +504,39 @@
}
needflush=needout=0;
+ if (state->oggtype == VCEDIT_ISVORBIS) {
+ int size;
+ size = _blocksize(state, &op);
+ granpos += size;
- if(op.granulepos == -1)
- {
- op.granulepos = granpos;
- ogg_stream_packetin(&streamout, &op);
- }
- else /* granulepos is set, validly. Use it, and force a flush to
- account for shortened blocks (vcut) when appropriate */
- {
- if(granpos > op.granulepos)
+ if(op.granulepos == -1)
{
- granpos = op.granulepos;
+ op.granulepos = granpos;
ogg_stream_packetin(&streamout, &op);
- needflush=1;
}
- else
+ else /* granulepos is set, validly. Use it, and force a flush to
+ account for shortened blocks (vcut) when appropriate */
{
- ogg_stream_packetin(&streamout, &op);
- needout=1;
- }
- }
+ if(granpos > op.granulepos)
+ {
+ granpos = op.granulepos;
+ ogg_stream_packetin(&streamout, &op);
+ needflush=1;
+ }
+ else
+ {
+ ogg_stream_packetin(&streamout, &op);
+ needout=1;
+ }
+ }
+ }
+
+ /* Don't know about granulepos for speex, will just assume the original
+ was appropriate. Not sure about the flushing?? */
+ else if (state->oggtype == VCEDIT_ISSPEEX) {
+ ogg_stream_packetin(&streamout, &op);
+ needout=1;
+ }
}
streamout.e_o_s = 1;
diff -uar easytag-1.99.8/src/vcedit.h easytag-1.99.8_comp/src/vcedit.h
--- easytag-1.99.8/src/vcedit.h 2003-09-03 17:28:05.000000000 +0930
+++ easytag-1.99.8_comp/src/vcedit.h 2005-09-03 23:23:07.000000000 +0930
@@ -19,6 +19,14 @@
#include <ogg/ogg.h>
#include <vorbis/codec.h>
+#ifdef ENABLE_SPEEX
+#include <speex/speex.h>
+#include <speex/speex_header.h>
+#endif
+
+#define VCEDIT_ISSPEEX 1
+#define VCEDIT_ISVORBIS 2
+
typedef size_t (*vcedit_read_func)(void *, size_t, size_t, void *);
typedef size_t (*vcedit_write_func)(const void *, size_t, size_t, void *);
@@ -26,8 +34,15 @@
ogg_sync_state *oy;
ogg_stream_state *os;
+ int oggtype;
+
vorbis_comment *vc;
- vorbis_info *vi;
+
+ vorbis_info *vi;
+
+#ifdef ENABLE_SPEEX
+ SpeexHeader *si;
+#endif
vcedit_read_func read;
vcedit_write_func write;
[
Date Prev][
Date Next] [
Thread Prev][
Thread Next]
[
Thread Index]
[
Date Index]
[
Author Index]