[cvs-annodex] commit (libfishsound): trunk/configure.ac trunk/include/fishsound/Makefile.am trunk/include/fishsound/constants.h trunk/include/fishsound/fishsound.h trunk/src/Makefile.am trunk/src/examples/Makefile.am trunk/src/examples/encode.c trunk/src/libfishsound/Makefile.am trunk/src/libfishsound/Version_script.in trunk/src/libfishsound/fishsound.c trunk/src/libfishsound/private.h trunk/src/libfishsound/speex.c trunk/src/libfishsound/vorbis.c trunk/src/tests/Makefile.am trunk/win32/libfishsound/libfishsound.def +trunk/src/tests/comment-test.c +trunk/src/tests/encdec-audio.c +trunk/src/tests/encdec-comments.c +trunk/src/tests/fs_tests.h

conrad nobody at lists.annodex.net
Wed May 5 20:17:08 EST 2004


Update of /annodex/libfishsound (new revision 68)

Added files:
   trunk/src/tests/comment-test.c
   trunk/src/tests/encdec-audio.c
   trunk/src/tests/encdec-comments.c
   trunk/src/tests/fs_tests.h

Modified files:
   trunk/configure.ac
   trunk/include/fishsound/Makefile.am
   trunk/include/fishsound/constants.h
   trunk/include/fishsound/fishsound.h
   trunk/src/Makefile.am
   trunk/src/examples/Makefile.am
   trunk/src/examples/encode.c
   trunk/src/libfishsound/Makefile.am
   trunk/src/libfishsound/Version_script.in
   trunk/src/libfishsound/fishsound.c
   trunk/src/libfishsound/private.h
   trunk/src/libfishsound/speex.c
   trunk/src/libfishsound/vorbis.c
   trunk/src/tests/Makefile.am
   trunk/win32/libfishsound/libfishsound.def

Log Message:
Added support for comment packets, tests, and various bugfixes.
	* Added fish_sound_comment_() API, <fishsound/comments.h>
	* Fixed segv bug in decoding stereo Speex to non-interleaved
	* Added test for encode/decode pipeline with a variety of
	  combinations of format, interleave, samplerate, channels and
	  buffer size.
	* Added tests for comments data structure and encode/decode pipeline


Modified: trunk/configure.ac
===================================================================
--- trunk/configure.ac	2004-05-03 22:27:11 UTC (rev 67)
+++ trunk/configure.ac	2004-05-05 10:17:08 UTC (rev 68)
@@ -60,6 +60,7 @@
 else
     AC_DEFINE(FS_DECODE, [0], [Do not build decoding support])
 fi
+AM_CONDITIONAL(FS_DECODE, [test "x${ac_enable_decode}" = "xyes"])
 
 dnl
 dnl  Configuration option for building of encoding support.
@@ -75,6 +76,7 @@
 else
     AC_DEFINE(FS_ENCODE, [0], [Do not build encoding support])
 fi
+AM_CONDITIONAL(FS_ENCODE, [test "x${ac_enable_encode}" = "xyes"])
 
 dnl
 dnl  Check decode/encode option sanity

Modified: trunk/include/fishsound/Makefile.am
===================================================================
--- trunk/include/fishsound/Makefile.am	2004-05-03 22:27:11 UTC (rev 67)
+++ trunk/include/fishsound/Makefile.am	2004-05-05 10:17:08 UTC (rev 68)
@@ -2,5 +2,5 @@
 
 # Include files to install
 includedir = $(prefix)/include/fishsound
-include_HEADERS = fishsound.h constants.h
+include_HEADERS = fishsound.h comments.h constants.h
 

Modified: trunk/include/fishsound/constants.h
===================================================================
--- trunk/include/fishsound/constants.h	2004-05-03 22:27:11 UTC (rev 67)
+++ trunk/include/fishsound/constants.h	2004-05-05 10:17:08 UTC (rev 68)
@@ -82,11 +82,23 @@
   /** No error */
   FISH_SOUND_OK                         = 0,
 
+  /** generic error */
+  FISH_SOUND_ERR_GENERIC                = -1,
+
+  /** Not a valid FishSound* handle */
+  FISH_SOUND_ERR_BAD                    = -2,
+
+  /** The requested operation is not suitable for this FishSound* handle */
+  FISH_SOUND_ERR_INVALID                = -3,
+
   /** Functionality disabled at build time */
   FISH_SOUND_ERR_DISABLED               = -10,
 
   /** Too few bytes passed to fish_sound_identify() */
-  FISH_SOUND_ERR_SHORT_IDENTIFY         = -20
+  FISH_SOUND_ERR_SHORT_IDENTIFY         = -20,
+
+  /** Comment violates VorbisComment restrictions */
+  FISH_SOUND_ERR_COMMENT_INVALID        = -21
 } FishSoundError;
 
 #endif /* __FISH_SOUND_CONSTANTS_H__ */

Modified: trunk/include/fishsound/fishsound.h
===================================================================
--- trunk/include/fishsound/fishsound.h	2004-05-03 22:27:11 UTC (rev 67)
+++ trunk/include/fishsound/fishsound.h	2004-05-05 10:17:08 UTC (rev 68)
@@ -609,4 +609,6 @@
 }
 #endif
 
+#include <fishsound/comments.h>
+
 #endif /* __FISH_SOUND_H__ */

Modified: trunk/src/Makefile.am
===================================================================
--- trunk/src/Makefile.am	2004-05-03 22:27:11 UTC (rev 67)
+++ trunk/src/Makefile.am	2004-05-05 10:17:08 UTC (rev 68)
@@ -1,3 +1,3 @@
 ## Process this file with automake to produce Makefile.in
 
-SUBDIRS = libfishsound tests examples
+SUBDIRS = libfishsound examples tests

Modified: trunk/src/examples/Makefile.am
===================================================================
--- trunk/src/examples/Makefile.am	2004-05-03 22:27:11 UTC (rev 67)
+++ trunk/src/examples/Makefile.am	2004-05-05 10:17:08 UTC (rev 68)
@@ -9,23 +9,27 @@
 FISHSOUND_LIBS = $(FISHSOUNDDIR)/libfishsound.la $(VORBIS_LIBS) $(SPEEX_LIBS)
 
 if HAVE_OGGZ
-oggz_examples = identify
+oggz_examples = identify fishsound-info
 
 if HAVE_LIBSNDFILE1
-oggz_sndfile_examples = decode encode
+oggz_sndfile_examples = fishsound-decode fishsound-encode
 endif
 
 endif
 
 # Programs to build
-noinst_PROGRAMS = $(oggz_examples) $(oggz_sndfile_examples)
+#noinst_PROGRAMS = $(oggz_examples) $(oggz_sndfile_examples)
+bin_PROGRAMS = $(oggz_examples) $(oggz_sndfile_examples)
 
 identify_SOURCES = identify.c
 identify_LDADD = $(FISHSOUND_LIBS) $(OGGZ_LIBS)
 
-decode_SOURCES = decode.c
-decode_LDADD = $(FISHSOUND_LIBS) $(OGGZ_LIBS) $(SNDFILE_LIBS)
+fishsound_info_SOURCES = fishsound-info.c
+fishsound_info_LDADD = $(FISHSOUND_LIBS) $(OGGZ_LIBS)
 
-encode_SOURCES = encode.c
-encode_LDADD = $(FISHSOUND_LIBS) $(OGGZ_LIBS) $(SNDFILE_LIBS)
+fishsound_decode_SOURCES = decode.c
+fishsound_decode_LDADD = $(FISHSOUND_LIBS) $(OGGZ_LIBS) $(SNDFILE_LIBS)
 
+fishsound_encode_SOURCES = encode.c
+fishsound_encode_LDADD = $(FISHSOUND_LIBS) $(OGGZ_LIBS) $(SNDFILE_LIBS)
+

Modified: trunk/src/examples/encode.c
===================================================================
--- trunk/src/examples/encode.c	2004-05-03 22:27:11 UTC (rev 67)
+++ trunk/src/examples/encode.c	2004-05-05 10:17:08 UTC (rev 68)
@@ -119,6 +119,9 @@
 
   fish_sound_set_interleave (fsound, 1);
 
+  fish_sound_comment_add_byname (fsound, "Author", "crazy fish heads");
+  fish_sound_comment_add_byname (fsound, "FWOARR!", NULL);
+
   while (sf_readf_float (sndfile, pcm, 1024) > 0) {
     fish_sound_encode (fsound, (float **)pcm, 1024);
     while ((n = oggz_write (oggz, 1024)) > 0);

Modified: trunk/src/libfishsound/Makefile.am
===================================================================
--- trunk/src/libfishsound/Makefile.am	2004-05-03 22:27:11 UTC (rev 67)
+++ trunk/src/libfishsound/Makefile.am	2004-05-05 10:17:08 UTC (rev 68)
@@ -12,8 +12,10 @@
 libfishsound_la_SOURCES = \
 	fishsound.c \
 	private.h \
+	comments.c \
 	speex.c \
 	vorbis.c \
+	fs_vector.c fs_vector.h \
 	fs_compat.h
 
 libfishsound_la_LDFLAGS = -version-info @SHARED_VERSION_INFO@ @SHLIB_VERSION_ARG@

Modified: trunk/src/libfishsound/Version_script.in
===================================================================
--- trunk/src/libfishsound/Version_script.in	2004-05-03 22:27:11 UTC (rev 67)
+++ trunk/src/libfishsound/Version_script.in	2004-05-05 10:17:08 UTC (rev 68)
@@ -22,6 +22,16 @@
 		fish_sound_set_interleave;
 		fish_sound_get_frameno;
 		fish_sound_set_frameno;
+
+		fish_sound_comment_get_vendor;
+		fish_sound_comment_first;
+		fish_sound_comment_first_byname;
+		fish_sound_comment_next;
+		fish_sound_comment_next_byname;
+		fish_sound_comment_add;
+		fish_sound_comment_add_byname;
+		fish_sound_comment_remove;
+		fish_sound_comment_remove_byname;
         local:
                 *;
 };

Modified: trunk/src/libfishsound/fishsound.c
===================================================================
--- trunk/src/libfishsound/fishsound.c	2004-05-03 22:27:11 UTC (rev 67)
+++ trunk/src/libfishsound/fishsound.c	2004-05-05 10:17:08 UTC (rev 68)
@@ -106,6 +106,8 @@
   fsound->callback = NULL;
   fsound->user_data = NULL;
 
+  fish_sound_comments_init (fsound);
+
   if (mode == FISH_SOUND_DECODE) {
     fsound->info.samplerate = 0;
     fsound->info.channels = 0;

Modified: trunk/src/libfishsound/private.h
===================================================================
--- trunk/src/libfishsound/private.h	2004-05-03 22:27:11 UTC (rev 67)
+++ trunk/src/libfishsound/private.h	2004-05-05 10:17:08 UTC (rev 68)
@@ -36,6 +36,7 @@
 #include <stdlib.h>
 
 #include "fs_compat.h"
+#include "fs_vector.h"
 
 #include <fishsound/constants.h>
 
@@ -47,6 +48,7 @@
 typedef struct _FishSoundInfo FishSoundInfo;
 typedef struct _FishSoundCodec FishSoundCodec;
 typedef struct _FishSoundFormat FishSoundFormat;
+typedef struct _FishSoundComment FishSoundComment;
 
 typedef int         (*FSCodecIdentify) (unsigned char * buf, long bytes);
 typedef FishSound * (*FSCodecInit) (FishSound * fsound);
@@ -81,6 +83,11 @@
   int format;
 };
 
+struct _FishSoundComment {
+  char * name;
+  char * value;
+};
+
 struct _FishSound {
   /** FISH_SOUND_DECODE or FISH_SOUND_ENCODE */
   FishSoundMode mode;
@@ -102,6 +109,10 @@
 
   /** user data for encode/decode callback */
   void * user_data; 
+
+  /** The comments */
+  char * vendor;
+  FishSoundVector * comments;
 };
 
 struct _FishSoundFormat {
@@ -116,9 +127,32 @@
 typedef int (*FishSoundEncoded) (FishSound * fsound, unsigned char * buf,
 				 long bytes, void * user_data);
 
+/* data */
 extern FishSoundCodec fish_sound_vorbis;
 extern FishSoundCodec fish_sound_speex;
 
+/* comments */
+int fish_sound_comments_init (FishSound * fsound);
+int fish_sound_comments_decode (FishSound * fsound, unsigned char * buf,
+				long bytes);
+long fish_sound_comments_encode (FishSound * fsound, unsigned char * buf,
+				 long length);
+
+/**
+ * Set the vendor string.
+ * \param fsound A FishSound* handle (created with FISH_SOUND_ENCODE)
+ * \param vendor The vendor string.
+ * \retval 0 Success
+ * \retval FISH_SOUND_ERR_BAD \a fsound is not a valid FishSound* handle
+ * \retval FISH_SOUND_ERR_INVALID Operation not suitable for this FishSound
+ */
+int
+fish_sound_comment_set_vendor (FishSound * fsound, const char * vendor);
+
+const FishSoundComment * fish_sound_comment_first (FishSound * fsound);
+const FishSoundComment *
+fish_sound_comment_next (FishSound * fsound, const FishSoundComment * comment);
+
 /* inline functions */
 
 static inline void
@@ -126,10 +160,12 @@
 		  long frames, int channels, float mult_factor)
 {
   int i, j;
+  float * d, * s = (float *)src;
 
   for (i = 0; i < frames; i++) {
     for (j = 0; j < channels; j++) {
-      dest[j][i] = src[i][j] * mult_factor;
+      d = dest[j];
+      d[i] = s[i*channels + j] * mult_factor;
     }
   }
 }

Modified: trunk/src/libfishsound/speex.c
===================================================================
--- trunk/src/libfishsound/speex.c	2004-05-03 22:27:11 UTC (rev 67)
+++ trunk/src/libfishsound/speex.c	2004-05-05 10:17:08 UTC (rev 68)
@@ -49,6 +49,11 @@
 #include <speex_stereo.h>
 #include <speex_callbacks.h>
 
+/* Format for the vendor string: "Encoded with Speex VERSION", where VERSION
+ * is the libspeex version as read from a newly-generated Speex header.
+ */
+#define VENDOR_FORMAT "Encoded with Speex %s"
+
 #define DEFAULT_ENH_ENABLED 1
 
 #define MAX_FRAME_BYTES 2000
@@ -264,8 +269,11 @@
 
     if (fss->nframes == 0) fss->nframes = 1;
 
+  } else if (fss->packetno == 1) {
+    /* Comments */
+    fish_sound_comments_decode (fsound, buf, bytes);
   } else if (fss->packetno <= 1+fss->extra_headers) {
-    /* XXX: metadata etc. */
+    /* Unknown extra headers */
   } else {
     speex_bits_read_from (&fss->bits, (char *)buf, (int)bytes);
 
@@ -324,7 +332,7 @@
   FishSoundSpeexInfo * fss = (FishSoundSpeexInfo *)fsound->codec_data;
   SpeexMode * mode = NULL;
   SpeexHeader header;
-  char * buf;
+  unsigned char * buf;
   int bytes;
 
   /* XXX: set wb, nb, uwb modes */
@@ -340,15 +348,23 @@
 
   if (fsound->callback) {
     FishSoundEncoded encoded = (FishSoundEncoded)fsound->callback;
+    char vendor_string[128];
 
     /* header */
-    buf = speex_header_to_packet (&header, &bytes);    
-    encoded (fsound, (unsigned char *)buf, (long)bytes, fsound->user_data);
+    buf = (unsigned char *) speex_header_to_packet (&header, &bytes);    
+    encoded (fsound, buf, (long)bytes, fsound->user_data);
     fss->packetno++;
     free (buf);
 
-    /* XXX: and comments */
-    encoded (fsound, NULL, 0, fsound->user_data);
+    /* comments */
+    snprintf (vendor_string, 128, VENDOR_FORMAT, header.speex_version);
+    fish_sound_comment_set_vendor (fsound, vendor_string);
+    bytes = fish_sound_comments_encode (fsound, NULL, 0);
+    buf = malloc (bytes);
+    bytes = fish_sound_comments_encode (fsound, buf, bytes);
+    encoded (fsound, buf, (long)bytes, fsound->user_data);
+    fss->packetno++;
+    free (buf);
   }
 
   speex_encoder_ctl (fss->st, SPEEX_SET_SAMPLING_RATE,

Modified: trunk/src/libfishsound/vorbis.c
===================================================================
--- trunk/src/libfishsound/vorbis.c	2004-05-03 22:27:11 UTC (rev 67)
+++ trunk/src/libfishsound/vorbis.c	2004-05-05 10:17:08 UTC (rev 68)
@@ -197,6 +197,7 @@
   op.packetno = fsv->packetno;
 
   if (fsv->packetno < 3) {
+
     if ((ret = vorbis_synthesis_headerin (&fsv->vi, &fsv->vc, &op)) == 0) {
       if (fsv->vi.rate != 0) {
 #ifdef DEBUG
@@ -208,7 +209,12 @@
       }
     }
 
-    if (fsv->packetno == 2) {
+    /* Decode comments from packet 1. Vorbis has 7 bytes of marker at the
+     * start of vorbiscomment packet. */
+    if (fsv->packetno == 1 && bytes > 7 && buf[0] == 0x03 &&
+	!strncmp ((char *)&buf[1], "vorbis", 6)) {
+      fish_sound_comments_decode (fsound, buf+7, bytes-7);
+    } else if (fsv->packetno == 2) {
       vorbis_synthesis_init (&fsv->vd, &fsv->vi);
       vorbis_block_init (&fsv->vd, &fsv->vb);
     }
@@ -258,6 +264,7 @@
 fs_vorbis_enc_headers (FishSound * fsound)
 {
   FishSoundVorbisInfo * fsv = (FishSoundVorbisInfo *)fsound->codec_data;
+  const FishSoundComment * comment;
   ogg_packet header;
   ogg_packet header_comm;
   ogg_packet header_code;
@@ -268,10 +275,22 @@
      third header holds the bitstream codebook.  We merely need to
      make the headers, then pass them to libvorbis one at a time;
      libvorbis handles the additional Ogg bitstream constraints */
+
+  /* Update the comments */
+  for (comment = fish_sound_comment_first (fsound); comment;
+       comment = fish_sound_comment_next (fsound, comment)) {
+#ifdef DEBUG
+    fprintf (stderr, "fs_vorbis_enc_headers: %s = %s\n",
+	     comment->name, comment->value);
+#endif
+    vorbis_comment_add_tag (&fsv->vc, comment->name, comment->value);
+  }
   
+  /* Generate the headers */
   vorbis_analysis_headerout(&fsv->vd, &fsv->vc,
 			    &header, &header_comm, &header_code);
   
+  /* Pass the generated headers to the user */
   if (fsound->callback) {
     FishSoundEncoded encoded = (FishSoundEncoded)fsound->callback;
     
@@ -318,7 +337,6 @@
   FishSoundVorbisInfo * fsv = (FishSoundVorbisInfo *)fsound->codec_data;
   float ** vpcm;
   long len, remaining = frames;
-  int i, j;
   float * d = (float *)pcm;
 
   if (fsv->packetno == 0) {
@@ -331,12 +349,7 @@
     /* expose the buffer to submit data */
     vpcm = vorbis_analysis_buffer (&fsv->vd, 1024);
 
-    /*_fs_deinterleave (p, vpcm, len, fsound->info.channels, 1.0);*/
-    for (i = 0; i < fsound->info.channels; i++) {
-      for (j = 0; j < len; j++) {
-	vpcm[i][j] = d[j*fsound->info.channels + i];
-      }
-    }
+    _fs_deinterleave ((float **)d, vpcm, len, fsound->info.channels, 1.0);
 
     d += (len * fsound->info.channels);
 

Modified: trunk/src/tests/Makefile.am
===================================================================
--- trunk/src/tests/Makefile.am	2004-05-03 22:27:11 UTC (rev 67)
+++ trunk/src/tests/Makefile.am	2004-05-05 10:17:08 UTC (rev 68)
@@ -4,9 +4,33 @@
 
 INCLUDES = -I$(top_srcdir)/include
 
+FISHSOUNDDIR = ../libfishsound
+FISHSOUND_LIBS = $(FISHSOUNDDIR)/libfishsound.la $(VORBIS_LIBS) $(SPEEX_LIBS)
+
 # Test programs
 
-#xTESTS = 
+test: check
 
-#noinst_PROGRAMS = $(xTESTS)
+if FS_ENCODE
+encode_tests = comment-test
+endif
 
+if FS_DECODE
+if FS_ENCODE
+encdec_tests = encdec-comments encdec-audio
+endif
+endif
+
+TESTS = $(encode_tests) $(decode_tests) $(encdec_tests)
+
+noinst_PROGRAMS = $(TESTS)
+noinst_HEADERS = fs_tests.h
+
+comment_test_SOURCES = comment-test.c
+comment_test_LDADD = $(FISHSOUND_LIBS)
+
+encdec_comments_SOURCES = encdec-comments.c
+encdec_comments_LDADD = $(FISHSOUND_LIBS)
+
+encdec_audio_SOURCES = encdec-audio.c
+encdec_audio_LDADD = $(FISHSOUND_LIBS)
\ No newline at end of file

Added: trunk/src/tests/comment-test.c
===================================================================
--- trunk/src/tests/comment-test.c	2004-05-03 22:27:11 UTC (rev 67)
+++ trunk/src/tests/comment-test.c	2004-05-05 10:17:08 UTC (rev 68)
@@ -0,0 +1,221 @@
+/*
+   Copyright (C) 2003 Commonwealth Scientific and Industrial Research
+   Organisation (CSIRO) Australia
+
+   Redistribution and use in source and binary forms, with or without
+   modification, are permitted provided that the following conditions
+   are met:
+
+   - Redistributions of source code must retain the above copyright
+   notice, this list of conditions and the following disclaimer.
+
+   - Redistributions in binary form must reproduce the above copyright
+   notice, this list of conditions and the following disclaimer in the
+   documentation and/or other materials provided with the distribution.
+
+   - Neither the name of CSIRO Australia nor the names of its
+   contributors may be used to endorse or promote products derived from
+   this software without specific prior written permission.
+
+   THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
+   ``AS IS'' AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
+   LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A
+   PARTICULAR PURPOSE ARE DISCLAIMED.  IN NO EVENT SHALL THE ORGANISATION OR
+   CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL,
+   EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO,
+   PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR
+   PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF
+   LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING
+   NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
+   SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+*/
+
+#include "config.h"
+
+#include <stdio.h>
+#include <stdlib.h>
+#include <string.h>
+
+#include <fishsound/fishsound.h>
+
+#include "fs_tests.h"
+
+#define ARTIST1 "Trout Junkies"
+#define ARTIST2 "DJ Fugu"
+#define COPYRIGHT "Copyright (C) 2004. Some Rights Reserved."
+#define LICENSE "Creative Commons Attribute Share-Alike v1.0"
+#define COMMENT "Unstructured comments are evil."
+
+static FishSound * fsound;
+
+int
+main (int argc, char * argv[])
+{
+  FishSoundInfo fsinfo;
+  const FishSoundComment * comment, * comment2;
+  FishSoundComment mycomment;
+  int err;
+
+  fsinfo.samplerate = 16000;
+  fsinfo.channels = 1;
+  /* The format doesn't really matter as we're not actually
+   * going to encode any audio, so just ensure we can
+   * set this to something that's configured.
+   */
+#if HAVE_VORBIS
+  fsinfo.format = FISH_SOUND_VORBIS;
+#else
+  fsinfo.format = FISH_SOUND_SPEEX;
+#endif
+
+#if FS_ENCODE
+  INFO ("Initializing FishSound for comments (encode)");
+  fsound = fish_sound_new (FISH_SOUND_ENCODE, &fsinfo);
+
+  INFO ("+ Testing add of invalid unstructured COMMENT byname");
+  err = fish_sound_comment_add_byname (fsound, COMMENT, NULL);
+  if (err != FISH_SOUND_ERR_COMMENT_INVALID)
+    FAIL ("Invalid comment not detected");
+
+  INFO ("+ Testing add of invalid unstructured COMMENT from local storage");
+  mycomment.name = COMMENT;
+  mycomment.value = NULL;
+  err = fish_sound_comment_add (fsound, &mycomment);
+  if (err != FISH_SOUND_ERR_COMMENT_INVALID)
+    FAIL ("Invalid comment not detected");
+
+  INFO ("+ Adding ARTIST1 byname");
+  err = fish_sound_comment_add_byname (fsound, "ARTIST", ARTIST1);
+  if (err < 0) FAIL ("Operation failed");
+
+  INFO ("+ Adding COPYRIGHT byname");
+  err = fish_sound_comment_add_byname (fsound, "COPYRIGHT", COPYRIGHT);
+  if (err < 0) FAIL ("Operation failed");
+
+  INFO ("+ Retrieving first (expect ARTIST1)");
+  comment = fish_sound_comment_first (fsound);
+
+  if (comment == NULL)
+    FAIL ("Recently inserted ARTIST1 not retrieved");
+
+  if (strcmp (comment->name, "ARTIST"))
+    FAIL ("Incorrect ARTIST1 name found");
+
+  if (strcmp (comment->value, ARTIST1))
+    FAIL ("Incorrect ARTIST1 value found");
+
+  INFO ("+ Retrieving next (expect COPYRIGHT)");
+  comment = fish_sound_comment_next (fsound, comment);
+
+  if (comment == NULL)
+    FAIL ("Recently inserted COPYRIGHT not retrieved");
+
+  if (strcmp (comment->name, "COPYRIGHT"))
+    FAIL ("Incorrect COPYRIGHT name found");
+
+  if (strcmp (comment->value, COPYRIGHT))
+    FAIL ("Incorrect COPYRIGHT value found");
+
+  INFO ("+ Checking comments termination");
+  comment2 = fish_sound_comment_next (fsound, comment);
+
+  if (comment2 != NULL)
+    FAIL ("Comments unterminated");
+
+  INFO ("+ Adding LICENSE from local storage");
+  mycomment.name = "LICENSE";
+  mycomment.value = LICENSE;
+  err = fish_sound_comment_add (fsound, &mycomment);
+  if (err < 0) FAIL ("Operation failed");
+
+  INFO ("+ Retrieving next (expect LICENSE)");
+  comment = fish_sound_comment_next (fsound, comment);
+
+  if (comment == NULL)
+    FAIL ("Recently inserted LICENSE not retrieved");
+
+  if (comment == &mycomment)
+    FAIL ("Recently inserted LICENSE not restored");
+
+  if (strcmp (comment->name, "LICENSE"))
+    FAIL ("Incorrect LICENSE name found");
+
+  if (strcmp (comment->value, LICENSE))
+    FAIL ("Incorrect LICENSE value found");
+
+  INFO ("+ Adding ARTIST2 byname");  
+  err = fish_sound_comment_add_byname (fsound, "ARTIST", ARTIST2);
+  if (err < 0) FAIL ("Operation failed");
+
+  INFO ("+ Retrieving first ARTIST (expect ARTIST1)");
+  comment = fish_sound_comment_first_byname (fsound, "ARTIST");
+
+  if (comment == NULL)
+    FAIL ("Recently inserted ARTIST1 not retrieved");
+
+  if (strcmp (comment->name, "ARTIST"))
+    FAIL ("Incorrect ARTIST1 name found");
+
+  if (strcmp (comment->value, ARTIST1))
+    FAIL ("Incorrect ARTIST1 value found");
+
+  INFO ("+ Retrieving next ARTIST (expect ARTIST2)");
+  comment = fish_sound_comment_next_byname (fsound, comment);
+
+  if (comment == NULL)
+    FAIL ("Recently inserted ARTIST2 not retrieved");
+
+  if (strcmp (comment->name, "ARTIST"))
+    FAIL ("Incorrect ARTIST2 name found");
+
+  if (strcmp (comment->value, ARTIST2))
+    FAIL ("Incorrect ARTIST2 value found");
+
+  INFO ("+ Removing LICENSE byname");
+  err = fish_sound_comment_remove_byname (fsound, "LICENSE");
+  if (err != 1) FAIL ("Operation failed");
+
+  INFO ("+ Attempting to retrieve LICENSE");
+  comment = fish_sound_comment_first_byname (fsound, "LICENSE");
+
+  if (comment != NULL)
+    FAIL ("Removed comment incorrectly retrieved");
+
+  INFO ("+ Removing COPYRIGHT from local storage");
+  mycomment.name = "COPYRIGHT";
+  mycomment.value = COPYRIGHT;
+  err = fish_sound_comment_remove (fsound, &mycomment);
+  if (err != 1) FAIL ("Operation failed");
+
+  INFO ("+ Attempting to retrieve COPYRIGHT");
+  comment = fish_sound_comment_first_byname (fsound, "COPYRIGHT");
+
+  if (comment != NULL)
+    FAIL ("Removed comment incorrectly retrieved");
+
+  INFO ("Deleting FishSound (encode)");
+  fish_sound_delete (fsound);
+#endif /* FS_ENCODE */
+
+#if FS_DECODE
+  INFO ("Initializing FishSound for comments (decode)");
+  fsound = fish_sound_new (FISH_SOUND_DECODE, &fsinfo);
+
+  INFO ("+ Adding ARTIST1 byname (invalid for decode)");
+  err = fish_sound_comment_add_byname (fsound, "ARTIST", ARTIST1);
+
+  if (err == 0)
+    FAIL ("Operation disallowed");
+
+  INFO ("+ Removing ARTIST byname (invalid for decode)");
+  err = fish_sound_comment_remove_byname (fsound, "ARTIST");
+
+  if (err == 0)
+    FAIL ("Operation disallowed");
+
+  INFO ("Deleteing FishSound (decode)");
+  fish_sound_delete (fsound);
+#endif
+
+  exit (0);
+}

Added: trunk/src/tests/encdec-audio.c
===================================================================
--- trunk/src/tests/encdec-audio.c	2004-05-03 22:27:11 UTC (rev 67)
+++ trunk/src/tests/encdec-audio.c	2004-05-05 10:17:08 UTC (rev 68)
@@ -0,0 +1,195 @@
+/*
+   Copyright (C) 2003 Commonwealth Scientific and Industrial Research
+   Organisation (CSIRO) Australia
+
+   Redistribution and use in source and binary forms, with or without
+   modification, are permitted provided that the following conditions
+   are met:
+
+   - Redistributions of source code must retain the above copyright
+   notice, this list of conditions and the following disclaimer.
+
+   - Redistributions in binary form must reproduce the above copyright
+   notice, this list of conditions and the following disclaimer in the
+   documentation and/or other materials provided with the distribution.
+
+   - Neither the name of CSIRO Australia nor the names of its
+   contributors may be used to endorse or promote products derived from
+   this software without specific prior written permission.
+
+   THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
+   ``AS IS'' AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
+   LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A
+   PARTICULAR PURPOSE ARE DISCLAIMED.  IN NO EVENT SHALL THE ORGANISATION OR
+   CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL,
+   EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO,
+   PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR
+   PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF
+   LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING
+   NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
+   SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+*/
+
+#include "config.h"
+
+#include <stdio.h>
+#include <stdlib.h>
+#include <string.h>
+
+#include <fishsound/fishsound.h>
+
+#include "fs_tests.h"
+
+#define DEBUG
+
+typedef struct {
+  FishSound * encoder;
+  FishSound * decoder;
+  float ** pcm;
+} FS_EncDec;
+
+static int
+decoded (FishSound * fsound, float ** pcm, long frames, void * user_data)
+{
+  /* Boo! */
+  return 0;
+}
+
+static int
+encoded (FishSound * fsound, unsigned char * buf, long bytes, void * user_data)
+{
+  FS_EncDec * ed = (FS_EncDec *) user_data;
+  fish_sound_decode (ed->decoder, buf, bytes);
+  return 0;
+}
+
+/* Fill a PCM buffer with a squarish wave */
+static void
+fs_fill_square (float * pcm, int length)
+{
+  float value = 0.5;
+  int i;
+
+  for (i = 0; i < length; i++) {
+    pcm[i] = value;
+    if ((i % 100) == 0) {
+      value = -value;
+    }
+  }
+}
+
+static FS_EncDec *
+fs_encdec_new (int samplerate, int channels, int format, int interleave,
+	       int blocksize)
+{
+  FS_EncDec * ed;
+  FishSoundInfo fsinfo;
+  int i;
+
+  ed = malloc (sizeof (FS_EncDec));
+
+  fsinfo.samplerate = samplerate;
+  fsinfo.channels = channels;
+  fsinfo.format = format;
+
+  ed->encoder = fish_sound_new (FISH_SOUND_ENCODE, &fsinfo);
+  ed->decoder = fish_sound_new (FISH_SOUND_DECODE, &fsinfo);
+
+  fish_sound_set_interleave (ed->encoder, interleave);
+  fish_sound_set_interleave (ed->decoder, interleave);
+
+  fish_sound_set_encoded_callback (ed->encoder, encoded, ed);
+  fish_sound_set_decoded_callback (ed->decoder, decoded, ed);
+
+  if (interleave) {
+    ed->pcm = (float **) malloc (sizeof (float) * channels * blocksize);
+    fs_fill_square ((float *)ed->pcm, channels * blocksize);
+  } else {
+    ed->pcm = (float **) malloc (sizeof (float *) * channels);
+    for (i = 0; i < channels; i++) {
+      ed->pcm[i] = (float *) malloc (sizeof (float) * blocksize);
+      fs_fill_square (ed->pcm[i], blocksize);
+    }
+  }
+
+  return ed;
+}
+
+static int
+fs_encdec_delete (FS_EncDec * ed)
+{
+  if (!ed) return -1;
+
+  fish_sound_delete (ed->encoder);
+  fish_sound_delete (ed->decoder);
+  free (ed);
+
+  return 0;
+}
+
+static int
+fs_encdec_test (int samplerate, int channels, int format, int interleave,
+		int blocksize)
+{
+  FS_EncDec * ed;
+  int i;
+  
+  ed = fs_encdec_new (samplerate, channels, format, interleave, blocksize);
+
+  for (i = 0; i < 2; i++) {
+    fish_sound_encode (ed->encoder, ed->pcm, blocksize);
+  }
+
+  fs_encdec_delete (ed);
+
+  return 0;
+}
+
+int
+main (int argc, char * argv[])
+{
+
+#ifdef NASTY
+  int blocksizes[6] = {128, 256, 512, 1024, 2048, 4096};
+  int samplerates[4] = {8000, 16000, 32000, 48000};
+  int channels[9] = {1, 2, 4, 5, 6, 8, 10, 16, 32};
+#else
+  int blocksizes[2] = {128, 1024};
+  int samplerates[2] = {8000, 48000};
+  int channels[4] = {1, 2, 6, 16};
+#endif
+  int interleave, b, s, c;
+  char buf[128];
+
+  INFO ("Testing encode/decode pipeline for audio");
+
+  for (b = 0; b < sizeof (blocksizes) / sizeof (int); b++) {
+    for (s = 0; s < sizeof (samplerates) / sizeof (int); s++) {
+      for (c = 0; c < sizeof (channels) / sizeof (int); c++) {
+	for (interleave = 0; interleave < 2; interleave++) {
+
+	  /* Test VORBIS */
+	  snprintf (buf, 128, "+ %2d channel %6d Hz Vorbis, %d frame buffer (%s)",
+		    channels[c], samplerates[s], blocksizes[b],
+		    interleave ? "interleave" : "non-interleave");
+	  INFO (buf);
+	  fs_encdec_test (samplerates[s], channels[c], FISH_SOUND_VORBIS,
+			  interleave, blocksizes[b]);
+
+	  /* Test SPEEX */
+	  if (channels[c] <= 2) {
+	    snprintf (buf, 128, "+ %2d channel %6d Hz Speex,  %d frame buffer (%s)",
+		      channels[c], samplerates[s], blocksizes[b],
+		      interleave ? "interleave" : "non-interleave");
+	    INFO (buf);
+	    fs_encdec_test (samplerates[s], channels[c], FISH_SOUND_SPEEX,
+			    interleave, blocksizes[b]);
+
+	  }
+	}
+      }
+    }
+  }
+
+  exit (0);
+}

Added: trunk/src/tests/encdec-comments.c
===================================================================
--- trunk/src/tests/encdec-comments.c	2004-05-03 22:27:11 UTC (rev 67)
+++ trunk/src/tests/encdec-comments.c	2004-05-05 10:17:08 UTC (rev 68)
@@ -0,0 +1,230 @@
+/*
+   Copyright (C) 2003 Commonwealth Scientific and Industrial Research
+   Organisation (CSIRO) Australia
+
+   Redistribution and use in source and binary forms, with or without
+   modification, are permitted provided that the following conditions
+   are met:
+
+   - Redistributions of source code must retain the above copyright
+   notice, this list of conditions and the following disclaimer.
+
+   - Redistributions in binary form must reproduce the above copyright
+   notice, this list of conditions and the following disclaimer in the
+   documentation and/or other materials provided with the distribution.
+
+   - Neither the name of CSIRO Australia nor the names of its
+   contributors may be used to endorse or promote products derived from
+   this software without specific prior written permission.
+
+   THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
+   ``AS IS'' AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
+   LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A
+   PARTICULAR PURPOSE ARE DISCLAIMED.  IN NO EVENT SHALL THE ORGANISATION OR
+   CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL,
+   EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO,
+   PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR
+   PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF
+   LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING
+   NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
+   SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+*/
+
+#include "config.h"
+
+#include <stdio.h>
+#include <stdlib.h>
+#include <string.h>
+
+#include <fishsound/fishsound.h>
+
+#include "fs_tests.h"
+
+#define DEBUG
+
+#define ARTIST1 "Trout Junkies"
+#define ARTIST2 "DJ Fugu"
+#define COPYRIGHT "Copyright (C) 2004. Some Rights Reserved."
+#define LICENSE "Creative Commons Attribute Share-Alike v1.0"
+
+typedef struct {
+  FishSound * encoder;
+  FishSound * decoder;
+  float ** pcm;
+} FS_EncDec;
+
+static int
+decoded (FishSound * fsound, float ** pcm, long frames, void * user_data)
+{
+  const FishSoundComment * comment;
+
+  INFO ("+ Retrieving first (expect ARTIST1)");
+  comment = fish_sound_comment_first (fsound);
+
+  if (comment == NULL)
+    FAIL ("Recently inserted ARTIST1 not retrieved");
+
+  if (strcmp (comment->name, "ARTIST"))
+    FAIL ("Incorrect ARTIST1 name found");
+
+  if (strcmp (comment->value, ARTIST1))
+    FAIL ("Incorrect ARTIST1 value found");
+
+  INFO ("+ Retrieving next (expect COPYRIGHT)");
+  comment = fish_sound_comment_next (fsound, comment);
+
+  if (comment == NULL)
+    FAIL ("Recently inserted COPYRIGHT not retrieved");
+
+  if (strcmp (comment->name, "COPYRIGHT"))
+    FAIL ("Incorrect COPYRIGHT name found");
+
+  if (strcmp (comment->value, COPYRIGHT))
+    FAIL ("Incorrect COPYRIGHT value found");
+
+  INFO ("+ Retrieving next (expect LICENSE)");
+  comment = fish_sound_comment_next (fsound, comment);
+
+  if (comment == NULL)
+    FAIL ("Recently inserted LICENSE not retrieved");
+
+  if (strcmp (comment->name, "LICENSE"))
+    FAIL ("Incorrect LICENSE name found");
+
+  if (strcmp (comment->value, LICENSE))
+    FAIL ("Incorrect LICENSE value found");
+
+  INFO ("+ Retrieving first ARTIST (expect ARTIST1)");
+  comment = fish_sound_comment_first_byname (fsound, "ARTIST");
+
+  if (comment == NULL)
+    FAIL ("First artist ARTIST1 not retrieved");
+
+  if (strcmp (comment->name, "ARTIST"))
+    FAIL ("Incorrect ARTIST1 name found");
+
+  if (strcmp (comment->value, ARTIST1))
+    FAIL ("Incorrect ARTIST1 value found");
+
+  INFO ("+ Retrieving next ARTIST (expect ARTIST2)");
+  comment = fish_sound_comment_next_byname (fsound, comment);
+
+  if (comment == NULL)
+    FAIL ("Next artist ARTIST2 not retrieved");
+
+  if (strcmp (comment->name, "ARTIST"))
+    FAIL ("Incorrect ARTIST2 name found");
+
+  if (strcmp (comment->value, ARTIST2))
+    FAIL ("Incorrect ARTIST2 value found");
+
+  return 0;
+}
+
+static int
+encoded (FishSound * fsound, unsigned char * buf, long bytes, void * user_data)
+{
+  FS_EncDec * ed = (FS_EncDec *) user_data;
+  fish_sound_decode (ed->decoder, buf, bytes);
+  return 0;
+}
+
+/* Fill a PCM buffer with a squarish wave */
+static void
+fs_fill_square (float * pcm, int length)
+{
+  float value = 0.5;
+  int i;
+
+  for (i = 0; i < length; i++) {
+    pcm[i] = value;
+    if ((i % 100) == 0) {
+      value = -value;
+    }
+  }
+}
+
+static FS_EncDec *
+fs_encdec_new (int format, int blocksize)
+{
+  FS_EncDec * ed;
+  FishSoundInfo fsinfo;
+
+  ed = malloc (sizeof (FS_EncDec));
+
+  fsinfo.samplerate = 8000;
+  fsinfo.channels = 1;
+  fsinfo.format = format;
+
+  ed->encoder = fish_sound_new (FISH_SOUND_ENCODE, &fsinfo);
+  ed->decoder = fish_sound_new (FISH_SOUND_DECODE, &fsinfo);
+
+  fish_sound_set_interleave (ed->encoder, 1);
+  fish_sound_set_interleave (ed->decoder, 1);
+
+  fish_sound_set_encoded_callback (ed->encoder, encoded, ed);
+  fish_sound_set_decoded_callback (ed->decoder, decoded, ed);
+  
+  ed->pcm = (float **) malloc (sizeof (float) * blocksize);
+  fs_fill_square ((float *)ed->pcm, blocksize);
+
+  return ed;
+}
+
+static int
+fs_encdec_delete (FS_EncDec * ed)
+{
+  if (!ed) return -1;
+
+  fish_sound_delete (ed->encoder);
+  fish_sound_delete (ed->decoder);
+  free (ed);
+
+  return 0;
+}
+
+static int
+fs_encdec_comments_test (int format, int blocksize)
+{
+  FS_EncDec * ed;
+  FishSoundComment mycomment;
+  int err;
+  
+  ed = fs_encdec_new (format, blocksize);
+
+  INFO ("+ Adding ARTIST1 byname");
+  err = fish_sound_comment_add_byname (ed->encoder, "ARTIST", ARTIST1);
+  if (err < 0) FAIL ("Operation failed");
+
+  INFO ("+ Adding COPYRIGHT byname");
+  err = fish_sound_comment_add_byname (ed->encoder, "COPYRIGHT", COPYRIGHT);
+  if (err < 0) FAIL ("Operation failed");
+
+  INFO ("+ Adding LICENSE from local storage");
+  mycomment.name = "LICENSE";
+  mycomment.value = LICENSE;
+  err = fish_sound_comment_add (ed->encoder, &mycomment);
+  if (err < 0) FAIL ("Operation failed");
+
+  INFO ("+ Adding ARTIST2 byname");  
+  err = fish_sound_comment_add_byname (ed->encoder, "ARTIST", ARTIST2);
+  if (err < 0) FAIL ("Operation failed");
+
+  fish_sound_encode (ed->encoder, ed->pcm, blocksize);
+
+  fs_encdec_delete (ed);
+
+  return 0;
+}
+
+int
+main (int argc, char * argv[])
+{
+  INFO ("Testing encode/decode pipeline for comments: VORBIS");
+  fs_encdec_comments_test (FISH_SOUND_VORBIS, 2048);
+
+  INFO ("Testing encode/decode pipeline for comments: SPEEX");
+  fs_encdec_comments_test (FISH_SOUND_SPEEX, 2048);
+
+  exit (0);
+}

Added: trunk/src/tests/fs_tests.h
===================================================================
--- trunk/src/tests/fs_tests.h	2004-05-03 22:27:11 UTC (rev 67)
+++ trunk/src/tests/fs_tests.h	2004-05-05 10:17:08 UTC (rev 68)
@@ -0,0 +1,45 @@
+/*
+   Copyright (C) 2003 Commonwealth Scientific and Industrial Research
+   Organisation (CSIRO) Australia
+
+   Redistribution and use in source and binary forms, with or without
+   modification, are permitted provided that the following conditions
+   are met:
+
+   - Redistributions of source code must retain the above copyright
+   notice, this list of conditions and the following disclaimer.
+
+   - Redistributions in binary form must reproduce the above copyright
+   notice, this list of conditions and the following disclaimer in the
+   documentation and/or other materials provided with the distribution.
+
+   - Neither the name of CSIRO Australia nor the names of its
+   contributors may be used to endorse or promote products derived from
+   this software without specific prior written permission.
+
+   THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
+   ``AS IS'' AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
+   LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A
+   PARTICULAR PURPOSE ARE DISCLAIMED.  IN NO EVENT SHALL THE ORGANISATION OR
+   CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL,
+   EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO,
+   PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR
+   PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF
+   LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING
+   NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
+   SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+*/
+
+#include "config.h"
+
+#include <stdio.h>
+#include <stdlib.h>
+
+#define INFO(str) \
+  { printf ("----  %s ...\n", (str)); fflush (stdout); }
+
+#define WARN(str) \
+  { printf ("%s:%d: warning: %s\n", __FILE__, __LINE__, (str)); fflush (stdout); }
+
+#define FAIL(str) \
+  { printf ("%s:%d: %s\n", __FILE__, __LINE__, (str)); fflush (stdout); exit(1); }

Modified: trunk/win32/libfishsound/libfishsound.def
===================================================================
--- trunk/win32/libfishsound/libfishsound.def	2004-05-03 22:27:11 UTC (rev 67)
+++ trunk/win32/libfishsound/libfishsound.def	2004-05-05 10:17:08 UTC (rev 68)
@@ -13,4 +13,13 @@
 		fish_sound_get_interleave
 		fish_sound_set_interleave
 		fish_sound_get_frameno
-		fish_sound_set_frameno
\ No newline at end of file
+		fish_sound_set_frameno
+		fish_sound_get_vendor
+		fish_sound_comment_first
+		fish_sound_comment_next
+		fish_sound_comment_first_byname
+		fish_sound_comment_next_byname
+		fish_sound_comment_add
+		fish_sound_comment_add_byname
+		fish_sound_comment_remove
+		fish_sound_comment_remove_byname


-- 
conrad



More information about the cvs-annodex mailing list