Merged with trunk revision 600
authorDavid Robillard <d@drobilla.net>
Thu, 15 Jun 2006 01:34:54 +0000 (01:34 +0000)
committerDavid Robillard <d@drobilla.net>
Thu, 15 Jun 2006 01:34:54 +0000 (01:34 +0000)
git-svn-id: svn://localhost/ardour2/branches/midi@601 d708f5d6-7413-0410-9779-e7cbd77b26cf

207 files changed:
LAST_MERGE
SConstruct
gtk2_ardour/SConscript
gtk2_ardour/ardev_common.sh
gtk2_ardour/ardour.menus
gtk2_ardour/ardour_ui.cc
gtk2_ardour/ardour_ui.h
gtk2_ardour/ardour_ui_dialogs.cc
gtk2_ardour/ardour_ui_ed.cc
gtk2_ardour/ardour_ui_options.cc
gtk2_ardour/audio_clock.cc
gtk2_ardour/audio_clock.h
gtk2_ardour/audio_time_axis.cc
gtk2_ardour/audio_time_axis.h
gtk2_ardour/crossfade_edit.cc
gtk2_ardour/editor.cc
gtk2_ardour/editor.h
gtk2_ardour/editor_audio_import.cc
gtk2_ardour/editor_audiotrack.cc
gtk2_ardour/editor_canvas_events.cc
gtk2_ardour/editor_export_audio.cc
gtk2_ardour/editor_mouse.cc
gtk2_ardour/editor_ops.cc
gtk2_ardour/editor_region_list.cc
gtk2_ardour/editor_timefx.cc
gtk2_ardour/glade_factory.cc [deleted file]
gtk2_ardour/glade_factory.h [deleted file]
gtk2_ardour/glade_path.cc [deleted file]
gtk2_ardour/glade_path.h [deleted file]
gtk2_ardour/io_selector.cc
gtk2_ardour/main.cc
gtk2_ardour/meter_bridge.cc
gtk2_ardour/mixer_strip.cc
gtk2_ardour/mixer_strip.h
gtk2_ardour/mixer_ui.cc
gtk2_ardour/mixer_ui.h
gtk2_ardour/opts.cc
gtk2_ardour/playlist_selector.cc
gtk2_ardour/redirect_box.cc
gtk2_ardour/regionview.cc
gtk2_ardour/route_params_ui.cc
gtk2_ardour/route_ui.cc
gtk2_ardour/route_ui.h
gtk2_ardour/sfdb_ui.cc
gtk2_ardour/sfdb_ui.h
gtk2_ardour/streamview.cc
gtk2_ardour/streamview.h
gtk2_ardour/taperegionview.cc
libs/ardour/SConscript
libs/ardour/ardour/audio_diskstream.h [new file with mode: 0644]
libs/ardour/ardour/audio_track.h
libs/ardour/ardour/audiofilesource.h [new file with mode: 0644]
libs/ardour/ardour/audiofilter.h
libs/ardour/ardour/audioregion.h
libs/ardour/ardour/audiosource.h [new file with mode: 0644]
libs/ardour/ardour/coreaudio_source.h
libs/ardour/ardour/cycle_timer.h
libs/ardour/ardour/destructive_filesource.h
libs/ardour/ardour/diskstream.h [deleted file]
libs/ardour/ardour/externalsource.h [deleted file]
libs/ardour/ardour/playlist.h
libs/ardour/ardour/session.h
libs/ardour/ardour/session_diskstream.h
libs/ardour/ardour/sndfilesource.h
libs/ardour/ardour/source.h
libs/ardour/ardour/types.h
libs/ardour/audio_diskstream.cc [new file with mode: 0644]
libs/ardour/audio_track.cc
libs/ardour/audioengine.cc
libs/ardour/audiofilesource.cc [new file with mode: 0644]
libs/ardour/audiofilter.cc
libs/ardour/audioregion.cc
libs/ardour/audiosource.cc [new file with mode: 0644]
libs/ardour/auditioner.cc
libs/ardour/configuration.cc
libs/ardour/destructive_filesource.cc
libs/ardour/diskstream.cc [deleted file]
libs/ardour/externalsource.cc [deleted file]
libs/ardour/filesource.cc
libs/ardour/globals.cc
libs/ardour/import.cc
libs/ardour/osc.cc
libs/ardour/reverse.cc
libs/ardour/route_group.cc
libs/ardour/session.cc
libs/ardour/session_butler.cc
libs/ardour/session_events.cc
libs/ardour/session_export.cc
libs/ardour/session_feedback.cc
libs/ardour/session_midi.cc
libs/ardour/session_process.cc
libs/ardour/session_state.cc
libs/ardour/session_time.cc
libs/ardour/session_timefx.cc
libs/ardour/session_transport.cc
libs/ardour/sndfilesource.cc
libs/ardour/source.cc
libs/libsndfile/AUTHORS [new file with mode: 0644]
libs/libsndfile/ChangeLog [new file with mode: 0644]
libs/libsndfile/Mingw-make-dist.sh [new file with mode: 0755]
libs/libsndfile/NEWS [new file with mode: 0644]
libs/libsndfile/README [new file with mode: 0644]
libs/libsndfile/SConscript [new file with mode: 0644]
libs/libsndfile/acinclude.m4 [new file with mode: 0644]
libs/libsndfile/aclocal.m4 [new file with mode: 0644]
libs/libsndfile/compile [new file with mode: 0755]
libs/libsndfile/config.guess [new file with mode: 0755]
libs/libsndfile/config.sub [new file with mode: 0755]
libs/libsndfile/configure [new file with mode: 0755]
libs/libsndfile/configure.ac [new file with mode: 0644]
libs/libsndfile/depcomp [new file with mode: 0755]
libs/libsndfile/install-sh [new file with mode: 0755]
libs/libsndfile/libsndfile.spec.in [new file with mode: 0644]
libs/libsndfile/missing [new file with mode: 0755]
libs/libsndfile/mkinstalldirs [new file with mode: 0755]
libs/libsndfile/sndfile.pc.in [new file with mode: 0644]
libs/libsndfile/src/G72x/ChangeLog [new file with mode: 0644]
libs/libsndfile/src/G72x/README [new file with mode: 0644]
libs/libsndfile/src/G72x/README.original [new file with mode: 0644]
libs/libsndfile/src/G72x/g721.c [new file with mode: 0644]
libs/libsndfile/src/G72x/g723_16.c [new file with mode: 0644]
libs/libsndfile/src/G72x/g723_24.c [new file with mode: 0644]
libs/libsndfile/src/G72x/g723_40.c [new file with mode: 0644]
libs/libsndfile/src/G72x/g72x.c [new file with mode: 0644]
libs/libsndfile/src/G72x/g72x.h [new file with mode: 0644]
libs/libsndfile/src/G72x/g72x_priv.h [new file with mode: 0644]
libs/libsndfile/src/G72x/g72x_test.c [new file with mode: 0644]
libs/libsndfile/src/GSM610/COPYRIGHT [new file with mode: 0644]
libs/libsndfile/src/GSM610/ChangeLog [new file with mode: 0644]
libs/libsndfile/src/GSM610/README [new file with mode: 0644]
libs/libsndfile/src/GSM610/add.c [new file with mode: 0644]
libs/libsndfile/src/GSM610/code.c [new file with mode: 0644]
libs/libsndfile/src/GSM610/config.h [new file with mode: 0644]
libs/libsndfile/src/GSM610/decode.c [new file with mode: 0644]
libs/libsndfile/src/GSM610/gsm.h [new file with mode: 0644]
libs/libsndfile/src/GSM610/gsm610_priv.h [new file with mode: 0644]
libs/libsndfile/src/GSM610/gsm_create.c [new file with mode: 0644]
libs/libsndfile/src/GSM610/gsm_decode.c [new file with mode: 0644]
libs/libsndfile/src/GSM610/gsm_destroy.c [new file with mode: 0644]
libs/libsndfile/src/GSM610/gsm_encode.c [new file with mode: 0644]
libs/libsndfile/src/GSM610/gsm_option.c [new file with mode: 0644]
libs/libsndfile/src/GSM610/long_term.c [new file with mode: 0644]
libs/libsndfile/src/GSM610/lpc.c [new file with mode: 0644]
libs/libsndfile/src/GSM610/preprocess.c [new file with mode: 0644]
libs/libsndfile/src/GSM610/rpe.c [new file with mode: 0644]
libs/libsndfile/src/GSM610/short_term.c [new file with mode: 0644]
libs/libsndfile/src/GSM610/table.c [new file with mode: 0644]
libs/libsndfile/src/Symbols.darwin [new file with mode: 0644]
libs/libsndfile/src/Symbols.linux [new file with mode: 0644]
libs/libsndfile/src/aiff.c [new file with mode: 0644]
libs/libsndfile/src/alaw.c [new file with mode: 0644]
libs/libsndfile/src/au.c [new file with mode: 0644]
libs/libsndfile/src/avr.c [new file with mode: 0644]
libs/libsndfile/src/broadcast.c [new file with mode: 0644]
libs/libsndfile/src/caf.c [new file with mode: 0644]
libs/libsndfile/src/command.c [new file with mode: 0644]
libs/libsndfile/src/common.c [new file with mode: 0644]
libs/libsndfile/src/common.h [new file with mode: 0644]
libs/libsndfile/src/config.h.in [new file with mode: 0644]
libs/libsndfile/src/cygsndfile.def [new file with mode: 0644]
libs/libsndfile/src/dither.c [new file with mode: 0644]
libs/libsndfile/src/double64.c [new file with mode: 0644]
libs/libsndfile/src/dwd.c [new file with mode: 0644]
libs/libsndfile/src/dwvw.c [new file with mode: 0644]
libs/libsndfile/src/file_io.c [new file with mode: 0644]
libs/libsndfile/src/flac.c [new file with mode: 0644]
libs/libsndfile/src/float32.c [new file with mode: 0644]
libs/libsndfile/src/float_cast.h [new file with mode: 0644]
libs/libsndfile/src/g72x.c [new file with mode: 0644]
libs/libsndfile/src/gsm610.c [new file with mode: 0644]
libs/libsndfile/src/htk.c [new file with mode: 0644]
libs/libsndfile/src/ima_adpcm.c [new file with mode: 0644]
libs/libsndfile/src/interleave.c [new file with mode: 0644]
libs/libsndfile/src/ircam.c [new file with mode: 0644]
libs/libsndfile/src/libsndfile.def [new file with mode: 0644]
libs/libsndfile/src/macbinary3.c [new file with mode: 0644]
libs/libsndfile/src/macos.c [new file with mode: 0644]
libs/libsndfile/src/mat4.c [new file with mode: 0644]
libs/libsndfile/src/mat5.c [new file with mode: 0644]
libs/libsndfile/src/ms_adpcm.c [new file with mode: 0644]
libs/libsndfile/src/nist.c [new file with mode: 0644]
libs/libsndfile/src/ogg.c [new file with mode: 0644]
libs/libsndfile/src/paf.c [new file with mode: 0644]
libs/libsndfile/src/pcm.c [new file with mode: 0644]
libs/libsndfile/src/pvf.c [new file with mode: 0644]
libs/libsndfile/src/raw.c [new file with mode: 0644]
libs/libsndfile/src/rx2.c [new file with mode: 0644]
libs/libsndfile/src/sd2.c [new file with mode: 0644]
libs/libsndfile/src/sds.c [new file with mode: 0644]
libs/libsndfile/src/sf_unistd.h [new file with mode: 0644]
libs/libsndfile/src/sfconfig.h [new file with mode: 0644]
libs/libsndfile/src/sfendian.h [new file with mode: 0644]
libs/libsndfile/src/sndfile.c [new file with mode: 0644]
libs/libsndfile/src/sndfile.h.in [new file with mode: 0644]
libs/libsndfile/src/stamp-h1 [new file with mode: 0644]
libs/libsndfile/src/strings.c [new file with mode: 0644]
libs/libsndfile/src/svx.c [new file with mode: 0644]
libs/libsndfile/src/txw.c [new file with mode: 0644]
libs/libsndfile/src/ulaw.c [new file with mode: 0644]
libs/libsndfile/src/voc.c [new file with mode: 0644]
libs/libsndfile/src/vox_adpcm.c [new file with mode: 0644]
libs/libsndfile/src/w64.c [new file with mode: 0644]
libs/libsndfile/src/wav.c [new file with mode: 0644]
libs/libsndfile/src/wav_w64.c [new file with mode: 0644]
libs/libsndfile/src/wav_w64.h [new file with mode: 0644]
libs/libsndfile/src/wve.c [new file with mode: 0644]
libs/libsndfile/src/xi.c [new file with mode: 0644]

index b52bbc967eb0b5e6528fb147a6914139f98b6ba8..e8327edbfb3386f14fe520e8430d31614582319b 100644 (file)
@@ -1,3 +1,3 @@
 Last merged with trunk revision:
 
-579
+600
index 116cc2427590ba917765df9f663116926fbc9be6..f6ea965e29e1f19fb80bbfc1433010886be8d89b 100644 (file)
@@ -353,8 +353,8 @@ libraries = { }
 
 libraries['core'] = LibraryInfo (CCFLAGS = '-Ilibs')
 
-libraries['sndfile'] = LibraryInfo()
-libraries['sndfile'].ParseConfig('pkg-config --cflags --libs sndfile')
+#libraries['sndfile'] = LibraryInfo()
+#libraries['sndfile'].ParseConfig('pkg-config --cflags --libs sndfile')
 
 libraries['lrdf'] = LibraryInfo()
 libraries['lrdf'].ParseConfig('pkg-config --cflags --libs lrdf')
@@ -425,6 +425,15 @@ else:
     
 libraries['usb'] = conf.Finish ()
 
+#
+# Check for FLAC
+
+libraries['flac'] = LibraryInfo ()
+
+conf = Configure (libraries['flac'])
+conf.CheckLib ('FLAC', 'FLAC__stream_decoder_new')
+libraries['flac'] = conf.Finish ()
+
 #
 # Check for liblo
 
@@ -504,6 +513,14 @@ if env['SYSLIBS']:
     libraries['libgnomecanvasmm'] = LibraryInfo()
     libraries['libgnomecanvasmm'].ParseConfig ('pkg-config --cflags --libs libgnomecanvasmm-2.6')
 
+#
+# cannot use system one for the time being
+#
+
+    libraries['sndfile'] = LibraryInfo(LIBS='libsndfile',
+                                    LIBPATH='#libs/libsndfile',
+                                    CPPPATH=['#libs/libsndfile', '#libs/libsndfile/src'])
+
 #    libraries['libglademm'] = LibraryInfo()
 #    libraries['libglademm'].ParseConfig ('pkg-config --cflags --libs libglademm-2.4')
 
@@ -516,6 +533,7 @@ if env['SYSLIBS']:
     ]
 
     subdirs = [
+        'libs/libsndfile',
         'libs/pbd3',
         'libs/midi++2',
         'libs/ardour'
@@ -553,6 +571,9 @@ else:
     libraries['soundtouch'] = LibraryInfo(LIBS='soundtouch',
                                           LIBPATH='#libs/soundtouch',
                                           CPPPATH=['#libs', '#libs/soundtouch'])
+    libraries['sndfile'] = LibraryInfo(LIBS='libsndfile',
+                                    LIBPATH='#libs/libsndfile',
+                                    CPPPATH=['#libs/libsndfile', '#libs/libsndfile/src'])
 #    libraries['libglademm'] = LibraryInfo(LIBS='libglademm',
 #                                          LIBPATH='#libs/libglademm',
 #                                          CPPPATH='#libs/libglademm')
@@ -565,6 +586,7 @@ else:
     subdirs = [
 #          'libs/cassowary',
         'libs/sigc++2',
+        'libs/libsndfile',
         'libs/pbd3',
         'libs/midi++2',
         'libs/ardour'
index 8ab1c0c19cca7e30e32cf8c9b1251d13a25b7de3..b670a6d9694c26d3f0baf49bb8028075b0895b3a 100644 (file)
@@ -35,6 +35,7 @@ gtkardour.Merge ([
     libraries['libgnomecanvasmm'],
     libraries['sysmidi'],
     libraries['sndfile'],
+    libraries['flac'],
     libraries['lrdf'],
     libraries['glibmm2'],
     libraries['pangomm'],
index 9483ae29719835522efb6043a8bd030f31289683..5c68933a963f1443de292f4009b1be4c85693867 100755 (executable)
@@ -2,7 +2,7 @@
 
 export ARDOUR_PATH=./glade:./pixmaps:.
 
-export LD_LIBRARY_PATH=../libs/surfaces/control_protocol:../libs/ardour:../libs/midi++2:../libs/pbd3:../libs/soundtouch:../libs/gtkmm2ext:../libs/sigc++2:../libs/glibmm2:../libs/gtkmm2/atk:../libs/gtkmm2/pango:../libs/gtkmm2/gdk:../libs/gtkmm2/gtk:../libs/libgnomecanvasmm:../libs/libglademm:$LD_LIBRARY_PATH
+export LD_LIBRARY_PATH=../libs/surfaces/control_protocol:../libs/ardour:../libs/midi++2:../libs/pbd3:../libs/soundtouch:../libs/gtkmm2ext:../libs/sigc++2:../libs/glibmm2:../libs/gtkmm2/atk:../libs/gtkmm2/pango:../libs/gtkmm2/gdk:../libs/gtkmm2/gtk:../libs/libgnomecanvasmm:../libs/libsndfile:$LD_LIBRARY_PATH
 
 # DYLD_LIBRARY_PATH is for darwin.
 export DYLD_LIBRARY_PATH=$LD_LIBRARY_PATH
index 3c13ac8342fce442536d48159acd560e6f6d4381..9293883067040bd2beb789c22ec272f2e6b3f734 100644 (file)
                    <menu action='AudioFileFormatHeader'>
                        <menuitem action='FileHeaderFormatBWF'/>
                        <menuitem action='FileHeaderFormatWAVE'/>
+                       <menuitem action='FileHeaderFormatWAVE64'/>
+                       <menuitem action='FileHeaderFormatCAF'/>
                   </menu>
                </menu>
                <menu action='Autoconnect'>
index 640b62df1fb0773f31656b43c273d9339da07c0b..fa77c3f50b4fd7bc930ed3155e8c9fe53401c861 100644 (file)
@@ -50,8 +50,8 @@
 #include <ardour/audioengine.h>
 #include <ardour/playlist.h>
 #include <ardour/utils.h>
-#include <ardour/diskstream.h>
-#include <ardour/filesource.h>
+#include <ardour/audio_diskstream.h>
+#include <ardour/audiofilesource.h>
 #include <ardour/recent_sessions.h>
 #include <ardour/session_diskstream.h>
 #include <ardour/port.h>
@@ -184,9 +184,9 @@ ARDOUR_UI::ARDOUR_UI (int *argcp, char **argvp[], string rcfile)
        gettimeofday (&last_peak_grab, 0);
        gettimeofday (&last_shuttle_request, 0);
 
-       ARDOUR::DiskStream::DeleteSources.connect (mem_fun(*this, &ARDOUR_UI::delete_sources_in_the_right_thread));
-       ARDOUR::DiskStream::DiskOverrun.connect (mem_fun(*this, &ARDOUR_UI::disk_overrun_handler));
-       ARDOUR::DiskStream::DiskUnderrun.connect (mem_fun(*this, &ARDOUR_UI::disk_underrun_handler));
+       ARDOUR::AudioDiskstream::DeleteSources.connect (mem_fun(*this, &ARDOUR_UI::delete_sources_in_the_right_thread));
+       ARDOUR::AudioDiskstream::DiskOverrun.connect (mem_fun(*this, &ARDOUR_UI::disk_overrun_handler));
+       ARDOUR::AudioDiskstream::DiskUnderrun.connect (mem_fun(*this, &ARDOUR_UI::disk_underrun_handler));
 
        /* handle pending state with a dialog */
 
@@ -241,10 +241,10 @@ ARDOUR_UI::set_engine (AudioEngine& e)
 
        /* this being a GUI and all, we want peakfiles */
 
-       FileSource::set_build_peakfiles (true);
-       FileSource::set_build_missing_peakfiles (true);
+       AudioFileSource::set_build_peakfiles (true);
+       AudioFileSource::set_build_missing_peakfiles (true);
 
-       if (Source::start_peak_thread ()) {
+       if (AudioSource::start_peak_thread ()) {
                throw failed_constructor();
        }
 
@@ -281,7 +281,7 @@ ARDOUR_UI::~ARDOUR_UI ()
                delete add_route_dialog;
        }
 
-       Source::stop_peak_thread ();
+       AudioSource::stop_peak_thread ();
 }
 
 gint
@@ -542,7 +542,7 @@ ARDOUR_UI::update_buffer_load ()
 }
 
 void
-ARDOUR_UI::count_recenabled_diskstreams (DiskStream& ds)
+ARDOUR_UI::count_recenabled_diskstreams (AudioDiskstream& ds)
 {
        if (ds.record_enabled()) {
                rec_enabled_diskstreams++;
@@ -570,7 +570,7 @@ ARDOUR_UI::update_disk_space()
                if (session->actively_recording()){
                        
                        rec_enabled_diskstreams = 0;
-                       session->foreach_diskstream (this, &ARDOUR_UI::count_recenabled_diskstreams);
+                       session->foreach_audio_diskstream (this, &ARDOUR_UI::count_recenabled_diskstreams);
                        
                        if (rec_enabled_diskstreams) {
                                frames /= rec_enabled_diskstreams;
@@ -917,7 +917,7 @@ restart JACK with more ports."));
 }
 
 void
-ARDOUR_UI::diskstream_added (DiskStream* ds)
+ARDOUR_UI::diskstream_added (AudioDiskstream* ds)
 {
 }
 
@@ -1164,7 +1164,7 @@ ARDOUR_UI::toggle_monitor_enable (guint32 dstream)
                return;
        }
 
-       DiskStream *ds;
+       AudioDiskstream *ds;
 
        if ((ds = session->diskstream_by_id (dstream)) != 0) {
                Port *port = ds->io()->input (0);
@@ -1179,7 +1179,7 @@ ARDOUR_UI::toggle_record_enable (guint32 dstream)
                return;
        }
 
-       DiskStream *ds;
+       AudioDiskstream *ds;
 
        if ((ds = session->diskstream_by_id (dstream)) != 0) {
                ds->set_record_enabled (!ds->record_enabled(), this);
@@ -1386,7 +1386,7 @@ ARDOUR_UI::stop_blinking ()
 
 
 void
-ARDOUR_UI::add_diskstream_to_menu (DiskStream& dstream)
+ARDOUR_UI::add_diskstream_to_menu (AudioDiskstream& dstream)
 {
        using namespace Gtk;
        using namespace Menu_Helpers;
@@ -1424,7 +1424,7 @@ ARDOUR_UI::select_diskstream (GdkEventButton *ev)
        MenuList& items = diskstream_menu->items();
        items.push_back (MenuElem (_("No Stream"), (bind (mem_fun(*this, &ARDOUR_UI::diskstream_selected), -1))));
 
-       session->foreach_diskstream (this, &ARDOUR_UI::add_diskstream_to_menu);
+       session->foreach_audio_diskstream (this, &ARDOUR_UI::add_diskstream_to_menu);
 
        if (ev) {
                diskstream_menu->popup (ev->button, ev->time);
@@ -1569,7 +1569,7 @@ ARDOUR_UI::secondary_clock_value_changed ()
 }
 
 void
-ARDOUR_UI::rec_enable_button_blink (bool onoff, DiskStream *dstream, Widget *w)
+ARDOUR_UI::rec_enable_button_blink (bool onoff, AudioDiskstream *dstream, Widget *w)
 {
        if (session && dstream && dstream->record_enabled()) {
 
@@ -2216,11 +2216,11 @@ ARDOUR_UI::halt_on_xrun_message ()
 }
 
 void 
-ARDOUR_UI::delete_sources_in_the_right_thread (list<ARDOUR::Source*>* deletion_list)
+ARDOUR_UI::delete_sources_in_the_right_thread (list<ARDOUR::AudioFileSource*>* deletion_list)
 {
        ENSURE_GUI_THREAD (bind (mem_fun(*this, &ARDOUR_UI::delete_sources_in_the_right_thread), deletion_list));
 
-       for (list<Source*>::iterator i = deletion_list->begin(); i != deletion_list->end(); ++i) {
+       for (list<AudioFileSource*>::iterator i = deletion_list->begin(); i != deletion_list->end(); ++i) {
                delete *i;
        }
 
@@ -2377,6 +2377,12 @@ ARDOUR_UI::set_native_file_header_format (HeaderFormat hf)
        case RF64:
                act = ActionManager::get_action (X_("options"), X_("FileHeaderFormatRF64"));
                break;
+       case CAF:
+               act = ActionManager::get_action (X_("options"), X_("FileHeaderFormatCAF"));
+               break;
+       case AIFF:
+               act = ActionManager::get_action (X_("options"), X_("FileHeaderFormatAIFF"));
+               break;
        }
 
        if (act) {
@@ -2451,6 +2457,12 @@ ARDOUR_UI::use_config ()
        case RF64:
                act = ActionManager::get_action (X_("options"), X_("FileHeaderFormatRF64"));
                break;
+       case CAF:
+               act = ActionManager::get_action (X_("options"), X_("FileHeaderFormatCAF"));
+               break;
+       case AIFF:
+               act = ActionManager::get_action (X_("options"), X_("FileHeaderFormatAIFF"));
+               break;
        }
 
        if (act) {
index a759c6cd613dae819d5dac7fc312e21fd90e885b..678342f32bb6ad683ff64a1dead56dfa9110dec1 100644 (file)
@@ -167,7 +167,7 @@ class ARDOUR_UI : public Gtkmm2ext::UI
           blinking rec-enable buttons.
        */
 
-       void rec_enable_button_blink (bool onoff, ARDOUR::DiskStream *, Gtk::Widget *w);
+       void rec_enable_button_blink (bool onoff, ARDOUR::AudioDiskstream *, Gtk::Widget *w);
 
        void name_io_setup (ARDOUR::AudioEngine&, string&, ARDOUR::IO& io, bool in);
        void choose_io (ARDOUR::IO&, bool input);
@@ -522,7 +522,7 @@ class ARDOUR_UI : public Gtkmm2ext::UI
        sigc::connection point_one_second_connection;
        sigc::connection point_zero_one_second_connection;
 
-       void diskstream_added (ARDOUR::DiskStream*);
+       void diskstream_added (ARDOUR::AudioDiskstream*);
 
        gint session_menu (GdkEventButton *);
 
@@ -539,7 +539,7 @@ class ARDOUR_UI : public Gtkmm2ext::UI
 
        void session_add_audio_route (bool disk, int32_t input_channels, int32_t output_channels, ARDOUR::TrackMode mode);
 
-       void add_diskstream_to_menu (ARDOUR::DiskStream&);
+       void add_diskstream_to_menu (ARDOUR::AudioDiskstream&);
        void diskstream_selected (gint32);
        Gtk::Menu *diskstream_menu;
        gint32 selected_dstream;
@@ -630,7 +630,7 @@ class ARDOUR_UI : public Gtkmm2ext::UI
        void toggle_monitor_enable (guint32);
 
        uint32_t rec_enabled_diskstreams;
-       void count_recenabled_diskstreams (ARDOUR::DiskStream&);
+       void count_recenabled_diskstreams (ARDOUR::AudioDiskstream&);
 
        About* about;
        bool shown_flag;
@@ -649,7 +649,7 @@ class ARDOUR_UI : public Gtkmm2ext::UI
        struct timeval last_peak_grab;
        struct timeval last_shuttle_request;
 
-       void delete_sources_in_the_right_thread (list<ARDOUR::Source*>*);
+       void delete_sources_in_the_right_thread (list<ARDOUR::AudioFileSource*>*);
 
        void editor_display_control_changed (Editing::DisplayControl c);
 
index 6b1d0224db06394a9940762df974049e288c329e..eb9e72b253f3684d26fbf25edb6ff295d99ede22 100644 (file)
@@ -75,8 +75,8 @@ ARDOUR_UI::connect_to_session (Session *s)
        rec_button.set_sensitive (true);
        shuttle_box.set_sensitive (true);
        
-       if (session->n_diskstreams() == 0) {
-               session->DiskStreamAdded.connect (mem_fun(*this, &ARDOUR_UI::diskstream_added));
+       if (session->n_audio_diskstreams() == 0) {
+               session->AudioDiskstreamAdded.connect (mem_fun(*this, &ARDOUR_UI::diskstream_added));
        }
 
        if (connection_editor) {
index 5bcad97d26f23407c7cc79353e02c0b3cbfead6e..3ca435a24d82e8682e28fcb69f61f4a8987b7091 100644 (file)
@@ -381,8 +381,9 @@ ARDOUR_UI::install_actions ()
        act = ActionManager::register_radio_action (option_actions, file_header_group, X_("FileHeaderFormatBWF"), X_("Broadcast WAVE"), bind (mem_fun (*this, &ARDOUR_UI::set_native_file_header_format), ARDOUR::BWF));
        act = ActionManager::register_radio_action (option_actions, file_header_group, X_("FileHeaderFormatWAVE"), X_("WAVE"), bind (mem_fun (*this, &ARDOUR_UI::set_native_file_header_format), ARDOUR::WAVE));
        act = ActionManager::register_radio_action (option_actions, file_header_group, X_("FileHeaderFormatWAVE64"), X_("WAVE-64"), bind (mem_fun (*this, &ARDOUR_UI::set_native_file_header_format), ARDOUR::WAVE64));
-       act = ActionManager::register_radio_action (option_actions, file_header_group, X_("FileHeaderFormatiXML"), X_("iXML"), bind (mem_fun (*this, &ARDOUR_UI::set_native_file_header_format), ARDOUR::iXML));
-       act = ActionManager::register_radio_action (option_actions, file_header_group, X_("FileHeaderFormatRF64"), X_("RF64"), bind (mem_fun (*this, &ARDOUR_UI::set_native_file_header_format), ARDOUR::RF64));
+       // act = ActionManager::register_radio_action (option_actions, file_header_group, X_("FileHeaderFormatiXML"), X_("iXML"), bind (mem_fun (*this, &ARDOUR_UI::set_native_file_header_format), ARDOUR::iXML));
+       // act = ActionManager::register_radio_action (option_actions, file_header_group, X_("FileHeaderFormatRF64"), X_("RF64"), bind (mem_fun (*this, &ARDOUR_UI::set_native_file_header_format), ARDOUR::RF64));
+       act = ActionManager::register_radio_action (option_actions, file_header_group, X_("FileHeaderFormatCAF"), X_("CAF"), bind (mem_fun (*this, &ARDOUR_UI::set_native_file_header_format), ARDOUR::CAF));
 
        RadioAction::Group file_data_group;
 
index dbdcd6ae4582dc97800efd814689ab2e6c1ffbf5..ac0028b58c0d4a839064ec07e5a8e6d2fff773f0 100644 (file)
@@ -46,7 +46,7 @@ ARDOUR_UI::setup_config_options ()
        struct { 
            char* name;
            bool (Configuration::*method)(void) const;
-           char act_type;  // (t)oggle or (r)adio
+           char act_type;  //(t)oggle or (r)adio
        } options[] = {
                { "ToggleTimeMaster", &Configuration::get_jack_time_master, 't' },
                { "StopPluginsWithTransport", &Configuration::get_plugins_stop_with_transport, 't' },
@@ -76,7 +76,6 @@ ARDOUR_UI::setup_config_options ()
                        Glib::RefPtr<Action> act = ActionManager::get_action (i->c_str(), options[n].name);
                        if (act) {
                                Glib::RefPtr<ToggleAction> tact = Glib::RefPtr<ToggleAction>::cast_dynamic(act);
-                               cerr << "action = " << (options[n].name) << " val = " << (Config->*(options[n].method))() << endl;//DEBUG
                                if (options[n].act_type == 't' || (options[n].act_type == 'r' && (Config->*(options[n].method))()))
                                        tact->set_active ((Config->*(options[n].method))());
                                continue;
@@ -257,7 +256,6 @@ ARDOUR_UI::toggle_UseHardwareMonitoring()
        Glib::RefPtr<Action> act = ActionManager::get_action ("options", "UseHardwareMonitoring");
        if (act) {
                Glib::RefPtr<ToggleAction> tact = Glib::RefPtr<ToggleAction>::cast_dynamic(act);
-               cerr << "get_active() cond = " << tact->get_active() << endl;//DEBUG
                if (tact->get_active()) {
                        Config->set_use_hardware_monitoring (true);
                        Config->set_use_sw_monitoring (false);
index 2aa9387379a4f505870a408d1eda3e52d926d38c..25985c4a3b956ae1f7adc8c59e6679baac6e2211 100644 (file)
@@ -195,6 +195,8 @@ AudioClock::AudioClock (const string& name, bool allow_edit, bool duration, bool
        clock_base.add_events (Gdk::BUTTON_PRESS_MASK|Gdk::BUTTON_RELEASE_MASK|Gdk::SCROLL_MASK);
        clock_base.signal_button_release_event().connect (bind (mem_fun (*this, &AudioClock::field_button_release_event), SMPTE_Hours));
 
+       Session::SMPTEOffsetChanged.connect (mem_fun (*this, &AudioClock::smpte_offset_changed));
+
        if (editable) {
                setup_events ();
        }
@@ -389,6 +391,25 @@ AudioClock::set (jack_nframes_t when, bool force)
        last_when = when;
 }
 
+void
+AudioClock::smpte_offset_changed ()
+{
+       jack_nframes_t current;
+
+       switch (_mode) {
+       case SMPTE:
+               if (is_duration) {
+                       current = current_duration();
+               } else {
+                       current = current_time ();
+               }
+               set (current, true);
+               break;
+       default:
+               break;
+       }
+}
+
 void
 AudioClock::set_frames (jack_nframes_t when, bool force)
 {
@@ -446,9 +467,9 @@ AudioClock::set_smpte (jack_nframes_t when, bool force)
 
        if (force || smpte.hours != last_hrs || smpte.negative != last_negative) {
                if (smpte.negative) {
-                       sprintf (buf, "-%02ld", smpte.hours);
+                       sprintf (buf, "-%02" PRIu32, smpte.hours);
                } else {
-                       sprintf (buf, " %02ld", smpte.hours);
+                       sprintf (buf, " %02" PRIu32, smpte.hours);
                }
                hours_label.set_text (buf);
                last_hrs = smpte.hours;
@@ -456,19 +477,19 @@ AudioClock::set_smpte (jack_nframes_t when, bool force)
        }
 
        if (force || smpte.minutes != last_mins) {
-               sprintf (buf, "%02ld", smpte.minutes);
+               sprintf (buf, "%02" PRIu32, smpte.minutes);
                minutes_label.set_text (buf);
                last_mins = smpte.minutes;
        }
 
        if (force || smpte.seconds != last_secs) {
-               sprintf (buf, "%02ld", smpte.seconds);
+               sprintf (buf, "%02" PRIu32, smpte.seconds);
                seconds_label.set_text (buf);
                last_secs = smpte.seconds;
        }
 
        if (force || smpte.frames != last_frames) {
-               sprintf (buf, "%02ld", smpte.frames);
+               sprintf (buf, "%02" PRIu32, smpte.frames);
                frames_label.set_text (buf);
                last_frames = smpte.frames;
        }
@@ -1267,7 +1288,7 @@ AudioClock::smpte_frame_from_display () const
        smpte.minutes = atoi (minutes_label.get_text());
        smpte.seconds = atoi (seconds_label.get_text());
        smpte.frames = atoi (frames_label.get_text());
-       
+
        session->smpte_to_sample( smpte, sample, false /* use_offset */, false /* use_subframes */ );
        
 
index a0733e7de3acd1d229ee983f2bfc8970f963182a..14dc6ba67385057658fde5740001cfbeb5f571f5 100644 (file)
@@ -175,6 +175,8 @@ class AudioClock : public Gtk::HBox
        void build_ops_menu ();
        void setup_events ();
 
+       void smpte_offset_changed ();
+
        static const uint32_t field_length[(int)AudioFrames+1];
 };
 
index 84c7bf7e15b72616860c352b988e2b301a7e218f..32c303de349e0f7e00ae28f953f6c2e855a8b5cc 100644 (file)
@@ -38,7 +38,7 @@
 #include <gtkmm2ext/utils.h>
 
 #include <ardour/audioplaylist.h>
-#include <ardour/diskstream.h>
+#include <ardour/audio_diskstream.h>
 #include <ardour/insert.h>
 #include <ardour/ladspa_plugin.h>
 #include <ardour/location.h>
@@ -823,7 +823,7 @@ AudioTimeAxisView::rename_current_playlist ()
        string name;
 
        AudioPlaylist *pl;
-       DiskStream *ds;
+       AudioDiskstream *ds;
 
        if (((ds = get_diskstream()) == 0) || ds->destructive() || ((pl = ds->playlist()) == 0)) {
                return;
@@ -851,7 +851,7 @@ void
 AudioTimeAxisView::use_copy_playlist (bool prompt)
 {
        AudioPlaylist *pl;
-       DiskStream *ds;
+       AudioDiskstream *ds;
        string name;
 
        if (((ds = get_diskstream()) == 0) || ds->destructive() || ((pl = ds->playlist()) == 0)) {
@@ -891,7 +891,7 @@ void
 AudioTimeAxisView::use_new_playlist (bool prompt)
 {
        AudioPlaylist *pl;
-       DiskStream *ds;
+       AudioDiskstream *ds;
        string name;
 
        if (((ds = get_diskstream()) == 0) || ds->destructive() || ((pl = ds->playlist()) == 0)) {
@@ -930,7 +930,7 @@ void
 AudioTimeAxisView::clear_playlist ()
 {
        AudioPlaylist *pl;
-       DiskStream *ds;
+       AudioDiskstream *ds;
        
        if ((ds = get_diskstream()) != 0) {
                if ((pl = ds->playlist()) != 0) {
@@ -988,7 +988,7 @@ AudioTimeAxisView::diskstream_changed (void *src)
 void
 AudioTimeAxisView::update_diskstream_display ()
 {
-       DiskStream *ds;
+       AudioDiskstream *ds;
 
        if ((ds = get_diskstream()) != 0) {
                set_playlist (ds->playlist ());
@@ -1092,7 +1092,7 @@ AudioTimeAxisView::name() const
 Playlist *
 AudioTimeAxisView::playlist () const 
 {
-       DiskStream *ds;
+       AudioDiskstream *ds;
 
        if ((ds = get_diskstream()) != 0) {
                return ds->playlist(); 
@@ -1142,7 +1142,7 @@ AudioTimeAxisView::hide_click ()
 Region*
 AudioTimeAxisView::find_next_region (jack_nframes_t pos, RegionPoint point, int32_t dir)
 {
-       DiskStream *stream;
+       AudioDiskstream *stream;
        AudioPlaylist *playlist;
 
        if ((stream = get_diskstream()) != 0 && (playlist = stream->playlist()) != 0) {
@@ -1717,7 +1717,7 @@ bool
 AudioTimeAxisView::cut_copy_clear (Selection& selection, CutCopyOp op)
 {
        Playlist* what_we_got;
-       DiskStream* ds = get_diskstream();
+       AudioDiskstream* ds = get_diskstream();
        Playlist* playlist;
        bool ret = false;
 
index d1fbde3e9cf6ffd95d6704958aa3748c58850a41..b319d0ea9945c08733712f68a0cf3f222c908ded 100644 (file)
@@ -48,7 +48,7 @@ namespace ALSA {
 
 namespace ARDOUR {
        class Session;
-       class DiskStream;
+       class AudioDiskstream;
        class RouteGroup;
        class Redirect;
        class Insert;
index 6363178004811927697342d82e5b37314fe61783..293324dc916c1665d96d9ea821b046dd4729cac3 100644 (file)
@@ -34,6 +34,7 @@
 #include <ardour/session.h>
 #include <ardour/auditioner.h>
 #include <ardour/audioplaylist.h>
+#include <ardour/audiosource.h>
 #include <ardour/playlist_templates.h>
 
 #include <gtkmm2ext/gtk_ui.h>
index c7956386ced6848b3058a29d7e9122f12b3c9bbc..1d78c2fce0edbc9d78adc169c3ccf10b1819d55a 100644 (file)
@@ -38,7 +38,7 @@
 #include <gtkmm2ext/utils.h>
 
 #include <ardour/audio_track.h>
-#include <ardour/diskstream.h>
+#include <ardour/audio_diskstream.h>
 #include <ardour/plugin_manager.h>
 #include <ardour/location.h>
 #include <ardour/audioplaylist.h>
@@ -1636,7 +1636,7 @@ Editor::build_track_region_context_menu (jack_nframes_t frame)
        AudioTimeAxisView* atv = dynamic_cast<AudioTimeAxisView*> (clicked_trackview);
 
        if (atv) {
-               DiskStream* ds;
+               AudioDiskstream* ds;
                Playlist* pl;
                
                if ((ds = atv->get_diskstream()) && ((pl = ds->playlist()))) {
@@ -1663,7 +1663,7 @@ Editor::build_track_crossfade_context_menu (jack_nframes_t frame)
        AudioTimeAxisView* atv = dynamic_cast<AudioTimeAxisView*> (clicked_trackview);
 
        if (atv) {
-               DiskStream* ds;
+               AudioDiskstream* ds;
                Playlist* pl;
                AudioPlaylist* apl;
 
@@ -3107,7 +3107,7 @@ Editor::mapped_set_selected_regionview_from_click (AudioTimeAxisView& atv, uint3
        AudioPlaylist* pl;
        vector<AudioRegion*> results;
        AudioRegionView* marv;
-       DiskStream* ds;
+       AudioDiskstream* ds;
 
        if ((ds = atv.get_diskstream()) == 0) {
                /* bus */
@@ -3338,7 +3338,7 @@ Editor::set_selected_regionview_from_region_list (Region& r, Selection::Operatio
                        AudioPlaylist* pl;
                        vector<AudioRegion*> results;
                        AudioRegionView* marv;
-                       DiskStream* ds;
+                       AudioDiskstream* ds;
                        
                        if ((ds = tatv->get_diskstream()) == 0) {
                                /* bus */
index 8b7b2af1d0885b8b24a3f116a510c0b4ad463d40..be2f3ba44f719b0845646a6cb187c1352c257ca9 100644 (file)
@@ -45,7 +45,6 @@
 #include <ardour/tempo.h>
 #include <ardour/location.h>
 #include <ardour/region.h>
-#include <ardour/externalsource.h>
 
 #include "audio_clock.h"
 #include "gtk-custom-ruler.h"
@@ -67,9 +66,8 @@ namespace LinuxAudioSystems {
 }
 
 namespace ARDOUR {
-       class DiskStream;
+       class AudioDiskstream;
        class RouteGroup;
-       class Source;
        class Playlist;
        class Region;
        class Location;
index ee73c46b244f485955c7bf9324f930868846fc0a..6f9d96e61e1207ea18004afc8a411beee1dcda87 100644 (file)
 #include <ardour/session.h>
 #include <ardour/audioplaylist.h>
 #include <ardour/audioregion.h>
-#include <ardour/diskstream.h>
-#include <ardour/filesource.h>
-#include <ardour/externalsource.h>
+#include <ardour/audio_diskstream.h>
 #include <ardour/utils.h>
 #include <ardour/audio_track.h>
 #include <ardour/audioplaylist.h>
+#include <ardour/audiofilesource.h>
 
 #include "ardour_ui.h"
 #include "editor.h"
@@ -187,7 +186,7 @@ int
 Editor::embed_sndfile (Glib::ustring path, bool split, bool multiple_files, bool& check_sample_rate, ImportMode mode, 
                       AudioTrack* track, jack_nframes_t& pos, bool prompt)
 {
-       ExternalSource *source = 0; /* keep g++ quiet */
+       AudioFileSource *source = 0; /* keep g++ quiet */
        AudioRegion::SourceList sources;
        AudioRegion* region;
        string idspec;
@@ -220,7 +219,7 @@ Editor::embed_sndfile (Glib::ustring path, bool split, bool multiple_files, bool
 
        string error_msg;
 
-       if (!ExternalSource::get_soundfile_info (path, finfo, error_msg)) {
+       if (!AudioFileSource::get_soundfile_info (path, finfo, error_msg)) {
                error << string_compose(_("Editor: cannot open file \"%1\", (%2)"), selection, error_msg ) << endmsg;
                return 0;
        }
@@ -267,7 +266,7 @@ Editor::embed_sndfile (Glib::ustring path, bool split, bool multiple_files, bool
                idspec += string_compose(":%1", n);
                
                try {
-                       source = ExternalSource::create (idspec.c_str());
+                       source = AudioFileSource::create (idspec.c_str());
                        sources.push_back(source);
                } 
                
index b9ae734bde59f589f30a1f5c07266b2e8477ed29..db1353f15980f030486970a6fe7d3e6f81656f23 100644 (file)
@@ -1,5 +1,5 @@
 #include <ardour/location.h>
-#include <ardour/diskstream.h>
+#include <ardour/audio_diskstream.h>
 
 #include "editor.h"
 #include "editing.h"
index 29997f5f57f6dd85cfa587cb10582884880f9db5..ff4dda91825ee667d8380da6ece7c7d976195df1 100644 (file)
@@ -21,7 +21,7 @@
 #include <cstdlib>
 #include <cmath>
 
-#include <ardour/diskstream.h>
+#include <ardour/audio_diskstream.h>
 #include <ardour/audioplaylist.h>
 
 #include "editor.h"
index 8ad432ece6287f605a0604069ca293cd590ad353..9781a24d2965296b82071685c4c542a003f804bc 100644 (file)
@@ -37,8 +37,8 @@
 #include <ardour/types.h>
 #include <ardour/export.h>
 #include <ardour/audio_track.h>
-#include <ardour/filesource.h>
-#include <ardour/diskstream.h>
+#include <ardour/audiofilesource.h>
+#include <ardour/audio_diskstream.h>
 #include <ardour/audioregion.h>
 #include <ardour/audioplaylist.h>
 
@@ -154,7 +154,7 @@ Editor::bounce_region_selection ()
 bool
 Editor::write_region (string path, AudioRegion& region)
 {
-       FileSource* fs;
+       AudioFileSource* fs;
        const jack_nframes_t chunk_size = 4096;
        jack_nframes_t to_read;
        Sample buf[chunk_size];
@@ -163,7 +163,7 @@ Editor::write_region (string path, AudioRegion& region)
        jack_nframes_t pos;
        char s[PATH_MAX+1];
        uint32_t cnt;
-       vector<FileSource *> sources;
+       vector<AudioFileSource *> sources;
        uint32_t nchans;
        
        nchans = region.n_channels();
@@ -204,7 +204,7 @@ Editor::write_region (string path, AudioRegion& region)
                
                        
                        try {
-                               fs = new FileSource (path, session->frame_rate());
+                               fs = AudioFileSource::create (path);
                        }
                        
                        catch (failed_constructor& err) {
@@ -227,10 +227,10 @@ Editor::write_region (string path, AudioRegion& region)
 
                this_time = min (to_read, chunk_size);
 
-               for (vector<FileSource *>::iterator src=sources.begin(); src != sources.end(); ++src) {
-
-                       fs = (*src);
+               for (vector<AudioFileSource *>::iterator src=sources.begin(); src != sources.end(); ++src) {
                        
+                       fs = (*src);
+
                        if (region.read_at (buf, buf, gain_buffer, workbuf, pos, this_time) != this_time) {
                                break;
                        }
@@ -250,7 +250,7 @@ Editor::write_region (string path, AudioRegion& region)
        time (&tnow);
        now = localtime (&tnow);
        
-       for (vector<FileSource *>::iterator src = sources.begin(); src != sources.end(); ++src) {
+       for (vector<AudioFileSource *>::iterator src = sources.begin(); src != sources.end(); ++src) {
                (*src)->update_header (0, *now, tnow);
        }
 
@@ -258,7 +258,8 @@ Editor::write_region (string path, AudioRegion& region)
 
 error_out:
 
-       for (vector<FileSource*>::iterator i = sources.begin(); i != sources.end(); ++i) {
+       for (vector<AudioFileSource*>::iterator i = sources.begin(); i != sources.end(); ++i) {
+               
                (*i)->mark_for_remove ();
                delete (*i);
        }
@@ -300,7 +301,7 @@ Editor::write_audio_selection (TimeSelection& ts)
 bool
 Editor::write_audio_range (Playlist& playlist, uint32_t channels, list<AudioRange>& range)
 {
-       FileSource* fs;
+       AudioFileSource* fs;
        const jack_nframes_t chunk_size = 4096;
        jack_nframes_t nframes;
        Sample buf[chunk_size];
@@ -310,7 +311,7 @@ Editor::write_audio_range (Playlist& playlist, uint32_t channels, list<AudioRang
        char s[PATH_MAX+1];
        uint32_t cnt;
        string path;
-       vector<FileSource *> sources;
+       vector<AudioFileSource *> sources;
 
        for (uint32_t n=0; n < channels; ++n) {
                
@@ -337,7 +338,7 @@ Editor::write_audio_range (Playlist& playlist, uint32_t channels, list<AudioRang
                path = s;
                
                try {
-                       fs = new FileSource (path, session->frame_rate());
+                       fs = AudioFileSource::create (path);
                }
                
                catch (failed_constructor& err) {
@@ -420,7 +421,7 @@ Editor::write_audio_range (Playlist& playlist, uint32_t channels, list<AudioRang
 error_out:
        /* unref created files */
 
-       for (vector<FileSource*>::iterator i = sources.begin(); i != sources.end(); ++i) {
+       for (vector<AudioFileSource*>::iterator i = sources.begin(); i != sources.end(); ++i) {
                (*i)->mark_for_remove ();
                delete *i;
        }
index cc171617a631737925c8694c07c313e2c6d918a3..991a1b14431e2c1d50f65d528d230ca5ed06e0f0 100644 (file)
@@ -47,7 +47,7 @@
 #include <ardour/types.h>
 #include <ardour/route.h>
 #include <ardour/audio_track.h>
-#include <ardour/diskstream.h>
+#include <ardour/audio_diskstream.h>
 #include <ardour/playlist.h>
 #include <ardour/audioplaylist.h>
 #include <ardour/audioregion.h>
@@ -286,7 +286,7 @@ Editor::step_mouse_mode (bool next)
 void
 Editor::button_selection (ArdourCanvas::Item* item, GdkEvent* event, ItemType item_type)
 {
-       bool commit;
+       bool commit = false;
        bool c1; 
        bool c2;
 
index acf205d06f926e2b1c56dae7ac31e0ea5273a1d2..39b284375634eb7e587c74ffd1d980a0fc570a2c 100644 (file)
@@ -36,9 +36,7 @@
 #include <ardour/session.h>
 #include <ardour/audioplaylist.h>
 #include <ardour/audioregion.h>
-#include <ardour/diskstream.h>
-#include <ardour/filesource.h>
-#include <ardour/externalsource.h>
+#include <ardour/audio_diskstream.h>
 #include <ardour/utils.h>
 #include <ardour/location.h>
 #include <ardour/named_selection.h>
@@ -122,9 +120,9 @@ Editor::set_meter_hold (int32_t cnt)
 void
 Editor::set_meter_falloff (int intval)
 {
-       float val;
+       float val = 0.0f; /* off */
        std::string str;
-       cerr << "set_meter_falloff () called: intval = " << intval << endl;
+
        Config->set_meter_falloff_off(false);
        Config->set_meter_falloff_slowest(false);
        Config->set_meter_falloff_slow(false);
index bbcfb09a2902f2121aada484b5a531827c46d78b..26d9717d4ac96a17bedf5cad35fbc0a504c42d79 100644 (file)
@@ -26,6 +26,7 @@
 #include <pbd/basename.h>
 
 #include <ardour/audioregion.h>
+#include <ardour/audiosource.h>
 #include <ardour/session_region.h>
 
 #include <gtkmm2ext/stop_signal.h>
index 9760c5116bb604ee2e0a429bb220a0dfa835563a..ecb2f5ba4bf7f165d005c8d04c63d9e0965048bd 100644 (file)
@@ -36,7 +36,7 @@
 #include <ardour/audioplaylist.h>
 #include <ardour/audio_track.h>
 #include <ardour/audioregion.h>
-#include <ardour/diskstream.h>
+#include <ardour/audio_diskstream.h>
 
 #include "i18n.h"
 
diff --git a/gtk2_ardour/glade_factory.cc b/gtk2_ardour/glade_factory.cc
deleted file mode 100644 (file)
index 6dbced3..0000000
+++ /dev/null
@@ -1,37 +0,0 @@
-/*
-    Copyright (C) 2005 Paul Davis 
-
-    This program is free software; you can redistribute it and/or modify
-    it under the terms of the GNU General Public License as published by
-    the Free Software Foundation; either version 2 of the License, or
-    (at your option) any later version.
-
-    This program is distributed in the hope that it will be useful,
-    but WITHOUT ANY WARRANTY; without even the implied warranty of
-    MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
-    GNU General Public License for more details.
-
-    You should have received a copy of the GNU General Public License
-    along with this program; if not, write to the Free Software
-    Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
-
-    $Id$
-*/
-
-#include <iostream>
-
-#include "glade_factory.h"
-
-Glib::RefPtr<Gnome::Glade::Xml>
-GladeFactory::create(const std::string& full_path_to_file,
-                    const Glib::ustring& toplevel_widget)
-{
-       try {
-               return Gnome::Glade::Xml::create(full_path_to_file,
-                                                toplevel_widget,
-                                                PACKAGE );
-       } catch(const Gnome::Glade::XmlError& ex) {
-               std::cerr << ex.what() << std::endl;
-               throw ex;
-       }
-}
diff --git a/gtk2_ardour/glade_factory.h b/gtk2_ardour/glade_factory.h
deleted file mode 100644 (file)
index 2fff3bd..0000000
+++ /dev/null
@@ -1,45 +0,0 @@
-/*
-    Copyright (C) 2005 Paul Davis 
-
-    This program is free software; you can redistribute it and/or modify
-    it under the terms of the GNU General Public License as published by
-    the Free Software Foundation; either version 2 of the License, or
-    (at your option) any later version.
-
-    This program is distributed in the hope that it will be useful,
-    but WITHOUT ANY WARRANTY; without even the implied warranty of
-    MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
-    GNU General Public License for more details.
-
-    You should have received a copy of the GNU General Public License
-    along with this program; if not, write to the Free Software
-    Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
-
-    $Id$
-*/
-
-// -*- c++ -*-
-
-#ifndef GLADE_FACTORY_H
-#define GLADE_FACTORY_H
-
-#include <string>
-#include <libglademm/xml.h>
-
-typedef Glib::RefPtr<Gnome::Glade::Xml> GladeRef;
-
-/**
-   This is the base class for all glade 
-   factories so that the same domain is
-   used.
-*/
-class GladeFactory {
-       
-protected:
-       static GladeRef
-       create(const std::string& full_path,
-              const Glib::ustring& toplevel_widget = Glib::ustring());
-};
-
-
-#endif // GLADE_FACTORY_H
diff --git a/gtk2_ardour/glade_path.cc b/gtk2_ardour/glade_path.cc
deleted file mode 100644 (file)
index 29bca71..0000000
+++ /dev/null
@@ -1,38 +0,0 @@
-/*
-    Copyright (C) 2005 Paul Davis 
-
-    This program is free software; you can redistribute it and/or modify
-    it under the terms of the GNU General Public License as published by
-    the Free Software Foundation; either version 2 of the License, or
-    (at your option) any later version.
-
-    This program is distributed in the hope that it will be useful,
-    but WITHOUT ANY WARRANTY; without even the implied warranty of
-    MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
-    GNU General Public License for more details.
-
-    You should have received a copy of the GNU General Public License
-    along with this program; if not, write to the Free Software
-    Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
-
-    $Id$
-*/
-
-#include <glibmm/fileutils.h>
-#include <glibmm/miscutils.h>
-
-#include <ardour/ardour.h>
-
-#include "i18n.h"
-#include "glade_path.h"
-
-#include <iostream>
-
-std::string
-GladePath::path(const std::string& glade_file)
-{
-    std::string full_path;
-   
-    full_path = ARDOUR::find_data_file(glade_file, "glade");
-    return full_path;
-}
diff --git a/gtk2_ardour/glade_path.h b/gtk2_ardour/glade_path.h
deleted file mode 100644 (file)
index a651b5f..0000000
+++ /dev/null
@@ -1,49 +0,0 @@
-/*
-    Copyright (C) 2005 Paul Davis 
-
-    This program is free software; you can redistribute it and/or modify
-    it under the terms of the GNU General Public License as published by
-    the Free Software Foundation; either version 2 of the License, or
-    (at your option) any later version.
-
-    This program is distributed in the hope that it will be useful,
-    but WITHOUT ANY WARRANTY; without even the implied warranty of
-    MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
-    GNU General Public License for more details.
-
-    You should have received a copy of the GNU General Public License
-    along with this program; if not, write to the Free Software
-    Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
-
-    $Id$
-*/
-
-#ifndef GLADE_PATH_H
-#define GLADE_PATH_H
-
-#include <string>
-
-struct GladePath {
-
-       /**
-          @return Path to glade file.
-          
-          XXX subject to change upon discussion.
-
-          glade files are currently looked for in
-          three possible directories in this order.
-
-          In the directory defined in the environment
-          variable ARDOUR_GLADE_PATH
-
-          In the users .ardour/glade directory.
-          
-          In the system defined glade path.
-       */
-       static std::string
-       path(const std::string& glade_filename);
-
-};
-
-#endif // GLADE_PATH_H
-
index b45966c5e3cdaca419db25a28d3bc3310f9e63ed..b18e08fabd24f9d5cc84a525d413f851a7e42256 100644 (file)
@@ -31,7 +31,7 @@
 #include <ardour/port.h>
 #include <ardour/insert.h>
 #include <ardour/session.h>
-#include <ardour/diskstream.h>
+#include <ardour/audio_diskstream.h>
 
 #include <gtkmm2ext/doi.h>
 #include <gtkmm2ext/gtk_ui.h>
index e9ac25a8f81b0f28e8f781dc6eff69473a43e67e..dc306906112ffc9864a23df80b8b5d7823cf7f85 100644 (file)
@@ -458,7 +458,6 @@ main (int argc, char *argv[])
                ui = 0;
        }
 
-  out:
        delete engine;
        ARDOUR::cleanup ();
        shutdown (0);
index 6b83a343226e88d944542a71f07a253bce918fae..755058acb2e8785b15ef6c1d2fb7975708df0fe0 100644 (file)
@@ -20,7 +20,7 @@
 
 #include <ardour/session.h>
 #include <ardour/session_route.h>
-#include <ardour/diskstream.h>
+#include <ardour/audio_diskstream.h>
 #include <ardour/audio_track.h>
 
 #include "ardour_ui.h"
index 9bdc8c340aa025601d1026f72b7cea0b390ccc68..cc66d1128aa14a7c678da92ed4df6fabcfe1f8bf 100644 (file)
@@ -37,7 +37,7 @@
 #include <ardour/audioengine.h>
 #include <ardour/route.h>
 #include <ardour/audio_track.h>
-#include <ardour/diskstream.h>
+#include <ardour/audio_diskstream.h>
 #include <ardour/panner.h>
 #include <ardour/send.h>
 #include <ardour/insert.h>
@@ -665,9 +665,9 @@ MixerStrip::select_stream_input ()
        MenuList& items = stream_menu->items();
        stream_menu->set_name ("ArdourContextMenu");
        
-       Session::DiskStreamList streams = _session.disk_streams();
+       Session::AudioDiskstreamList streams = _session.audio_disk_streams();
 
-       for (Session::DiskStreamList::iterator i = streams.begin(); i != streams.end(); ++i) {
+       for (Session::AudioDiskstreamList::iterator i = streams.begin(); i != streams.end(); ++i) {
 
                if (!(*i)->hidden()) {
 
@@ -685,7 +685,7 @@ MixerStrip::select_stream_input ()
 }
 
 void
-MixerStrip::stream_input_chosen (DiskStream *stream)
+MixerStrip::stream_input_chosen (AudioDiskstream *stream)
 {
        if (is_audio_track()) {
                audio_track()->set_diskstream (*stream, this);
index 65be3c00c1f1a96f26a3d187d8123282e575d84d..0cc8fed8e3bcdacc4ec61ec1afe642565be74fb2 100644 (file)
@@ -170,7 +170,7 @@ class MixerStrip : public RouteUI, public Gtk::EventBox
        Gtk::Menu output_menu;
        void add_connection_to_output_menu (ARDOUR::Connection *);
        
-       void stream_input_chosen (ARDOUR::DiskStream*);
+       void stream_input_chosen (ARDOUR::AudioDiskstream*);
        void select_stream_input ();
        void connection_input_chosen (ARDOUR::Connection *);
        void connection_output_chosen (ARDOUR::Connection *);
index 1ded8625c6d7cad34ec4c3b58db81ea4c225f6ed..916424b9bde8deda9d1bdb92094a1a8b3893e4e7 100644 (file)
@@ -34,7 +34,7 @@
 #include <ardour/session.h>
 #include <ardour/audio_track.h>
 #include <ardour/session_route.h>
-#include <ardour/diskstream.h>
+#include <ardour/audio_diskstream.h>
 #include <ardour/plugin_manager.h>
 
 #include "mixer_ui.h"
index 35320b3a48483ed720917ce0a830d94044afcefd..5108df60142677a433dbf75fdd17cd9e27244d4e 100644 (file)
@@ -45,7 +45,7 @@ namespace ARDOUR {
        class Route;
        class RouteGroup;
        class Session;
-       class DiskStream;
+       class AudioDiskstream;
        class AudioEngine;
 };
 
index 2ea5805098e7f3a359799fd8543a4b2a6ecfe879..69b812882411f25fc36780962bdeedad8c3561de 100644 (file)
@@ -83,7 +83,7 @@ GTK_ARDOUR::parse_opts (int argc, char *argv[])
                { "name", 1, 0, 'c' },
                { "novst", 0, 0, 'V' },
                { "new", 1, 0, 'N' },
-               { "use-hw-optimizations", 0, 0, 'o' },
+               { "no-hw-optimizations", 0, 0, 'O' },
                { "curvetest", 1, 0, 'C' },
                { "gtktheme", 0, 0, 'g' },
                { 0, 0, 0, 0 }
@@ -124,8 +124,8 @@ GTK_ARDOUR::parse_opts (int argc, char *argv[])
                        session_name = optarg;
                        break;
 
-               case 'o':
-                       try_hw_optimization = true;
+               case 'O':
+                       try_hw_optimization = false;
                        break;
 
                case 'V':
index eb0e7e3203040cc7a23692383a7267b9181c65f6..870fa2df5f18e85063ce011388d3b9bfa80edbab 100644 (file)
@@ -22,7 +22,7 @@
 #include <gtkmm/button.h>
 
 #include <ardour/session_playlist.h>
-#include <ardour/diskstream.h>
+#include <ardour/audio_diskstream.h>
 #include <ardour/playlist.h>
 #include <ardour/audio_track.h>
 #include <ardour/audioplaylist.h>
@@ -89,7 +89,7 @@ void
 PlaylistSelector::show_for (RouteUI* ruix)
 {
        vector<const char*> item;
-       DiskStream* this_ds;
+       AudioDiskstream* this_ds;
        string str;
 
        rui = ruix;
@@ -115,7 +115,7 @@ PlaylistSelector::show_for (RouteUI* ruix)
        
        for (DSPL_Map::iterator x = dspl_map.begin(); x != dspl_map.end(); ++x) {
 
-               DiskStream* ds = session->diskstream_by_id (x->first);
+               AudioDiskstream* ds = session->diskstream_by_id (x->first);
 
                if (ds == 0) {
                        continue;
index f186fab2d5be97ae7c638b2bdb17f21530e30b20..3d858a8f60a05ffdf7e068907bbcb115d669da69 100644 (file)
@@ -38,7 +38,7 @@
 #include <ardour/audioengine.h>
 #include <ardour/route.h>
 #include <ardour/audio_track.h>
-#include <ardour/diskstream.h>
+#include <ardour/audio_diskstream.h>
 #include <ardour/send.h>
 #include <ardour/insert.h>
 #include <ardour/ladspa_plugin.h>
index dbca103239c31b791a5cd6bd28e642cd74bcddf2..ad012b34831c54d90c0886ca18a148b0343483c1 100644 (file)
@@ -27,7 +27,8 @@
 
 #include <ardour/playlist.h>
 #include <ardour/audioregion.h>
-#include <ardour/diskstream.h>
+#include <ardour/audiosource.h>
+#include <ardour/audio_diskstream.h>
 
 #include "streamview.h"
 #include "regionview.h"
index aee247df026b500193e217e045f858a3b276fb18..7b6f00d76b2ca5844847a33c944f37f9934dc3bc 100644 (file)
@@ -26,7 +26,7 @@
 
 #include <ardour/session.h>
 #include <ardour/session_route.h>
-#include <ardour/diskstream.h>
+#include <ardour/audio_diskstream.h>
 #include <ardour/plugin.h>
 #include <ardour/plugin_manager.h>
 #include <ardour/ardour.h>
index 05f36831759ba54f7886139b36da5f459196c903..bd2cee26e9e8f17756dcf4420bc9bb2412e61165 100644 (file)
@@ -34,7 +34,7 @@
 
 #include <ardour/route.h>
 #include <ardour/audio_track.h>
-#include <ardour/diskstream.h>
+#include <ardour/audio_diskstream.h>
 
 #include "i18n.h"
 using namespace sigc;
@@ -433,7 +433,13 @@ RouteUI::refresh_remote_control_menu ()
 
        limit += 4; /* leave some breathing room */
        
-       for (uint32_t i = 0; i < limit; ++i) {
+       rc_items.push_back (RadioMenuElem (rc_group, _("None")));
+       if (_route.remote_control_id() == 0) {
+               rc_active = dynamic_cast<CheckMenuItem*> (&rc_items.back());
+               rc_active->set_active ();
+       }
+               
+       for (uint32_t i = 1; i < limit; ++i) {
                snprintf (buf, sizeof (buf), "%u", i);
                rc_items.push_back (RadioMenuElem (rc_group, buf));
                rc_active = dynamic_cast<RadioMenuItem*>(&rc_items.back());
@@ -872,7 +878,7 @@ RouteUI::is_audio_track () const
        return dynamic_cast<AudioTrack*>(&_route) != 0;
 }
 
-DiskStream*
+AudioDiskstream*
 RouteUI::get_diskstream () const
 {
        AudioTrack *at;
index b7a5b059f02b337cdf501984aee8f3be24575ca5..69c9b7f5a9ac92f0788e2f4183fb028517774c99 100644 (file)
@@ -50,7 +50,7 @@ class RouteUI : public virtual AxisView
        virtual ~RouteUI();
 
        bool is_audio_track() const;
-       ARDOUR::DiskStream* get_diskstream() const;
+       ARDOUR::AudioDiskstream* get_diskstream() const;
 
        ARDOUR::Route& route() const { return _route; }
        ARDOUR::AudioTrack* audio_track() const;
@@ -116,7 +116,7 @@ class RouteUI : public virtual AxisView
 
        sigc::connection blink_connection;
 
-       void rec_enable_button_blink (bool onoff, ARDOUR::DiskStream *, Gtk::Widget *w);
+       void rec_enable_button_blink (bool onoff, ARDOUR::AudioDiskstream *, Gtk::Widget *w);
        
        void remove_this_route ();
        static gint idle_remove_this_route (RouteUI *);
index 947f470ac8f342144a17892bd764520362f0234c..aa06d86bb893572bd0d5c07c483512d1b4375653 100644 (file)
@@ -31,7 +31,7 @@
 
 #include <ardour/audio_library.h>
 #include <ardour/audioregion.h>
-#include <ardour/externalsource.h>
+#include <ardour/audiofilesource.h>
 
 #include "ardour_ui.h"
 #include "gui_thread.h"
@@ -122,7 +122,7 @@ SoundFileBox::setup_labels (string filename)
        path = filename;
 
        string error_msg;
-       if(!ExternalSource::get_soundfile_info (filename, sf_info, error_msg)) {
+       if(!AudioFileSource::get_soundfile_info (filename, sf_info, error_msg)) {
                return false;
        }
 
@@ -187,12 +187,12 @@ SoundFileBox::play_btn_clicked ()
 
        if (region_cache.find (path) == region_cache.end()) {
                AudioRegion::SourceList srclist;
-               ExternalSource* sfs;
+               AudioFileSource* afs;
 
                for (int n = 0; n < sf_info.channels; ++n) {
                        try {
-                               sfs = ExternalSource::create (path+":"+string_compose("%1", n), false);
-                               srclist.push_back(sfs);
+                               afs = AudioFileSource::create (path+":"+string_compose("%1", n));
+                               srclist.push_back(afs);
 
                        } catch (failed_constructor& err) {
                                error << _("Could not access soundfile: ") << path << endmsg;
index 769e4ff02d9e4c587e735570f140b0ff49a4ff45..79c73b97ac9b5f800bbe7701e304488289f17b17 100644 (file)
@@ -40,7 +40,7 @@
 #include <gtkmm/treeview.h>
 
 #include <ardour/session.h>
-#include <ardour/externalsource.h>
+#include <ardour/audiofilesource.h>
 
 #include "ardour_dialog.h"
 #include "editing.h"
@@ -69,7 +69,7 @@ class SoundFileBox : public Gtk::VBox
 
     LabelModelColumns label_columns;
     
-       ARDOUR::SoundFileInfo sf_info;
+    ARDOUR::SoundFileInfo sf_info;
 
     pid_t current_pid;
 
index bceaf09f99a5e21063e34ea26b5e6bf1da836842..70c06b1db7da51f3aab2f411b51e409777be368d 100644 (file)
@@ -6,7 +6,8 @@
 
 #include <ardour/audioplaylist.h>
 #include <ardour/audioregion.h>
-#include <ardour/diskstream.h>
+#include <ardour/audiosource.h>
+#include <ardour/audio_diskstream.h>
 #include <ardour/audio_track.h>
 #include <ardour/playlist_templates.h>
 #include <ardour/source.h>
@@ -311,7 +312,7 @@ StreamView::undisplay_diskstream ()
 }
 
 void
-StreamView::display_diskstream (DiskStream *ds)
+StreamView::display_diskstream (AudioDiskstream *ds)
 {
        playlist_change_connection.disconnect();
        playlist_changed (ds);
@@ -337,7 +338,7 @@ StreamView::playlist_modified ()
 }
 
 void
-StreamView::playlist_changed (DiskStream *ds)
+StreamView::playlist_changed (AudioDiskstream *ds)
 {
        ENSURE_GUI_THREAD (bind (mem_fun (*this, &StreamView::playlist_changed), ds));
 
@@ -491,7 +492,7 @@ StreamView::diskstream_changed (void *src_ignored)
        AudioTrack *at;
 
        if ((at = _trackview.audio_track()) != 0) {
-               DiskStream& ds = at->disk_stream();
+               AudioDiskstream& ds = at->disk_stream();
                /* XXX grrr: when will SigC++ allow me to bind references? */
                Gtkmm2ext::UI::instance()->call_slot (bind (mem_fun (*this, &StreamView::display_diskstream), &ds));
        } else {
@@ -634,7 +635,7 @@ StreamView::setup_rec_box ()
                                peak_ready_connections.clear();
                                        
                                for (uint32_t n=0; n < _trackview.get_diskstream()->n_channels(); ++n) {
-                                       Source *src = (Source *) _trackview.get_diskstream()->write_source (n);
+                                       AudioSource *src = (AudioSource *) _trackview.get_diskstream()->write_source (n);
                                        if (src) {
                                                sources.push_back (src);
                                                peak_ready_connections.push_back (src->PeakRangeReady.connect (bind (mem_fun (*this, &StreamView::rec_peak_range_ready), src))); 
@@ -662,7 +663,7 @@ StreamView::setup_rec_box ()
                        AudioTrack* at;
 
                        at = _trackview.audio_track(); /* we know what it is already */
-                       DiskStream& ds = at->disk_stream();
+                       AudioDiskstream& ds = at->disk_stream();
                        jack_nframes_t frame_pos = ds.current_capture_start ();
                        gdouble xstart = _trackview.editor.frame_to_pixel (frame_pos);
                        gdouble xend;
index eb17083de11685628b2c465150cfc68aff560013..00ec2d93f2a8a13b52a52fd10f935b805caaf87f 100644 (file)
@@ -37,7 +37,7 @@ namespace Gdk {
 
 namespace ARDOUR {
        class Route;
-       class DiskStream;
+       class AudioDiskstream;
        class Crossfade;
        class PeakData;
        class AudioRegion;
@@ -151,12 +151,12 @@ class StreamView : public sigc::trackable
        void remove_audio_region_view (ARDOUR::AudioRegion* );
        void remove_audio_rec_region (ARDOUR::AudioRegion*);
 
-       void display_diskstream (ARDOUR::DiskStream* );
+       void display_diskstream (ARDOUR::AudioDiskstream* );
        void undisplay_diskstream ();
        void redisplay_diskstream ();
        void diskstream_changed (void* );
        void playlist_state_changed (ARDOUR::Change);
-       void playlist_changed (ARDOUR::DiskStream* );
+       void playlist_changed (ARDOUR::AudioDiskstream* );
        void playlist_modified ();
 
        bool crossfades_visible;
index 19276223ef1f4ebf87a21281d241681ceb468b70..533b715ce4f9150896660702ae914a2ef7cf1095 100644 (file)
@@ -27,7 +27,8 @@
 
 #include <ardour/playlist.h>
 #include <ardour/audioregion.h>
-#include <ardour/diskstream.h>
+#include <ardour/audiosource.h>
+#include <ardour/audio_diskstream.h>
 
 #include "taperegionview.h"
 #include "audio_time_axis.h"
index 33e4633a79312a3b7655ffcab337029ee240033a..33e40f4230d7f99733c9e7188700e65aea5718fa 100644 (file)
@@ -27,12 +27,15 @@ ardour.Append(POTFILE = domain + '.pot')
 ardour.Append(CPPPATH = '#libs/surfaces/control_protocol')
 
 ardour_files=Split("""
+audio_diskstream.cc
 audio_library.cc
 audio_playlist.cc
 audio_track.cc
 audioengine.cc
+audiofilesource.cc
 audiofilter.cc
 audioregion.cc
+audiosource.cc
 auditioner.cc
 automation.cc
 automation_event.cc
@@ -44,9 +47,6 @@ curve.cc
 cycle_timer.cc
 default_click.cc
 destructive_filesource.cc
-diskstream.cc
-externalsource.cc
-filesource.cc
 gain.cc
 gdither.cc
 globals.cc
@@ -202,8 +202,8 @@ ardour.Merge ([
             libraries['pbd3'],
             libraries['soundtouch'],
             libraries['midi++2'],
-             libraries['glib2'],
-             libraries['glibmm2']
+            libraries['glib2'],
+            libraries['glibmm2']
             ])
 
 if ardour['LIBLO']:
diff --git a/libs/ardour/ardour/audio_diskstream.h b/libs/ardour/ardour/audio_diskstream.h
new file mode 100644 (file)
index 0000000..9355a3f
--- /dev/null
@@ -0,0 +1,447 @@
+/*
+    Copyright (C) 2000 Paul Davis 
+
+    This program is free software; you can redistribute it and/or modify
+    it under the terms of the GNU General Public License as published by
+    the Free Software Foundation; either version 2 of the License, or
+    (at your option) any later version.
+
+    This program is distributed in the hope that it will be useful,
+    but WITHOUT ANY WARRANTY; without even the implied warranty of
+    MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+    GNU General Public License for more details.
+
+    You should have received a copy of the GNU General Public License
+    along with this program; if not, write to the Free Software
+    Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
+
+    $Id: diskstream.h 579 2006-06-12 19:56:37Z essej $
+*/
+
+#ifndef __ardour_diskstream_h__
+#define __ardour_diskstream_h__
+
+#include <sigc++/signal.h>
+
+#include <cmath>
+#include <string>
+#include <queue>
+#include <map>
+#include <vector>
+
+#include <time.h>
+
+#include <pbd/fastlog.h>
+#include <pbd/ringbufferNPT.h>
+
+#include <ardour/ardour.h>
+#include <ardour/configuration.h>
+#include <ardour/session.h>
+#include <ardour/route_group.h>
+#include <ardour/route.h>
+#include <ardour/port.h>
+#include <ardour/utils.h>
+#include <ardour/stateful.h>
+
+struct tm;
+
+namespace ARDOUR {
+
+class AudioEngine;
+class Send;
+class Session;
+class AudioPlaylist;
+class AudioFileSource;
+class IO;
+
+class AudioDiskstream : public Stateful, public sigc::trackable
+{      
+  public:
+       enum Flag {
+               Recordable = 0x1,
+               Hidden = 0x2,
+               Destructive = 0x4
+       };
+
+       AudioDiskstream (Session &, const string& name, Flag f = Recordable);
+       AudioDiskstream (Session &, const XMLNode&);
+
+       string name() const { return _name; }
+
+       ARDOUR::IO* io() const { return _io; }
+       void set_io (ARDOUR::IO& io);
+
+       AudioDiskstream& ref() { _refcnt++; return *this; }
+       void unref() { if (_refcnt) _refcnt--; if (_refcnt == 0) delete this; }
+       uint32_t refcnt() const { return _refcnt; }
+
+       float playback_buffer_load() const;
+       float capture_buffer_load() const;
+
+       void set_flag (Flag f) {
+               _flags |= f;
+       }
+
+       void unset_flag (Flag f) {
+               _flags &= ~f;
+       }
+
+       AlignStyle alignment_style() const { return _alignment_style; }
+       void set_align_style (AlignStyle);
+       void set_persistent_align_style (AlignStyle);
+
+       bool hidden() const { return _flags & Hidden; }
+       bool recordable() const { return _flags & Recordable; }
+       bool destructive() const { return _flags & Destructive; }
+
+       void set_destructive (bool yn);
+
+       jack_nframes_t roll_delay() const { return _roll_delay; }
+       void set_roll_delay (jack_nframes_t);
+
+       int set_name (string str, void* src);
+
+       string input_source (uint32_t n=0) const {
+               if (n < channels.size()) {
+                       return channels[n].source ? channels[n].source->name() : "";
+               } else {
+                       return ""; 
+               }
+       }
+
+       Port *input_source_port (uint32_t n=0) const { 
+               if (n < channels.size()) return channels[n].source; return 0; 
+       }
+
+       void set_record_enabled (bool yn, void *src);
+       bool record_enabled() const { return g_atomic_int_get (&_record_enabled); }
+       void punch_in ();
+       void punch_out ();
+
+       bool  reversed() const { return _actual_speed < 0.0f; }
+       double speed() const { return _visible_speed; }
+       void set_speed (double);
+
+       float peak_power(uint32_t n=0) { 
+               float x = channels[n].peak_power;
+               channels[n].peak_power = 0.0f;
+               if (x > 0.0f) {
+                       return 20.0f * fast_log10(x);
+               } else {
+                       return minus_infinity();
+               }
+       }
+
+       int  use_playlist (AudioPlaylist *);
+       int use_new_playlist ();
+       int use_copy_playlist ();
+
+       void start_scrub (jack_nframes_t where);
+       void end_scrub ();
+
+       Sample *playback_buffer (uint32_t n=0) {
+               if (n < channels.size())
+                       return channels[n].current_playback_buffer;
+               return 0;
+       }
+       
+       Sample *capture_buffer (uint32_t n=0) {
+               if (n < channels.size())
+                       return channels[n].current_capture_buffer;
+               return 0;
+       }
+
+       AudioPlaylist *playlist () { return _playlist; }
+
+       AudioFileSource *write_source (uint32_t n=0) {
+               if (n < channels.size())
+                       return channels[n].write_source;
+               return 0;
+       }
+
+       jack_nframes_t current_capture_start() const { return capture_start_frame; }
+       jack_nframes_t current_capture_end() const { return capture_start_frame + capture_captured; }
+       jack_nframes_t get_capture_start_frame (uint32_t n=0);
+       jack_nframes_t get_captured_frames (uint32_t n=0);
+       
+       uint32_t n_channels() { return _n_channels; }
+
+       int add_channel ();
+       int remove_channel ();
+       
+       static void set_disk_io_chunk_frames (uint32_t n) {
+               disk_io_chunk_frames = n;
+       }
+
+       static jack_nframes_t disk_io_frames() { return disk_io_chunk_frames; }
+       
+       sigc::signal<void,void*> record_enable_changed;
+       sigc::signal<void>       speed_changed;
+       sigc::signal<void,void*> reverse_changed;
+       sigc::signal<void>       PlaylistChanged;
+       sigc::signal<void>       AlignmentStyleChanged;
+
+       static sigc::signal<void> DiskOverrun;
+       static sigc::signal<void> DiskUnderrun;
+       static sigc::signal<void,AudioDiskstream*> AudioDiskstreamCreated;   // XXX use a ref with sigc2
+       static sigc::signal<void,list<AudioFileSource*>*> DeleteSources;
+
+       /* stateful */
+
+       XMLNode& get_state(void);
+       int set_state(const XMLNode& node);
+
+       void monitor_input (bool);
+
+       jack_nframes_t capture_offset() const { return _capture_offset; }
+       void           set_capture_offset ();
+
+       static void swap_by_ptr (Sample *first, Sample *last) {
+               while (first < last) {
+                       Sample tmp = *first;
+                       *first++ = *last;
+                       *last-- = tmp;
+               }
+       }
+
+       static void swap_by_ptr (Sample *first, Sample *last, jack_nframes_t n) {
+               while (n--) {
+                       Sample tmp = *first;
+                       *first++ = *last;
+                       *last-- = tmp;
+               }
+       }
+
+       bool slaved() const { return _slaved; }
+       void set_slaved(bool yn) { _slaved = yn; }
+
+       int set_loop (Location *loc);
+       sigc::signal<void,Location *> LoopSet;
+
+       std::list<Region*>& last_capture_regions () {
+               return _last_capture_regions;
+       }
+
+       void handle_input_change (IOChange, void *src);
+
+       id_t id() const { return _id; }
+
+       XMLNode* deprecated_io_node;
+
+  protected:
+       friend class Session;
+
+       /* the Session is the only point of access for these
+          because they require that the Session is "inactive"
+          while they are called.
+       */
+
+       void set_pending_overwrite (bool);
+       int  overwrite_existing_buffers ();
+       void reverse_scrub_buffer (bool to_forward);
+       void set_block_size (jack_nframes_t);
+       int  internal_playback_seek (jack_nframes_t distance);
+       int  can_internal_playback_seek (jack_nframes_t distance);
+       int  rename_write_sources ();
+       void reset_write_sources (bool, bool force = false);
+       void non_realtime_input_change ();
+
+       uint32_t read_data_count() const { return _read_data_count; }
+       uint32_t write_data_count() const { return _write_data_count; }
+
+  protected:
+       friend class Auditioner;
+       int  seek (jack_nframes_t which_sample, bool complete_refill = false);
+
+  protected:
+       friend class AudioTrack;
+
+       void prepare ();
+       int  process (jack_nframes_t transport_frame, jack_nframes_t nframes, jack_nframes_t offset, bool can_record, bool rec_monitors_input);
+       bool commit  (jack_nframes_t nframes);
+       void recover (); /* called if commit will not be called, but process was */
+
+  private:
+
+       /* use unref() to destroy a diskstream */
+
+       ~AudioDiskstream();
+
+       enum TransitionType {
+               CaptureStart = 0,
+               CaptureEnd
+       };
+       
+       struct CaptureTransition {
+
+               TransitionType   type;
+               // the start or end file frame pos
+               jack_nframes_t   capture_val;
+       };
+       
+       struct ChannelInfo {
+
+               Sample     *playback_wrap_buffer;
+               Sample     *capture_wrap_buffer;
+               Sample     *speed_buffer;
+
+               float       peak_power;
+
+               AudioFileSource   *fades_source;
+               AudioFileSource   *write_source;
+
+               Port         *source;
+               Sample       *current_capture_buffer;
+               Sample       *current_playback_buffer;
+
+               RingBufferNPT<Sample> *playback_buf;
+               RingBufferNPT<Sample> *capture_buf;
+
+               Sample* scrub_buffer;
+               Sample* scrub_forward_buffer;
+               Sample* scrub_reverse_buffer;
+
+               RingBufferNPT<Sample>::rw_vector playback_vector;
+               RingBufferNPT<Sample>::rw_vector capture_vector;
+
+               RingBufferNPT<CaptureTransition> * capture_transition_buf;
+               // the following are used in the butler thread only
+               jack_nframes_t                     curr_capture_cnt;
+       };
+
+       typedef vector<ChannelInfo> ChannelList;
+
+
+       string            _name;
+       ARDOUR::Session&  _session;
+       ARDOUR::IO*       _io;
+       ChannelList        channels;
+       uint32_t      _n_channels;
+       id_t              _id;
+
+       mutable gint             _record_enabled;
+       AudioPlaylist*           _playlist;
+       double                   _visible_speed;
+       double                   _actual_speed;
+       /* items needed for speed change logic */
+       bool                     _buffer_reallocation_required;
+       bool                     _seek_required;
+       
+       bool                      force_refill;
+       jack_nframes_t            capture_start_frame;
+       jack_nframes_t            capture_captured;
+       bool                      was_recording;
+       jack_nframes_t            adjust_capture_position;
+       jack_nframes_t           _capture_offset;
+       jack_nframes_t           _roll_delay;
+       jack_nframes_t            first_recordable_frame;
+       jack_nframes_t            last_recordable_frame;
+       int                       last_possibly_recording;
+       AlignStyle               _alignment_style;
+       bool                     _scrubbing;
+       bool                     _slaved;
+       bool                     _processed;
+       Location*                 loop_location;
+       jack_nframes_t            overwrite_frame;
+       off_t                     overwrite_offset;
+       bool                      pending_overwrite;
+       bool                      overwrite_queued;
+       IOChange                  input_change_pending;
+       jack_nframes_t            wrap_buffer_size;
+       jack_nframes_t            speed_buffer_size;
+
+       uint64_t                  last_phase;
+       uint64_t                  phi;
+       
+       jack_nframes_t            file_frame;           
+       jack_nframes_t            playback_sample;
+       jack_nframes_t            playback_distance;
+
+       uint32_t                 _read_data_count;
+       uint32_t                 _write_data_count;
+
+       bool                      in_set_state;
+       AlignStyle               _persistent_alignment_style;
+       bool                      first_input_change;
+
+       Glib::Mutex  state_lock;
+
+       jack_nframes_t scrub_start;
+       jack_nframes_t scrub_buffer_size;
+       jack_nframes_t scrub_offset;
+       uint32_t _refcnt;
+
+       sigc::connection ports_created_c;
+       sigc::connection plmod_connection;
+       sigc::connection plstate_connection;
+       sigc::connection plgone_connection;
+
+       /* the two central butler operations */
+
+       int do_flush (char * workbuf, bool force = false);
+       int do_refill (Sample *mixdown_buffer, float *gain_buffer, char *workbuf);
+
+       int read (Sample* buf, Sample* mixdown_buffer, float* gain_buffer, char * workbuf, jack_nframes_t& start, jack_nframes_t cnt, 
+                 ChannelInfo& channel_info, int channel, bool reversed);
+
+       uint32_t i_am_the_modifier;
+       
+       /* XXX fix this redundancy ... */
+
+       void playlist_changed (Change);
+       void playlist_modified ();
+       void playlist_deleted (Playlist*);
+       void session_controls_changed (Session::ControlType);
+
+       void finish_capture (bool rec_monitors_input);
+       void clean_up_capture (struct tm&, time_t, bool abort);
+       void transport_stopped (struct tm&, time_t, bool abort);
+
+       struct CaptureInfo {
+           uint32_t start;
+           uint32_t frames;
+       };
+
+       vector<CaptureInfo*> capture_info;
+       Glib::Mutex  capture_info_lock;
+       
+       void init (Flag);
+
+       void init_channel (ChannelInfo &chan);
+       void destroy_channel (ChannelInfo &chan);
+       
+       static jack_nframes_t disk_io_chunk_frames;
+
+       int use_new_write_source (uint32_t n=0);
+       int use_new_fade_source (uint32_t n=0);
+
+       int find_and_use_playlist (const string&);
+
+       void allocate_temporary_buffers ();
+
+       unsigned char _flags;
+
+       int  create_input_port ();
+       int  connect_input_port ();
+       int  seek_unlocked (jack_nframes_t which_sample);
+
+       int ports_created ();
+
+       bool realtime_set_speed (double, bool global_change);
+       void non_realtime_set_speed ();
+
+       std::list<Region*> _last_capture_regions;
+       std::vector<AudioFileSource*> capturing_sources;
+       int use_pending_capture_data (XMLNode& node);
+
+       void get_input_sources ();
+       void check_record_status (jack_nframes_t transport_frame, jack_nframes_t nframes, bool can_record);
+       void set_align_style_from_io();
+       void setup_destructive_playlist ();
+       void use_destructive_playlist ();
+};
+
+}; /* namespace ARDOUR */
+
+#endif /* __ardour_diskstream_h__ */
index c7af9fc5d81794e0bf6651b9024b4d57677a75b2..1c17cbc85991e91e8356211d6ef0a954ce3d0d7b 100644 (file)
@@ -26,7 +26,7 @@
 namespace ARDOUR {
 
 class Session;
-class DiskStream;
+class AudioDiskstream;
 class AudioPlaylist;
 class RouteGroup;
 
@@ -52,8 +52,8 @@ class AudioTrack : public Route
        bool can_record() const { return true; }
        void set_record_enable (bool yn, void *src);
 
-       DiskStream& disk_stream() const { return *diskstream; }
-       int set_diskstream (DiskStream&, void *);
+       AudioDiskstream& disk_stream() const { return *diskstream; }
+       int set_diskstream (AudioDiskstream&, void *);
        int use_diskstream (string name);
        int use_diskstream (id_t id);
 
@@ -99,7 +99,7 @@ class AudioTrack : public Route
        void set_meter_point (MeterPoint, void* src);
 
   protected:
-       DiskStream *diskstream;
+       AudioDiskstream *diskstream;
        MeterPoint _saved_meter_point;
        TrackMode _mode;
 
diff --git a/libs/ardour/ardour/audiofilesource.h b/libs/ardour/ardour/audiofilesource.h
new file mode 100644 (file)
index 0000000..ecbac56
--- /dev/null
@@ -0,0 +1,157 @@
+/*
+    Copyright (C) 2006 Paul Davis 
+
+    This program is free software; you can redistribute it and/or modify
+    it under the terms of the GNU General Public License as published by
+    the Free Software Foundation; either version 2 of the License, or
+    (at your option) any later version.
+
+    This program is distributed in the hope that it will be useful,
+    but WITHOUT ANY WARRANTY; without even the implied warranty of
+    MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+    GNU General Public License for more details.
+
+    You should have received a copy of the GNU General Public License
+    along with this program; if not, write to the Free Software
+    Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
+
+*/
+
+#ifndef __ardour_audiofilesource_h__ 
+#define __ardour_audiofilesource_h__
+
+#include <time.h>
+
+#include <ardour/audiosource.h>
+
+namespace ARDOUR {
+
+struct SoundFileInfo {
+    float       samplerate;
+    uint16_t    channels;
+    int64_t     length;
+    std::string format_name;
+};
+
+class AudioFileSource : public AudioSource {
+  public:
+       enum Flag {
+               Writable = 0x1,
+               CanRename = 0x2,
+               Broadcast = 0x4,
+               Removable = 0x8,
+               RemovableIfEmpty = 0x10,
+               RemoveAtDestroy = 0x20,
+               BuildPeaks = 0x40
+       };
+
+       virtual ~AudioFileSource ();
+
+       int set_name (string newname, bool destructive);
+
+       string path() const { return _path; }
+       string peak_path (string audio_path);
+       string old_peak_path (string audio_path);
+
+       static void set_peak_dir (string dir) { peak_dir = dir; }
+
+       /* factory for an existing but not-used-in-session audio file. this exists
+          because there maybe multiple back-end derivations of AudioFileSource,
+          some of which can handle formats that cannot be handled by others.
+          For example, CoreAudioFileSource can handle MP3 files, which SndFileSource
+          cannot.
+        */
+
+       static AudioFileSource* create (string path_plus_channel);
+       static AudioFileSource* create (const XMLNode&);
+
+       static bool get_soundfile_info (string path, SoundFileInfo& _info, string& error);
+
+       void set_allow_remove_if_empty (bool yn);
+       void mark_for_remove();
+
+       /* this block of methods do nothing for regular file sources, but are significant
+          for files used in destructive recording.
+       */
+
+       virtual jack_nframes_t last_capture_start_frame() const { return 0; }
+       virtual void           mark_capture_start (jack_nframes_t) {}
+       virtual void           mark_capture_end () {}
+       virtual void           clear_capture_marks() {}
+
+       virtual int update_header (jack_nframes_t when, struct tm&, time_t) = 0;
+       virtual int flush_header () = 0;
+
+       int move_to_trash (const string trash_dir_name);
+
+       static bool is_empty (string path);
+       void mark_streaming_write_completed ();
+
+       void   mark_take (string);
+       string take_id() const { return _take_id; }
+
+       static void set_bwf_country_code (string x);
+       static void set_bwf_organization_code (string x);
+       static void set_bwf_serial_number (int);
+       
+       static void set_search_path (string);
+       static void set_header_position_offset (jack_nframes_t offset, bool negative);
+
+       static sigc::signal<void,struct tm*, time_t> HeaderPositionOffsetChanged;
+
+       XMLNode& get_state ();
+       int set_state (const XMLNode&);
+
+       /* this should really be protected, but C++ is getting stricter
+          and creating slots from protected member functions is starting
+          to cause issues.
+       */
+
+       void handle_header_position_change (struct tm*, time_t tnow);
+
+  protected:
+       
+       /* constructor to be called for existing external-to-session files */
+
+       AudioFileSource (std::string path, Flag flags);
+
+       /* constructor to be called for new in-session files */
+
+       AudioFileSource (std::string path, Flag flags,
+                        SampleFormat samp_format, HeaderFormat hdr_format);
+
+       /* constructor to be called for existing in-session files */
+
+       AudioFileSource (const XMLNode&);
+
+       int init (string idstr, bool must_exist);
+
+       uint16_t       channel;
+       string        _path;
+       Flag          _flags;
+       string        _take_id;
+       bool           allow_remove_if_empty;
+       uint64_t       timeline_position;
+
+       static string peak_dir;
+       static string search_path;
+
+       static char bwf_country_code[3];
+       static char bwf_organization_code[4];
+       static char bwf_serial_number[13];
+
+       static uint64_t header_position_offset;
+       static bool     header_position_negative;
+
+       virtual void set_timeline_position (jack_nframes_t pos);
+       virtual void set_header_timeline_position () = 0;
+
+       bool find (std::string path, bool must_exist, bool& is_new);
+       bool removable() const;
+       bool writable() const { return _flags & Writable; }
+};
+
+}; /* namespace ARDOUR */
+
+#endif /* __ardour_audiofilesource_h__ */
+
index d0fc275cf6a2d94895f2532fff685620613b80a4..02e5e6f06171c03ae3e540570d50168a11736a0b 100644 (file)
@@ -28,7 +28,6 @@ namespace ARDOUR {
 
 class AudioRegion;
 class Session;
-class FileSource;
 
 class AudioFilter {
 
@@ -37,7 +36,6 @@ class AudioFilter {
                : session (s){}
        virtual ~AudioFilter() {}
 
-
        virtual int run (ARDOUR::AudioRegion&) = 0;
        std::vector<ARDOUR::AudioRegion*> results;
 
index f210fa595be3a1f91da145b244c68ceb312d7dca..009aa4b5b0da34b3f1acf55cba17dfa5025c3d1e 100644 (file)
@@ -27,7 +27,6 @@
 #include <pbd/undo.h>
 
 #include <ardour/ardour.h>
-#include <ardour/source.h>
 #include <ardour/gain.h>
 #include <ardour/region.h>
 #include <ardour/export.h>
@@ -40,6 +39,7 @@ class Route;
 class Playlist;
 class Session;
 class AudioFilter;
+class AudioSource;
 
 struct AudioRegionState : public RegionState 
 {
@@ -56,7 +56,7 @@ struct AudioRegionState : public RegionState
 class AudioRegion : public Region
 {
   public:
-       typedef vector<Source *> SourceList;
+       typedef vector<AudioSource *> SourceList;
 
        static Change FadeInChanged;
        static Change FadeOutChanged;
@@ -66,12 +66,12 @@ class AudioRegion : public Region
        static Change ScaleAmplitudeChanged;
        static Change EnvelopeChanged;
 
-       AudioRegion (Source&, jack_nframes_t start, jack_nframes_t length, bool announce = true);
-       AudioRegion (Source&, jack_nframes_t start, jack_nframes_t length, const string& name, layer_t = 0, Region::Flag flags = Region::DefaultFlags, bool announce = true);
+       AudioRegion (AudioSource&, jack_nframes_t start, jack_nframes_t length, bool announce = true);
+       AudioRegion (AudioSource&, jack_nframes_t start, jack_nframes_t length, const string& name, layer_t = 0, Region::Flag flags = Region::DefaultFlags, bool announce = true);
        AudioRegion (SourceList &, jack_nframes_t start, jack_nframes_t length, const string& name, layer_t = 0, Region::Flag flags = Region::DefaultFlags, bool announce = true);
        AudioRegion (const AudioRegion&, jack_nframes_t start, jack_nframes_t length, const string& name, layer_t = 0, Region::Flag flags = Region::DefaultFlags, bool announce = true);
        AudioRegion (const AudioRegion&);
-       AudioRegion (Source&, const XMLNode&);
+       AudioRegion (AudioSource&, const XMLNode&);
        AudioRegion (SourceList &, const XMLNode&);
        ~AudioRegion();
 
@@ -85,7 +85,7 @@ class AudioRegion : public Region
 
        void lock_sources ();
        void unlock_sources ();
-       Source& source (uint32_t n=0) const { if (n < sources.size()) return *sources[n]; else return *sources[0]; } 
+       AudioSource& source (uint32_t n=0) const { if (n < sources.size()) return *sources[n]; else return *sources[0]; } 
 
        void set_scale_amplitude (gain_t);
        gain_t scale_amplitude() const { return _scale_amplitude; }
diff --git a/libs/ardour/ardour/audiosource.h b/libs/ardour/ardour/audiosource.h
new file mode 100644 (file)
index 0000000..1dcf5b4
--- /dev/null
@@ -0,0 +1,166 @@
+/*
+    Copyright (C) 2000 Paul Davis 
+
+    This program is free software; you can redistribute it and/or modify
+    it under the terms of the GNU General Public License as published by
+    the Free Software Foundation; either version 2 of the License, or
+    (at your option) any later version.
+
+    This program is distributed in the hope that it will be useful,
+    but WITHOUT ANY WARRANTY; without even the implied warranty of
+    MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+    GNU General Public License for more details.
+
+    You should have received a copy of the GNU General Public License
+    along with this program; if not, write to the Free Software
+    Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
+
+    $Id: audio_source.h 486 2006-04-27 09:04:24Z pauld $
+*/
+
+#ifndef __ardour_audio_source_h__
+#define __ardour_audio_source_h__
+
+#include <list>
+#include <vector>
+#include <string>
+
+#include <time.h>
+
+#include <glibmm/thread.h>
+
+#include <sigc++/signal.h>
+
+#include <ardour/source.h>
+#include <ardour/ardour.h>
+#include <ardour/stateful.h>
+#include <pbd/xml++.h>
+
+using std::list;
+using std::vector;
+using std::string;
+
+namespace ARDOUR {
+
+const jack_nframes_t frames_per_peak = 256;
+
+class AudioSource : public Source
+{
+  public:
+       AudioSource (string name);
+       AudioSource (const XMLNode&);
+       virtual ~AudioSource ();
+
+       /* returns the number of items in this `audio_source' */
+
+       virtual jack_nframes_t length() const {
+               return _length;
+       }
+
+       virtual jack_nframes_t available_peaks (double zoom) const;
+
+       virtual jack_nframes_t read (Sample *dst, jack_nframes_t start, jack_nframes_t cnt, char * workbuf) const;
+       virtual jack_nframes_t write (Sample *src, jack_nframes_t cnt, char * workbuf);
+
+       virtual float sample_rate () const = 0;
+
+       virtual void mark_for_remove() = 0;
+       virtual void mark_streaming_write_completed () {}
+
+       void set_captured_for (string str) { _captured_for = str; }
+       string captured_for() const { return _captured_for; }
+
+       uint32_t read_data_count() const { return _read_data_count; }
+       uint32_t write_data_count() const { return _write_data_count; }
+
+       int  read_peaks (PeakData *peaks, jack_nframes_t npeaks, jack_nframes_t start, jack_nframes_t cnt, double samples_per_unit) const;
+       int  build_peaks ();
+       bool peaks_ready (sigc::slot<void>, sigc::connection&) const;
+
+       static sigc::signal<void,AudioSource*> AudioSourceCreated;
+              
+       mutable sigc::signal<void>  PeaksReady;
+       mutable sigc::signal<void,jack_nframes_t,jack_nframes_t>  PeakRangeReady;
+       
+       XMLNode& get_state ();
+       int set_state (const XMLNode&);
+
+       static int  start_peak_thread ();
+       static void stop_peak_thread ();
+
+       int rename_peakfile (std::string newpath);
+
+       static void set_build_missing_peakfiles (bool yn) {
+               _build_missing_peakfiles = yn;
+       }
+
+       static void set_build_peakfiles (bool yn) {
+               _build_peakfiles = yn;
+       }
+
+  protected:
+       static bool _build_missing_peakfiles;
+       static bool _build_peakfiles;
+
+       bool                _peaks_built;
+       mutable Glib::Mutex _lock;
+       jack_nframes_t      _length;
+       bool                 next_peak_clear_should_notify;
+       string               peakpath;
+       string              _captured_for;
+
+       mutable uint32_t _read_data_count;  // modified in read()
+       mutable uint32_t _write_data_count; // modified in write()
+
+       int initialize_peakfile (bool newfile, string path);
+       void build_peaks_from_scratch ();
+
+       int  do_build_peak (jack_nframes_t, jack_nframes_t);
+
+       virtual jack_nframes_t read_unlocked (Sample *dst, jack_nframes_t start, jack_nframes_t cnt, char * workbuf) const = 0;
+       virtual jack_nframes_t write_unlocked (Sample *dst, jack_nframes_t cnt, char * workbuf) = 0;
+       virtual string peak_path(string audio_path) = 0;
+       virtual string old_peak_path(string audio_path) = 0;
+       
+       void update_length (jack_nframes_t pos, jack_nframes_t cnt);
+
+       static pthread_t peak_thread;
+       static bool      have_peak_thread;
+       static void*     peak_thread_work(void*);
+
+       static int peak_request_pipe[2];
+
+       struct PeakRequest {
+           enum Type {
+                   Build,
+                   Quit
+           };
+       };
+
+       static vector<AudioSource*> pending_peak_sources;
+       static Glib::Mutex* pending_peak_sources_lock;
+
+       static void queue_for_peaks (AudioSource&);
+       static void clear_queue_for_peaks ();
+       
+       struct PeakBuildRecord {
+           jack_nframes_t frame;
+           jack_nframes_t cnt;
+
+           PeakBuildRecord (jack_nframes_t f, jack_nframes_t c) 
+                   : frame (f), cnt (c) {}
+           PeakBuildRecord (const PeakBuildRecord& other) {
+                   frame = other.frame;
+                   cnt = other.cnt;
+           }
+       };
+
+       list<AudioSource::PeakBuildRecord *> pending_peak_builds;
+
+  private:
+       bool file_changed (string path);
+};
+
+}
+
+#endif /* __ardour_audio_source_h__ */
index 736ea32df796994fb848935ab896ed6ddafc4f46..82533de95097eac4b8be5931bec8a5346a2990a6 100644 (file)
@@ -31,8 +31,11 @@ class CoreAudioSource : public ExternalSource {
        CoreAudioSource (const XMLNode&);
        ~CoreAudioSource ();
 
-       jack_nframes_t read (Sample *dst, jack_nframes_t start, jack_nframes_t cnt, char * workbuf) const;
        float sample_rate() const;
+       int update_header (jack_nframes_t when, struct tm&, time_t);
+
+  protected:
+       jack_nframes_t read_unlocked (Sample *dst, jack_nframes_t start, jack_nframes_t cnt, char * workbuf) const;
 
   private:
        ExtAudioFileRef af;
index 1ec7c7490385301a1d3ce1ff32cdb7b5ad9950c8..b9cbbbf0a8ded5550947f0a33c45228309cf6b0a 100644 (file)
 #define __ardour_cycle_timer_h__
 
 #include <string>
-#include <cstdio>
+#include <iostream>
 
 #include <ardour/cycles.h>
 
-using std::string;
-
 class CycleTimer {
   private:
        static float cycles_per_usec;
-       uint32_t long entry;
-       uint32_t long exit;
-       string _name;
+       cycles_t _entry;
+       cycles_t _exit;
+       std::string _name;
        
   public:
-       CycleTimer(string name) : _name (name){
+       CycleTimer(std::string name) : _name (name){
                if (cycles_per_usec == 0) {
                        cycles_per_usec = get_mhz ();
                }
-               entry = get_cycles();
+               _entry = get_cycles();
        }
        ~CycleTimer() {
-               exit = get_cycles();
-               printf ("%s: %.9f usecs (%lu-%lu)\n", _name.c_str(), (float) (exit - entry) / cycles_per_usec, entry, exit);
+               _exit = get_cycles();
+               std::cerr << _name << ": " << (float) (_exit - _entry) / cycles_per_usec << " (" <<  _entry << ", " << _exit << ')' << endl;
        }
 
        static float get_mhz ();
index dbaf379257ad0023cbc82432a610c308b3fc1e43..49a1e3b48aa0ab7b3603d74c39f5b50e46e43d9a 100644 (file)
 
 #include <string>
 
-#include <ardour/filesource.h>
+#include <ardour/sndfilesource.h>
 
 struct tm;
 
 namespace ARDOUR {
 
-class DestructiveFileSource : public FileSource {
+class DestructiveFileSource : public SndFileSource {
   public:
-       DestructiveFileSource (std::string path, jack_nframes_t rate, bool repair_first = false, SampleFormat samp_format=FormatInt24);
-       DestructiveFileSource (const XMLNode&, jack_nframes_t rate);
+       DestructiveFileSource (std::string path, SampleFormat samp_format, HeaderFormat hdr_format, jack_nframes_t rate,
+                              Flag flags = AudioFileSource::Flag (AudioFileSource::Writable|
+                                                                  AudioFileSource::BuildPeaks));
+
+       DestructiveFileSource (const XMLNode&);
        ~DestructiveFileSource ();
 
-       int  seek (jack_nframes_t frame);
        jack_nframes_t last_capture_start_frame() const;
        void mark_capture_start (jack_nframes_t);
        void mark_capture_end ();
        void clear_capture_marks();
 
-       jack_nframes_t write (Sample *src, jack_nframes_t cnt, char * workbuf);
-
        XMLNode& get_state ();
 
        static void setup_standard_crossfades (jack_nframes_t sample_rate);
 
+  protected:
+       jack_nframes_t write_unlocked (Sample *src, jack_nframes_t start, jack_nframes_t cnt, char * workbuf);
+
   private:
        static jack_nframes_t xfade_frames;
        static gain_t* out_coefficient;
@@ -59,7 +62,7 @@ class DestructiveFileSource : public FileSource {
        Sample*        xfade_buf;
 
        jack_nframes_t crossfade (Sample* data, jack_nframes_t cnt, int dir, char * workbuf);
-
+       void set_timeline_position (jack_nframes_t);
 };
 
 }
diff --git a/libs/ardour/ardour/diskstream.h b/libs/ardour/ardour/diskstream.h
deleted file mode 100644 (file)
index 316daba..0000000
+++ /dev/null
@@ -1,447 +0,0 @@
-/*
-    Copyright (C) 2000 Paul Davis 
-
-    This program is free software; you can redistribute it and/or modify
-    it under the terms of the GNU General Public License as published by
-    the Free Software Foundation; either version 2 of the License, or
-    (at your option) any later version.
-
-    This program is distributed in the hope that it will be useful,
-    but WITHOUT ANY WARRANTY; without even the implied warranty of
-    MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
-    GNU General Public License for more details.
-
-    You should have received a copy of the GNU General Public License
-    along with this program; if not, write to the Free Software
-    Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
-
-    $Id$
-*/
-
-#ifndef __ardour_diskstream_h__
-#define __ardour_diskstream_h__
-
-#include <sigc++/signal.h>
-
-#include <cmath>
-#include <string>
-#include <queue>
-#include <map>
-#include <vector>
-
-#include <time.h>
-
-#include <pbd/fastlog.h>
-#include <pbd/ringbufferNPT.h>
-
-#include <ardour/ardour.h>
-#include <ardour/configuration.h>
-#include <ardour/session.h>
-#include <ardour/route_group.h>
-#include <ardour/route.h>
-#include <ardour/port.h>
-#include <ardour/utils.h>
-#include <ardour/stateful.h>
-
-struct tm;
-
-namespace ARDOUR {
-
-class AudioEngine;
-class Send;
-class Session;
-class AudioPlaylist;
-class FileSource;
-class IO;
-
-class DiskStream : public Stateful, public sigc::trackable
-{      
-  public:
-       enum Flag {
-               Recordable = 0x1,
-               Hidden = 0x2,
-               Destructive = 0x4
-       };
-
-       DiskStream (Session &, const string& name, Flag f = Recordable);
-       DiskStream (Session &, const XMLNode&);
-
-       string name() const { return _name; }
-
-       ARDOUR::IO* io() const { return _io; }
-       void set_io (ARDOUR::IO& io);
-
-       DiskStream& ref() { _refcnt++; return *this; }
-       void unref() { if (_refcnt) _refcnt--; if (_refcnt == 0) delete this; }
-       uint32_t refcnt() const { return _refcnt; }
-
-       float playback_buffer_load() const;
-       float capture_buffer_load() const;
-
-       void set_flag (Flag f) {
-               _flags |= f;
-       }
-
-       void unset_flag (Flag f) {
-               _flags &= ~f;
-       }
-
-       AlignStyle alignment_style() const { return _alignment_style; }
-       void set_align_style (AlignStyle);
-       void set_persistent_align_style (AlignStyle);
-
-       bool hidden() const { return _flags & Hidden; }
-       bool recordable() const { return _flags & Recordable; }
-       bool destructive() const { return _flags & Destructive; }
-
-       void set_destructive (bool yn);
-
-       jack_nframes_t roll_delay() const { return _roll_delay; }
-       void set_roll_delay (jack_nframes_t);
-
-       int set_name (string str, void* src);
-
-       string input_source (uint32_t n=0) const {
-               if (n < channels.size()) {
-                       return channels[n].source ? channels[n].source->name() : "";
-               } else {
-                       return ""; 
-               }
-       }
-
-       Port *input_source_port (uint32_t n=0) const { 
-               if (n < channels.size()) return channels[n].source; return 0; 
-       }
-
-       void set_record_enabled (bool yn, void *src);
-       bool record_enabled() const { return g_atomic_int_get (&_record_enabled); }
-       void punch_in ();
-       void punch_out ();
-
-       bool  reversed() const { return _actual_speed < 0.0f; }
-       double speed() const { return _visible_speed; }
-       void set_speed (double);
-
-       float peak_power(uint32_t n=0) { 
-               float x = channels[n].peak_power;
-               channels[n].peak_power = 0.0f;
-               if (x > 0.0f) {
-                       return 20.0f * fast_log10(x);
-               } else {
-                       return minus_infinity();
-               }
-       }
-
-       int  use_playlist (AudioPlaylist *);
-       int use_new_playlist ();
-       int use_copy_playlist ();
-
-       void start_scrub (jack_nframes_t where);
-       void end_scrub ();
-
-       Sample *playback_buffer (uint32_t n=0) {
-               if (n < channels.size())
-                       return channels[n].current_playback_buffer;
-               return 0;
-       }
-       
-       Sample *capture_buffer (uint32_t n=0) {
-               if (n < channels.size())
-                       return channels[n].current_capture_buffer;
-               return 0;
-       }
-
-       AudioPlaylist *playlist () { return _playlist; }
-
-       FileSource *write_source (uint32_t n=0) {
-               if (n < channels.size())
-                       return channels[n].write_source;
-               return 0;
-       }
-
-       jack_nframes_t current_capture_start() const { return capture_start_frame; }
-       jack_nframes_t current_capture_end() const { return capture_start_frame + capture_captured; }
-       jack_nframes_t get_capture_start_frame (uint32_t n=0);
-       jack_nframes_t get_captured_frames (uint32_t n=0);
-       
-       uint32_t n_channels() { return _n_channels; }
-
-       int add_channel ();
-       int remove_channel ();
-       
-       static void set_disk_io_chunk_frames (uint32_t n) {
-               disk_io_chunk_frames = n;
-       }
-
-       static jack_nframes_t disk_io_frames() { return disk_io_chunk_frames; }
-       
-       sigc::signal<void,void*> record_enable_changed;
-       sigc::signal<void>       speed_changed;
-       sigc::signal<void,void*> reverse_changed;
-       sigc::signal<void>       PlaylistChanged;
-       sigc::signal<void>       AlignmentStyleChanged;
-
-       static sigc::signal<void> DiskOverrun;
-       static sigc::signal<void> DiskUnderrun;
-       static sigc::signal<void,DiskStream*> DiskStreamCreated;   // XXX use a ref with sigc2
-       static sigc::signal<void,list<Source*>*> DeleteSources;
-
-       /* stateful */
-
-       XMLNode& get_state(void);
-       int set_state(const XMLNode& node);
-
-       void monitor_input (bool);
-
-       jack_nframes_t capture_offset() const { return _capture_offset; }
-       void           set_capture_offset ();
-
-       static void swap_by_ptr (Sample *first, Sample *last) {
-               while (first < last) {
-                       Sample tmp = *first;
-                       *first++ = *last;
-                       *last-- = tmp;
-               }
-       }
-
-       static void swap_by_ptr (Sample *first, Sample *last, jack_nframes_t n) {
-               while (n--) {
-                       Sample tmp = *first;
-                       *first++ = *last;
-                       *last-- = tmp;
-               }
-       }
-
-       bool slaved() const { return _slaved; }
-       void set_slaved(bool yn) { _slaved = yn; }
-
-       int set_loop (Location *loc);
-       sigc::signal<void,Location *> LoopSet;
-
-       std::list<Region*>& last_capture_regions () {
-               return _last_capture_regions;
-       }
-
-       void handle_input_change (IOChange, void *src);
-
-       id_t id() const { return _id; }
-
-       XMLNode* deprecated_io_node;
-
-  protected:
-       friend class Session;
-
-       /* the Session is the only point of access for these
-          because they require that the Session is "inactive"
-          while they are called.
-       */
-
-       void set_pending_overwrite (bool);
-       int  overwrite_existing_buffers ();
-       void reverse_scrub_buffer (bool to_forward);
-       void set_block_size (jack_nframes_t);
-       int  internal_playback_seek (jack_nframes_t distance);
-       int  can_internal_playback_seek (jack_nframes_t distance);
-       int  rename_write_sources ();
-       void reset_write_sources (bool, bool force = false);
-       void non_realtime_input_change ();
-
-       uint32_t read_data_count() const { return _read_data_count; }
-       uint32_t write_data_count() const { return _write_data_count; }
-
-  protected:
-       friend class Auditioner;
-       int  seek (jack_nframes_t which_sample, bool complete_refill = false);
-
-  protected:
-       friend class AudioTrack;
-
-       void prepare ();
-       int  process (jack_nframes_t transport_frame, jack_nframes_t nframes, jack_nframes_t offset, bool can_record, bool rec_monitors_input);
-       bool commit  (jack_nframes_t nframes);
-       void recover (); /* called if commit will not be called, but process was */
-
-  private:
-
-       /* use unref() to destroy a diskstream */
-
-       ~DiskStream();
-
-       enum TransitionType {
-               CaptureStart = 0,
-               CaptureEnd
-       };
-       
-       struct CaptureTransition {
-
-               TransitionType   type;
-               // the start or end file frame pos
-               jack_nframes_t   capture_val;
-       };
-       
-       struct ChannelInfo {
-
-               Sample     *playback_wrap_buffer;
-               Sample     *capture_wrap_buffer;
-               Sample     *speed_buffer;
-
-               float       peak_power;
-
-               FileSource   *fades_source;
-               FileSource   *write_source;
-
-               Port         *source;
-               Sample       *current_capture_buffer;
-               Sample       *current_playback_buffer;
-
-               RingBufferNPT<Sample> *playback_buf;
-               RingBufferNPT<Sample> *capture_buf;
-
-               Sample* scrub_buffer;
-               Sample* scrub_forward_buffer;
-               Sample* scrub_reverse_buffer;
-
-               RingBufferNPT<Sample>::rw_vector playback_vector;
-               RingBufferNPT<Sample>::rw_vector capture_vector;
-
-               RingBufferNPT<CaptureTransition> * capture_transition_buf;
-               // the following are used in the butler thread only
-               jack_nframes_t                     curr_capture_cnt;
-       };
-
-       typedef vector<ChannelInfo> ChannelList;
-
-
-       string            _name;
-       ARDOUR::Session&  _session;
-       ARDOUR::IO*       _io;
-       ChannelList        channels;
-       uint32_t      _n_channels;
-       id_t              _id;
-
-       mutable gint             _record_enabled;
-       AudioPlaylist*           _playlist;
-       double                   _visible_speed;
-       double                   _actual_speed;
-       /* items needed for speed change logic */
-       bool                     _buffer_reallocation_required;
-       bool                     _seek_required;
-       
-       bool                      force_refill;
-       jack_nframes_t            capture_start_frame;
-       jack_nframes_t            capture_captured;
-       bool                      was_recording;
-       jack_nframes_t            adjust_capture_position;
-       jack_nframes_t           _capture_offset;
-       jack_nframes_t           _roll_delay;
-       jack_nframes_t            first_recordable_frame;
-       jack_nframes_t            last_recordable_frame;
-       int                       last_possibly_recording;
-       AlignStyle               _alignment_style;
-       bool                     _scrubbing;
-       bool                     _slaved;
-       bool                     _processed;
-       Location*                 loop_location;
-       jack_nframes_t            overwrite_frame;
-       off_t                     overwrite_offset;
-       bool                      pending_overwrite;
-       bool                      overwrite_queued;
-       IOChange                  input_change_pending;
-       jack_nframes_t            wrap_buffer_size;
-       jack_nframes_t            speed_buffer_size;
-
-       uint64_t                  last_phase;
-       uint64_t                  phi;
-       
-       jack_nframes_t            file_frame;           
-       jack_nframes_t            playback_sample;
-       jack_nframes_t            playback_distance;
-
-       uint32_t                 _read_data_count;
-       uint32_t                 _write_data_count;
-
-       bool                      in_set_state;
-       AlignStyle               _persistent_alignment_style;
-       bool                      first_input_change;
-
-       Glib::Mutex  state_lock;
-
-       jack_nframes_t scrub_start;
-       jack_nframes_t scrub_buffer_size;
-       jack_nframes_t scrub_offset;
-       uint32_t _refcnt;
-
-       sigc::connection ports_created_c;
-       sigc::connection plmod_connection;
-       sigc::connection plstate_connection;
-       sigc::connection plgone_connection;
-
-       /* the two central butler operations */
-
-       int do_flush (char * workbuf, bool force = false);
-       int do_refill (Sample *mixdown_buffer, float *gain_buffer, char *workbuf);
-
-       int read (Sample* buf, Sample* mixdown_buffer, float* gain_buffer, char * workbuf, jack_nframes_t& start, jack_nframes_t cnt, 
-                 ChannelInfo& channel_info, int channel, bool reversed);
-
-       uint32_t i_am_the_modifier;
-       
-       /* XXX fix this redundancy ... */
-
-       void playlist_changed (Change);
-       void playlist_modified ();
-       void playlist_deleted (Playlist*);
-       void session_controls_changed (Session::ControlType);
-
-       void finish_capture (bool rec_monitors_input);
-       void clean_up_capture (struct tm&, time_t, bool abort);
-       void transport_stopped (struct tm&, time_t, bool abort);
-
-       struct CaptureInfo {
-           uint32_t start;
-           uint32_t frames;
-       };
-
-       vector<CaptureInfo*> capture_info;
-       Glib::Mutex  capture_info_lock;
-       
-       void init (Flag);
-
-       void init_channel (ChannelInfo &chan);
-       void destroy_channel (ChannelInfo &chan);
-       
-       static jack_nframes_t disk_io_chunk_frames;
-
-       int use_new_write_source (uint32_t n=0);
-       int use_new_fade_source (uint32_t n=0);
-
-       int find_and_use_playlist (const string&);
-
-       void allocate_temporary_buffers ();
-
-       unsigned char _flags;
-
-       int  create_input_port ();
-       int  connect_input_port ();
-       int  seek_unlocked (jack_nframes_t which_sample);
-
-       int ports_created ();
-
-       bool realtime_set_speed (double, bool global_change);
-       void non_realtime_set_speed ();
-
-       std::list<Region*> _last_capture_regions;
-       std::vector<FileSource*> capturing_sources;
-       int use_pending_capture_data (XMLNode& node);
-
-       void get_input_sources ();
-       void check_record_status (jack_nframes_t transport_frame, jack_nframes_t nframes, bool can_record);
-       void set_align_style_from_io();
-       void setup_destructive_playlist ();
-       void use_destructive_playlist ();
-};
-
-}; /* namespace ARDOUR */
-
-#endif /* __ardour_diskstream_h__ */
diff --git a/libs/ardour/ardour/externalsource.h b/libs/ardour/ardour/externalsource.h
deleted file mode 100644 (file)
index 17504d0..0000000
+++ /dev/null
@@ -1,67 +0,0 @@
-/*
-    Copyright (C) 2006 Paul Davis 
-
-    This program is free software; you can redistribute it and/or modify
-    it under the terms of the GNU General Public License as published by
-    the Free Software Foundation; either version 2 of the License, or
-    (at your option) any later version.
-
-    This program is distributed in the hope that it will be useful,
-    but WITHOUT ANY WARRANTY; without even the implied warranty of
-    MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
-    GNU General Public License for more details.
-
-    You should have received a copy of the GNU General Public License
-    along with this program; if not, write to the Free Software
-    Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
-
-*/
-
-#ifndef __external_source_h__ 
-#define __external_source_h__
-
-#include <ardour/source.h>
-
-namespace ARDOUR {
-
-struct SoundFileInfo {
-    float    samplerate;
-    uint16_t channels;
-    int64_t length;
-    std::string format_name;
-};
-
-class ExternalSource : public Source {
-  public:
-       virtual ~ExternalSource ();
-
-       string path() const { return _path; }
-
-       virtual jack_nframes_t read (Sample *dst, jack_nframes_t start, jack_nframes_t cnt, char * workbuf) const = 0;
-
-       void mark_for_remove() {} // we never remove external sndfiles 
-       string peak_path(string audio_path);
-       string old_peak_path(string audio_path);
-
-       static void set_peak_dir (string dir) { peak_dir = dir; }
-
-       static ExternalSource* create (const string& path_plus_channel, bool build_peak = true);
-       static ExternalSource* create (const XMLNode& node);
-       static bool get_soundfile_info (string path, SoundFileInfo& _info, string& error);
-
-  protected:
-       ExternalSource (const string& path_plus_channel, bool build_peak = true);
-       ExternalSource (const XMLNode&);
-
-       static string peak_dir;
-
-       uint16_t channel;
-       string  _path;
-
-       jack_nframes_t read_unlocked (Sample *dst, jack_nframes_t start, jack_nframes_t cnt, char * workbuf) const;
-};
-
-}; /* namespace ARDOUR */
-
-#endif /* __external_source_h__ */
-
index d322f564eed7be4245a1678ebe45935882767879..c653c8502e07ded5ec6db448f072d2a2a6b44ea7 100644 (file)
@@ -37,7 +37,6 @@
 #include <ardour/crossfade_compare.h>
 #include <ardour/location.h>
 #include <ardour/stateful.h>
-#include <ardour/source.h>
 #include <ardour/state_manager.h>
 
 namespace ARDOUR  {
index 9339e448dbbf067ddab7c24c8f73103b737a7e9f..0554d13e68950e5546f997c7ae94f161bf55b96b 100644 (file)
@@ -62,11 +62,12 @@ namespace ARDOUR {
 class Port;
 class AudioEngine;
 class Slave;
-class DiskStream;      
+class AudioDiskstream; 
 class Route;
 class AuxInput;
 class Source;
-class FileSource;
+class AudioSource;
+class AudioFileSource;
 class Auditioner;
 class Insert;
 class Send;
@@ -263,25 +264,30 @@ class Session : public sigc::trackable, public Stateful
        vector<Sample*>& get_silent_buffers (uint32_t howmany);
        vector<Sample*>& get_send_buffers () { return _send_buffers; }
 
-       DiskStream    *diskstream_by_id (id_t id);
-       DiskStream    *diskstream_by_name (string name);
+       AudioDiskstream    *diskstream_by_id (id_t id);
+       AudioDiskstream    *diskstream_by_name (string name);
 
        bool have_captured() const { return _have_captured; }
 
        void refill_all_diskstream_buffers ();
        uint32_t diskstream_buffer_size() const { return dstream_buffer_size; }
-       uint32_t get_next_diskstream_id() const { return n_diskstreams(); }
-       uint32_t n_diskstreams() const;
        
-       typedef list<DiskStream *> DiskStreamList;
+       /* XXX fix required here when we get new diskstream types *, but
+          not sure of the direction to take this in until then.
+       */
+
+       uint32_t get_next_diskstream_id() const { return n_audio_diskstreams(); }
+       uint32_t n_audio_diskstreams() const;
+       
+       typedef list<AudioDiskstream *> AudioDiskstreamList;
 
-       Session::DiskStreamList disk_streams() const {
+       Session::AudioDiskstreamList audio_disk_streams() const {
                Glib::RWLock::ReaderLock lm (diskstream_lock);
-               return diskstreams; /* XXX yes, force a copy */
+               return audio_diskstreams; /* XXX yes, force a copy */
        }
 
-       void foreach_diskstream (void (DiskStream::*func)(void));
-       template<class T> void foreach_diskstream (T *obj, void (T::*func)(DiskStream&));
+       void foreach_audio_diskstream (void (AudioDiskstream::*func)(void));
+       template<class T> void foreach_audio_diskstream (T *obj, void (T::*func)(AudioDiskstream&));
 
        typedef list<Route *> RouteList;
 
@@ -346,7 +352,7 @@ class Session : public sigc::trackable, public Stateful
        sigc::signal<void> HaltOnXrun;
 
        sigc::signal<void,Route*> RouteAdded;
-       sigc::signal<void,DiskStream*> DiskStreamAdded;
+       sigc::signal<void,AudioDiskstream*> AudioDiskstreamAdded;
 
        void request_roll ();
        void request_bounded_roll (jack_nframes_t start, jack_nframes_t end);
@@ -358,15 +364,15 @@ class Session : public sigc::trackable, public Stateful
        void goto_start () { request_locate (start_location->start(), false); }
        void use_rf_shuttle_speed ();
        void request_transport_speed (float speed);
-       void request_overwrite_buffer (DiskStream*);
-       void request_diskstream_speed (DiskStream&, float speed);
+       void request_overwrite_buffer (AudioDiskstream*);
+       void request_diskstream_speed (AudioDiskstream&, float speed);
        void request_input_change_handling ();
 
        bool locate_pending() const { return static_cast<bool>(post_transport_work&PostTransportLocate); }
        bool transport_locked () const;
 
        int wipe ();
-       int wipe_diskstream (DiskStream *);
+       int wipe_diskstream (AudioDiskstream *);
 
        int remove_region_from_region_list (Region&);
 
@@ -603,7 +609,7 @@ class Session : public sigc::trackable, public Stateful
 
        jack_nframes_t convert_to_frames_at (jack_nframes_t position, AnyTime&);
 
-       sigc::signal<void> SMPTEOffsetChanged;
+       static sigc::signal<void> SMPTEOffsetChanged;
        sigc::signal<void> SMPTETypeChanged;
 
        void        request_slave_source (SlaveSource, jack_nframes_t pos = 0);
@@ -659,8 +665,9 @@ class Session : public sigc::trackable, public Stateful
        int start_audio_export (ARDOUR::AudioExportSpecification&);
        int stop_audio_export (ARDOUR::AudioExportSpecification&);
        
-       void add_source (Source *);
-       int  remove_file_source (FileSource&);
+       void add_audio_source (AudioSource *);
+       void remove_source (Source *);
+       int  cleanup_audio_file_source (AudioFileSource&);
 
        struct cleanup_report {
            vector<string> paths;
@@ -692,7 +699,8 @@ class Session : public sigc::trackable, public Stateful
        sigc::signal<void,Source *> SourceAdded;
        sigc::signal<void,Source *> SourceRemoved;
 
-       FileSource *create_file_source (ARDOUR::DiskStream&, int32_t chan, bool destructive);
+       AudioFileSource *create_audio_source_for_session (ARDOUR::AudioDiskstream&, uint32_t which_channel, bool destructive);
+
        Source *get_source (ARDOUR::id_t);
 
        /* playlist management */
@@ -736,8 +744,8 @@ class Session : public sigc::trackable, public Stateful
 
        /* flattening stuff */
 
-       int write_one_track (AudioTrack&, jack_nframes_t start, jack_nframes_t cnt, bool overwrite, vector<Source*>&,
-                            InterThreadInfo& wot);
+       int write_one_audio_track (AudioTrack&, jack_nframes_t start, jack_nframes_t cnt, bool overwrite, vector<AudioSource*>&,
+                                  InterThreadInfo& wot);
        int freeze (InterThreadInfo&);
 
        /* session-wide solo/mute/rec-enable */
@@ -963,7 +971,7 @@ class Session : public sigc::trackable, public Stateful
        void set_frame_rate (jack_nframes_t nframes);
 
   protected:
-       friend class DiskStream;
+       friend class AudioDiskstream;
        void stop_butler ();
        void wait_till_butler_finished();
 
@@ -1422,12 +1430,12 @@ class Session : public sigc::trackable, public Stateful
        bool waiting_to_start;
 
        void set_auto_loop (bool yn);
-       void overwrite_some_buffers (DiskStream*);
+       void overwrite_some_buffers (AudioDiskstream*);
        void flush_all_redirects ();
        void locate (jack_nframes_t, bool with_roll, bool with_flush, bool with_loop=false);
        void start_locate (jack_nframes_t, bool with_roll, bool with_flush, bool with_loop=false);
        void force_locate (jack_nframes_t frame, bool with_roll = false);
-       void set_diskstream_speed (DiskStream*, float speed);
+       void set_diskstream_speed (AudioDiskstream*, float speed);
        void set_transport_speed (float speed, bool abort = false);
        void stop_transport (bool abort = false);
        void start_transport ();
@@ -1458,10 +1466,10 @@ class Session : public sigc::trackable, public Stateful
 
        /* disk-streams */
 
-       DiskStreamList  diskstreams; 
+       AudioDiskstreamList  audio_diskstreams; 
        mutable Glib::RWLock diskstream_lock;
        uint32_t dstream_buffer_size;
-       void add_diskstream (DiskStream*);
+       void add_diskstream (AudioDiskstream*);
        int  load_diskstreams (const XMLNode&);
 
        /* routes stuff */
@@ -1503,16 +1511,14 @@ class Session : public sigc::trackable, public Stateful
 
        /* SOURCES */
        
-       mutable Glib::Mutex source_lock;
-       typedef std::map<id_t, Source *>    SourceList;
+       mutable Glib::Mutex audio_source_lock;
+       typedef std::map<id_t, AudioSource *>    AudioSourceList;
 
-       SourceList sources;
+       AudioSourceList audio_sources;
 
        int load_sources (const XMLNode& node);
        XMLNode& get_sources_as_xml ();
 
-       void remove_source (Source *);
-
        Source *XMLSourceFactory (const XMLNode&);
 
        /* PLAYLISTS */
@@ -1531,7 +1537,7 @@ class Session : public sigc::trackable, public Stateful
        Playlist *XMLPlaylistFactory (const XMLNode&);
 
        void playlist_length_changed (Playlist *);
-       void diskstream_playlist_changed (DiskStream *);
+       void diskstream_playlist_changed (AudioDiskstream *);
 
        /* NAMED SELECTIONS */
 
index 3c888c92c30131ddbb0b7768f99ab7a4199340b5..33fc5419ba348cbf2477b6008a138f8252573d46 100644 (file)
 #define __ardour_session_diskstream_h__
 
 #include <ardour/session.h>
-#include <ardour/diskstream.h>
+#include <ardour/audio_diskstream.h>
 
 namespace ARDOUR {
 
 template<class T> void 
-Session::foreach_diskstream (T *obj, void (T::*func)(DiskStream&)) 
+Session::foreach_audio_diskstream (T *obj, void (T::*func)(AudioDiskstream&)) 
 {
        Glib::RWLock::ReaderLock lm (diskstream_lock);
-       for (DiskStreamList::iterator i = diskstreams.begin(); i != diskstreams.end(); i++) {
+       for (AudioDiskstreamList::iterator i = audio_diskstreams.begin(); i != audio_diskstreams.end(); i++) {
                if (!(*i)->hidden()) {
                        (obj->*func) (**i);
                }
index 5d11c9ef095e6be2599dd40abd88cca875205c63..d146bb57938ed64c9bfd38f610392dea51a518df 100644 (file)
 
 #include <sndfile.h>
 
-#include <ardour/externalsource.h>
+#include <ardour/audiofilesource.h>
 
 namespace ARDOUR {
 
-class SndFileSource : public ExternalSource {
+class SndFileSource : public AudioFileSource {
   public:
-       SndFileSource (const string& path_plus_channel, bool build_peak = true);
+       /* constructor to be called for existing external-to-session files */
+
+       SndFileSource (std::string path, Flag flags);
+
+       /* constructor to be called for new in-session files */
+
+       SndFileSource (std::string path, SampleFormat samp_format, HeaderFormat hdr_format, jack_nframes_t rate, 
+                      Flag flags = AudioFileSource::Flag (AudioFileSource::Writable|
+                                                          AudioFileSource::Removable|
+                                                          AudioFileSource::RemovableIfEmpty|
+                                                          AudioFileSource::CanRename|
+                                                          AudioFileSource::BuildPeaks));
+                      
+       /* constructor to be called for existing in-session files */
+       
        SndFileSource (const XMLNode&);
+
        ~SndFileSource ();
 
-       jack_nframes_t length() const { return _info.frames; } 
-       jack_nframes_t read (Sample *dst, jack_nframes_t start, jack_nframes_t cnt, char * workbuf) const;
        float sample_rate () const;
+       int update_header (jack_nframes_t when, struct tm&, time_t);
+       int flush_header ();
+
+       static Flag default_in_session_flags();
+
+  protected:
+       void set_header_timeline_position ();
+
+       jack_nframes_t read_unlocked (Sample *dst, jack_nframes_t start, jack_nframes_t cnt, char * workbuf) const;
+       jack_nframes_t write_unlocked (Sample *dst, jack_nframes_t cnt, char * workbuf);
+
+       jack_nframes_t write_float (Sample* data, jack_nframes_t pos, jack_nframes_t cnt);
 
   private:
        SNDFILE *sf;
        SF_INFO _info;
+       SF_BROADCAST_INFO *_broadcast_info;
 
-       mutable float *tmpbuf;
-       mutable jack_nframes_t tmpbufsize;
-       mutable Glib::Mutex _tmpbuf_lock;
+       mutable float *interleave_buf;
+       mutable jack_nframes_t interleave_bufsize;
 
-       void init (const string &str, bool build_peak);
+       void init (const string &str);
+       int open();
+       void close();
+       int setup_broadcast_info (jack_nframes_t when, struct tm&, time_t);
 };
 
 }; /* namespace ARDOUR */
index 3781950fbf979a2a5422df049c43f5f1f5d6f9f1..f3133c71cd9618b038d20903b9b5c39e933afa2a 100644 (file)
 #ifndef __ardour_source_h__
 #define __ardour_source_h__
 
-#include <list>
-#include <vector>
 #include <string>
 
-#include <ctime>
-
 #include <sigc++/signal.h>
 
-#include <glibmm/thread.h>
-
 #include <ardour/ardour.h>
 #include <ardour/stateful.h>
-#include <pbd/xml++.h>
-
-using std::list;
-using std::vector;
-using std::string;
 
 namespace ARDOUR {
 
-struct PeakData {
-    typedef Sample PeakDatum;
-
-    PeakDatum min;
-    PeakDatum max;
-};
-
-const jack_nframes_t frames_per_peak = 256;
-
 class Source : public Stateful, public sigc::trackable
 {
   public:
-       Source (bool announce=true);
+       Source (std::string name);
        Source (const XMLNode&);
        virtual ~Source ();
 
-       const string& name() const { return _name; }
+       std::string name() const { return _name; }
+       int set_name (std::string str, bool destructive);
 
        ARDOUR::id_t  id() const   { return _id; }
 
-       /* returns the number of items in this `source' */
-
-       virtual jack_nframes_t length() const {
-               return _length;
-       }
-
-       virtual jack_nframes_t available_peaks (double zoom) const;
-
-       virtual jack_nframes_t read (Sample *dst, jack_nframes_t start, jack_nframes_t cnt, char * workbuf) const {
-               return 0;
-       }
-
-       virtual jack_nframes_t write (Sample *src, jack_nframes_t cnt, char * workbuf) {
-               return 0;
-       }
-
-       virtual float sample_rate () const { return 0; }
-
        uint32_t use_cnt() const { return _use_cnt; }
        void use ();
        void release ();
 
-       virtual void mark_for_remove() = 0;
-       virtual void mark_streaming_write_completed () {}
-
        time_t timestamp() const { return _timestamp; }
        void stamp (time_t when) { _timestamp = when; }
 
-       void set_captured_for (string str) { _captured_for = str; }
-       string captured_for() const { return _captured_for; }
-
-       uint32_t read_data_count() const { return _read_data_count; }
-       uint32_t write_data_count() const { return _write_data_count; }
-
-       int  read_peaks (PeakData *peaks, jack_nframes_t npeaks, jack_nframes_t start, jack_nframes_t cnt, double samples_per_unit) const;
-       int  build_peaks ();
-       bool peaks_ready (sigc::slot<void>, sigc::connection&) const;
-
-       static sigc::signal<void,Source*> SourceCreated;
-              
-       sigc::signal<void,Source *> GoingAway;
-       mutable sigc::signal<void>  PeaksReady;
-       mutable sigc::signal<void,jack_nframes_t,jack_nframes_t>  PeakRangeReady;
-       
        XMLNode& get_state ();
        int set_state (const XMLNode&);
 
-       static int  start_peak_thread ();
-       static void stop_peak_thread ();
-
-       int rename_peakfile (std::string newpath);
-
-       static void set_build_missing_peakfiles (bool yn) {
-               _build_missing_peakfiles = yn;
-       }
-       static void set_build_peakfiles (bool yn) {
-               _build_peakfiles = yn;
-       }
+       sigc::signal<void,Source *> GoingAway;
 
   protected:
-       static bool _build_missing_peakfiles;
-       static bool _build_peakfiles;
-
        string            _name;
-       uint32_t     _use_cnt;
-       bool              _peaks_built;
-       mutable Glib::Mutex _lock;
-       jack_nframes_t    _length;
-       bool               next_peak_clear_should_notify;
-       string             peakpath;
+       uint32_t          _use_cnt;
        time_t            _timestamp;
-       string            _captured_for;
-
-       mutable uint32_t _read_data_count;  // modified in read()
-       mutable uint32_t _write_data_count; // modified in write()
-
-       int initialize_peakfile (bool newfile, string path);
-       void build_peaks_from_scratch ();
-
-       int  do_build_peak (jack_nframes_t, jack_nframes_t);
-       virtual jack_nframes_t read_unlocked (Sample *dst, jack_nframes_t start, jack_nframes_t cnt, char * workbuf) const = 0;
-       virtual string peak_path(string audio_path) = 0;
-
-       static pthread_t peak_thread;
-       static bool      have_peak_thread;
-       static void*     peak_thread_work(void*);
-
-       static int peak_request_pipe[2];
-
-       struct PeakRequest {
-           enum Type {
-                   Build,
-                   Quit
-           };
-       };
-
-       static vector<Source*> pending_peak_sources;
-       static Glib::StaticMutex pending_peak_sources_lock;
-
-       static void queue_for_peaks (Source&);
-       static void clear_queue_for_peaks ();
-       
-       struct PeakBuildRecord {
-           jack_nframes_t frame;
-           jack_nframes_t cnt;
-
-           PeakBuildRecord (jack_nframes_t f, jack_nframes_t c) 
-                   : frame (f), cnt (c) {}
-           PeakBuildRecord (const PeakBuildRecord& other) {
-                   frame = other.frame;
-                   cnt = other.cnt;
-           }
-       };
-
-       list<Source::PeakBuildRecord *> pending_peak_builds;
 
   private:
        ARDOUR::id_t _id;
-       
-       bool file_changed (string path);
 };
 
 }
index 3d7ab4b59a35be30d89187b9da92d56c9b053c8e..cdf71b8cc63d406ed9b9208ccaf6724d9dfd6325 100644 (file)
@@ -255,10 +255,18 @@ namespace ARDOUR {
                BWF,
                WAVE,
                WAVE64,
+               CAF,
+               AIFF,
                iXML,
                RF64
        };
 
+       struct PeakData {
+           typedef Sample PeakDatum;
+           
+           PeakDatum min;
+           PeakDatum max;
+       };
 };
 
 std::istream& operator>>(std::istream& o, ARDOUR::SampleFormat& sf);
diff --git a/libs/ardour/audio_diskstream.cc b/libs/ardour/audio_diskstream.cc
new file mode 100644 (file)
index 0000000..043b2a1
--- /dev/null
@@ -0,0 +1,2562 @@
+/*
+    Copyright (C) 2000-2003 Paul Davis 
+
+    This program is free software; you can redistribute it and/or modify
+    it under the terms of the GNU General Public License as published by
+    the Free Software Foundation; either version 2 of the License, or
+    (at your option) any later version.
+
+    This program is distributed in the hope that it will be useful,
+    but WITHOUT ANY WARRANTY; without even the implied warranty of
+    MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+    GNU General Public License for more details.
+
+    You should have received a copy of the GNU General Public License
+    along with this program; if not, write to the Free Software
+    Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
+
+    $Id: diskstream.cc 567 2006-06-07 14:54:12Z trutkin $
+*/
+
+#include <fstream>
+#include <cstdio>
+#include <unistd.h>
+#include <cmath>
+#include <cerrno>
+#include <string>
+#include <climits>
+#include <fcntl.h>
+#include <cstdlib>
+#include <ctime>
+#include <sys/stat.h>
+#include <sys/mman.h>
+
+#include <pbd/error.h>
+#include <pbd/basename.h>
+#include <glibmm/thread.h>
+#include <pbd/xml++.h>
+
+#include <ardour/ardour.h>
+#include <ardour/audioengine.h>
+#include <ardour/audio_diskstream.h>
+#include <ardour/utils.h>
+#include <ardour/configuration.h>
+#include <ardour/audiofilesource.h>
+#include <ardour/destructive_filesource.h>
+#include <ardour/send.h>
+#include <ardour/audioplaylist.h>
+#include <ardour/cycle_timer.h>
+#include <ardour/audioregion.h>
+
+#include "i18n.h"
+#include <locale.h>
+
+using namespace std;
+using namespace ARDOUR;
+
+jack_nframes_t AudioDiskstream::disk_io_chunk_frames;
+
+sigc::signal<void,AudioDiskstream*>    AudioDiskstream::AudioDiskstreamCreated;
+sigc::signal<void,list<AudioFileSource*>*> AudioDiskstream::DeleteSources;
+sigc::signal<void>                AudioDiskstream::DiskOverrun;
+sigc::signal<void>                AudioDiskstream::DiskUnderrun;
+
+AudioDiskstream::AudioDiskstream (Session &sess, const string &name, Flag flag)
+       : _name (name),
+         _session (sess)
+{
+       /* prevent any write sources from being created */
+
+       in_set_state = true;
+
+       init (flag);
+       use_new_playlist ();
+
+       in_set_state = false;
+
+       AudioDiskstreamCreated (this); /* EMIT SIGNAL */
+}
+       
+AudioDiskstream::AudioDiskstream (Session& sess, const XMLNode& node)
+       : _session (sess)
+       
+{
+       in_set_state = true;
+       init (Recordable);
+
+       if (set_state (node)) {
+               in_set_state = false;
+               throw failed_constructor();
+       }
+
+       in_set_state = false;
+
+       if (destructive()) {
+               use_destructive_playlist ();
+       }
+
+       AudioDiskstreamCreated (this); /* EMIT SIGNAL */
+}
+
+void
+AudioDiskstream::init_channel (ChannelInfo &chan)
+{
+       chan.playback_wrap_buffer = 0;
+       chan.capture_wrap_buffer = 0;
+       chan.speed_buffer = 0;
+       chan.peak_power = 0.0f;
+       chan.write_source = 0;
+       chan.source = 0;
+       chan.current_capture_buffer = 0;
+       chan.current_playback_buffer = 0;
+       chan.curr_capture_cnt = 0;
+       
+       chan.playback_buf = new RingBufferNPT<Sample> (_session.diskstream_buffer_size());
+       chan.capture_buf = new RingBufferNPT<Sample> (_session.diskstream_buffer_size());
+       chan.capture_transition_buf = new RingBufferNPT<CaptureTransition> (128);
+       
+       
+       /* touch the ringbuffer buffers, which will cause
+          them to be mapped into locked physical RAM if
+          we're running with mlockall(). this doesn't do
+          much if we're not.  
+       */
+       memset (chan.playback_buf->buffer(), 0, sizeof (Sample) * chan.playback_buf->bufsize());
+       memset (chan.capture_buf->buffer(), 0, sizeof (Sample) * chan.capture_buf->bufsize());
+       memset (chan.capture_transition_buf->buffer(), 0, sizeof (CaptureTransition) * chan.capture_transition_buf->bufsize());
+}
+
+
+void
+AudioDiskstream::init (Flag f)
+{
+       _id = new_id();
+       _refcnt = 0;
+       _flags = f;
+       _io = 0;
+       _alignment_style = ExistingMaterial;
+       _persistent_alignment_style = ExistingMaterial;
+       first_input_change = true;
+       _playlist = 0;
+       i_am_the_modifier = 0;
+       g_atomic_int_set (&_record_enabled, 0);
+       was_recording = false;
+       capture_start_frame = 0;
+       capture_captured = 0;
+       _visible_speed = 1.0f;
+       _actual_speed = 1.0f;
+       _buffer_reallocation_required = false;
+       _seek_required = false;
+       first_recordable_frame = max_frames;
+       last_recordable_frame = max_frames;
+       _roll_delay = 0;
+       _capture_offset = 0;
+       _processed = false;
+       _slaved = false;
+       adjust_capture_position = 0;
+       last_possibly_recording = 0;
+       loop_location = 0;
+       wrap_buffer_size = 0;
+       speed_buffer_size = 0;
+       last_phase = 0;
+       phi = (uint64_t) (0x1000000);
+       file_frame = 0;
+       playback_sample = 0;
+       playback_distance = 0;
+       _read_data_count = 0;
+       _write_data_count = 0;
+       deprecated_io_node = 0;
+
+       /* there are no channels at this point, so these
+          two calls just get speed_buffer_size and wrap_buffer
+          size setup without duplicating their code.
+       */
+
+       set_block_size (_session.get_block_size());
+       allocate_temporary_buffers ();
+
+       pending_overwrite = false;
+       overwrite_frame = 0;
+       overwrite_queued = false;
+       input_change_pending = NoChange;
+
+       add_channel ();
+       _n_channels = 1;
+}
+
+void
+AudioDiskstream::destroy_channel (ChannelInfo &chan)
+{
+       if (chan.write_source) {
+               chan.write_source->release ();
+               chan.write_source = 0;
+       }
+               
+       if (chan.speed_buffer) {
+               delete [] chan.speed_buffer;
+       }
+
+       if (chan.playback_wrap_buffer) {
+               delete [] chan.playback_wrap_buffer;
+       }
+       if (chan.capture_wrap_buffer) {
+               delete [] chan.capture_wrap_buffer;
+       }
+       
+       delete chan.playback_buf;
+       delete chan.capture_buf;
+       delete chan.capture_transition_buf;
+       
+       chan.playback_buf = 0;
+       chan.capture_buf = 0;
+}
+
+AudioDiskstream::~AudioDiskstream ()
+{
+       Glib::Mutex::Lock lm (state_lock);
+
+       if (_playlist) {
+               _playlist->unref ();
+       }
+
+       for (ChannelList::iterator chan = channels.begin(); chan != channels.end(); ++chan) {
+               destroy_channel((*chan));
+       }
+       
+       channels.clear();
+}
+
+void
+AudioDiskstream::handle_input_change (IOChange change, void *src)
+{
+       Glib::Mutex::Lock lm (state_lock);
+
+       if (!(input_change_pending & change)) {
+               input_change_pending = IOChange (input_change_pending|change);
+               _session.request_input_change_handling ();
+       }
+}
+
+void
+AudioDiskstream::non_realtime_input_change ()
+{
+       { 
+               Glib::Mutex::Lock lm (state_lock);
+
+               if (input_change_pending == NoChange) {
+                       return;
+               }
+
+               if (input_change_pending & ConfigurationChanged) {
+
+                       if (_io->n_inputs() > _n_channels) {
+                               
+                               // we need to add new channel infos
+                               
+                               int diff = _io->n_inputs() - channels.size();
+                               
+                               for (int i = 0; i < diff; ++i) {
+                                       add_channel ();
+                               }
+                               
+               } else if (_io->n_inputs() < _n_channels) {
+                               
+                               // we need to get rid of channels
+                               
+                               int diff = channels.size() - _io->n_inputs();
+                               
+                               for (int i = 0; i < diff; ++i) {
+                                       remove_channel ();
+                               }
+                       }
+               } 
+
+               get_input_sources ();
+               set_capture_offset ();
+               
+               if (first_input_change) {
+                       set_align_style (_persistent_alignment_style);
+                       first_input_change = false;
+               } else {
+                       set_align_style_from_io ();
+               }
+
+               input_change_pending = NoChange;
+       }
+
+       /* reset capture files */
+
+       reset_write_sources (false);
+
+       /* now refill channel buffers */
+
+       if (speed() != 1.0f || speed() != -1.0f) {
+               seek ((jack_nframes_t) (_session.transport_frame() * (double) speed()));
+       }
+       else {
+               seek (_session.transport_frame());
+       }
+}
+
+void
+AudioDiskstream::get_input_sources ()
+{
+       uint32_t ni = _io->n_inputs();
+       
+       for (uint32_t n = 0; n < ni; ++n) {
+               
+               const char **connections = _io->input(n)->get_connections ();
+               ChannelInfo& chan = channels[n];
+               
+               if (connections == 0 || connections[0] == 0) {
+                       
+                       if (chan.source) {
+                               // _source->disable_metering ();
+                       }
+                       
+                       chan.source = 0;
+                       
+               } else {
+                       chan.source = _session.engine().get_port_by_name (connections[0]);
+               }
+               
+               if (connections) {
+                       free (connections);
+               }
+       }
+}              
+
+int
+AudioDiskstream::find_and_use_playlist (const string& name)
+{
+       Playlist* pl;
+       AudioPlaylist* playlist;
+               
+       if ((pl = _session.get_playlist (name)) == 0) {
+               error << string_compose(_("AudioDiskstream: Session doesn't know about a Playlist called \"%1\""), name) << endmsg;
+               return -1;
+       }
+
+       if ((playlist = dynamic_cast<AudioPlaylist*> (pl)) == 0) {
+               error << string_compose(_("AudioDiskstream: Playlist \"%1\" isn't an audio playlist"), name) << endmsg;
+               return -1;
+       }
+
+       return use_playlist (playlist);
+}
+
+int
+AudioDiskstream::use_playlist (AudioPlaylist* playlist)
+{
+       {
+               Glib::Mutex::Lock lm (state_lock);
+
+               if (playlist == _playlist) {
+                       return 0;
+               }
+
+               plstate_connection.disconnect();
+               plmod_connection.disconnect ();
+               plgone_connection.disconnect ();
+
+               if (_playlist) {
+                       _playlist->unref();
+               }
+                       
+               _playlist = playlist;
+               _playlist->ref();
+
+               if (!in_set_state && recordable()) {
+                       reset_write_sources (false);
+               }
+               
+               plstate_connection = _playlist->StateChanged.connect (mem_fun (*this, &AudioDiskstream::playlist_changed));
+               plmod_connection = _playlist->Modified.connect (mem_fun (*this, &AudioDiskstream::playlist_modified));
+               plgone_connection = _playlist->GoingAway.connect (mem_fun (*this, &AudioDiskstream::playlist_deleted));
+       }
+
+       if (!overwrite_queued) {
+               _session.request_overwrite_buffer (this);
+               overwrite_queued = true;
+       }
+       
+       PlaylistChanged (); /* EMIT SIGNAL */
+       _session.set_dirty ();
+
+       return 0;
+}
+
+void
+AudioDiskstream::playlist_deleted (Playlist* pl)
+{
+       /* this catches an ordering issue with session destruction. playlists 
+          are destroyed before diskstreams. we have to invalidate any handles
+          we have to the playlist.
+       */
+
+       _playlist = 0;
+}
+
+int
+AudioDiskstream::use_new_playlist ()
+{
+       string newname;
+       AudioPlaylist* playlist;
+
+       if (!in_set_state && destructive()) {
+               return 0;
+       }
+
+       if (_playlist) {
+               newname = Playlist::bump_name (_playlist->name(), _session);
+       } else {
+               newname = Playlist::bump_name (_name, _session);
+       }
+
+       if ((playlist = new AudioPlaylist (_session, newname, hidden())) != 0) {
+               playlist->set_orig_diskstream_id (id());
+               return use_playlist (playlist);
+       } else { 
+               return -1;
+       }
+}
+
+int
+AudioDiskstream::use_copy_playlist ()
+{
+       if (destructive()) {
+               return 0;
+       }
+
+       if (_playlist == 0) {
+               error << string_compose(_("AudioDiskstream %1: there is no existing playlist to make a copy of!"), _name) << endmsg;
+               return -1;
+       }
+
+       string newname;
+       AudioPlaylist* playlist;
+
+       newname = Playlist::bump_name (_playlist->name(), _session);
+       
+       if ((playlist  = new AudioPlaylist (*_playlist, newname)) != 0) {
+               playlist->set_orig_diskstream_id (id());
+               return use_playlist (playlist);
+       } else { 
+               return -1;
+       }
+}
+
+void
+AudioDiskstream::setup_destructive_playlist ()
+{
+       AudioRegion::SourceList srcs;
+
+       for (ChannelList::iterator chan = channels.begin(); chan != channels.end(); ++chan) {
+               srcs.push_back ((*chan).write_source);
+       }
+
+       /* a single full-sized region */
+
+       AudioRegion* region = new AudioRegion (srcs, 0, max_frames, _name);
+       _playlist->add_region (*region, 0);             
+}
+
+void
+AudioDiskstream::use_destructive_playlist ()
+{
+       /* use the sources associated with the single full-extent region */
+       
+       Playlist::RegionList* rl = _playlist->regions_at (0);
+
+       if (rl->empty()) {
+               reset_write_sources (false, true);
+               return;
+       }
+
+       AudioRegion* region = dynamic_cast<AudioRegion*> (rl->front());
+
+       if (region == 0) {
+               throw failed_constructor();
+       }
+
+       delete rl;
+
+       uint32_t n;
+       ChannelList::iterator chan;
+
+       for (n = 0, chan = channels.begin(); chan != channels.end(); ++chan, ++n) {
+               (*chan).write_source = dynamic_cast<AudioFileSource*>(&region->source (n));
+               (*chan).write_source->set_allow_remove_if_empty (false);
+       }
+
+       /* the source list will never be reset for a destructive track */
+}
+
+void
+AudioDiskstream::set_io (IO& io)
+{
+       _io = &io;
+       set_align_style_from_io ();
+}
+
+int
+AudioDiskstream::set_name (string str, void *src)
+{
+       if (str != _name) {
+               _playlist->set_name (str);
+               _name = str;
+               
+               if (!in_set_state && recordable()) {
+                       /* rename existing capture files so that they have the correct name */
+                       return rename_write_sources ();
+               } else {
+                       return -1;
+               }
+       }
+
+       return 0;
+}
+
+void
+AudioDiskstream::set_speed (double sp)
+{
+       _session.request_diskstream_speed (*this, sp);
+
+       /* to force a rebuffering at the right place */
+       playlist_modified();
+}
+
+bool
+AudioDiskstream::realtime_set_speed (double sp, bool global)
+{
+       bool changed = false;
+       double new_speed = sp * _session.transport_speed();
+       
+       if (_visible_speed != sp) {
+               _visible_speed = sp;
+               changed = true;
+       }
+       
+       if (new_speed != _actual_speed) {
+               
+               jack_nframes_t required_wrap_size = (jack_nframes_t) floor (_session.get_block_size() * 
+                                                                           fabs (new_speed)) + 1;
+               
+               if (required_wrap_size > wrap_buffer_size) {
+                       _buffer_reallocation_required = true;
+               }
+               
+               _actual_speed = new_speed;
+               phi = (uint64_t) (0x1000000 * fabs(_actual_speed));
+       }
+
+       if (changed) {
+               if (!global) {
+                       _seek_required = true;
+               }
+                speed_changed (); /* EMIT SIGNAL */
+       }
+
+       return _buffer_reallocation_required || _seek_required;
+}
+
+void
+AudioDiskstream::non_realtime_set_speed ()
+{
+       if (_buffer_reallocation_required)
+       {
+               Glib::Mutex::Lock lm (state_lock);
+               allocate_temporary_buffers ();
+
+               _buffer_reallocation_required = false;
+       }
+
+       if (_seek_required) {
+               if (speed() != 1.0f || speed() != -1.0f) {
+                       seek ((jack_nframes_t) (_session.transport_frame() * (double) speed()), true);
+               }
+               else {
+                       seek (_session.transport_frame(), true);
+               }
+
+               _seek_required = false;
+       }
+}
+
+void
+AudioDiskstream::prepare ()
+{
+       _processed = false;
+       playback_distance = 0;
+}
+
+void
+AudioDiskstream::check_record_status (jack_nframes_t transport_frame, jack_nframes_t nframes, bool can_record)
+{
+       int possibly_recording;
+       int rolling;
+       int change;
+       const int transport_rolling = 0x4;
+       const int track_rec_enabled = 0x2;
+       const int global_rec_enabled = 0x1;
+
+       /* merge together the 3 factors that affect record status, and compute
+          what has changed.
+       */
+
+       rolling = _session.transport_speed() != 0.0f;
+       possibly_recording = (rolling << 2) | (record_enabled() << 1) | can_record;
+       change = possibly_recording ^ last_possibly_recording;
+
+       if (possibly_recording == last_possibly_recording) {
+               return;
+       }
+
+       /* change state */
+
+       /* if per-track or global rec-enable turned on while the other was already on, we've started recording */
+
+       if ((change & track_rec_enabled) && record_enabled() && (!(change & global_rec_enabled) && can_record) || 
+           ((change & global_rec_enabled) && can_record && (!(change & track_rec_enabled) && record_enabled()))) {
+               
+               /* starting to record: compute first+last frames */
+
+               first_recordable_frame = transport_frame + _capture_offset;
+               last_recordable_frame = max_frames;
+               capture_start_frame = transport_frame;
+
+               if (!(last_possibly_recording & transport_rolling) && (possibly_recording & transport_rolling)) {
+
+                       /* was stopped, now rolling (and recording) */
+
+                       if (_alignment_style == ExistingMaterial) {
+                               first_recordable_frame += _session.worst_output_latency();
+                       } else {
+                               first_recordable_frame += _roll_delay;
+                       }
+
+               } else {
+
+                       /* was rolling, but record state changed */
+
+                       if (_alignment_style == ExistingMaterial) {
+
+
+                               if (!_session.get_punch_in()) {
+
+                                       /* manual punch in happens at the correct transport frame
+                                          because the user hit a button. but to get alignment correct 
+                                          we have to back up the position of the new region to the 
+                                          appropriate spot given the roll delay.
+                                       */
+
+                                       capture_start_frame -= _roll_delay;
+
+                                       /* XXX paul notes (august 2005): i don't know why
+                                          this is needed.
+                                       */
+
+                                       first_recordable_frame += _capture_offset;
+
+                               } else {
+
+                                       /* autopunch toggles recording at the precise
+                                          transport frame, and then the DS waits
+                                          to start recording for a time that depends
+                                          on the output latency.
+                                       */
+
+                                       first_recordable_frame += _session.worst_output_latency();
+                               }
+
+                       } else {
+
+                               if (_session.get_punch_in()) {
+                                       first_recordable_frame += _roll_delay;
+                               } else {
+                                       capture_start_frame -= _roll_delay;
+                               }
+                       }
+                       
+               }
+
+               if (_flags & Recordable) {
+                       for (ChannelList::iterator chan = channels.begin(); chan != channels.end(); ++chan) {
+                               
+                               RingBufferNPT<CaptureTransition>::rw_vector transvec;
+                               (*chan).capture_transition_buf->get_write_vector(&transvec);
+                               
+                               if (transvec.len[0] > 0) {
+                                       transvec.buf[0]->type = CaptureStart;
+                                       transvec.buf[0]->capture_val = capture_start_frame;
+                                       (*chan).capture_transition_buf->increment_write_ptr(1);
+                               }
+                               else {
+                                       // bad!
+                                       fatal << X_("programming error: capture_transition_buf is full on rec start!  inconceivable!") 
+                                             << endmsg;
+                               }
+                       }
+               }
+
+       } else if (!record_enabled() || !can_record) {
+               
+               /* stop recording */
+
+               last_recordable_frame = transport_frame + _capture_offset;
+               
+               if (_alignment_style == ExistingMaterial) {
+                       last_recordable_frame += _session.worst_output_latency();
+               } else {
+                       last_recordable_frame += _roll_delay;
+               }
+       }
+
+       last_possibly_recording = possibly_recording;
+}
+
+int
+AudioDiskstream::process (jack_nframes_t transport_frame, jack_nframes_t nframes, jack_nframes_t offset, bool can_record, bool rec_monitors_input)
+{
+       uint32_t n;
+       ChannelList::iterator c;
+       int ret = -1;
+       jack_nframes_t rec_offset = 0;
+       jack_nframes_t rec_nframes = 0;
+       bool nominally_recording;
+       bool re = record_enabled ();
+       bool collect_playback = false;
+
+       /* if we've already processed the frames corresponding to this call,
+          just return. this allows multiple routes that are taking input
+          from this diskstream to call our ::process() method, but have
+          this stuff only happen once. more commonly, it allows both
+          the AudioTrack that is using this AudioDiskstream *and* the Session
+          to call process() without problems.
+       */
+
+       if (_processed) {
+               return 0;
+       }
+
+       check_record_status (transport_frame, nframes, can_record);
+
+       nominally_recording = (can_record && re);
+
+       if (nframes == 0) {
+               _processed = true;
+               return 0;
+       }
+
+       /* This lock is held until the end of AudioDiskstream::commit, so these two functions
+          must always be called as a pair. The only exception is if this function
+          returns a non-zero value, in which case, ::commit should not be called.
+       */
+
+        // If we can't take the state lock return.
+       if (!state_lock.trylock()) {
+               return 1;
+       }
+
+       adjust_capture_position = 0;
+
+       for (c = channels.begin(); c != channels.end(); ++c) {
+               (*c).current_capture_buffer = 0;
+               (*c).current_playback_buffer  = 0;
+       }
+
+       if (nominally_recording || (_session.get_record_enabled() && _session.get_punch_in())) {
+               OverlapType ot;
+               
+               ot = coverage (first_recordable_frame, last_recordable_frame, transport_frame, transport_frame + nframes);
+
+               switch (ot) {
+               case OverlapNone:
+                       rec_nframes = 0;
+                       break;
+                       
+               case OverlapInternal:
+               /*     ----------    recrange
+                         |---|       transrange
+               */
+                       rec_nframes = nframes;
+                       rec_offset = 0;
+                       break;
+                       
+               case OverlapStart:
+                       /*    |--------|    recrange
+                            -----|          transrange
+                       */
+                       rec_nframes = transport_frame + nframes - first_recordable_frame;
+                       if (rec_nframes) {
+                               rec_offset = first_recordable_frame - transport_frame;
+                       }
+                       break;
+                       
+               case OverlapEnd:
+                       /*    |--------|    recrange
+                                 |--------  transrange
+                       */
+                       rec_nframes = last_recordable_frame - transport_frame;
+                       rec_offset = 0;
+                       break;
+                       
+               case OverlapExternal:
+                       /*    |--------|    recrange
+                            --------------  transrange
+                       */
+                       rec_nframes = last_recordable_frame - last_recordable_frame;
+                       rec_offset = first_recordable_frame - transport_frame;
+                       break;
+               }
+
+               if (rec_nframes && !was_recording) {
+                       capture_captured = 0;
+                       was_recording = true;
+               }
+       }
+
+
+       if (can_record && !_last_capture_regions.empty()) {
+               _last_capture_regions.clear ();
+       }
+
+       if (nominally_recording || rec_nframes) {
+
+               for (n = 0, c = channels.begin(); c != channels.end(); ++c, ++n) {
+                       
+                       ChannelInfo& chan (*c);
+               
+                       chan.capture_buf->get_write_vector (&chan.capture_vector);
+
+                       if (rec_nframes <= chan.capture_vector.len[0]) {
+                               
+                               chan.current_capture_buffer = chan.capture_vector.buf[0];
+
+                               /* note: grab the entire port buffer, but only copy what we were supposed to for recording, and use
+                                  rec_offset
+                               */
+
+                               memcpy (chan.current_capture_buffer, _io->input(n)->get_buffer (rec_nframes) + offset + rec_offset, sizeof (Sample) * rec_nframes);
+
+                       } else {
+
+                               jack_nframes_t total = chan.capture_vector.len[0] + chan.capture_vector.len[1];
+
+                               if (rec_nframes > total) {
+                                       DiskOverrun ();
+                                       goto out;
+                               }
+
+                               Sample* buf = _io->input (n)->get_buffer (nframes) + offset;
+                               jack_nframes_t first = chan.capture_vector.len[0];
+
+                               memcpy (chan.capture_wrap_buffer, buf, sizeof (Sample) * first);
+                               memcpy (chan.capture_vector.buf[0], buf, sizeof (Sample) * first);
+                               memcpy (chan.capture_wrap_buffer+first, buf + first, sizeof (Sample) * (rec_nframes - first));
+                               memcpy (chan.capture_vector.buf[1], buf + first, sizeof (Sample) * (rec_nframes - first));
+                               
+                               chan.current_capture_buffer = chan.capture_wrap_buffer;
+                       }
+               }
+
+       } else {
+
+               if (was_recording) {
+                       finish_capture (rec_monitors_input);
+               }
+
+       }
+       
+       if (rec_nframes) {
+               
+               /* data will be written to disk */
+
+               if (rec_nframes == nframes && rec_offset == 0) {
+
+                       for (c = channels.begin(); c != channels.end(); ++c) {
+                               (*c).current_playback_buffer = (*c).current_capture_buffer;
+                       }
+
+                       playback_distance = nframes;
+
+               } else {
+
+
+                       /* we can't use the capture buffer as the playback buffer, because
+                          we recorded only a part of the current process' cycle data
+                          for capture.
+                       */
+
+                       collect_playback = true;
+               }
+
+               adjust_capture_position = rec_nframes;
+
+       } else if (nominally_recording) {
+
+               /* can't do actual capture yet - waiting for latency effects to finish before we start*/
+
+               for (c = channels.begin(); c != channels.end(); ++c) {
+                       (*c).current_playback_buffer = (*c).current_capture_buffer;
+               }
+
+               playback_distance = nframes;
+
+       } else {
+
+               collect_playback = true;
+       }
+
+       if (collect_playback) {
+
+               /* we're doing playback */
+
+               jack_nframes_t necessary_samples;
+
+               /* no varispeed playback if we're recording, because the output .... TBD */
+
+               if (rec_nframes == 0 && _actual_speed != 1.0f) {
+                       necessary_samples = (jack_nframes_t) floor ((nframes * fabs (_actual_speed))) + 1;
+               } else {
+                       necessary_samples = nframes;
+               }
+               
+               for (c = channels.begin(); c != channels.end(); ++c) {
+                       (*c).playback_buf->get_read_vector (&(*c).playback_vector);
+               }
+
+               n = 0;                  
+
+               for (c = channels.begin(); c != channels.end(); ++c, ++n) {
+               
+                       ChannelInfo& chan (*c);
+
+                       if (necessary_samples <= chan.playback_vector.len[0]) {
+
+                               chan.current_playback_buffer = chan.playback_vector.buf[0];
+
+                       } else {
+                               jack_nframes_t total = chan.playback_vector.len[0] + chan.playback_vector.len[1];
+                               
+                               if (necessary_samples > total) {
+                                       DiskUnderrun ();
+                                       goto out;
+                                       
+                               } else {
+                                       
+                                       memcpy ((char *) chan.playback_wrap_buffer, chan.playback_vector.buf[0],
+                                               chan.playback_vector.len[0] * sizeof (Sample));
+                                       memcpy (chan.playback_wrap_buffer + chan.playback_vector.len[0], chan.playback_vector.buf[1], 
+                                               (necessary_samples - chan.playback_vector.len[0]) * sizeof (Sample));
+                                       
+                                       chan.current_playback_buffer = chan.playback_wrap_buffer;
+                               }
+                       }
+               } 
+
+               if (rec_nframes == 0 && _actual_speed != 1.0f && _actual_speed != -1.0f) {
+                       
+                       uint64_t phase = last_phase;
+                       jack_nframes_t i = 0;
+
+                       // Linearly interpolate into the alt buffer
+                       // using 40.24 fixp maths (swh)
+
+                       for (c = channels.begin(); c != channels.end(); ++c) {
+
+                               float fr;
+                               ChannelInfo& chan (*c);
+
+                               i = 0;
+                               phase = last_phase;
+
+                               for (jack_nframes_t outsample = 0; outsample < nframes; ++outsample) {
+                                       i = phase >> 24;
+                                       fr = (phase & 0xFFFFFF) / 16777216.0f;
+                                       chan.speed_buffer[outsample] = 
+                                               chan.current_playback_buffer[i] * (1.0f - fr) +
+                                               chan.current_playback_buffer[i+1] * fr;
+                                       phase += phi;
+                               }
+                               
+                               chan.current_playback_buffer = chan.speed_buffer;
+                       }
+
+                       playback_distance = i + 1;
+                       last_phase = (phase & 0xFFFFFF);
+
+               } else {
+                       playback_distance = nframes;
+               }
+
+       }
+
+       ret = 0;
+
+  out:
+       _processed = true;
+
+       if (ret) {
+
+               /* we're exiting with failure, so ::commit will not
+                  be called. unlock the state lock.
+               */
+               
+               state_lock.unlock();
+       } 
+
+       return ret;
+}
+
+void
+AudioDiskstream::recover ()
+{
+       state_lock.unlock();
+       _processed = false;
+}
+
+bool
+AudioDiskstream::commit (jack_nframes_t nframes)
+{
+       bool need_butler = false;
+
+       if (_actual_speed < 0.0) {
+               playback_sample -= playback_distance;
+       } else {
+               playback_sample += playback_distance;
+       }
+
+       for (ChannelList::iterator chan = channels.begin(); chan != channels.end(); ++chan) {
+
+               (*chan).playback_buf->increment_read_ptr (playback_distance);
+               
+               if (adjust_capture_position) {
+                       (*chan).capture_buf->increment_write_ptr (adjust_capture_position);
+               }
+       }
+       
+       if (adjust_capture_position != 0) {
+               capture_captured += adjust_capture_position;
+               adjust_capture_position = 0;
+       }
+       
+       if (_slaved) {
+               need_butler = channels[0].playback_buf->write_space() >= channels[0].playback_buf->bufsize() / 2;
+       } else {
+               need_butler = channels[0].playback_buf->write_space() >= disk_io_chunk_frames
+                       || channels[0].capture_buf->read_space() >= disk_io_chunk_frames;
+       }
+
+       state_lock.unlock();
+
+       _processed = false;
+
+       return need_butler;
+}
+
+void
+AudioDiskstream::set_pending_overwrite (bool yn)
+{
+       /* called from audio thread, so we can use the read ptr and playback sample as we wish */
+       
+       pending_overwrite = yn;
+
+       overwrite_frame = playback_sample;
+       overwrite_offset = channels.front().playback_buf->get_read_ptr();
+}
+
+int
+AudioDiskstream::overwrite_existing_buffers ()
+{
+       Sample* mixdown_buffer;
+       float* gain_buffer;
+       char * workbuf;
+       int ret = -1;
+       bool reversed = (_visible_speed * _session.transport_speed()) < 0.0f;
+
+       overwrite_queued = false;
+
+       /* assume all are the same size */
+       jack_nframes_t size = channels[0].playback_buf->bufsize();
+       
+       mixdown_buffer = new Sample[size];
+       gain_buffer = new float[size];
+       workbuf = new char[size*4];
+       
+       /* reduce size so that we can fill the buffer correctly. */
+       size--;
+       
+       uint32_t n=0;
+       jack_nframes_t start;
+
+       for (ChannelList::iterator chan = channels.begin(); chan != channels.end(); ++chan, ++n) {
+
+               start = overwrite_frame;
+               jack_nframes_t cnt = size;
+               
+               /* to fill the buffer without resetting the playback sample, we need to
+                  do it one or two chunks (normally two).
+
+                  |----------------------------------------------------------------------|
+
+                                      ^
+                                      overwrite_offset
+                   |<- second chunk->||<----------------- first chunk ------------------>|
+                  
+               */
+               
+               jack_nframes_t to_read = size - overwrite_offset;
+
+               if (read ((*chan).playback_buf->buffer() + overwrite_offset, mixdown_buffer, gain_buffer, workbuf,
+                         start, to_read, *chan, n, reversed)) {
+                       error << string_compose(_("AudioDiskstream %1: when refilling, cannot read %2 from playlist at frame %3"),
+                                        _id, size, playback_sample) << endmsg;
+                       goto out;
+               }
+                       
+               if (cnt > to_read) {
+
+                       cnt -= to_read;
+               
+                       if (read ((*chan).playback_buf->buffer(), mixdown_buffer, gain_buffer, workbuf,
+                                 start, cnt, *chan, n, reversed)) {
+                               error << string_compose(_("AudioDiskstream %1: when refilling, cannot read %2 from playlist at frame %3"),
+                                                _id, size, playback_sample) << endmsg;
+                               goto out;
+                       }
+               }
+       }
+
+       ret = 0;
+  out:
+       pending_overwrite = false;
+       delete [] gain_buffer;
+       delete [] mixdown_buffer;
+       delete [] workbuf;
+       return ret;
+}
+
+int
+AudioDiskstream::seek (jack_nframes_t frame, bool complete_refill)
+{
+       Glib::Mutex::Lock lm (state_lock);
+       uint32_t n;
+       int ret;
+       ChannelList::iterator chan;
+
+       for (n = 0, chan = channels.begin(); chan != channels.end(); ++chan, ++n) {
+               (*chan).playback_buf->reset ();
+               (*chan).capture_buf->reset ();
+       }
+       
+       playback_sample = frame;
+       file_frame = frame;
+
+       if (complete_refill) {
+               while ((ret = do_refill (0, 0, 0)) > 0);
+       } else {
+               ret = do_refill (0, 0, 0);
+       }
+
+       return ret;
+}
+
+int
+AudioDiskstream::can_internal_playback_seek (jack_nframes_t distance)
+{
+       ChannelList::iterator chan;
+
+       for (chan = channels.begin(); chan != channels.end(); ++chan) {
+               if ((*chan).playback_buf->read_space() < distance) {
+                       return false;
+               } 
+       }
+       return true;
+}
+
+int
+AudioDiskstream::internal_playback_seek (jack_nframes_t distance)
+{
+       ChannelList::iterator chan;
+
+       for (chan = channels.begin(); chan != channels.end(); ++chan) {
+               (*chan).playback_buf->increment_read_ptr (distance);
+       }
+
+       first_recordable_frame += distance;
+       playback_sample += distance;
+       
+       return 0;
+}
+
+int
+AudioDiskstream::read (Sample* buf, Sample* mixdown_buffer, float* gain_buffer, char * workbuf, jack_nframes_t& start, jack_nframes_t cnt, 
+                 ChannelInfo& channel_info, int channel, bool reversed)
+{
+       jack_nframes_t this_read = 0;
+       bool reloop = false;
+       jack_nframes_t loop_end = 0;
+       jack_nframes_t loop_start = 0;
+       jack_nframes_t loop_length = 0;
+       jack_nframes_t offset = 0;
+       Location *loc = 0;
+
+       if (!reversed) {
+               /* Make the use of a Location atomic for this read operation.
+                  
+                  Note: Locations don't get deleted, so all we care about
+                  when I say "atomic" is that we are always pointing to
+                  the same one and using a start/length values obtained
+                  just once.
+               */
+               
+               if ((loc = loop_location) != 0) {
+                       loop_start = loc->start();
+                       loop_end = loc->end();
+                       loop_length = loop_end - loop_start;
+               }
+               
+               /* if we are looping, ensure that the first frame we read is at the correct
+                  position within the loop.
+               */
+               
+               if (loc && start >= loop_end) {
+                       //cerr << "start adjusted from " << start;
+                       start = loop_start + ((start - loop_start) % loop_length);
+                       //cerr << "to " << start << endl;
+               }
+               //cerr << "start is " << start << "  loopstart: " << loop_start << "  loopend: " << loop_end << endl;
+       }
+
+       while (cnt) {
+
+               /* take any loop into account. we can't read past the end of the loop. */
+
+               if (loc && (loop_end - start < cnt)) {
+                       this_read = loop_end - start;
+                       //cerr << "reloop true: thisread: " << this_read << "  cnt: " << cnt << endl;
+                       reloop = true;
+               } else {
+                       reloop = false;
+                       this_read = cnt;
+               }
+
+               if (this_read == 0) {
+                       break;
+               }
+
+               this_read = min(cnt,this_read);
+
+               if (_playlist->read (buf+offset, mixdown_buffer, gain_buffer, workbuf, start, this_read, channel) != this_read) {
+                       error << string_compose(_("AudioDiskstream %1: cannot read %2 from playlist at frame %3"), _id, this_read, 
+                                        start) << endmsg;
+                       return -1;
+               }
+
+               _read_data_count = _playlist->read_data_count();
+               
+               if (reversed) {
+
+                       /* don't adjust start, since caller has already done that
+                        */
+
+                       swap_by_ptr (buf, buf + this_read - 1);
+                       
+               } else {
+                       
+                       /* if we read to the end of the loop, go back to the beginning */
+                       
+                       if (reloop) {
+                               start = loop_start;
+                       } else {
+                               start += this_read;
+                       }
+               } 
+
+               cnt -= this_read;
+               offset += this_read;
+       }
+
+       return 0;
+}
+
+int
+AudioDiskstream::do_refill (Sample* mixdown_buffer, float* gain_buffer, char * workbuf)
+{
+       int32_t ret = 0;
+       jack_nframes_t to_read;
+       RingBufferNPT<Sample>::rw_vector vector;
+       bool free_mixdown;
+       bool free_gain;
+       bool free_workbuf;
+       bool reversed = (_visible_speed * _session.transport_speed()) < 0.0f;
+       jack_nframes_t total_space;
+       jack_nframes_t zero_fill;
+       uint32_t chan_n;
+       ChannelList::iterator i;
+       jack_nframes_t ts;
+
+       channels.front().playback_buf->get_write_vector (&vector);
+       
+       if ((total_space = vector.len[0] + vector.len[1]) == 0) {
+               return 0;
+       }
+       
+       /* if there are 2+ chunks of disk i/o possible for
+          this track, let the caller know so that it can arrange
+          for us to be called again, ASAP.
+       */
+       
+       if (total_space >= (_slaved?3:2) * disk_io_chunk_frames) {
+               ret = 1;
+       }
+       
+       /* if we're running close to normal speed and there isn't enough 
+          space to do disk_io_chunk_frames of I/O, then don't bother.  
+          
+          at higher speeds, just do it because the sync between butler
+          and audio thread may not be good enough.
+       */
+       
+       if ((total_space < disk_io_chunk_frames) && fabs (_actual_speed) < 2.0f) {
+               return 0;
+       }
+       
+       /* when slaved, don't try to get too close to the read pointer. this
+          leaves space for the buffer reversal to have something useful to
+          work with.
+       */
+       
+       if (_slaved && total_space < (channels.front().playback_buf->bufsize() / 2)) {
+               return 0;
+       }
+
+       total_space = min (disk_io_chunk_frames, total_space);
+
+       if (reversed) {
+
+               if (file_frame == 0) {
+
+                       /* at start: nothing to do but fill with silence */
+
+                       for (chan_n = 0, i = channels.begin(); i != channels.end(); ++i, ++chan_n) {
+                                       
+                               ChannelInfo& chan (*i);
+                               chan.playback_buf->get_write_vector (&vector);
+                               memset (vector.buf[0], 0, sizeof(Sample) * vector.len[0]);
+                               if (vector.len[1]) {
+                                       memset (vector.buf[1], 0, sizeof(Sample) * vector.len[1]);
+                               }
+                               chan.playback_buf->increment_write_ptr (vector.len[0] + vector.len[1]);
+                       }
+                       return 0;
+               }
+
+               if (file_frame < total_space) {
+
+                       /* too close to the start: read what we can, 
+                          and then zero fill the rest 
+                       */
+
+                       zero_fill = total_space - file_frame;
+                       total_space = file_frame;
+                       file_frame = 0;
+
+               } else {
+                       
+                       /* move read position backwards because we are going
+                          to reverse the data.
+                       */
+                       
+                       file_frame -= total_space;
+                       zero_fill = 0;
+               }
+
+       } else {
+
+               if (file_frame == max_frames) {
+
+                       /* at end: nothing to do but fill with silence */
+                       
+                       for (chan_n = 0, i = channels.begin(); i != channels.end(); ++i, ++chan_n) {
+                                       
+                               ChannelInfo& chan (*i);
+                               chan.playback_buf->get_write_vector (&vector);
+                               memset (vector.buf[0], 0, sizeof(Sample) * vector.len[0]);
+                               if (vector.len[1]) {
+                                       memset (vector.buf[1], 0, sizeof(Sample) * vector.len[1]);
+                               }
+                               chan.playback_buf->increment_write_ptr (vector.len[0] + vector.len[1]);
+                       }
+                       return 0;
+               }
+               
+               if (file_frame > max_frames - total_space) {
+
+                       /* to close to the end: read what we can, and zero fill the rest */
+
+                       zero_fill = total_space - (max_frames - file_frame);
+                       total_space = max_frames - file_frame;
+
+               } else {
+                       zero_fill = 0;
+               }
+       }
+
+       /* Please note: the code to allocate buffers isn't run
+          during normal butler thread operation. Its there
+          for other times when we need to call do_refill()
+          from somewhere other than the butler thread.
+       */
+
+       if (mixdown_buffer == 0) {
+               mixdown_buffer = new Sample[disk_io_chunk_frames];
+               free_mixdown = true;
+       } else {
+               free_mixdown = false;
+       }
+
+       if (gain_buffer == 0) {
+               gain_buffer = new float[disk_io_chunk_frames];
+               free_gain = true;
+       } else {
+               free_gain = false;
+       }
+
+       if (workbuf == 0) {
+               workbuf = new char[disk_io_chunk_frames * 4];
+               free_workbuf = true;
+       } else {
+               free_workbuf = false;
+       }
+       
+       jack_nframes_t file_frame_tmp = 0;
+
+       for (chan_n = 0, i = channels.begin(); i != channels.end(); ++i, ++chan_n) {
+
+               ChannelInfo& chan (*i);
+               Sample* buf1;
+               Sample* buf2;
+               jack_nframes_t len1, len2;
+
+               chan.playback_buf->get_write_vector (&vector);
+
+               ts = total_space;
+               file_frame_tmp = file_frame;
+
+               if (reversed) {
+                       buf1 = vector.buf[1];
+                       len1 = vector.len[1];
+                       buf2 = vector.buf[0];
+                       len2 = vector.len[0];
+               } else {
+                       buf1 = vector.buf[0];
+                       len1 = vector.len[0];
+                       buf2 = vector.buf[1];
+                       len2 = vector.len[1];
+               }
+
+
+               to_read = min (ts, len1);
+               to_read = min (to_read, disk_io_chunk_frames);
+
+               if (to_read) {
+
+                       if (read (buf1, mixdown_buffer, gain_buffer, workbuf, file_frame_tmp, to_read, chan, chan_n, reversed)) {
+                               ret = -1;
+                               goto out;
+                       }
+                       
+                       chan.playback_buf->increment_write_ptr (to_read);
+                       ts -= to_read;
+               }
+
+               to_read = min (ts, len2);
+
+               if (to_read) {
+
+                       
+                       /* we read all of vector.len[0], but it wasn't an entire disk_io_chunk_frames of data,
+                          so read some or all of vector.len[1] as well.
+                       */
+
+                       if (read (buf2, mixdown_buffer, gain_buffer, workbuf, file_frame_tmp, to_read, chan, chan_n, reversed)) {
+                               ret = -1;
+                               goto out;
+                       }
+               
+                       chan.playback_buf->increment_write_ptr (to_read);
+               }
+
+               if (zero_fill) {
+                       /* do something */
+               }
+
+       }
+       
+       file_frame = file_frame_tmp;
+
+  out:
+       if (free_mixdown) {
+               delete [] mixdown_buffer;
+       }
+       if (free_gain) {
+               delete [] gain_buffer;
+       }
+       if (free_workbuf) {
+               delete [] workbuf;
+       }
+
+       return ret;
+}      
+
+int
+AudioDiskstream::do_flush (char * workbuf, bool force_flush)
+{
+       uint32_t to_write;
+       int32_t ret = 0;
+       RingBufferNPT<Sample>::rw_vector vector;
+       RingBufferNPT<CaptureTransition>::rw_vector transvec;
+       jack_nframes_t total;
+       
+       /* important note: this function will write *AT MOST* 
+          disk_io_chunk_frames of data to disk. it will never 
+          write more than that. if its writes that much and there 
+          is more than that waiting to be written, it will return 1,
+          otherwise 0 on success or -1 on failure.
+
+          if there is less than disk_io_chunk_frames to be written, 
+          no data will be written at all unless `force_flush' is true.  
+       */
+
+       _write_data_count = 0;
+
+       for (ChannelList::iterator chan = channels.begin(); chan != channels.end(); ++chan) {
+       
+               (*chan).capture_buf->get_read_vector (&vector);
+
+               total = vector.len[0] + vector.len[1];
+
+               
+               if (total == 0 || (total < disk_io_chunk_frames && !force_flush && was_recording)) {
+                       goto out;
+               }
+
+               
+               /* if there are 2+ chunks of disk i/o possible for
+                  this track, let the caller know so that it can arrange
+                  for us to be called again, ASAP.
+                  
+                  if we are forcing a flush, then if there is* any* extra
+                  work, let the caller know.
+
+                  if we are no longer recording and there is any extra work,
+                  let the caller know too.
+               */
+
+               if (total >= 2 * disk_io_chunk_frames || ((force_flush || !was_recording) && total > disk_io_chunk_frames)) {
+                       ret = 1;
+               } 
+
+               to_write = min (disk_io_chunk_frames, (jack_nframes_t) vector.len[0]);
+               
+               
+               // check the transition buffer when recording destructive
+               // important that we get this after the capture buf
+
+               if (destructive()) {
+                       (*chan).capture_transition_buf->get_read_vector(&transvec);
+                       size_t transcount = transvec.len[0] + transvec.len[1];
+                       bool have_start = false;
+                       size_t ti;
+
+                       for (ti=0; ti < transcount; ++ti) {
+                               CaptureTransition & captrans = (ti < transvec.len[0]) ? transvec.buf[0][ti] : transvec.buf[1][ti-transvec.len[0]];
+                               
+                               if (captrans.type == CaptureStart) {
+                                       // by definition, the first data we got above represents the given capture pos
+
+                                       (*chan).write_source->mark_capture_start (captrans.capture_val);
+                                       (*chan).curr_capture_cnt = 0;
+
+                                       have_start = true;
+                               }
+                               else if (captrans.type == CaptureEnd) {
+
+                                       // capture end, the capture_val represents total frames in capture
+
+                                       if (captrans.capture_val <= (*chan).curr_capture_cnt + to_write) {
+
+                                               // shorten to make the write a perfect fit
+                                               uint32_t nto_write = (captrans.capture_val - (*chan).curr_capture_cnt); 
+
+                                               if (nto_write < to_write) {
+                                                       ret = 1; // should we?
+                                               }
+                                               to_write = nto_write;
+
+                                               (*chan).write_source->mark_capture_end ();
+                                               
+                                               // increment past this transition, but go no further
+                                               ++ti;
+                                               break;
+                                       }
+                                       else {
+                                               // actually ends just beyond this chunk, so force more work
+                                               ret = 1;
+                                               break;
+                                       }
+                               }
+                       }
+
+                       if (ti > 0) {
+                               (*chan).capture_transition_buf->increment_read_ptr(ti);
+                       }
+               }
+
+               if ((!(*chan).write_source) || (*chan).write_source->write (vector.buf[0], to_write, workbuf) != to_write) {
+                       error << string_compose(_("AudioDiskstream %1: cannot write to disk"), _id) << endmsg;
+                       return -1;
+               }
+
+               (*chan).capture_buf->increment_read_ptr (to_write);
+               (*chan).curr_capture_cnt += to_write;
+               
+               if ((to_write == vector.len[0]) && (total > to_write) && (to_write < disk_io_chunk_frames) && !destructive()) {
+               
+                       /* we wrote all of vector.len[0] but it wasn't an entire
+                          disk_io_chunk_frames of data, so arrange for some part 
+                          of vector.len[1] to be flushed to disk as well.
+                       */
+               
+                       to_write = min ((jack_nframes_t)(disk_io_chunk_frames - to_write), (jack_nframes_t) vector.len[1]);
+               
+                       if ((*chan).write_source->write (vector.buf[1], to_write, workbuf) != to_write) {
+                               error << string_compose(_("AudioDiskstream %1: cannot write to disk"), _id) << endmsg;
+                               return -1;
+                       }
+
+                       _write_data_count += (*chan).write_source->write_data_count();
+       
+                       (*chan).capture_buf->increment_read_ptr (to_write);
+                       (*chan).curr_capture_cnt += to_write;
+               }
+       }
+
+  out:
+       return ret;
+}
+
+void
+AudioDiskstream::playlist_changed (Change ignored)
+{
+       playlist_modified ();
+}
+
+void
+AudioDiskstream::playlist_modified ()
+{
+       if (!i_am_the_modifier && !overwrite_queued) {
+               _session.request_overwrite_buffer (this);
+               overwrite_queued = true;
+       } 
+}
+
+void
+AudioDiskstream::transport_stopped (struct tm& when, time_t twhen, bool abort_capture)
+{
+       uint32_t buffer_position;
+       bool more_work = true;
+       int err = 0;
+       AudioRegion* region = 0;
+       jack_nframes_t total_capture;
+       AudioRegion::SourceList srcs;
+       AudioRegion::SourceList::iterator src;
+       ChannelList::iterator chan;
+       vector<CaptureInfo*>::iterator ci;
+       uint32_t n = 0; 
+       list<AudioFileSource*>* deletion_list;
+       bool mark_write_completed = false;
+
+       finish_capture (true);
+
+       /* butler is already stopped, but there may be work to do 
+          to flush remaining data to disk.
+       */
+
+       while (more_work && !err) {
+               switch (do_flush ( _session.conversion_buffer(Session::TransportContext), true)) {
+               case 0:
+                       more_work = false;
+                       break;
+               case 1:
+                       break;
+               case -1:
+                       error << string_compose(_("AudioDiskstream \"%1\": cannot flush captured data to disk!"), _name) << endmsg;
+                       err++;
+               }
+       }
+
+       /* XXX is there anything we can do if err != 0 ? */
+       Glib::Mutex::Lock lm (capture_info_lock);
+       
+       if (capture_info.empty()) {
+               return;
+       }
+
+       if (abort_capture) {
+               
+               ChannelList::iterator chan;
+               
+               deletion_list = new list<AudioFileSource*>;
+
+               for ( chan = channels.begin(); chan != channels.end(); ++chan) {
+
+                       if ((*chan).write_source) {
+                               
+                               (*chan).write_source->mark_for_remove ();
+                               (*chan).write_source->release ();
+                               
+                               deletion_list->push_back ((*chan).write_source);
+
+                               (*chan).write_source = 0;
+                       }
+                       
+                       /* new source set up in "out" below */
+               }
+               
+               if (!deletion_list->empty()) {
+                       DeleteSources (deletion_list);
+               } else {
+                       delete deletion_list;
+               }
+
+               goto out;
+       } 
+
+       for (total_capture = 0, ci = capture_info.begin(); ci != capture_info.end(); ++ci) {
+               total_capture += (*ci)->frames;
+       }
+
+       /* figure out the name for this take */
+
+       for (n = 0, chan = channels.begin(); chan != channels.end(); ++chan, ++n) {
+
+               AudioFileSource* s = (*chan).write_source;
+               
+               if (s) {
+
+                       AudioFileSource* fsrc;
+
+                       srcs.push_back (s);
+
+                       if ((fsrc = dynamic_cast<AudioFileSource *>(s)) != 0) {
+                               fsrc->update_header (capture_info.front()->start, when, twhen);
+                       }
+
+                       s->set_captured_for (_name);
+                       
+               }
+       }
+
+       /* destructive tracks have a single, never changing region */
+
+       if (destructive()) {
+
+               /* send a signal that any UI can pick up to do the right thing. there is 
+                  a small problem here in that a UI may need the peak data to be ready
+                  for the data that was recorded and this isn't interlocked with that
+                  process. this problem is deferred to the UI.
+                */
+               
+               _playlist->Modified();
+
+       } else {
+
+               /* Register a new region with the Session that
+                  describes the entire source. Do this first
+                  so that any sub-regions will obviously be
+                  children of this one (later!)
+               */
+               
+               try {
+                       region = new AudioRegion (srcs, channels[0].write_source->last_capture_start_frame(), total_capture, 
+                                                 region_name_from_path (channels[0].write_source->name()), 
+                                                 0, AudioRegion::Flag (AudioRegion::DefaultFlags|AudioRegion::Automatic|AudioRegion::WholeFile));
+                       
+                       region->special_set_position (capture_info.front()->start);
+               }
+               
+               
+               catch (failed_constructor& err) {
+                       error << string_compose(_("%1: could not create region for complete audio file"), _name) << endmsg;
+                       /* XXX what now? */
+               }
+               
+               _last_capture_regions.push_back (region);
+
+               // cerr << _name << ": there are " << capture_info.size() << " capture_info records\n";
+               
+               _session.add_undo (_playlist->get_memento());
+               _playlist->freeze ();
+               
+               for (buffer_position = channels[0].write_source->last_capture_start_frame(), ci = capture_info.begin(); ci != capture_info.end(); ++ci) {
+                       
+                       string region_name;
+                       _session.region_name (region_name, channels[0].write_source->name(), false);
+                       
+                       // cerr << _name << ": based on ci of " << (*ci)->start << " for " << (*ci)->frames << " add a region\n";
+                       
+                       try {
+                               region = new AudioRegion (srcs, buffer_position, (*ci)->frames, region_name);
+                       }
+                       
+                       catch (failed_constructor& err) {
+                               error << _("AudioDiskstream: could not create region for captured audio!") << endmsg;
+                               continue; /* XXX is this OK? */
+                       }
+                       
+                       _last_capture_regions.push_back (region);
+                       
+                       // cerr << "add new region, buffer position = " << buffer_position << " @ " << (*ci)->start << endl;
+                       
+                       i_am_the_modifier++;
+                       _playlist->add_region (*region, (*ci)->start);
+                       i_am_the_modifier--;
+                       
+                       buffer_position += (*ci)->frames;
+               }
+
+               _playlist->thaw ();
+               _session.add_redo_no_execute (_playlist->get_memento());
+       }
+
+       mark_write_completed = true;
+
+       reset_write_sources (mark_write_completed);
+
+  out:
+       for (ci = capture_info.begin(); ci != capture_info.end(); ++ci) {
+               delete *ci;
+       }
+
+       capture_info.clear ();
+       capture_start_frame = 0;
+}
+
+void
+AudioDiskstream::finish_capture (bool rec_monitors_input)
+{
+       was_recording = false;
+       
+       if (capture_captured == 0) {
+               return;
+       }
+
+       if (recordable() && destructive()) {
+               for (ChannelList::iterator chan = channels.begin(); chan != channels.end(); ++chan) {
+                       
+                       RingBufferNPT<CaptureTransition>::rw_vector transvec;
+                       (*chan).capture_transition_buf->get_write_vector(&transvec);
+                       
+                       
+                       if (transvec.len[0] > 0) {
+                               transvec.buf[0]->type = CaptureEnd;
+                               transvec.buf[0]->capture_val = capture_captured;
+                               (*chan).capture_transition_buf->increment_write_ptr(1);
+                       }
+                       else {
+                               // bad!
+                               fatal << string_compose (_("programmer error: %1"), X_("capture_transition_buf is full when stopping record!  inconceivable!")) << endmsg;
+                       }
+               }
+       }
+       
+       
+       CaptureInfo* ci = new CaptureInfo;
+       
+       ci->start =  capture_start_frame;
+       ci->frames = capture_captured;
+       
+       /* XXX theoretical race condition here. Need atomic exchange ? 
+          However, the circumstances when this is called right 
+          now (either on record-disable or transport_stopped)
+          mean that no actual race exists. I think ...
+          We now have a capture_info_lock, but it is only to be used
+          to synchronize in the transport_stop and the capture info
+          accessors, so that invalidation will not occur (both non-realtime).
+       */
+
+       // cerr << "Finish capture, add new CI, " << ci->start << '+' << ci->frames << endl;
+
+       capture_info.push_back (ci);
+       capture_captured = 0;
+}
+
+void
+AudioDiskstream::set_record_enabled (bool yn, void* src)
+{
+        bool rolling = _session.transport_speed() != 0.0f;
+
+       if (!recordable() || !_session.record_enabling_legal()) {
+               return;
+       }
+       
+       /* if we're turning on rec-enable, there needs to be an
+          input connection.
+        */
+
+       if (yn && channels[0].source == 0) {
+
+               /* pick up connections not initiated *from* the IO object
+                  we're associated with.
+               */
+
+               get_input_sources ();
+       }
+
+       /* yes, i know that this not proof against race conditions, but its
+          good enough. i think.
+       */
+
+       if (record_enabled() != yn) {
+               if (yn) {
+                       g_atomic_int_set (&_record_enabled, 1);
+                       capturing_sources.clear ();
+                       if (Config->get_use_hardware_monitoring())  {
+                               for (ChannelList::iterator chan = channels.begin(); chan != channels.end(); ++chan) {
+                                       if ((*chan).source) {
+                                               (*chan).source->request_monitor_input (!(_session.get_auto_input() && rolling));
+                                       }
+                                       capturing_sources.push_back ((*chan).write_source);
+                               }
+                       } else {
+                               for (ChannelList::iterator chan = channels.begin(); chan != channels.end(); ++chan) {
+                                       capturing_sources.push_back ((*chan).write_source);
+                               }
+                       }
+
+               } else {
+                       g_atomic_int_set (&_record_enabled, 0);
+                       if (Config->get_use_hardware_monitoring()) {
+                               for (ChannelList::iterator chan = channels.begin(); chan != channels.end(); ++chan) {
+                                       if ((*chan).source) {
+                                               (*chan).source->request_monitor_input (false);
+                                       }
+                               }
+                       }
+                       capturing_sources.clear ();
+               }
+
+               record_enable_changed (src); /* EMIT SIGNAL */
+       }
+}
+
+XMLNode&
+AudioDiskstream::get_state ()
+{
+       XMLNode* node = new XMLNode ("AudioDiskstream");
+       char buf[64];
+       LocaleGuard lg (X_("POSIX"));
+
+       snprintf (buf, sizeof(buf), "0x%x", _flags);
+       node->add_property ("flags", buf);
+
+       snprintf (buf, sizeof(buf), "%zd", channels.size());
+       node->add_property ("channels", buf);
+
+       node->add_property ("playlist", _playlist->name());
+       
+       snprintf (buf, sizeof(buf), "%f", _visible_speed);
+       node->add_property ("speed", buf);
+
+       node->add_property("name", _name);
+       snprintf (buf, sizeof(buf), "%" PRIu64, id());
+       node->add_property("id", buf);
+
+       if (!capturing_sources.empty() && _session.get_record_enabled()) {
+
+               XMLNode* cs_child = new XMLNode (X_("CapturingSources"));
+               XMLNode* cs_grandchild;
+
+               for (vector<AudioFileSource*>::iterator i = capturing_sources.begin(); i != capturing_sources.end(); ++i) {
+                       cs_grandchild = new XMLNode (X_("file"));
+                       cs_grandchild->add_property (X_("path"), (*i)->path());
+                       cs_child->add_child_nocopy (*cs_grandchild);
+               }
+
+               /* store the location where capture will start */
+
+               Location* pi;
+
+               if (_session.get_punch_in() && ((pi = _session.locations()->auto_punch_location()) != 0)) {
+                       snprintf (buf, sizeof (buf), "%" PRIu32, pi->start());
+               } else {
+                       snprintf (buf, sizeof (buf), "%" PRIu32, _session.transport_frame());
+               }
+
+               cs_child->add_property (X_("at"), buf);
+               node->add_child_nocopy (*cs_child);
+       }
+
+       if (_extra_xml) {
+               node->add_child_copy (*_extra_xml);
+       }
+
+       return* node;
+}
+
+int
+AudioDiskstream::set_state (const XMLNode& node)
+{
+       const XMLProperty* prop;
+       XMLNodeList nlist = node.children();
+       XMLNodeIterator niter;
+       uint32_t nchans = 1;
+       XMLNode* capture_pending_node = 0;
+       LocaleGuard lg (X_("POSIX"));
+
+       in_set_state = true;
+
+       for (niter = nlist.begin(); niter != nlist.end(); ++niter) {
+               if ((*niter)->name() == IO::state_node_name) {
+                       deprecated_io_node = new XMLNode (**niter);
+               }
+
+               if ((*niter)->name() == X_("CapturingSources")) {
+                       capture_pending_node = *niter;
+               }
+       }
+
+       /* prevent write sources from being created */
+       
+       in_set_state = true;
+       
+       if ((prop = node.property ("name")) != 0) {
+               _name = prop->value();
+       } 
+
+       if (deprecated_io_node) {
+               if ((prop = deprecated_io_node->property ("id")) != 0) {
+                       sscanf (prop->value().c_str(), "%" PRIu64, &_id);
+               }
+       } else {
+               if ((prop = node.property ("id")) != 0) {
+                       sscanf (prop->value().c_str(), "%" PRIu64, &_id);
+               }
+       }
+
+       if ((prop = node.property ("flags")) != 0) {
+               _flags = strtol (prop->value().c_str(), 0, 0);
+       }
+
+       if ((prop = node.property ("channels")) != 0) {
+               nchans = atoi (prop->value().c_str());
+       }
+       
+       // create necessary extra channels
+       // we are always constructed with one
+       // and we always need one
+
+       if (nchans > _n_channels) {
+
+               // we need to add new channel infos
+               //LockMonitor lm (state_lock, __LINE__, __FILE__);
+
+               int diff = nchans - channels.size();
+
+               for (int i=0; i < diff; ++i) {
+                       add_channel ();
+               }
+
+       } else if (nchans < _n_channels) {
+
+               // we need to get rid of channels
+               //LockMonitor lm (state_lock, __LINE__, __FILE__);
+
+               int diff = channels.size() - nchans;
+               
+               for (int i = 0; i < diff; ++i) {
+                       remove_channel ();
+               }
+       }
+
+       if ((prop = node.property ("playlist")) == 0) {
+               return -1;
+       }
+
+       {
+               bool had_playlist = (_playlist != 0);
+       
+               if (find_and_use_playlist (prop->value())) {
+                       return -1;
+               }
+
+               if (!had_playlist) {
+                       _playlist->set_orig_diskstream_id (_id);
+               }
+               
+               if (!destructive() && capture_pending_node) {
+                       /* destructive streams have one and only one source per channel,
+                          and so they never end up in pending capture in any useful
+                          sense.
+                       */
+                       use_pending_capture_data (*capture_pending_node);
+               }
+
+       }
+
+       if ((prop = node.property ("speed")) != 0) {
+               double sp = atof (prop->value().c_str());
+
+               if (realtime_set_speed (sp, false)) {
+                       non_realtime_set_speed ();
+               }
+       }
+
+       _n_channels = channels.size();
+
+       in_set_state = false;
+
+       /* make sure this is clear before we do anything else */
+
+       capturing_sources.clear ();
+
+       /* write sources are handled when we handle the input set 
+          up of the IO that owns this DS (::non_realtime_input_change())
+       */
+               
+       in_set_state = false;
+
+       return 0;
+}
+
+int
+AudioDiskstream::use_new_write_source (uint32_t n)
+{
+       if (!recordable()) {
+               return 1;
+       }
+
+       if (n >= channels.size()) {
+               error << string_compose (_("AudioDiskstream: channel %1 out of range"), n) << endmsg;
+               return -1;
+       }
+
+       ChannelInfo &chan = channels[n];
+       
+       if (chan.write_source) {
+
+               if (AudioFileSource::is_empty (chan.write_source->path())) {
+                       chan.write_source->mark_for_remove ();
+                       chan.write_source->release();
+                       delete chan.write_source;
+               } else {
+                       chan.write_source->release();
+                       chan.write_source = 0;
+               }
+       }
+
+       try {
+               if ((chan.write_source = _session.create_audio_source_for_session (*this, n, destructive())) == 0) {
+                       throw failed_constructor();
+               }
+       } 
+
+       catch (failed_constructor &err) {
+               error << string_compose (_("%1:%2 new capture file not initialized correctly"), _name, n) << endmsg;
+               chan.write_source = 0;
+               return -1;
+       }
+
+       chan.write_source->use ();
+
+       /* do not remove destructive files even if they are empty */
+
+       chan.write_source->set_allow_remove_if_empty (!destructive());
+
+       return 0;
+}
+
+void
+AudioDiskstream::reset_write_sources (bool mark_write_complete, bool force)
+{
+       ChannelList::iterator chan;
+       uint32_t n;
+
+       if (!recordable()) {
+               return;
+       }
+       
+       capturing_sources.clear ();
+       
+       for (chan = channels.begin(), n = 0; chan != channels.end(); ++chan, ++n) {
+               if (!destructive()) {
+
+                       if ((*chan).write_source && mark_write_complete) {
+                               (*chan).write_source->mark_streaming_write_completed ();
+                       }
+                       use_new_write_source (n);
+
+                       if (record_enabled()) {
+                               capturing_sources.push_back ((*chan).write_source);
+                       }
+
+               } else {
+                       if ((*chan).write_source == 0) {
+                               use_new_write_source (n);
+                       }
+               }
+       }
+
+       if (destructive()) {
+
+               /* we now have all our write sources set up, so create the
+                  playlist's single region.
+               */
+
+               if (_playlist->empty()) {
+                       setup_destructive_playlist ();
+               }
+       }
+}
+
+int
+AudioDiskstream::rename_write_sources ()
+{
+       ChannelList::iterator chan;
+       uint32_t n;
+
+       for (chan = channels.begin(), n = 0; chan != channels.end(); ++chan, ++n) {
+               if ((*chan).write_source != 0) {
+                       (*chan).write_source->set_name (_name, destructive());
+                       /* XXX what to do if one of them fails ? */
+               }
+       }
+
+       return 0;
+}
+
+void
+AudioDiskstream::set_block_size (jack_nframes_t nframes)
+{
+       if (_session.get_block_size() > speed_buffer_size) {
+               speed_buffer_size = _session.get_block_size();
+
+               for (ChannelList::iterator chan = channels.begin(); chan != channels.end(); ++chan) {
+                       if ((*chan).speed_buffer) delete [] (*chan).speed_buffer;
+                       (*chan).speed_buffer = new Sample[speed_buffer_size];
+               }
+       }
+       allocate_temporary_buffers ();
+}
+
+void
+AudioDiskstream::allocate_temporary_buffers ()
+{
+       /* make sure the wrap buffer is at least large enough to deal
+          with the speeds up to 1.2, to allow for micro-variation
+          when slaving to MTC, SMPTE etc.
+       */
+
+       double sp = max (fabsf (_actual_speed), 1.2f);
+       jack_nframes_t required_wrap_size = (jack_nframes_t) floor (_session.get_block_size() * sp) + 1;
+
+       if (required_wrap_size > wrap_buffer_size) {
+
+               for (ChannelList::iterator chan = channels.begin(); chan != channels.end(); ++chan) {
+                       if ((*chan).playback_wrap_buffer) delete [] (*chan).playback_wrap_buffer;
+                       (*chan).playback_wrap_buffer = new Sample[required_wrap_size];  
+                       if ((*chan).capture_wrap_buffer) delete [] (*chan).capture_wrap_buffer;
+                       (*chan).capture_wrap_buffer = new Sample[required_wrap_size];   
+               }
+
+               wrap_buffer_size = required_wrap_size;
+       }
+}
+
+void
+AudioDiskstream::monitor_input (bool yn)
+{
+       for (ChannelList::iterator chan = channels.begin(); chan != channels.end(); ++chan) {
+               
+               if ((*chan).source) {
+                       (*chan).source->request_monitor_input (yn);
+               }
+       }
+}
+
+void
+AudioDiskstream::set_capture_offset ()
+{
+       if (_io == 0) {
+               /* can't capture, so forget it */
+               return;
+       }
+
+       _capture_offset = _io->input_latency();
+}
+
+void
+AudioDiskstream::set_persistent_align_style (AlignStyle a)
+{
+       _persistent_alignment_style = a;
+}
+
+void
+AudioDiskstream::set_align_style_from_io ()
+{
+       bool have_physical = false;
+
+       if (_io == 0) {
+               return;
+       }
+
+       get_input_sources ();
+       
+       for (ChannelList::iterator chan = channels.begin(); chan != channels.end(); ++chan) {
+               if ((*chan).source && (*chan).source->flags() & JackPortIsPhysical) {
+                       have_physical = true;
+                       break;
+               }
+       }
+
+       if (have_physical) {
+               set_align_style (ExistingMaterial);
+       } else {
+               set_align_style (CaptureTime);
+       }
+}
+
+void
+AudioDiskstream::set_align_style (AlignStyle a)
+{
+       if (record_enabled() && _session.actively_recording()) {
+               return;
+       }
+
+
+       if (a != _alignment_style) {
+               _alignment_style = a;
+               AlignmentStyleChanged ();
+       }
+}
+
+int
+AudioDiskstream::add_channel ()
+{
+       /* XXX need to take lock??? */
+
+       ChannelInfo chan;
+
+       init_channel (chan);
+
+       chan.speed_buffer = new Sample[speed_buffer_size];
+       chan.playback_wrap_buffer = new Sample[wrap_buffer_size];
+       chan.capture_wrap_buffer = new Sample[wrap_buffer_size];
+
+       channels.push_back (chan);
+
+       _n_channels = channels.size();
+
+       return 0;
+}
+
+int
+AudioDiskstream::remove_channel ()
+{
+       if (channels.size() > 1) {
+               /* XXX need to take lock??? */
+               ChannelInfo & chan = channels.back();
+               destroy_channel (chan);
+               channels.pop_back();
+
+               _n_channels = channels.size();
+               return 0;
+       }
+
+       return -1;
+}
+
+float
+AudioDiskstream::playback_buffer_load () const
+{
+       return (float) ((double) channels.front().playback_buf->read_space()/
+                       (double) channels.front().playback_buf->bufsize());
+}
+
+float
+AudioDiskstream::capture_buffer_load () const
+{
+       return (float) ((double) channels.front().capture_buf->write_space()/
+                       (double) channels.front().capture_buf->bufsize());
+}
+
+int
+AudioDiskstream::set_loop (Location *location)
+{
+       if (location) {
+               if (location->start() >= location->end()) {
+                       error << string_compose(_("Location \"%1\" not valid for track loop (start >= end)"), location->name()) << endl;
+                       return -1;
+               }
+       }
+
+       loop_location = location;
+
+        LoopSet (location); /* EMIT SIGNAL */
+       return 0;
+}
+
+jack_nframes_t
+AudioDiskstream::get_capture_start_frame (uint32_t n)
+{
+       Glib::Mutex::Lock lm (capture_info_lock);
+
+       if (capture_info.size() > n) {
+               return capture_info[n]->start;
+       }
+       else {
+               return capture_start_frame;
+       }
+}
+
+jack_nframes_t
+AudioDiskstream::get_captured_frames (uint32_t n)
+{
+       Glib::Mutex::Lock lm (capture_info_lock);
+
+       if (capture_info.size() > n) {
+               return capture_info[n]->frames;
+       }
+       else {
+               return capture_captured;
+       }
+}
+
+void
+AudioDiskstream::punch_in ()
+{
+}
+
+void
+AudioDiskstream::punch_out ()
+{
+}
+
+int
+AudioDiskstream::use_pending_capture_data (XMLNode& node)
+{
+       const XMLProperty* prop;
+       XMLNodeList nlist = node.children();
+       XMLNodeIterator niter;
+       AudioFileSource* fs;
+       AudioFileSource* first_fs = 0;
+       AudioRegion::SourceList pending_sources;
+       jack_nframes_t position;
+
+       if ((prop = node.property (X_("at"))) == 0) {
+               return -1;
+       }
+
+       if (sscanf (prop->value().c_str(), "%" PRIu32, &position) != 1) {
+               return -1;
+       }
+
+       for (niter = nlist.begin(); niter != nlist.end(); ++niter) {
+               if ((*niter)->name() == X_("file")) {
+
+                       if ((prop = (*niter)->property (X_("path"))) == 0) {
+                               continue;
+                       }
+
+                       try {
+                               fs = new SndFileSource (prop->value(), 
+                                                       Config->get_native_file_data_format(),
+                                                       Config->get_native_file_header_format(),
+                                                       _session.frame_rate());
+                       }
+
+                       catch (failed_constructor& err) {
+                               error << string_compose (_("%1: cannot restore pending capture source file %2"),
+                                                 _name, prop->value())
+                                     << endmsg;
+                               return -1;
+                       }
+
+                       pending_sources.push_back (fs);
+                       
+                       if (first_fs == 0) {
+                               first_fs = fs;
+                       }
+
+                       fs->set_captured_for (_name);
+               }
+       }
+
+       if (pending_sources.size() == 0) {
+               /* nothing can be done */
+               return 1;
+       }
+
+       if (pending_sources.size() != _n_channels) {
+               error << string_compose (_("%1: incorrect number of pending sources listed - ignoring them all"), _name)
+                     << endmsg;
+               return -1;
+       }
+
+       AudioRegion* region;
+       
+       try {
+               region = new AudioRegion (pending_sources, 0, first_fs->length(),
+                                         region_name_from_path (first_fs->name()), 
+                                         0, AudioRegion::Flag (AudioRegion::DefaultFlags|AudioRegion::Automatic|AudioRegion::WholeFile));
+               
+               region->special_set_position (0);
+       }
+
+       catch (failed_constructor& err) {
+               error << string_compose (_("%1: cannot create whole-file region from pending capture sources"),
+                                 _name)
+                     << endmsg;
+               
+               return -1;
+       }
+
+       try {
+               region = new AudioRegion (pending_sources, 0, first_fs->length(), region_name_from_path (first_fs->name()));
+       }
+
+       catch (failed_constructor& err) {
+               error << string_compose (_("%1: cannot create region from pending capture sources"),
+                                 _name)
+                     << endmsg;
+               
+               return -1;
+       }
+
+       _playlist->add_region (*region, position);
+
+       return 0;
+}
+
+void
+AudioDiskstream::set_roll_delay (jack_nframes_t nframes)
+{
+       _roll_delay = nframes;
+}
+
+void
+AudioDiskstream::set_destructive (bool yn)
+{
+       if (yn != destructive()) {
+               reset_write_sources (true, true);
+               if (yn) {
+                       _flags |= Destructive;
+               } else {
+                       _flags &= ~Destructive;
+               }
+       }
+}
index 30adc54d1a29aa2ef17df5cfca3f806e34e04d80..d146b92a4ba4c5e042ad49224424e9578f3444ff 100644 (file)
 #include <sigc++/bind.h>
 
 #include <ardour/audio_track.h>
-#include <ardour/diskstream.h>
+#include <ardour/audio_diskstream.h>
 #include <ardour/session.h>
 #include <ardour/redirect.h>
 #include <ardour/audioregion.h>
+#include <ardour/audiosource.h>
 #include <ardour/route_group_specialized.h>
 #include <ardour/insert.h>
 #include <ardour/audioplaylist.h>
@@ -43,19 +44,19 @@ AudioTrack::AudioTrack (Session& sess, string name, Route::Flag flag, TrackMode
          diskstream (0),
          _midi_rec_enable_control (*this, _session.midi_port())
 {
-       DiskStream::Flag dflags = DiskStream::Flag (0);
+       AudioDiskstream::Flag dflags = AudioDiskstream::Flag (0);
 
        if (_flags & Hidden) {
-               dflags = DiskStream::Flag (dflags | DiskStream::Hidden);
+               dflags = AudioDiskstream::Flag (dflags | AudioDiskstream::Hidden);
        } else {
-               dflags = DiskStream::Flag (dflags | DiskStream::Recordable);
+               dflags = AudioDiskstream::Flag (dflags | AudioDiskstream::Recordable);
        }
 
        if (mode == Destructive) {
-               dflags = DiskStream::Flag (dflags | DiskStream::Destructive);
+               dflags = AudioDiskstream::Flag (dflags | AudioDiskstream::Destructive);
        }
 
-       DiskStream* ds = new DiskStream (_session, name, dflags);
+       AudioDiskstream* ds = new AudioDiskstream (_session, name, dflags);
        
        _declickable = true;
        _freeze_record.state = NoFreeze;
@@ -64,6 +65,8 @@ AudioTrack::AudioTrack (Session& sess, string name, Route::Flag flag, TrackMode
 
        set_diskstream (*ds, this);
 
+       // session.SMPTEOffsetChanged.connect (mem_fun (*this, &AudioTrack::handle_smpte_offset_change));
+
        // we do this even though Route already did it in it's init
        reset_midi_control (_session.midi_port(), _session.get_midi_control());
        
@@ -90,6 +93,14 @@ AudioTrack::~AudioTrack ()
        }
 }
 
+#if 0
+void
+AudioTrack::handle_smpte_offset_change ()
+{
+       diskstream
+}
+#endif
+
 int
 AudioTrack::deprecated_use_diskstream_connections ()
 {
@@ -143,7 +154,7 @@ AudioTrack::deprecated_use_diskstream_connections ()
 }
 
 int
-AudioTrack::set_diskstream (DiskStream& ds, void *src)
+AudioTrack::set_diskstream (AudioDiskstream& ds, void *src)
 {
        if (diskstream) {
                diskstream->unref();
@@ -166,7 +177,7 @@ AudioTrack::set_diskstream (DiskStream& ds, void *src)
        diskstream->monitor_input (false);
 
        ic_connection.disconnect();
-       ic_connection = input_changed.connect (mem_fun (*diskstream, &DiskStream::handle_input_change));
+       ic_connection = input_changed.connect (mem_fun (*diskstream, &AudioDiskstream::handle_input_change));
 
        diskstream_changed (src); /* EMIT SIGNAL */
 
@@ -176,7 +187,7 @@ AudioTrack::set_diskstream (DiskStream& ds, void *src)
 int 
 AudioTrack::use_diskstream (string name)
 {
-       DiskStream *dstream;
+       AudioDiskstream *dstream;
 
        if ((dstream = _session.diskstream_by_name (name)) == 0) {
          error << string_compose(_("AudioTrack: diskstream \"%1\" not known by session"), name) << endmsg;
@@ -189,7 +200,7 @@ AudioTrack::use_diskstream (string name)
 int 
 AudioTrack::use_diskstream (id_t id)
 {
-       DiskStream *dstream;
+       AudioDiskstream *dstream;
 
        if ((dstream = _session.diskstream_by_id (id)) == 0) {
                error << string_compose(_("AudioTrack: diskstream \"%1\" not known by session"), id) << endmsg;
@@ -899,23 +910,23 @@ AudioTrack::update_total_latency ()
 void
 AudioTrack::bounce (InterThreadInfo& itt)
 {
-       vector<Source*> srcs;
-       _session.write_one_track (*this, 0, _session.current_end_frame(), false, srcs, itt);
+       vector<AudioSource*> srcs;
+       _session.write_one_audio_track (*this, 0, _session.current_end_frame(), false, srcs, itt);
 }
 
 
 void
 AudioTrack::bounce_range (jack_nframes_t start, jack_nframes_t end, InterThreadInfo& itt)
 {
-       vector<Source*> srcs;
-       _session.write_one_track (*this, start, end, false, srcs, itt);
+       vector<AudioSource*> srcs;
+       _session.write_one_audio_track (*this, start, end, false, srcs, itt);
 }
 
 void
 AudioTrack::freeze (InterThreadInfo& itt)
 {
        Insert* insert;
-       vector<Source*> srcs;
+       vector<AudioSource*> srcs;
        string new_playlist_name;
        Playlist* new_playlist;
        string dir;
@@ -950,7 +961,7 @@ AudioTrack::freeze (InterThreadInfo& itt)
                return;
        }
 
-       if (_session.write_one_track (*this, 0, _session.current_end_frame(), true, srcs, itt)) {
+       if (_session.write_one_audio_track (*this, 0, _session.current_end_frame(), true, srcs, itt)) {
                return;
        }
 
index 87866e7b31591c6eeeedca196ed9b948e221458e..c4f90efd4945955e65f30bef09bf279b45a20e1d 100644 (file)
@@ -229,9 +229,10 @@ AudioEngine::_freewheel_callback (int onoff, void *arg)
 int
 AudioEngine::process_callback (jack_nframes_t nframes)
 {
+       // CycleTimer ct ("AudioEngine::process");
        Glib::Mutex::Lock tm (_process_lock, Glib::TRY_LOCK);
        jack_nframes_t next_processed_frames;
-
+       
        /* handle wrap around of total frames counter */
 
        if (max_frames - _processed_frames < nframes) {
diff --git a/libs/ardour/audiofilesource.cc b/libs/ardour/audiofilesource.cc
new file mode 100644 (file)
index 0000000..fbddcda
--- /dev/null
@@ -0,0 +1,661 @@
+/*
+    Copyright (C) 2006 Paul Davis 
+
+    This program is free software; you can redistribute it and/or modify
+    it under the terms of the GNU General Public License as published by
+    the Free Software Foundation; either version 2 of the License, or
+    (at your option) any later version.
+
+    This program is distributed in the hope that it will be useful,
+    but WITHOUT ANY WARRANTY; without even the implied warranty of
+    MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+    GNU General Public License for more details.
+
+    You should have received a copy of the GNU General Public License
+    along with this program; if not, write to the Free Software
+    Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
+
+*/
+
+#include <vector>
+
+#include <sys/time.h>
+#include <sys/stat.h>
+#include <unistd.h>
+#include <errno.h>
+
+#include <pbd/mountpoint.h>
+#include <pbd/pathscanner.h>
+#include <pbd/stl_delete.h>
+#include <pbd/strsplit.h>
+
+#include <sndfile.h>
+
+#include <glibmm/miscutils.h>
+
+#include <ardour/audiofilesource.h>
+#include <ardour/sndfile_helpers.h>
+#include <ardour/sndfilesource.h>
+#include <ardour/destructive_filesource.h>
+#include <ardour/session.h>
+
+// if these headers come before sigc++ is included
+// the parser throws ObjC++ errors. (nil is a keyword)
+#ifdef HAVE_COREAUDIO 
+#include <ardour/coreaudio_source.h>
+#include <AudioToolbox/ExtendedAudioFile.h>
+#include <AudioToolbox/AudioFormat.h>
+#endif // HAVE_COREAUDIO
+
+#include "i18n.h"
+
+using namespace ARDOUR;
+
+string AudioFileSource::peak_dir = "";
+string AudioFileSource::search_path;
+
+sigc::signal<void,struct tm*, time_t> AudioFileSource::HeaderPositionOffsetChanged;
+bool                                  AudioFileSource::header_position_negative;
+uint64_t                              AudioFileSource::header_position_offset;
+
+char   AudioFileSource::bwf_country_code[3] = "US";
+char   AudioFileSource::bwf_organization_code[4] = "LAS";
+char   AudioFileSource::bwf_serial_number[13] = "000000000000";
+
+AudioFileSource::AudioFileSource (string idstr, Flag flags)
+       : AudioSource (idstr), _flags (flags)
+{
+       /* constructor used for existing external to session files. file must exist already */
+
+       if (init (idstr, true)) {
+               throw failed_constructor ();
+       }
+
+}
+
+AudioFileSource::AudioFileSource (std::string path, Flag flags, SampleFormat samp_format, HeaderFormat hdr_format)
+       : AudioSource (path), _flags (flags)
+{
+       /* constructor used for new internal-to-session files. file cannot exist */
+
+       if (init (path, false)) {
+               throw failed_constructor ();
+       }
+}
+
+AudioFileSource::AudioFileSource (const XMLNode& node)
+       : AudioSource (node), _flags (Flag (Writable|CanRename))
+{
+       /* constructor used for existing internal-to-session files. file must exist */
+
+       if (set_state (node)) {
+               throw failed_constructor ();
+       }
+       
+       if (init (_name, true)) {
+               throw failed_constructor ();
+       }
+}
+
+AudioFileSource::~AudioFileSource ()
+{
+       if (removable()) {
+               unlink (_path.c_str());
+               unlink (peakpath.c_str());
+       }
+}
+
+bool
+AudioFileSource::removable () const
+{
+       return (_flags & Removable) && ((_flags & RemoveAtDestroy) || 
+                                     ((_flags & RemovableIfEmpty) && is_empty (_path)));
+}
+
+int
+AudioFileSource::init (string pathstr, bool must_exist)
+{
+       bool is_new = false;
+
+       _length = 0;
+       next_peak_clear_should_notify = false;
+       
+       if (!find (pathstr, must_exist, is_new)) {
+               cerr << "cannot find " << pathstr << " with me = " << must_exist << endl;
+               return -1;
+       }
+
+       if (is_new && must_exist) {
+               return -1;
+       }
+
+       return 0;
+}
+
+
+string
+AudioFileSource::peak_path (string audio_path)
+{
+       return Session::peak_path_from_audio_path (audio_path);
+}
+
+string
+AudioFileSource::old_peak_path (string audio_path)
+{
+       /* XXX hardly bombproof! fix me */
+
+       struct stat stat_file;
+       struct stat stat_mount;
+
+       string mp = mountpoint (audio_path);
+
+       stat (audio_path.c_str(), &stat_file);
+       stat (mp.c_str(), &stat_mount);
+
+       char buf[32];
+#ifdef __APPLE__
+       snprintf (buf, sizeof (buf), "%u-%u-%d.peak", stat_mount.st_ino, stat_file.st_ino, channel);
+#else
+       snprintf (buf, sizeof (buf), "%ld-%ld-%d.peak", stat_mount.st_ino, stat_file.st_ino, channel);
+#endif
+
+       string res = peak_dir;
+       res += buf;
+
+       return res;
+}
+
+#ifdef HAVE_COREAUDIO
+
+AudioFileSource*
+AudioFileSource::create (const XMLNode& node)
+{
+       AudioFileSource* es = 0;
+
+       if (node.property (X_("destructive")) != 0) {
+               
+               es = new DestructiveFileSource (node);
+       
+       } else {
+               
+               try {
+                       es = new CoreAudioSource (node);
+               } 
+               
+               
+               catch (failed_constructor& err) {
+                       es = new SndFileSource (node);
+               }
+       }
+       
+       return es;
+}
+
+#else
+
+AudioFileSource*
+AudioFileSource::create (const XMLNode& node)
+{
+       if (node.property (X_("destructive")) != 0) {
+               
+               return new DestructiveFileSource (node);
+               
+       } else {
+               
+               return new SndFileSource (node);
+       }
+}
+
+#endif // HAVE_COREAUDIO
+
+#ifdef HAVE_COREAUDIO
+AudioFileSource*
+AudioFileSource::create (const string& idstr)
+{
+       AudioFileSource* es = 0;
+
+       try {
+               es = new CoreAudioSource (idstr);
+       }
+
+       catch (failed_constructor& err) {
+               es = new SndFileSource (idstr);
+       }
+
+       return es;
+}
+
+#else
+
+AudioFileSource*
+AudioFileSource::create (string idstr)
+{
+       return new SndFileSource (idstr);
+}
+
+#endif // HAVE_COREAUDIO
+
+#ifdef HAVE_COREAUDIO
+std::string 
+CFStringRefToStdString(CFStringRef stringRef)
+{
+       CFIndex size = 
+               CFStringGetMaximumSizeForEncoding(CFStringGetLength(stringRef) , 
+               kCFStringEncodingASCII);
+           char *buf = new char[size];
+       
+       std::string result;
+
+       if(CFStringGetCString(stringRef, buf, size, kCFStringEncodingASCII)) {
+           result = buf;
+       }
+       delete [] buf;
+       return result;
+}
+#endif // HAVE_COREAUDIO
+
+bool
+AudioFileSource::get_soundfile_info (string path, SoundFileInfo& _info, string& error_msg)
+{
+#ifdef HAVE_COREAUDIO
+       OSStatus err = noErr;
+    FSRef ref; 
+       ExtAudioFileRef af = 0;
+       size_t size;
+    CFStringRef name;
+
+    err = FSPathMakeRef ((UInt8*)path.c_str(), &ref, 0);
+       if (err != noErr) {
+        ExtAudioFileDispose (af);
+               goto libsndfile;
+       }
+
+       err = ExtAudioFileOpen(&ref, &af);
+       if (err != noErr) {
+        ExtAudioFileDispose (af);
+               goto libsndfile;
+       }
+
+       AudioStreamBasicDescription absd;
+       memset(&absd, 0, sizeof(absd));
+       size = sizeof(AudioStreamBasicDescription);
+       err = ExtAudioFileGetProperty(af,
+                       kExtAudioFileProperty_FileDataFormat, &size, &absd);
+       if (err != noErr) {
+        ExtAudioFileDispose (af);
+               goto libsndfile;
+       }
+
+       _info.samplerate = absd.mSampleRate;
+       _info.channels   = absd.mChannelsPerFrame;
+
+    size = sizeof(_info.length);
+    err = ExtAudioFileGetProperty(af, kExtAudioFileProperty_FileLengthFrames, &size, &_info.length);
+    if (err != noErr) {
+        ExtAudioFileDispose (af);
+               goto libsndfile;
+    }
+
+       size = sizeof(CFStringRef);
+       err = AudioFormatGetProperty(
+                       kAudioFormatProperty_FormatName, sizeof(absd), &absd, &size, &name);
+       if (err != noErr) {
+        ExtAudioFileDispose (af);
+               goto libsndfile;
+       }
+
+       _info.format_name = CFStringRefToStdString(name);
+
+    ExtAudioFileDispose (af);
+       return true;
+       
+libsndfile:
+#endif // HAVE_COREAUDIO
+
+       SNDFILE *sf;
+       SF_INFO sf_info;
+
+       sf_info.format = 0; // libsndfile says to clear this before sf_open().
+
+       if ((sf = sf_open ((char*) path.c_str(), SFM_READ, &sf_info)) == 0) { 
+               char errbuf[256];
+               error_msg = sf_error_str (0, errbuf, sizeof (errbuf) - 1);
+               return false;
+       }
+
+       sf_close (sf);
+
+       _info.samplerate  = sf_info.samplerate;
+       _info.channels    = sf_info.channels;
+       _info.length      = sf_info.frames;
+       _info.format_name = string_compose("Format: %1, %2",
+                                          sndfile_major_format(sf_info.format),
+                                          sndfile_minor_format(sf_info.format));
+       return true;
+}
+
+XMLNode&
+AudioFileSource::get_state ()
+{
+       XMLNode& root (AudioSource::get_state());
+       char buf[16];
+       snprintf (buf, sizeof (buf), "0x%x", (int)_flags);
+       root.add_property ("flags", buf);
+       return root;
+}
+
+int
+AudioFileSource::set_state (const XMLNode& node)
+{
+       const XMLProperty* prop;
+
+       if (AudioSource::set_state (node)) {
+               return -1;
+       }
+
+       if ((prop = node.property (X_("flags"))) != 0) {
+
+               int ival;
+               sscanf (prop->value().c_str(), "0x%x", &ival);
+               _flags = Flag (ival);
+
+       } else {
+
+               _flags = Flag (0);
+
+       }
+
+       return 0;
+}
+
+void
+AudioFileSource::mark_for_remove ()
+{
+       if (!writable()) {
+               return;
+       }
+       _flags = Flag (_flags | RemoveAtDestroy);
+}
+
+void
+AudioFileSource::mark_streaming_write_completed ()
+{
+       if (!writable()) {
+               return;
+       }
+
+       Glib::Mutex::Lock lm (_lock);
+
+       next_peak_clear_should_notify = true;
+
+       if (_peaks_built || pending_peak_builds.empty()) {
+               _peaks_built = true;
+                PeaksReady (); /* EMIT SIGNAL */
+       }
+}
+
+void
+AudioFileSource::mark_take (string id)
+{
+       if (writable()) {
+               _take_id = id;
+       }
+}
+
+int
+AudioFileSource::move_to_trash (const string trash_dir_name)
+{
+       string newpath;
+
+       if (!writable()) {
+               return -1;
+       }
+
+       /* don't move the file across filesystems, just
+          stick it in the `trash_dir_name' directory
+          on whichever filesystem it was already on.
+       */
+
+       newpath = Glib::path_get_dirname (_path);
+       newpath = Glib::path_get_dirname (newpath);
+
+       newpath += '/';
+       newpath += trash_dir_name;
+       newpath += '/';
+       newpath += Glib::path_get_basename (_path);
+
+       if (access (newpath.c_str(), F_OK) == 0) {
+
+               /* the new path already exists, try versioning */
+               
+               char buf[PATH_MAX+1];
+               int version = 1;
+               string newpath_v;
+
+               snprintf (buf, sizeof (buf), "%s.%d", newpath.c_str(), version);
+               newpath_v = buf;
+
+               while (access (newpath_v.c_str(), F_OK) == 0 && version < 999) {
+                       snprintf (buf, sizeof (buf), "%s.%d", newpath.c_str(), ++version);
+                       newpath_v = buf;
+               }
+               
+               if (version == 999) {
+                       error << string_compose (_("there are already 1000 files with names like %1; versioning discontinued"),
+                                         newpath)
+                             << endmsg;
+               } else {
+                       newpath = newpath_v;
+               }
+
+       } else {
+
+               /* it doesn't exist, or we can't read it or something */
+
+       }
+
+       if (::rename (_path.c_str(), newpath.c_str()) != 0) {
+               error << string_compose (_("cannot rename audio file source from %1 to %2 (%3)"),
+                                 _path, newpath, strerror (errno))
+                     << endmsg;
+               return -1;
+       }
+
+       if (::unlink (peakpath.c_str()) != 0) {
+               error << string_compose (_("cannot remove peakfile %1 for %2 (%3)"),
+                                 peakpath, _path, strerror (errno))
+                     << endmsg;
+               /* try to back out */
+               rename (newpath.c_str(), _path.c_str());
+               return -1;
+       }
+           
+       _path = newpath;
+       peakpath = "";
+       
+       /* file can not be removed twice, since the operation is not idempotent */
+
+       _flags = Flag (_flags & ~(RemoveAtDestroy|Removable|RemovableIfEmpty));
+
+       return 0;
+}
+
+bool
+AudioFileSource::find (string pathstr, bool must_exist, bool& isnew)
+{
+       string::size_type pos;
+       bool ret = false;
+
+       isnew = false;
+
+       /* clean up PATH:CHANNEL notation so that we are looking for the correct path */
+
+       if ((pos = pathstr.find_last_of (':')) == string::npos) {
+               pathstr = pathstr;
+       } else {
+               pathstr = pathstr.substr (0, pos);
+       }
+
+       if (pathstr[0] != '/') {
+
+               /* non-absolute pathname: find pathstr in search path */
+
+               vector<string> dirs;
+               int cnt;
+               string fullpath;
+               string keeppath;
+
+               if (search_path.length() == 0) {
+                       error << _("FileSource: search path not set") << endmsg;
+                       goto out;
+               }
+
+               split (search_path, dirs, ':');
+
+               cnt = 0;
+               
+               for (vector<string>::iterator i = dirs.begin(); i != dirs.end(); ++i) {
+
+                       fullpath = *i;
+                       if (fullpath[fullpath.length()-1] != '/') {
+                               fullpath += '/';
+                       }
+                       fullpath += pathstr;
+                       
+                       if (access (fullpath.c_str(), R_OK) == 0) {
+                               keeppath = fullpath;
+                               ++cnt;
+                       } 
+               }
+
+               if (cnt > 1) {
+
+                       error << string_compose (_("FileSource: \"%1\" is ambigous when searching %2\n\t"), pathstr, search_path) << endmsg;
+                       goto out;
+
+               } else if (cnt == 0) {
+
+                       if (must_exist) {
+                               error << string_compose(_("Filesource: cannot find required file (%1): while searching %2"), pathstr, search_path) << endmsg;
+                               goto out;
+                       } else {
+                               isnew = true;
+                       }
+               }
+               
+               _name = pathstr;
+               _path = keeppath;
+               ret = true;
+
+       } else {
+               
+               /* external files and/or very very old style sessions include full paths */
+               
+               _path = pathstr;
+               _name = pathstr.substr (pathstr.find_last_of ('/') + 1);
+               
+               if (access (_path.c_str(), R_OK) != 0) {
+
+                       /* file does not exist or we cannot read it */
+
+                       if (must_exist) {
+                               error << string_compose(_("Filesource: cannot find required file (%1): %2"), _path, strerror (errno)) << endmsg;
+                               goto out;
+                       }
+                       
+                       if (errno != ENOENT) {
+                               error << string_compose(_("Filesource: cannot check for existing file (%1): %2"), _path, strerror (errno)) << endmsg;
+                               goto out;
+                       }
+                       
+                       /* a new file */
+
+                       isnew = true;
+                       ret = true;
+
+               } else {
+                       
+                       /* already exists */
+
+                       ret = true;
+               }
+       }
+       
+  out:
+       return ret;
+}
+
+void
+AudioFileSource::set_search_path (string p)
+{
+       search_path = p;
+}
+
+void
+AudioFileSource::set_header_position_offset (jack_nframes_t offset, bool negative)
+{
+       time_t tnow;
+
+       time (&tnow);
+
+       header_position_offset = offset;
+       header_position_negative = negative;
+       HeaderPositionOffsetChanged (localtime (&tnow), tnow); /* EMIT SIGNAL */
+}
+
+void
+AudioFileSource::set_timeline_position (jack_nframes_t pos)
+{
+       timeline_position = pos;
+}
+
+void
+AudioFileSource::handle_header_position_change (struct tm* now, time_t tnow)
+{
+       /* don't do this if the file has never had its header flushed to disk yet */
+
+       if (writable() && _timestamp) {
+               set_header_timeline_position ();
+               flush_header ();
+       }
+}
+
+void
+AudioFileSource::set_allow_remove_if_empty (bool yn)
+{
+       if (writable()) {
+               allow_remove_if_empty = yn;
+       }
+}
+
+int
+AudioFileSource::set_name (string newname, bool destructive)
+{
+       Glib::Mutex::Lock lm (_lock);
+       string oldpath = _path;
+       string newpath = Session::change_audio_path_by_name (oldpath, _name, newname, destructive);
+
+       if (newpath.empty()) {
+               error << string_compose (_("programming error: %1"), "cannot generate a changed audio path") << endmsg;
+               return -1;
+       }
+
+       if (rename (oldpath.c_str(), newpath.c_str()) != 0) {
+               error << string_compose (_("cannot rename audio file for %1 to %2"), _name, newpath) << endmsg;
+               return -1;
+       }
+
+       _name = Glib::path_get_basename (newpath);
+       _path = newpath;
+
+       return rename_peakfile (peak_path (_path));
+}
+
+bool
+AudioFileSource::is_empty (string path)
+{
+       /* XXX fix me */
+
+       return false;
+}
+
index c340bccb2c30890adeb42fb936d8312cd7074100..843a3a7d3409d379e229796b31c689a9e31fd57f 100644 (file)
@@ -22,7 +22,7 @@
 #include <cerrno>
 
 #include <pbd/basename.h>
-#include <ardour/filesource.h>
+#include <ardour/sndfilesource.h>
 #include <ardour/session.h>
 #include <ardour/audioregion.h>
 #include <ardour/audiofilter.h>
@@ -47,7 +47,10 @@ AudioFilter::make_new_sources (AudioRegion& region, AudioRegion::SourceList& nsr
                }
 
                try {
-                       nsrcs.push_back (new FileSource (path, session.frame_rate(), false, Config->get_native_file_data_format()));
+                       nsrcs.push_back (new SndFileSource (path, 
+                                                           Config->get_native_file_data_format(),
+                                                           Config->get_native_file_header_format(),
+                                                           session.frame_rate()));
                } 
 
                catch (failed_constructor& err) {
@@ -73,7 +76,10 @@ AudioFilter::finish (AudioRegion& region, AudioRegion::SourceList& nsrcs)
        now = localtime (&xnow);
 
        for (AudioRegion::SourceList::iterator si = nsrcs.begin(); si != nsrcs.end(); ++si) {
-               dynamic_cast<FileSource*>((*si))->update_header (region.position(), *now, xnow);
+               AudioFileSource* afs = dynamic_cast<AudioFileSource*>(*si);
+               if (afs) {
+                       afs->update_header (region.position(), *now, xnow);
+               }
        }
 
        /* create a new region */
index 21773d92220293e208c0001ddafb1e0b990832da..6b118faa514f57e5f0df9821cb2ff10ffe2a7a57 100644 (file)
@@ -38,6 +38,7 @@
 #include <ardour/dB.h>
 #include <ardour/playlist.h>
 #include <ardour/audiofilter.h>
+#include <ardour/audiosource.h>
 
 #include "i18n.h"
 #include <locale.h>
@@ -63,7 +64,7 @@ AudioRegionState::AudioRegionState (string why)
 {
 }
 
-AudioRegion::AudioRegion (Source& src, jack_nframes_t start, jack_nframes_t length, bool announce)
+AudioRegion::AudioRegion (AudioSource& src, jack_nframes_t start, jack_nframes_t length, bool announce)
        : Region (start, length, PBD::basename_nosuffix(src.name()), 0,  Region::Flag(Region::DefaultFlags|Region::External)),
          _fade_in (0.0, 2.0, 1.0, false),
          _fade_out (0.0, 2.0, 1.0, false),
@@ -89,7 +90,7 @@ AudioRegion::AudioRegion (Source& src, jack_nframes_t start, jack_nframes_t leng
        }
 }
 
-AudioRegion::AudioRegion (Source& src, jack_nframes_t start, jack_nframes_t length, const string& name, layer_t layer, Flag flags, bool announce)
+AudioRegion::AudioRegion (AudioSource& src, jack_nframes_t start, jack_nframes_t length, const string& name, layer_t layer, Flag flags, bool announce)
        : Region (start, length, name, layer, flags),
          _fade_in (0.0, 2.0, 1.0, false),
          _fade_out (0.0, 2.0, 1.0, false),
@@ -150,7 +151,7 @@ AudioRegion::AudioRegion (const AudioRegion& other, jack_nframes_t offset, jack_
 {
        /* create a new AudioRegion, that is part of an existing one */
        
-       set<Source*> unique_srcs;
+       set<AudioSource*> unique_srcs;
 
        for (SourceList::const_iterator i= other.sources.begin(); i != other.sources.end(); ++i) {
                sources.push_back (*i);
@@ -209,7 +210,7 @@ AudioRegion::AudioRegion (const AudioRegion &other)
 {
        /* Pure copy constructor */
 
-       set<Source*> unique_srcs;
+       set<AudioSource*> unique_srcs;
 
        for (SourceList::const_iterator i = other.sources.begin(); i != other.sources.end(); ++i) {
                sources.push_back (*i);
@@ -237,7 +238,7 @@ AudioRegion::AudioRegion (const AudioRegion &other)
        /* NOTE: no CheckNewRegion signal emitted here. This is the copy constructor */
 }
 
-AudioRegion::AudioRegion (Source& src, const XMLNode& node)
+AudioRegion::AudioRegion (AudioSource& src, const XMLNode& node)
        : Region (node),
          _fade_in (0.0, 2.0, 1.0, false),
          _fade_out (0.0, 2.0, 1.0, false),
@@ -268,7 +269,7 @@ AudioRegion::AudioRegion (SourceList& srcs, const XMLNode& node)
 {
        /* basic AudioRegion constructor */
 
-       set<Source*> unique_srcs;
+       set<AudioSource*> unique_srcs;
 
        for (SourceList::iterator i=srcs.begin(); i != srcs.end(); ++i) {
                sources.push_back (*i);
@@ -1094,7 +1095,7 @@ void
 AudioRegion::lock_sources ()
 {
        SourceList::iterator i;
-       set<Source*> unique_srcs;
+       set<AudioSource*> unique_srcs;
 
        for (i = sources.begin(); i != sources.end(); ++i) {
                unique_srcs.insert (*i);
@@ -1112,7 +1113,7 @@ void
 AudioRegion::unlock_sources ()
 {
        SourceList::iterator i;
-       set<Source*> unique_srcs;
+       set<AudioSource*> unique_srcs;
 
        for (i = sources.begin(); i != sources.end(); ++i) {
                unique_srcs.insert (*i);
diff --git a/libs/ardour/audiosource.cc b/libs/ardour/audiosource.cc
new file mode 100644 (file)
index 0000000..46596ad
--- /dev/null
@@ -0,0 +1,897 @@
+/*
+    Copyright (C) 2000 Paul Davis 
+
+    This program is free software; you can redistribute it and/or modify
+    it under the terms of the GNU General Public License as published by
+    the Free Software Foundation; either version 2 of the License, or
+    (at your option) any later version.
+
+    This program is distributed in the hope that it will be useful,
+    but WITHOUT ANY WARRANTY; without even the implied warranty of
+    MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+    GNU General Public License for more details.
+
+    You should have received a copy of the GNU General Public License
+    along with this program; if not, write to the Free Software
+    Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
+
+    $Id: source.cc 404 2006-03-17 17:39:21Z pauld $
+*/
+
+#include <sys/stat.h>
+#include <unistd.h>
+#include <fcntl.h>
+#include <poll.h>
+#include <float.h>
+#include <cerrno>
+#include <ctime>
+#include <cmath>
+#include <iomanip>
+#include <algorithm>
+
+#include <pbd/xml++.h>
+#include <pbd/pthread_utils.h>
+
+#include <ardour/audiosource.h>
+
+#include "i18n.h"
+
+using namespace std;
+using namespace ARDOUR;
+using namespace PBD;
+
+sigc::signal<void,AudioSource *> AudioSource::AudioSourceCreated;
+pthread_t                    AudioSource::peak_thread;
+bool                         AudioSource::have_peak_thread = false;
+vector<AudioSource*>         AudioSource::pending_peak_sources;
+Glib::Mutex*                 AudioSource::pending_peak_sources_lock = 0;
+int                          AudioSource::peak_request_pipe[2];
+
+bool AudioSource::_build_missing_peakfiles = false;
+bool AudioSource::_build_peakfiles = false;
+
+AudioSource::AudioSource (string name)
+       : Source (name)
+{
+       if (pending_peak_sources_lock == 0) {
+               pending_peak_sources_lock = new Glib::Mutex;
+       }
+
+       _peaks_built = false;
+       next_peak_clear_should_notify = true;
+       _read_data_count = 0;
+       _write_data_count = 0;
+}
+
+AudioSource::AudioSource (const XMLNode& node) 
+       : Source (node)
+{
+       if (pending_peak_sources_lock == 0) {
+               pending_peak_sources_lock = new Glib::Mutex;
+       }
+
+       _peaks_built = false;
+       next_peak_clear_should_notify = true;
+       _read_data_count = 0;
+       _write_data_count = 0;
+
+       if (set_state (node)) {
+               throw failed_constructor();
+       }
+}
+
+AudioSource::~AudioSource ()
+{
+}
+
+XMLNode&
+AudioSource::get_state ()
+{
+       XMLNode& node (Source::get_state());
+
+       if (_captured_for.length()) {
+               node.add_property ("captured-for", _captured_for);
+       }
+
+       return node;
+}
+
+int
+AudioSource::set_state (const XMLNode& node)
+{
+       const XMLProperty* prop;
+
+       Source::set_state (node);
+
+       if ((prop = node.property ("captured-for")) != 0) {
+               _captured_for = prop->value();
+       }
+
+       return 0;
+}
+
+/***********************************************************************
+  PEAK FILE STUFF
+ ***********************************************************************/
+
+void*
+AudioSource::peak_thread_work (void* arg)
+{
+       PBD::ThreadCreated (pthread_self(), X_("Peak"));
+       struct pollfd pfd[1];
+
+       if (pending_peak_sources_lock == 0) {
+               pending_peak_sources_lock = new Glib::Mutex;
+       }
+
+       Glib::Mutex::Lock lm (*pending_peak_sources_lock);
+
+       while (true) {
+
+               pfd[0].fd = peak_request_pipe[0];
+               pfd[0].events = POLLIN|POLLERR|POLLHUP;
+
+               pending_peak_sources_lock->unlock ();
+
+               if (poll (pfd, 1, -1) < 0) {
+
+                       if (errno == EINTR) {
+                               pending_peak_sources_lock->lock ();
+                               continue;
+                       }
+                       
+                       error << string_compose (_("poll on peak request pipe failed (%1)"),
+                                         strerror (errno))
+                             << endmsg;
+                       break;
+               }
+
+               if (pfd[0].revents & ~POLLIN) {
+                       error << _("Error on peak thread request pipe") << endmsg;
+                       break;
+               }
+
+               if (pfd[0].revents & POLLIN) {
+
+                       char req;
+                       
+                       /* empty the pipe of all current requests */
+
+                       while (1) {
+                               size_t nread = ::read (peak_request_pipe[0], &req, sizeof (req));
+
+                               if (nread == 1) {
+                                       switch ((PeakRequest::Type) req) {
+                                       
+                                       case PeakRequest::Build:
+                                               break;
+                                               
+                                       case PeakRequest::Quit:
+                                               pthread_exit_pbd (0);
+                                               /*NOTREACHED*/
+                                               break;
+                                               
+                                       default:
+                                               break;
+                                       }
+
+                               } else if (nread == 0) {
+                                       break;
+                               } else if (errno == EAGAIN) {
+                                       break;
+                               } else {
+                                       fatal << _("Error reading from peak request pipe") << endmsg;
+                                       /*NOTREACHED*/
+                               }
+                       }
+               }
+
+               pending_peak_sources_lock->lock ();
+
+               while (!pending_peak_sources.empty()) {
+
+                       AudioSource* s = pending_peak_sources.front();
+                       pending_peak_sources.erase (pending_peak_sources.begin());
+                       
+                       pending_peak_sources_lock->unlock ();
+                       s->build_peaks();
+                       pending_peak_sources_lock->lock ();
+               }
+       }
+
+       pthread_exit_pbd (0);
+       /*NOTREACHED*/
+       return 0;
+}
+
+int
+AudioSource::start_peak_thread ()
+{
+       if (!_build_peakfiles) {
+               return 0;
+       }
+
+       if (pipe (peak_request_pipe)) {
+               error << string_compose(_("Cannot create transport request signal pipe (%1)"), strerror (errno)) << endmsg;
+               return -1;
+       }
+
+       if (fcntl (peak_request_pipe[0], F_SETFL, O_NONBLOCK)) {
+               error << string_compose(_("UI: cannot set O_NONBLOCK on peak request pipe (%1)"), strerror (errno)) << endmsg;
+               return -1;
+       }
+
+       if (fcntl (peak_request_pipe[1], F_SETFL, O_NONBLOCK)) {
+               error << string_compose(_("UI: cannot set O_NONBLOCK on peak request pipe (%1)"), strerror (errno)) << endmsg;
+               return -1;
+       }
+
+       if (pthread_create_and_store ("peak file builder", &peak_thread, 0, peak_thread_work, 0)) {
+               error << _("AudioSource: could not create peak thread") << endmsg;
+               return -1;
+       }
+
+       have_peak_thread = true;
+       return 0;
+}
+
+void
+AudioSource::stop_peak_thread ()
+{
+       if (!have_peak_thread) {
+               return;
+       }
+
+       void* status;
+
+       char c = (char) PeakRequest::Quit;
+       ::write (peak_request_pipe[1], &c, 1);
+       pthread_join (peak_thread, &status);
+}
+
+void 
+AudioSource::queue_for_peaks (AudioSource& source)
+{
+       if (have_peak_thread) {
+
+               Glib::Mutex::Lock lm (*pending_peak_sources_lock);
+               
+               source.next_peak_clear_should_notify = true;
+               
+               if (find (pending_peak_sources.begin(),
+                         pending_peak_sources.end(),
+                         &source) == pending_peak_sources.end()) {
+                       pending_peak_sources.push_back (&source);
+               }
+
+               char c = (char) PeakRequest::Build;
+               ::write (peak_request_pipe[1], &c, 1);
+       }
+}
+
+void AudioSource::clear_queue_for_peaks ()
+{
+       /* this is done to cancel a group of running peak builds */
+       if (have_peak_thread) {
+               Glib::Mutex::Lock lm (*pending_peak_sources_lock);
+               pending_peak_sources.clear ();
+       }
+}
+
+
+bool
+AudioSource::peaks_ready (sigc::slot<void> the_slot, sigc::connection& conn) const
+{
+       bool ret;
+       Glib::Mutex::Lock lm (_lock);
+
+       /* check to see if the peak data is ready. if not
+          connect the slot while still holding the lock.
+       */
+
+       if (!(ret = _peaks_built)) {
+               conn = PeaksReady.connect (the_slot);
+       }
+
+       return ret;
+}
+
+int
+AudioSource::rename_peakfile (string newpath)
+{
+       /* caller must hold _lock */
+
+       string oldpath = peakpath;
+
+       if (access (oldpath.c_str(), F_OK) == 0) {
+               if (rename (oldpath.c_str(), newpath.c_str()) != 0) {
+                       error << string_compose (_("cannot rename peakfile for %1 from %2 to %3 (%4)"), _name, oldpath, newpath, strerror (errno)) << endmsg;
+                       return -1;
+               }
+       }
+
+       peakpath = newpath;
+
+       return 0;
+}
+
+int
+AudioSource::initialize_peakfile (bool newfile, string audio_path)
+{
+       struct stat statbuf;
+
+       peakpath = peak_path (audio_path);
+
+       /* Nasty band-aid for older sessions that were created before we
+          used libsndfile for all audio files.
+       */
+       
+       if (!newfile && access (peakpath.c_str(), R_OK) != 0) {
+               string str = old_peak_path (audio_path);
+               if (access (str.c_str(), R_OK) == 0) {
+                       peakpath = str;
+               }
+       }
+
+       if (newfile) {
+
+               if (!_build_peakfiles) {
+                       return 0;
+               }
+
+               _peaks_built = false;
+
+       } else {
+
+               if (stat (peakpath.c_str(), &statbuf)) {
+                       if (errno != ENOENT) {
+                               /* it exists in the peaks dir, but there is some kind of error */
+                               
+                               error << string_compose(_("AudioSource: cannot stat peakfile \"%1\""), peakpath) << endmsg;
+                               return -1;
+                       }
+
+               } else {
+                       
+                       /* we found it in the peaks dir */
+               }
+               
+               if (statbuf.st_size == 0) {
+                       _peaks_built = false;
+               } else {
+                       // Check if the audio file has changed since the peakfile was built.
+                       struct stat stat_file;
+                       int err = stat (audio_path.c_str(), &stat_file);
+                       
+                       if (!err && stat_file.st_mtime > statbuf.st_mtime){
+                               _peaks_built = false;
+                       } else {
+                               _peaks_built = true;
+                       }
+               }
+       }
+
+       if (!newfile && !_peaks_built && _build_missing_peakfiles && _build_peakfiles) {
+               build_peaks_from_scratch ();
+       } 
+
+       return 0;
+}
+
+jack_nframes_t
+AudioSource::read (Sample *dst, jack_nframes_t start, jack_nframes_t cnt, char * workbuf) const
+{
+       Glib::Mutex::Lock lm (_lock);
+       return read_unlocked (dst, start, cnt, workbuf);
+}
+
+jack_nframes_t
+AudioSource::write (Sample *dst, jack_nframes_t cnt, char * workbuf)
+{
+       Glib::Mutex::Lock lm (_lock);
+       return write_unlocked (dst, cnt, workbuf);
+}
+
+int 
+AudioSource::read_peaks (PeakData *peaks, jack_nframes_t npeaks, jack_nframes_t start, jack_nframes_t cnt, double samples_per_visual_peak) const
+{
+       Glib::Mutex::Lock lm (_lock);
+       double scale;
+       double expected_peaks;
+       PeakData::PeakDatum xmax;
+       PeakData::PeakDatum xmin;
+       int32_t to_read;
+       uint32_t nread;
+       jack_nframes_t zero_fill = 0;
+       int ret = -1;
+       PeakData* staging = 0;
+       Sample* raw_staging = 0;
+       char * workbuf = 0;
+       int peakfile = -1;
+
+       expected_peaks = (cnt / (double) frames_per_peak);
+       scale = npeaks/expected_peaks;
+
+#if 0
+       cerr << "======>RP: npeaks = " << npeaks 
+            << " start = " << start 
+            << " cnt = " << cnt 
+            << " len = " << _length 
+            << "   samples_per_visual_peak =" << samples_per_visual_peak 
+            << " expected was " << expected_peaks << " ... scale = " << scale
+            << " PD ptr = " << peaks
+            <<endl;
+       
+#endif
+
+       /* fix for near-end-of-file conditions */
+
+       if (cnt > _length - start) {
+               // cerr << "too close to end @ " << _length << " given " << start << " + " << cnt << endl;
+               cnt = _length - start;
+               jack_nframes_t old = npeaks;
+               npeaks = min ((jack_nframes_t) floor (cnt / samples_per_visual_peak), npeaks);
+               zero_fill = old - npeaks;
+       }
+
+       // cerr << "actual npeaks = " << npeaks << " zf = " << zero_fill << endl;
+       
+       if (npeaks == cnt) {
+
+               // cerr << "RAW DATA\n";
+               
+               /* no scaling at all, just get the sample data and duplicate it for
+                  both max and min peak values.
+               */
+
+               Sample* raw_staging = new Sample[cnt];
+               workbuf = new char[cnt*4];
+               
+               if (read_unlocked (raw_staging, start, cnt, workbuf) != cnt) {
+                       error << _("cannot read sample data for unscaled peak computation") << endmsg;
+                       return -1;
+               }
+
+               for (jack_nframes_t i = 0; i < npeaks; ++i) {
+                       peaks[i].max = raw_staging[i];
+                       peaks[i].min = raw_staging[i];
+               }
+
+               delete [] raw_staging;
+               delete [] workbuf;
+               return 0;
+       }
+
+       if (scale == 1.0) {
+
+               off_t first_peak_byte = (start / frames_per_peak) * sizeof (PeakData);
+
+               /* open, read, close */
+
+               if ((peakfile = ::open (peakpath.c_str(), O_RDWR|O_CREAT, 0664)) < 0) {
+                       error << string_compose(_("AudioSource: cannot open peakpath \"%1\" (%2)"), peakpath, strerror (errno)) << endmsg;
+                       return -1;
+               }
+
+               // cerr << "DIRECT PEAKS\n";
+               
+               nread = ::pread (peakfile, peaks, sizeof (PeakData)* npeaks, first_peak_byte);
+               close (peakfile);
+
+               if (nread != sizeof (PeakData) * npeaks) {
+                       cerr << "AudioSource["
+                            << _name
+                            << "]: cannot read peaks from peakfile! (read only " 
+                            << nread
+                            << " not " 
+                            << npeaks
+                             << "at sample " 
+                            << start
+                            << " = byte "
+                            << first_peak_byte
+                            << ')'
+                            << endl;
+                       return -1;
+               }
+
+               if (zero_fill) {
+                       memset (&peaks[npeaks], 0, sizeof (PeakData) * zero_fill);
+               }
+
+               return 0;
+       }
+
+
+       jack_nframes_t tnp;
+
+       if (scale < 1.0) {
+
+               // cerr << "DOWNSAMPLE\n";
+
+               /* the caller wants:
+
+                   - more frames-per-peak (lower resolution) than the peakfile, or to put it another way,
+                    - less peaks than the peakfile holds for the same range
+
+                   So, read a block into a staging area, and then downsample from there.
+
+                   to avoid confusion, I'll refer to the requested peaks as visual_peaks and the peakfile peaks as stored_peaks  
+               */
+
+               const uint32_t chunksize = (uint32_t) min (expected_peaks, 4096.0);
+               
+               staging = new PeakData[chunksize];
+               
+               /* compute the rounded up frame position  */
+       
+               jack_nframes_t current_frame = start;
+               jack_nframes_t current_stored_peak = (jack_nframes_t) ceil (current_frame / (double) frames_per_peak);
+               uint32_t       next_visual_peak  = (uint32_t) ceil (current_frame / samples_per_visual_peak);
+               double         next_visual_peak_frame = next_visual_peak * samples_per_visual_peak;
+               uint32_t       stored_peak_before_next_visual_peak = (jack_nframes_t) next_visual_peak_frame / frames_per_peak;
+               uint32_t       nvisual_peaks = 0;
+               uint32_t       stored_peaks_read = 0;
+               uint32_t       i = 0;
+
+               /* handle the case where the initial visual peak is on a pixel boundary */
+
+               current_stored_peak = min (current_stored_peak, stored_peak_before_next_visual_peak);
+
+               /* open ... close during out: handling */
+
+               if ((peakfile = ::open (peakpath.c_str(), O_RDWR|O_CREAT, 0664)) < 0) {
+                       error << string_compose(_("AudioSource: cannot open peakpath \"%1\" (%2)"), peakpath, strerror (errno)) << endmsg;
+                       return 0;
+               }
+
+               while (nvisual_peaks < npeaks) {
+
+                       if (i == stored_peaks_read) {
+
+                               uint32_t       start_byte = current_stored_peak * sizeof(PeakData);
+                               tnp = min ((_length/frames_per_peak - current_stored_peak), (jack_nframes_t) expected_peaks);
+                               to_read = min (chunksize, tnp);
+                               
+                               off_t fend = lseek (peakfile, 0, SEEK_END);
+                               
+                               if ((nread = ::pread (peakfile, staging, sizeof (PeakData) * to_read, start_byte))
+                                   != sizeof (PeakData) * to_read) {
+                                       cerr << "AudioSource["
+                                            << _name
+                                            << "]: cannot read peak data from peakfile ("
+                                            << (nread / sizeof(PeakData))
+                                            << " peaks instead of "
+                                            << to_read
+                                            << ") ("
+                                            << strerror (errno)
+                                            << ')'
+                                            << " at start_byte = " << start_byte 
+                                            << " _length = " << _length << " versus len = " << fend
+                                            << " expected maxpeaks = " << (_length - current_frame)/frames_per_peak
+                                            << " npeaks was " << npeaks
+                                            << endl;
+                                       goto out;
+                               }
+
+                               i = 0;
+                               stored_peaks_read = nread / sizeof(PeakData);
+                       }
+
+                       xmax = -1.0;
+                       xmin = 1.0;
+
+                       while ((i < stored_peaks_read) && (current_stored_peak <= stored_peak_before_next_visual_peak)) {
+
+                               xmax = max (xmax, staging[i].max);
+                               xmin = min (xmin, staging[i].min);
+                               ++i;
+                               ++current_stored_peak;
+                               --expected_peaks;
+                       }
+
+                       peaks[nvisual_peaks].max = xmax;
+                       peaks[nvisual_peaks].min = xmin;
+                       ++nvisual_peaks;
+                       ++next_visual_peak;
+
+                       //next_visual_peak_frame = min ((next_visual_peak * samples_per_visual_peak), (next_visual_peak_frame+samples_per_visual_peak) );
+                       next_visual_peak_frame =  min ((double) start+cnt, (next_visual_peak_frame+samples_per_visual_peak) );
+                       stored_peak_before_next_visual_peak = (uint32_t) next_visual_peak_frame / frames_per_peak; 
+               }
+
+               if (zero_fill) {
+                       memset (&peaks[npeaks], 0, sizeof (PeakData) * zero_fill);
+               }
+               
+               ret = 0;
+
+       } else {
+               
+               // cerr << "UPSAMPLE\n";
+
+               /* the caller wants 
+
+                    - less frames-per-peak (more resolution)
+                    - more peaks than stored in the Peakfile
+
+                  So, fetch data from the raw source, and generate peak
+                  data on the fly.
+               */
+
+               jack_nframes_t frames_read = 0;
+               jack_nframes_t current_frame = start;
+               jack_nframes_t i = 0;
+               jack_nframes_t nvisual_peaks = 0;
+               jack_nframes_t chunksize = (jack_nframes_t) min (cnt, (jack_nframes_t) 4096);
+               raw_staging = new Sample[chunksize];
+               workbuf = new char[chunksize *4];
+               
+               jack_nframes_t frame_pos = start;
+               double pixel_pos = floor (frame_pos / samples_per_visual_peak);
+               double next_pixel_pos = ceil (frame_pos / samples_per_visual_peak);
+               double pixels_per_frame = 1.0 / samples_per_visual_peak;
+
+               xmin = 1.0;
+               xmax = -1.0;
+
+               while (nvisual_peaks < npeaks) {
+
+                       if (i == frames_read) {
+                               
+                               to_read = min (chunksize, (_length - current_frame));
+                               
+                               if ((frames_read = read_unlocked (raw_staging, current_frame, to_read, workbuf)) < 0) {
+                                       error << string_compose(_("AudioSource[%1]: peak read - cannot read %2 samples at offset %3")
+                                                        , _name, to_read, current_frame) 
+                                             << endmsg;
+                                       goto out;
+                               }
+
+                               i = 0;
+                       }
+                       
+                       xmax = max (xmax, raw_staging[i]);
+                       xmin = min (xmin, raw_staging[i]);
+                       ++i;
+                       ++current_frame;
+                       pixel_pos += pixels_per_frame;
+
+                       if (pixel_pos >= next_pixel_pos) {
+
+                               peaks[nvisual_peaks].max = xmax;
+                               peaks[nvisual_peaks].min = xmin;
+                               ++nvisual_peaks;
+                               xmin = 1.0;
+                               xmax = -1.0;
+
+                               next_pixel_pos = ceil (pixel_pos + 0.5);
+                       }
+               }
+               
+               if (zero_fill) {
+                       memset (&peaks[npeaks], 0, sizeof (PeakData) * zero_fill);
+               }
+
+               ret = 0;
+       }
+
+  out:
+       if (peakfile >= 0) {
+               close (peakfile);
+       }
+
+       if (staging) {
+               delete [] staging;
+       } 
+
+       if (raw_staging) {
+               delete [] raw_staging;
+       }
+
+       if (workbuf) {
+               delete [] workbuf;
+       }
+       
+       return ret;
+}
+
+#undef DEBUG_PEAK_BUILD
+
+int
+AudioSource::build_peaks ()
+{
+       vector<PeakBuildRecord*> built;
+       int status = -1;
+       bool pr_signal = false;
+       list<PeakBuildRecord*> copy;
+
+       {
+               Glib::Mutex::Lock lm (_lock);
+               copy = pending_peak_builds;
+               pending_peak_builds.clear ();
+       }
+               
+#ifdef DEBUG_PEAK_BUILD
+       cerr << "build peaks with " << copy.size() << " requests pending\n";
+#endif         
+
+       for (list<PeakBuildRecord *>::iterator i = copy.begin(); i != copy.end(); ++i) {
+               
+               if ((status = do_build_peak ((*i)->frame, (*i)->cnt)) != 0) { 
+                       unlink (peakpath.c_str());
+                       break;
+               }
+               built.push_back (new PeakBuildRecord (*(*i)));
+               delete *i;
+       }
+
+       { 
+               Glib::Mutex::Lock lm (_lock);
+
+               if (status == 0) {
+                       _peaks_built = true;
+                       
+                       if (next_peak_clear_should_notify) {
+                               next_peak_clear_should_notify = false;
+                               pr_signal = true;
+                       }
+               }
+       }
+
+       if (status == 0) {
+               for (vector<PeakBuildRecord *>::iterator i = built.begin(); i != built.end(); ++i) {
+                       PeakRangeReady ((*i)->frame, (*i)->cnt); /* EMIT SIGNAL */
+                       delete *i;
+               }
+
+               if (pr_signal) {
+                       PeaksReady (); /* EMIT SIGNAL */
+               }
+       }
+
+       return status;
+}
+
+int
+AudioSource::do_build_peak (jack_nframes_t first_frame, jack_nframes_t cnt)
+{
+       jack_nframes_t current_frame;
+       Sample buf[frames_per_peak];
+       Sample xmin, xmax;
+       uint32_t  peaki;
+       PeakData* peakbuf;
+       char * workbuf = 0;
+       jack_nframes_t frames_read;
+       jack_nframes_t frames_to_read;
+       off_t first_peak_byte;
+       int peakfile = -1;
+       int ret = -1;
+
+#ifdef DEBUG_PEAK_BUILD
+       cerr << pthread_self() << ": " << _name << ": building peaks for " << first_frame << " to " << first_frame + cnt - 1 << endl;
+#endif
+
+       first_peak_byte = (first_frame / frames_per_peak) * sizeof (PeakData);
+
+#ifdef DEBUG_PEAK_BUILD
+       cerr << "seeking to " << first_peak_byte << " before writing new peak data\n";
+#endif
+
+       current_frame = first_frame;
+       peakbuf = new PeakData[(cnt/frames_per_peak)+1];
+       peaki = 0;
+
+       workbuf = new char[max(frames_per_peak, cnt) * 4];
+       
+       if ((peakfile = ::open (peakpath.c_str(), O_RDWR|O_CREAT, 0664)) < 0) {
+               error << string_compose(_("AudioSource: cannot open peakpath \"%1\" (%2)"), peakpath, strerror (errno)) << endmsg;
+               return -1;
+       }
+       
+       while (cnt) {
+
+               frames_to_read = min (frames_per_peak, cnt);
+
+               if ((frames_read = read_unlocked (buf, current_frame, frames_to_read, workbuf)) != frames_to_read) {
+                       error << string_compose(_("%1: could not write read raw data for peak computation (%2)"), _name, strerror (errno)) << endmsg;
+                       goto out;
+               }
+
+               xmin = buf[0];
+               xmax = buf[0];
+
+               for (jack_nframes_t n = 1; n < frames_read; ++n) {
+                       xmax = max (xmax, buf[n]);
+                       xmin = min (xmin, buf[n]);
+
+//                     if (current_frame < frames_read) {
+//                             cerr << "sample = " << buf[n] << " max = " << xmax << " min = " << xmin << " max of 2 = " << max (xmax, buf[n]) << endl;
+//                     }
+               }
+
+               peakbuf[peaki].max = xmax;
+               peakbuf[peaki].min = xmin;
+               peaki++;
+
+               current_frame += frames_read;
+               cnt -= frames_read;
+       }
+
+       if (::pwrite (peakfile, peakbuf, sizeof (PeakData) * peaki, first_peak_byte) != (ssize_t) (sizeof (PeakData) * peaki)) {
+               error << string_compose(_("%1: could not write peak file data (%2)"), _name, strerror (errno)) << endmsg;
+               goto out;
+       }
+
+       ret = 0;
+
+  out:
+       delete [] peakbuf;
+       if (peakfile >= 0) {
+               close (peakfile);
+       }
+       if (workbuf)
+               delete [] workbuf;
+       return ret;
+}
+
+void
+AudioSource::build_peaks_from_scratch ()
+{
+       Glib::Mutex::Lock lp (_lock);
+
+       next_peak_clear_should_notify = true;
+       pending_peak_builds.push_back (new PeakBuildRecord (0, _length));
+       queue_for_peaks (*this);
+}
+
+bool
+AudioSource::file_changed (string path)
+{
+       struct stat stat_file;
+       struct stat stat_peak;
+
+       int e1 = stat (path.c_str(), &stat_file);
+       int e2 = stat (peak_path(path).c_str(), &stat_peak);
+       
+       if (!e1 && !e2 && stat_file.st_mtime > stat_peak.st_mtime){
+               return true;
+       } else {
+               return false;
+       }
+}
+
+jack_nframes_t
+AudioSource::available_peaks (double zoom_factor) const
+{
+       int peakfile;
+       off_t end;
+
+       if (zoom_factor < frames_per_peak) {
+               return length(); // peak data will come from the audio file
+       } 
+       
+       /* peak data comes from peakfile */
+
+       if ((peakfile = ::open (peakpath.c_str(), O_RDONLY)) < 0) {
+               error << string_compose(_("AudioSource: cannot open peakpath \"%1\" (%2)"), peakpath, strerror (errno)) << endmsg;
+               return 0;
+       }
+
+       { 
+               Glib::Mutex::Lock lm (_lock);
+               end = lseek (peakfile, 0, SEEK_END);
+       }
+
+       close (peakfile);
+
+       return (end/sizeof(PeakData)) * frames_per_peak;
+}
+
+void
+AudioSource::update_length (jack_nframes_t pos, jack_nframes_t cnt)
+{
+       if (pos + cnt > _length) {
+               _length = pos+cnt;
+       }
+}
+
index ce7b9a3e6faeaceb6c085cb34f15ec2a669cd7bf..2f0b943c0e68e95827a4476b64c35946d02205d4 100644 (file)
@@ -20,7 +20,7 @@
 
 #include <glibmm/thread.h>
 
-#include <ardour/diskstream.h>
+#include <ardour/audio_diskstream.h>
 #include <ardour/audioregion.h>
 #include <ardour/route.h>
 #include <ardour/session.h>
index b7b1d65815ef236b452a56688fd12282414648ad..e73208b872ec8b6ca36cbc59737014eae1190e3f 100644 (file)
@@ -26,7 +26,7 @@
 
 #include <ardour/ardour.h>
 #include <ardour/configuration.h>
-#include <ardour/diskstream.h>
+#include <ardour/audio_diskstream.h>
 #include <ardour/destructive_filesource.h>
 #include <ardour/control_protocol_manager.h>
 
@@ -231,7 +231,7 @@ Configuration::set_state (const XMLNode& root)
                }
        }
 
-       DiskStream::set_disk_io_chunk_frames (minimum_disk_io_bytes.get() / sizeof (Sample));
+       AudioDiskstream::set_disk_io_chunk_frames (minimum_disk_io_bytes.get() / sizeof (Sample));
 
        return 0;
 }
index 9a4c2425e9bdd0b6cadb5127de6c2ff1802f6dbb..00fabba4454d3e6117420dc9590e6db920b33d76 100644 (file)
@@ -66,13 +66,9 @@ gain_t* DestructiveFileSource::out_coefficient = 0;
 gain_t* DestructiveFileSource::in_coefficient = 0;
 jack_nframes_t DestructiveFileSource::xfade_frames = 64;
 
-DestructiveFileSource::DestructiveFileSource (string path, jack_nframes_t rate, bool repair_first, SampleFormat samp_format)
-       : FileSource (path, rate, repair_first, samp_format)
+DestructiveFileSource::DestructiveFileSource (string path, SampleFormat samp_format, HeaderFormat hdr_format, jack_nframes_t rate, Flag flags)
+       : SndFileSource (path, samp_format, hdr_format, rate, flags)
 {
-       if (out_coefficient == 0) {
-               setup_standard_crossfades (rate);
-       }
-
        xfade_buf = new Sample[xfade_frames];
 
        _capture_start = false;
@@ -80,13 +76,9 @@ DestructiveFileSource::DestructiveFileSource (string path, jack_nframes_t rate,
        file_pos = 0;
 }
 
-DestructiveFileSource::DestructiveFileSource (const XMLNode& node, jack_nframes_t rate)
-       : FileSource (node, rate)
+DestructiveFileSource::DestructiveFileSource (const XMLNode& node)
+       : SndFileSource (node)
 {
-       if (out_coefficient == 0) {
-               setup_standard_crossfades (rate);
-       }
-
        xfade_buf = new Sample[xfade_frames];
 
        _capture_start = false;
@@ -102,6 +94,10 @@ DestructiveFileSource::~DestructiveFileSource()
 void
 DestructiveFileSource::setup_standard_crossfades (jack_nframes_t rate)
 {
+       /* This static method is assumed to have been called by the Session
+          before any DFS's are created.
+       */
+
        xfade_frames = (jack_nframes_t) floor ((Config->get_destructive_xfade_msecs () / 1000.0) * rate);
 
        if (out_coefficient) {
@@ -124,12 +120,6 @@ DestructiveFileSource::setup_standard_crossfades (jack_nframes_t rate)
        }
 }
 
-int
-DestructiveFileSource::seek (jack_nframes_t frame)
-{
-       return 0;
-}
-
 void
 DestructiveFileSource::mark_capture_start (jack_nframes_t pos)
 {
@@ -188,7 +178,7 @@ DestructiveFileSource::crossfade (Sample* data, jack_nframes_t cnt, int fade_in,
        }
 
        if (file_cnt) {
-               if ((retval = file_read (xfade_buf, fade_position, file_cnt, workbuf)) != (ssize_t) file_cnt) {
+               if ((retval = write_float (xfade_buf, fade_position, file_cnt)) != (ssize_t) file_cnt) {
                        if (retval >= 0 && errno == EAGAIN) {
                                /* XXX - can we really trust that errno is meaningful here?  yes POSIX, i'm talking to you.
                                 * short or no data there */
@@ -206,7 +196,7 @@ DestructiveFileSource::crossfade (Sample* data, jack_nframes_t cnt, int fade_in,
        }
        
        if (nofade && !fade_in) {
-               if (file_write (data, file_pos, nofade, workbuf) != (ssize_t) nofade) {
+               if (write_float (data, file_pos, nofade) != nofade) {
                        error << string_compose(_("DestructiveFileSource: \"%1\" bad write (%2)"), _path, strerror (errno)) << endmsg;
                        return 0;
                }
@@ -248,14 +238,14 @@ DestructiveFileSource::crossfade (Sample* data, jack_nframes_t cnt, int fade_in,
        }
 
        if (xfade) {
-               if (file_write (xfade_buf, fade_position, xfade, workbuf) != (ssize_t) xfade) {
+               if (write_float (xfade_buf, fade_position, xfade) != xfade) {
                        error << string_compose(_("DestructiveFileSource: \"%1\" bad write (%2)"), _path, strerror (errno)) << endmsg;
                        return 0;
                }
        }
        
        if (fade_in && nofade) {
-               if (file_write (data + xfade, file_pos + xfade, nofade, workbuf) != (ssize_t) nofade) {
+               if (write_float (data + xfade, file_pos + xfade, nofade) != nofade) {
                        error << string_compose(_("DestructiveFileSource: \"%1\" bad write (%2)"), _path, strerror (errno)) << endmsg;
                        return 0;
                }
@@ -265,96 +255,100 @@ DestructiveFileSource::crossfade (Sample* data, jack_nframes_t cnt, int fade_in,
 }
 
 jack_nframes_t
-DestructiveFileSource::write (Sample* data, jack_nframes_t cnt, char * workbuf)
+DestructiveFileSource::write_unlocked (Sample* data, jack_nframes_t start, jack_nframes_t cnt, char * workbuf)
 {
-       {
-               Glib::Mutex::Lock lm (_lock);
-               
-               jack_nframes_t old_file_pos;
+       jack_nframes_t old_file_pos;
 
-               if (_capture_start && _capture_end) {
-                       _capture_start = false;
-                       _capture_end = false;
-
-                       /* move to the correct location place */
-                       file_pos = capture_start_frame;
-                       
-                       // split cnt in half
-                       jack_nframes_t subcnt = cnt / 2;
-                       jack_nframes_t ofilepos = file_pos;
-                       
-                       // fade in
-                       if (crossfade (data, subcnt, 1, workbuf) != subcnt) {
-                               return 0;
-                       }
+       if (!writable()) {
+               return 0;
+       }
 
-                       file_pos += subcnt;
-                       Sample * tmpdata = data + subcnt;
-                       
-                       // fade out
-                       subcnt = cnt - subcnt;
-                       if (crossfade (tmpdata, subcnt, 0, workbuf) != subcnt) {
-                               return 0;
-                       }
+       if (_capture_start && _capture_end) {
+               _capture_start = false;
+               _capture_end = false;
+               
+               /* move to the correct location place */
+               file_pos = capture_start_frame;
+               
+               // split cnt in half
+               jack_nframes_t subcnt = cnt / 2;
+               jack_nframes_t ofilepos = file_pos;
+               
+               // fade in
+               if (crossfade (data, subcnt, 1, workbuf) != subcnt) {
+                       return 0;
+               }
+               
+               file_pos += subcnt;
+               Sample * tmpdata = data + subcnt;
+               
+               // fade out
+               subcnt = cnt - subcnt;
+               if (crossfade (tmpdata, subcnt, 0, workbuf) != subcnt) {
+                       return 0;
+               }
+               
+               file_pos = ofilepos; // adjusted below
+       }
+       else if (_capture_start) {
 
-                       file_pos = ofilepos; // adjusted below
+               _capture_start = false;
+               _capture_end = false;
+               
+               /* move to the correct location place */
+               file_pos = capture_start_frame;
+               
+               if (crossfade (data, cnt, 1, workbuf) != cnt) {
+                       return 0;
                }
-               else if (_capture_start) {
-                       _capture_start = false;
-                       _capture_end = false;
+               
+       } else if (_capture_end) {
 
-                       /* move to the correct location place */
-                       file_pos = capture_start_frame;
-                       
-                       if (crossfade (data, cnt, 1, workbuf) != cnt) {
-                               return 0;
-                       }
+               _capture_start = false;
+               _capture_end = false;
+               
+               if (crossfade (data, cnt, 0, workbuf) != cnt) {
+                       return 0;
+               }
 
-               } else if (_capture_end) {
-                       _capture_start = false;
-                       _capture_end = false;
+       } else {
 
-                       if (crossfade (data, cnt, 0, workbuf) != cnt) {
-                               return 0;
-                       }
-               } else {
-                       if (file_write(data, file_pos, cnt, workbuf) != (ssize_t) cnt) {
-                               return 0;
-                       }
+               if (write_float (data, file_pos, cnt) != cnt) {
+                       return 0;
                }
-
-               old_file_pos = file_pos;
-               if (file_pos + cnt > _length) {
-                       _length = file_pos + cnt;
+       }
+       
+       old_file_pos = file_pos;
+       if (file_pos + cnt > _length) {
+               _length = file_pos + cnt;
+       }
+       file_pos += cnt;
+       
+       if (_build_peakfiles) {
+               PeakBuildRecord *pbr = 0;
+               
+               if (pending_peak_builds.size()) {
+                       pbr = pending_peak_builds.back();
                }
-               file_pos += cnt;
                
-               if (_build_peakfiles) {
-                       PeakBuildRecord *pbr = 0;
-                       
-                       if (pending_peak_builds.size()) {
-                               pbr = pending_peak_builds.back();
-                       }
+               if (pbr && pbr->frame + pbr->cnt == old_file_pos) {
                        
-                       if (pbr && pbr->frame + pbr->cnt == old_file_pos) {
-                               
-                               /* the last PBR extended to the start of the current write,
-                                  so just extend it again.
-                               */
-
-                               pbr->cnt += cnt;
-                       } else {
-                               pending_peak_builds.push_back (new PeakBuildRecord (old_file_pos, cnt));
-                       }
+                       /* the last PBR extended to the start of the current write,
+                          so just extend it again.
+                       */
                        
-                       _peaks_built = false;
+                       pbr->cnt += cnt;
+               } else {
+                       pending_peak_builds.push_back (new PeakBuildRecord (old_file_pos, cnt));
                }
+               
+               _peaks_built = false;
        }
 
        if (_build_peakfiles) {
                queue_for_peaks (*this);
        }
-
+       
        return cnt;
 }
 
@@ -367,7 +361,14 @@ DestructiveFileSource::last_capture_start_frame () const
 XMLNode& 
 DestructiveFileSource::get_state ()
 {
-       XMLNode& node = FileSource::get_state ();
+       XMLNode& node = AudioFileSource::get_state ();
        node.add_property (X_("destructive"), "true");
        return node;
 }
+
+void
+DestructiveFileSource::set_timeline_position (jack_nframes_t pos)
+{
+       /* destructive tracks always start at where our reference frame zero is */
+       timeline_position = 0;
+}
diff --git a/libs/ardour/diskstream.cc b/libs/ardour/diskstream.cc
deleted file mode 100644 (file)
index 90e8387..0000000
+++ /dev/null
@@ -1,2562 +0,0 @@
-/*
-    Copyright (C) 2000-2003 Paul Davis 
-
-    This program is free software; you can redistribute it and/or modify
-    it under the terms of the GNU General Public License as published by
-    the Free Software Foundation; either version 2 of the License, or
-    (at your option) any later version.
-
-    This program is distributed in the hope that it will be useful,
-    but WITHOUT ANY WARRANTY; without even the implied warranty of
-    MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
-    GNU General Public License for more details.
-
-    You should have received a copy of the GNU General Public License
-    along with this program; if not, write to the Free Software
-    Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
-
-    $Id$
-*/
-
-#include <fstream>
-#include <cstdio>
-#include <unistd.h>
-#include <cmath>
-#include <cerrno>
-#include <string>
-#include <climits>
-#include <fcntl.h>
-#include <cstdlib>
-#include <ctime>
-#include <sys/stat.h>
-#include <sys/mman.h>
-
-#include <pbd/error.h>
-#include <pbd/basename.h>
-#include <glibmm/thread.h>
-#include <pbd/xml++.h>
-
-#include <ardour/ardour.h>
-#include <ardour/audioengine.h>
-#include <ardour/diskstream.h>
-#include <ardour/utils.h>
-#include <ardour/configuration.h>
-#include <ardour/filesource.h>
-#include <ardour/destructive_filesource.h>
-#include <ardour/send.h>
-#include <ardour/audioplaylist.h>
-#include <ardour/cycle_timer.h>
-#include <ardour/audioregion.h>
-
-#include "i18n.h"
-#include <locale.h>
-
-using namespace std;
-using namespace ARDOUR;
-
-jack_nframes_t DiskStream::disk_io_chunk_frames;
-
-sigc::signal<void,DiskStream*>    DiskStream::DiskStreamCreated;
-sigc::signal<void,list<Source*>*> DiskStream::DeleteSources;
-sigc::signal<void>                DiskStream::DiskOverrun;
-sigc::signal<void>                DiskStream::DiskUnderrun;
-
-DiskStream::DiskStream (Session &sess, const string &name, Flag flag)
-       : _name (name),
-         _session (sess)
-{
-       /* prevent any write sources from being created */
-
-       in_set_state = true;
-
-       init (flag);
-       use_new_playlist ();
-
-       in_set_state = false;
-
-       DiskStreamCreated (this); /* EMIT SIGNAL */
-}
-       
-DiskStream::DiskStream (Session& sess, const XMLNode& node)
-       : _session (sess)
-       
-{
-       in_set_state = true;
-       init (Recordable);
-
-       if (set_state (node)) {
-               in_set_state = false;
-               throw failed_constructor();
-       }
-
-       in_set_state = false;
-
-       if (destructive()) {
-               use_destructive_playlist ();
-       }
-
-       DiskStreamCreated (this); /* EMIT SIGNAL */
-}
-
-void
-DiskStream::init_channel (ChannelInfo &chan)
-{
-       chan.playback_wrap_buffer = 0;
-       chan.capture_wrap_buffer = 0;
-       chan.speed_buffer = 0;
-       chan.peak_power = 0.0f;
-       chan.write_source = 0;
-       chan.source = 0;
-       chan.current_capture_buffer = 0;
-       chan.current_playback_buffer = 0;
-       chan.curr_capture_cnt = 0;
-       
-       chan.playback_buf = new RingBufferNPT<Sample> (_session.diskstream_buffer_size());
-       chan.capture_buf = new RingBufferNPT<Sample> (_session.diskstream_buffer_size());
-       chan.capture_transition_buf = new RingBufferNPT<CaptureTransition> (128);
-       
-       
-       /* touch the ringbuffer buffers, which will cause
-          them to be mapped into locked physical RAM if
-          we're running with mlockall(). this doesn't do
-          much if we're not.  
-       */
-       memset (chan.playback_buf->buffer(), 0, sizeof (Sample) * chan.playback_buf->bufsize());
-       memset (chan.capture_buf->buffer(), 0, sizeof (Sample) * chan.capture_buf->bufsize());
-       memset (chan.capture_transition_buf->buffer(), 0, sizeof (CaptureTransition) * chan.capture_transition_buf->bufsize());
-}
-
-
-void
-DiskStream::init (Flag f)
-{
-       _id = new_id();
-       _refcnt = 0;
-       _flags = f;
-       _io = 0;
-       _alignment_style = ExistingMaterial;
-       _persistent_alignment_style = ExistingMaterial;
-       first_input_change = true;
-       _playlist = 0;
-       i_am_the_modifier = 0;
-       g_atomic_int_set (&_record_enabled, 0);
-       was_recording = false;
-       capture_start_frame = 0;
-       capture_captured = 0;
-       _visible_speed = 1.0f;
-       _actual_speed = 1.0f;
-       _buffer_reallocation_required = false;
-       _seek_required = false;
-       first_recordable_frame = max_frames;
-       last_recordable_frame = max_frames;
-       _roll_delay = 0;
-       _capture_offset = 0;
-       _processed = false;
-       _slaved = false;
-       adjust_capture_position = 0;
-       last_possibly_recording = 0;
-       loop_location = 0;
-       wrap_buffer_size = 0;
-       speed_buffer_size = 0;
-       last_phase = 0;
-       phi = (uint64_t) (0x1000000);
-       file_frame = 0;
-       playback_sample = 0;
-       playback_distance = 0;
-       _read_data_count = 0;
-       _write_data_count = 0;
-       deprecated_io_node = 0;
-
-       /* there are no channels at this point, so these
-          two calls just get speed_buffer_size and wrap_buffer
-          size setup without duplicating their code.
-       */
-
-       set_block_size (_session.get_block_size());
-       allocate_temporary_buffers ();
-
-       pending_overwrite = false;
-       overwrite_frame = 0;
-       overwrite_queued = false;
-       input_change_pending = NoChange;
-
-       add_channel ();
-       _n_channels = 1;
-}
-
-void
-DiskStream::destroy_channel (ChannelInfo &chan)
-{
-       if (chan.write_source) {
-               chan.write_source->release ();
-               chan.write_source = 0;
-       }
-               
-       if (chan.speed_buffer) {
-               delete [] chan.speed_buffer;
-       }
-
-       if (chan.playback_wrap_buffer) {
-               delete [] chan.playback_wrap_buffer;
-       }
-       if (chan.capture_wrap_buffer) {
-               delete [] chan.capture_wrap_buffer;
-       }
-       
-       delete chan.playback_buf;
-       delete chan.capture_buf;
-       delete chan.capture_transition_buf;
-       
-       chan.playback_buf = 0;
-       chan.capture_buf = 0;
-}
-
-DiskStream::~DiskStream ()
-{
-       Glib::Mutex::Lock lm (state_lock);
-
-       if (_playlist) {
-               _playlist->unref ();
-       }
-
-       for (ChannelList::iterator chan = channels.begin(); chan != channels.end(); ++chan) {
-               destroy_channel((*chan));
-       }
-       
-       channels.clear();
-}
-
-void
-DiskStream::handle_input_change (IOChange change, void *src)
-{
-       Glib::Mutex::Lock lm (state_lock);
-
-       if (!(input_change_pending & change)) {
-               input_change_pending = IOChange (input_change_pending|change);
-               _session.request_input_change_handling ();
-       }
-}
-
-void
-DiskStream::non_realtime_input_change ()
-{
-       { 
-               Glib::Mutex::Lock lm (state_lock);
-
-               if (input_change_pending == NoChange) {
-                       return;
-               }
-
-               if (input_change_pending & ConfigurationChanged) {
-
-                       if (_io->n_inputs() > _n_channels) {
-                               
-                               // we need to add new channel infos
-                               
-                               int diff = _io->n_inputs() - channels.size();
-                               
-                               for (int i = 0; i < diff; ++i) {
-                                       add_channel ();
-                               }
-                               
-               } else if (_io->n_inputs() < _n_channels) {
-                               
-                               // we need to get rid of channels
-                               
-                               int diff = channels.size() - _io->n_inputs();
-                               
-                               for (int i = 0; i < diff; ++i) {
-                                       remove_channel ();
-                               }
-                       }
-               } 
-
-               get_input_sources ();
-               set_capture_offset ();
-               
-               if (first_input_change) {
-                       set_align_style (_persistent_alignment_style);
-                       first_input_change = false;
-               } else {
-                       set_align_style_from_io ();
-               }
-
-               input_change_pending = NoChange;
-       }
-
-       /* reset capture files */
-
-       reset_write_sources (false);
-
-       /* now refill channel buffers */
-
-       if (speed() != 1.0f || speed() != -1.0f) {
-               seek ((jack_nframes_t) (_session.transport_frame() * (double) speed()));
-       }
-       else {
-               seek (_session.transport_frame());
-       }
-}
-
-void
-DiskStream::get_input_sources ()
-{
-       uint32_t ni = _io->n_inputs();
-       
-       for (uint32_t n = 0; n < ni; ++n) {
-               
-               const char **connections = _io->input(n)->get_connections ();
-               ChannelInfo& chan = channels[n];
-               
-               if (connections == 0 || connections[0] == 0) {
-                       
-                       if (chan.source) {
-                               // _source->disable_metering ();
-                       }
-                       
-                       chan.source = 0;
-                       
-               } else {
-                       chan.source = _session.engine().get_port_by_name (connections[0]);
-               }
-               
-               if (connections) {
-                       free (connections);
-               }
-       }
-}              
-
-int
-DiskStream::find_and_use_playlist (const string& name)
-{
-       Playlist* pl;
-       AudioPlaylist* playlist;
-               
-       if ((pl = _session.get_playlist (name)) == 0) {
-               error << string_compose(_("DiskStream: Session doesn't know about a Playlist called \"%1\""), name) << endmsg;
-               return -1;
-       }
-
-       if ((playlist = dynamic_cast<AudioPlaylist*> (pl)) == 0) {
-               error << string_compose(_("DiskStream: Playlist \"%1\" isn't an audio playlist"), name) << endmsg;
-               return -1;
-       }
-
-       return use_playlist (playlist);
-}
-
-int
-DiskStream::use_playlist (AudioPlaylist* playlist)
-{
-       {
-               Glib::Mutex::Lock lm (state_lock);
-
-               if (playlist == _playlist) {
-                       return 0;
-               }
-
-               plstate_connection.disconnect();
-               plmod_connection.disconnect ();
-               plgone_connection.disconnect ();
-
-               if (_playlist) {
-                       _playlist->unref();
-               }
-                       
-               _playlist = playlist;
-               _playlist->ref();
-
-               if (!in_set_state && recordable()) {
-                       reset_write_sources (false);
-               }
-               
-               plstate_connection = _playlist->StateChanged.connect (mem_fun (*this, &DiskStream::playlist_changed));
-               plmod_connection = _playlist->Modified.connect (mem_fun (*this, &DiskStream::playlist_modified));
-               plgone_connection = _playlist->GoingAway.connect (mem_fun (*this, &DiskStream::playlist_deleted));
-       }
-
-       if (!overwrite_queued) {
-               _session.request_overwrite_buffer (this);
-               overwrite_queued = true;
-       }
-       
-       PlaylistChanged (); /* EMIT SIGNAL */
-       _session.set_dirty ();
-
-       return 0;
-}
-
-void
-DiskStream::playlist_deleted (Playlist* pl)
-{
-       /* this catches an ordering issue with session destruction. playlists 
-          are destroyed before diskstreams. we have to invalidate any handles
-          we have to the playlist.
-       */
-
-       _playlist = 0;
-}
-
-int
-DiskStream::use_new_playlist ()
-{
-       string newname;
-       AudioPlaylist* playlist;
-
-       if (!in_set_state && destructive()) {
-               return 0;
-       }
-
-       if (_playlist) {
-               newname = Playlist::bump_name (_playlist->name(), _session);
-       } else {
-               newname = Playlist::bump_name (_name, _session);
-       }
-
-       if ((playlist = new AudioPlaylist (_session, newname, hidden())) != 0) {
-               playlist->set_orig_diskstream_id (id());
-               return use_playlist (playlist);
-       } else { 
-               return -1;
-       }
-}
-
-int
-DiskStream::use_copy_playlist ()
-{
-       if (destructive()) {
-               return 0;
-       }
-
-       if (_playlist == 0) {
-               error << string_compose(_("DiskStream %1: there is no existing playlist to make a copy of!"), _name) << endmsg;
-               return -1;
-       }
-
-       string newname;
-       AudioPlaylist* playlist;
-
-       newname = Playlist::bump_name (_playlist->name(), _session);
-       
-       if ((playlist  = new AudioPlaylist (*_playlist, newname)) != 0) {
-               playlist->set_orig_diskstream_id (id());
-               return use_playlist (playlist);
-       } else { 
-               return -1;
-       }
-}
-
-void
-DiskStream::setup_destructive_playlist ()
-{
-       AudioRegion::SourceList srcs;
-
-       for (ChannelList::iterator chan = channels.begin(); chan != channels.end(); ++chan) {
-               srcs.push_back ((*chan).write_source);
-       }
-
-       /* a single full-sized region */
-
-       AudioRegion* region = new AudioRegion (srcs, 0, max_frames, _name);
-       _playlist->add_region (*region, 0);             
-}
-
-void
-DiskStream::use_destructive_playlist ()
-{
-       /* use the sources associated with the single full-extent region */
-       
-       Playlist::RegionList* rl = _playlist->regions_at (0);
-
-       if (rl->empty()) {
-               reset_write_sources (false, true);
-               return;
-       }
-
-       AudioRegion* region = dynamic_cast<AudioRegion*> (rl->front());
-
-       if (region == 0) {
-               throw failed_constructor();
-       }
-
-       delete rl;
-
-       uint32_t n;
-       ChannelList::iterator chan;
-
-       for (n = 0, chan = channels.begin(); chan != channels.end(); ++chan, ++n) {
-               (*chan).write_source = dynamic_cast<FileSource*>(&region->source (n));
-               (*chan).write_source->set_allow_remove_if_empty (false);
-       }
-
-       /* the source list will never be reset for a destructive track */
-}
-
-void
-DiskStream::set_io (IO& io)
-{
-       _io = &io;
-       set_align_style_from_io ();
-}
-
-int
-DiskStream::set_name (string str, void *src)
-{
-       if (str != _name) {
-               _playlist->set_name (str);
-               _name = str;
-               
-               if (!in_set_state && recordable()) {
-                       /* rename existing capture files so that they have the correct name */
-                       return rename_write_sources ();
-               } else {
-                       return -1;
-               }
-       }
-
-       return 0;
-}
-
-void
-DiskStream::set_speed (double sp)
-{
-       _session.request_diskstream_speed (*this, sp);
-
-       /* to force a rebuffering at the right place */
-       playlist_modified();
-}
-
-bool
-DiskStream::realtime_set_speed (double sp, bool global)
-{
-       bool changed = false;
-       double new_speed = sp * _session.transport_speed();
-       
-       if (_visible_speed != sp) {
-               _visible_speed = sp;
-               changed = true;
-       }
-       
-       if (new_speed != _actual_speed) {
-               
-               jack_nframes_t required_wrap_size = (jack_nframes_t) floor (_session.get_block_size() * 
-                                                                           fabs (new_speed)) + 1;
-               
-               if (required_wrap_size > wrap_buffer_size) {
-                       _buffer_reallocation_required = true;
-               }
-               
-               _actual_speed = new_speed;
-               phi = (uint64_t) (0x1000000 * fabs(_actual_speed));
-       }
-
-       if (changed) {
-               if (!global) {
-                       _seek_required = true;
-               }
-                speed_changed (); /* EMIT SIGNAL */
-       }
-
-       return _buffer_reallocation_required || _seek_required;
-}
-
-void
-DiskStream::non_realtime_set_speed ()
-{
-       if (_buffer_reallocation_required)
-       {
-               Glib::Mutex::Lock lm (state_lock);
-               allocate_temporary_buffers ();
-
-               _buffer_reallocation_required = false;
-       }
-
-       if (_seek_required) {
-               if (speed() != 1.0f || speed() != -1.0f) {
-                       seek ((jack_nframes_t) (_session.transport_frame() * (double) speed()), true);
-               }
-               else {
-                       seek (_session.transport_frame(), true);
-               }
-
-               _seek_required = false;
-       }
-}
-
-void
-DiskStream::prepare ()
-{
-       _processed = false;
-       playback_distance = 0;
-}
-
-void
-DiskStream::check_record_status (jack_nframes_t transport_frame, jack_nframes_t nframes, bool can_record)
-{
-       int possibly_recording;
-       int rolling;
-       int change;
-       const int transport_rolling = 0x4;
-       const int track_rec_enabled = 0x2;
-       const int global_rec_enabled = 0x1;
-
-       /* merge together the 3 factors that affect record status, and compute
-          what has changed.
-       */
-
-       rolling = _session.transport_speed() != 0.0f;
-       possibly_recording = (rolling << 2) | (record_enabled() << 1) | can_record;
-       change = possibly_recording ^ last_possibly_recording;
-
-       if (possibly_recording == last_possibly_recording) {
-               return;
-       }
-
-       /* change state */
-
-       /* if per-track or global rec-enable turned on while the other was already on, we've started recording */
-
-       if ((change & track_rec_enabled) && record_enabled() && (!(change & global_rec_enabled) && can_record) || 
-           ((change & global_rec_enabled) && can_record && (!(change & track_rec_enabled) && record_enabled()))) {
-               
-               /* starting to record: compute first+last frames */
-
-               first_recordable_frame = transport_frame + _capture_offset;
-               last_recordable_frame = max_frames;
-               capture_start_frame = transport_frame;
-
-               if (!(last_possibly_recording & transport_rolling) && (possibly_recording & transport_rolling)) {
-
-                       /* was stopped, now rolling (and recording) */
-
-                       if (_alignment_style == ExistingMaterial) {
-                               first_recordable_frame += _session.worst_output_latency();
-                       } else {
-                               first_recordable_frame += _roll_delay;
-                       }
-
-               } else {
-
-                       /* was rolling, but record state changed */
-
-                       if (_alignment_style == ExistingMaterial) {
-
-
-                               if (!_session.get_punch_in()) {
-
-                                       /* manual punch in happens at the correct transport frame
-                                          because the user hit a button. but to get alignment correct 
-                                          we have to back up the position of the new region to the 
-                                          appropriate spot given the roll delay.
-                                       */
-
-                                       capture_start_frame -= _roll_delay;
-
-                                       /* XXX paul notes (august 2005): i don't know why
-                                          this is needed.
-                                       */
-
-                                       first_recordable_frame += _capture_offset;
-
-                               } else {
-
-                                       /* autopunch toggles recording at the precise
-                                          transport frame, and then the DS waits
-                                          to start recording for a time that depends
-                                          on the output latency.
-                                       */
-
-                                       first_recordable_frame += _session.worst_output_latency();
-                               }
-
-                       } else {
-
-                               if (_session.get_punch_in()) {
-                                       first_recordable_frame += _roll_delay;
-                               } else {
-                                       capture_start_frame -= _roll_delay;
-                               }
-                       }
-                       
-               }
-
-               if (_flags & Recordable) {
-                       for (ChannelList::iterator chan = channels.begin(); chan != channels.end(); ++chan) {
-                               
-                               RingBufferNPT<CaptureTransition>::rw_vector transvec;
-                               (*chan).capture_transition_buf->get_write_vector(&transvec);
-                               
-                               if (transvec.len[0] > 0) {
-                                       transvec.buf[0]->type = CaptureStart;
-                                       transvec.buf[0]->capture_val = capture_start_frame;
-                                       (*chan).capture_transition_buf->increment_write_ptr(1);
-                               }
-                               else {
-                                       // bad!
-                                       fatal << X_("programming error: capture_transition_buf is full on rec start!  inconceivable!") 
-                                             << endmsg;
-                               }
-                       }
-               }
-
-       } else if (!record_enabled() || !can_record) {
-               
-               /* stop recording */
-
-               last_recordable_frame = transport_frame + _capture_offset;
-               
-               if (_alignment_style == ExistingMaterial) {
-                       last_recordable_frame += _session.worst_output_latency();
-               } else {
-                       last_recordable_frame += _roll_delay;
-               }
-       }
-
-       last_possibly_recording = possibly_recording;
-}
-
-int
-DiskStream::process (jack_nframes_t transport_frame, jack_nframes_t nframes, jack_nframes_t offset, bool can_record, bool rec_monitors_input)
-{
-       uint32_t n;
-       ChannelList::iterator c;
-       int ret = -1;
-       jack_nframes_t rec_offset = 0;
-       jack_nframes_t rec_nframes = 0;
-       bool nominally_recording;
-       bool re = record_enabled ();
-       bool collect_playback = false;
-
-       /* if we've already processed the frames corresponding to this call,
-          just return. this allows multiple routes that are taking input
-          from this diskstream to call our ::process() method, but have
-          this stuff only happen once. more commonly, it allows both
-          the AudioTrack that is using this DiskStream *and* the Session
-          to call process() without problems.
-       */
-
-       if (_processed) {
-               return 0;
-       }
-
-       check_record_status (transport_frame, nframes, can_record);
-
-       nominally_recording = (can_record && re);
-
-       if (nframes == 0) {
-               _processed = true;
-               return 0;
-       }
-
-       /* This lock is held until the end of DiskStream::commit, so these two functions
-          must always be called as a pair. The only exception is if this function
-          returns a non-zero value, in which case, ::commit should not be called.
-       */
-
-        // If we can't take the state lock return.
-       if (!state_lock.trylock()) {
-               return 1;
-       }
-
-       adjust_capture_position = 0;
-
-       for (c = channels.begin(); c != channels.end(); ++c) {
-               (*c).current_capture_buffer = 0;
-               (*c).current_playback_buffer  = 0;
-       }
-
-       if (nominally_recording || (_session.get_record_enabled() && _session.get_punch_in())) {
-               OverlapType ot;
-               
-               ot = coverage (first_recordable_frame, last_recordable_frame, transport_frame, transport_frame + nframes);
-
-               switch (ot) {
-               case OverlapNone:
-                       rec_nframes = 0;
-                       break;
-                       
-               case OverlapInternal:
-               /*     ----------    recrange
-                         |---|       transrange
-               */
-                       rec_nframes = nframes;
-                       rec_offset = 0;
-                       break;
-                       
-               case OverlapStart:
-                       /*    |--------|    recrange
-                            -----|          transrange
-                       */
-                       rec_nframes = transport_frame + nframes - first_recordable_frame;
-                       if (rec_nframes) {
-                               rec_offset = first_recordable_frame - transport_frame;
-                       }
-                       break;
-                       
-               case OverlapEnd:
-                       /*    |--------|    recrange
-                                 |--------  transrange
-                       */
-                       rec_nframes = last_recordable_frame - transport_frame;
-                       rec_offset = 0;
-                       break;
-                       
-               case OverlapExternal:
-                       /*    |--------|    recrange
-                            --------------  transrange
-                       */
-                       rec_nframes = last_recordable_frame - last_recordable_frame;
-                       rec_offset = first_recordable_frame - transport_frame;
-                       break;
-               }
-
-               if (rec_nframes && !was_recording) {
-                       capture_captured = 0;
-                       was_recording = true;
-               }
-       }
-
-
-       if (can_record && !_last_capture_regions.empty()) {
-               _last_capture_regions.clear ();
-       }
-
-       if (nominally_recording || rec_nframes) {
-
-               for (n = 0, c = channels.begin(); c != channels.end(); ++c, ++n) {
-                       
-                       ChannelInfo& chan (*c);
-               
-                       chan.capture_buf->get_write_vector (&chan.capture_vector);
-
-                       if (rec_nframes <= chan.capture_vector.len[0]) {
-                               
-                               chan.current_capture_buffer = chan.capture_vector.buf[0];
-
-                               /* note: grab the entire port buffer, but only copy what we were supposed to for recording, and use
-                                  rec_offset
-                               */
-
-                               memcpy (chan.current_capture_buffer, _io->input(n)->get_buffer (rec_nframes) + offset + rec_offset, sizeof (Sample) * rec_nframes);
-
-                       } else {
-
-                               jack_nframes_t total = chan.capture_vector.len[0] + chan.capture_vector.len[1];
-
-                               if (rec_nframes > total) {
-                                       DiskOverrun ();
-                                       goto out;
-                               }
-
-                               Sample* buf = _io->input (n)->get_buffer (nframes) + offset;
-                               jack_nframes_t first = chan.capture_vector.len[0];
-
-                               memcpy (chan.capture_wrap_buffer, buf, sizeof (Sample) * first);
-                               memcpy (chan.capture_vector.buf[0], buf, sizeof (Sample) * first);
-                               memcpy (chan.capture_wrap_buffer+first, buf + first, sizeof (Sample) * (rec_nframes - first));
-                               memcpy (chan.capture_vector.buf[1], buf + first, sizeof (Sample) * (rec_nframes - first));
-                               
-                               chan.current_capture_buffer = chan.capture_wrap_buffer;
-                       }
-               }
-
-       } else {
-
-               if (was_recording) {
-                       finish_capture (rec_monitors_input);
-               }
-
-       }
-       
-       if (rec_nframes) {
-               
-               /* data will be written to disk */
-
-               if (rec_nframes == nframes && rec_offset == 0) {
-
-                       for (c = channels.begin(); c != channels.end(); ++c) {
-                               (*c).current_playback_buffer = (*c).current_capture_buffer;
-                       }
-
-                       playback_distance = nframes;
-
-               } else {
-
-
-                       /* we can't use the capture buffer as the playback buffer, because
-                          we recorded only a part of the current process' cycle data
-                          for capture.
-                       */
-
-                       collect_playback = true;
-               }
-
-               adjust_capture_position = rec_nframes;
-
-       } else if (nominally_recording) {
-
-               /* can't do actual capture yet - waiting for latency effects to finish before we start*/
-
-               for (c = channels.begin(); c != channels.end(); ++c) {
-                       (*c).current_playback_buffer = (*c).current_capture_buffer;
-               }
-
-               playback_distance = nframes;
-
-       } else {
-
-               collect_playback = true;
-       }
-
-       if (collect_playback) {
-
-               /* we're doing playback */
-
-               jack_nframes_t necessary_samples;
-
-               /* no varispeed playback if we're recording, because the output .... TBD */
-
-               if (rec_nframes == 0 && _actual_speed != 1.0f) {
-                       necessary_samples = (jack_nframes_t) floor ((nframes * fabs (_actual_speed))) + 1;
-               } else {
-                       necessary_samples = nframes;
-               }
-               
-               for (c = channels.begin(); c != channels.end(); ++c) {
-                       (*c).playback_buf->get_read_vector (&(*c).playback_vector);
-               }
-
-               n = 0;                  
-
-               for (c = channels.begin(); c != channels.end(); ++c, ++n) {
-               
-                       ChannelInfo& chan (*c);
-
-                       if (necessary_samples <= chan.playback_vector.len[0]) {
-
-                               chan.current_playback_buffer = chan.playback_vector.buf[0];
-
-                       } else {
-                               jack_nframes_t total = chan.playback_vector.len[0] + chan.playback_vector.len[1];
-                               
-                               if (necessary_samples > total) {
-                                       DiskUnderrun ();
-                                       goto out;
-                                       
-                               } else {
-                                       
-                                       memcpy ((char *) chan.playback_wrap_buffer, chan.playback_vector.buf[0],
-                                               chan.playback_vector.len[0] * sizeof (Sample));
-                                       memcpy (chan.playback_wrap_buffer + chan.playback_vector.len[0], chan.playback_vector.buf[1], 
-                                               (necessary_samples - chan.playback_vector.len[0]) * sizeof (Sample));
-                                       
-                                       chan.current_playback_buffer = chan.playback_wrap_buffer;
-                               }
-                       }
-               } 
-
-               if (rec_nframes == 0 && _actual_speed != 1.0f && _actual_speed != -1.0f) {
-                       
-                       uint64_t phase = last_phase;
-                       jack_nframes_t i = 0;
-
-                       // Linearly interpolate into the alt buffer
-                       // using 40.24 fixp maths (swh)
-
-                       for (c = channels.begin(); c != channels.end(); ++c) {
-
-                               float fr;
-                               ChannelInfo& chan (*c);
-
-                               i = 0;
-                               phase = last_phase;
-
-                               for (jack_nframes_t outsample = 0; outsample < nframes; ++outsample) {
-                                       i = phase >> 24;
-                                       fr = (phase & 0xFFFFFF) / 16777216.0f;
-                                       chan.speed_buffer[outsample] = 
-                                               chan.current_playback_buffer[i] * (1.0f - fr) +
-                                               chan.current_playback_buffer[i+1] * fr;
-                                       phase += phi;
-                               }
-                               
-                               chan.current_playback_buffer = chan.speed_buffer;
-                       }
-
-                       playback_distance = i + 1;
-                       last_phase = (phase & 0xFFFFFF);
-
-               } else {
-                       playback_distance = nframes;
-               }
-
-       }
-
-       ret = 0;
-
-  out:
-       _processed = true;
-
-       if (ret) {
-
-               /* we're exiting with failure, so ::commit will not
-                  be called. unlock the state lock.
-               */
-               
-               state_lock.unlock();
-       } 
-
-       return ret;
-}
-
-void
-DiskStream::recover ()
-{
-       state_lock.unlock();
-       _processed = false;
-}
-
-bool
-DiskStream::commit (jack_nframes_t nframes)
-{
-       bool need_butler = false;
-
-       if (_actual_speed < 0.0) {
-               playback_sample -= playback_distance;
-       } else {
-               playback_sample += playback_distance;
-       }
-
-       for (ChannelList::iterator chan = channels.begin(); chan != channels.end(); ++chan) {
-
-               (*chan).playback_buf->increment_read_ptr (playback_distance);
-               
-               if (adjust_capture_position) {
-                       (*chan).capture_buf->increment_write_ptr (adjust_capture_position);
-               }
-       }
-       
-       if (adjust_capture_position != 0) {
-               capture_captured += adjust_capture_position;
-               adjust_capture_position = 0;
-       }
-       
-       if (_slaved) {
-               need_butler = channels[0].playback_buf->write_space() >= channels[0].playback_buf->bufsize() / 2;
-       } else {
-               need_butler = channels[0].playback_buf->write_space() >= disk_io_chunk_frames
-                       || channels[0].capture_buf->read_space() >= disk_io_chunk_frames;
-       }
-
-       state_lock.unlock();
-
-       _processed = false;
-
-       return need_butler;
-}
-
-void
-DiskStream::set_pending_overwrite (bool yn)
-{
-       /* called from audio thread, so we can use the read ptr and playback sample as we wish */
-       
-       pending_overwrite = yn;
-
-       overwrite_frame = playback_sample;
-       overwrite_offset = channels.front().playback_buf->get_read_ptr();
-}
-
-int
-DiskStream::overwrite_existing_buffers ()
-{
-       Sample* mixdown_buffer;
-       float* gain_buffer;
-       char * workbuf;
-       int ret = -1;
-       bool reversed = (_visible_speed * _session.transport_speed()) < 0.0f;
-
-       overwrite_queued = false;
-
-       /* assume all are the same size */
-       jack_nframes_t size = channels[0].playback_buf->bufsize();
-       
-       mixdown_buffer = new Sample[size];
-       gain_buffer = new float[size];
-       workbuf = new char[size*4];
-       
-       /* reduce size so that we can fill the buffer correctly. */
-       size--;
-       
-       uint32_t n=0;
-       jack_nframes_t start;
-
-       for (ChannelList::iterator chan = channels.begin(); chan != channels.end(); ++chan, ++n) {
-
-               start = overwrite_frame;
-               jack_nframes_t cnt = size;
-               
-               /* to fill the buffer without resetting the playback sample, we need to
-                  do it one or two chunks (normally two).
-
-                  |----------------------------------------------------------------------|
-
-                                      ^
-                                      overwrite_offset
-                   |<- second chunk->||<----------------- first chunk ------------------>|
-                  
-               */
-               
-               jack_nframes_t to_read = size - overwrite_offset;
-
-               if (read ((*chan).playback_buf->buffer() + overwrite_offset, mixdown_buffer, gain_buffer, workbuf,
-                         start, to_read, *chan, n, reversed)) {
-                       error << string_compose(_("DiskStream %1: when refilling, cannot read %2 from playlist at frame %3"),
-                                        _id, size, playback_sample) << endmsg;
-                       goto out;
-               }
-                       
-               if (cnt > to_read) {
-
-                       cnt -= to_read;
-               
-                       if (read ((*chan).playback_buf->buffer(), mixdown_buffer, gain_buffer, workbuf,
-                                 start, cnt, *chan, n, reversed)) {
-                               error << string_compose(_("DiskStream %1: when refilling, cannot read %2 from playlist at frame %3"),
-                                                _id, size, playback_sample) << endmsg;
-                               goto out;
-                       }
-               }
-       }
-
-       ret = 0;
-  out:
-       pending_overwrite = false;
-       delete [] gain_buffer;
-       delete [] mixdown_buffer;
-       delete [] workbuf;
-       return ret;
-}
-
-int
-DiskStream::seek (jack_nframes_t frame, bool complete_refill)
-{
-       Glib::Mutex::Lock lm (state_lock);
-       uint32_t n;
-       int ret;
-       ChannelList::iterator chan;
-
-       for (n = 0, chan = channels.begin(); chan != channels.end(); ++chan, ++n) {
-               (*chan).playback_buf->reset ();
-               (*chan).capture_buf->reset ();
-               if ((*chan).write_source) {
-                       (*chan).write_source->seek (frame);
-               }
-       }
-       
-       playback_sample = frame;
-       file_frame = frame;
-
-       if (complete_refill) {
-               while ((ret = do_refill (0, 0, 0)) > 0);
-       } else {
-               ret = do_refill (0, 0, 0);
-       }
-
-       return ret;
-}
-
-int
-DiskStream::can_internal_playback_seek (jack_nframes_t distance)
-{
-       ChannelList::iterator chan;
-
-       for (chan = channels.begin(); chan != channels.end(); ++chan) {
-               if ((*chan).playback_buf->read_space() < distance) {
-                       return false;
-               } 
-       }
-       return true;
-}
-
-int
-DiskStream::internal_playback_seek (jack_nframes_t distance)
-{
-       ChannelList::iterator chan;
-
-       for (chan = channels.begin(); chan != channels.end(); ++chan) {
-               (*chan).playback_buf->increment_read_ptr (distance);
-       }
-
-       first_recordable_frame += distance;
-       playback_sample += distance;
-       
-       return 0;
-}
-
-int
-DiskStream::read (Sample* buf, Sample* mixdown_buffer, float* gain_buffer, char * workbuf, jack_nframes_t& start, jack_nframes_t cnt, 
-                 ChannelInfo& channel_info, int channel, bool reversed)
-{
-       jack_nframes_t this_read = 0;
-       bool reloop = false;
-       jack_nframes_t loop_end = 0;
-       jack_nframes_t loop_start = 0;
-       jack_nframes_t loop_length = 0;
-       jack_nframes_t offset = 0;
-       Location *loc = 0;
-
-       if (!reversed) {
-               /* Make the use of a Location atomic for this read operation.
-                  
-                  Note: Locations don't get deleted, so all we care about
-                  when I say "atomic" is that we are always pointing to
-                  the same one and using a start/length values obtained
-                  just once.
-               */
-               
-               if ((loc = loop_location) != 0) {
-                       loop_start = loc->start();
-                       loop_end = loc->end();
-                       loop_length = loop_end - loop_start;
-               }
-               
-               /* if we are looping, ensure that the first frame we read is at the correct
-                  position within the loop.
-               */
-               
-               if (loc && start >= loop_end) {
-                       //cerr << "start adjusted from " << start;
-                       start = loop_start + ((start - loop_start) % loop_length);
-                       //cerr << "to " << start << endl;
-               }
-               //cerr << "start is " << start << "  loopstart: " << loop_start << "  loopend: " << loop_end << endl;
-       }
-
-       while (cnt) {
-
-               /* take any loop into account. we can't read past the end of the loop. */
-
-               if (loc && (loop_end - start < cnt)) {
-                       this_read = loop_end - start;
-                       //cerr << "reloop true: thisread: " << this_read << "  cnt: " << cnt << endl;
-                       reloop = true;
-               } else {
-                       reloop = false;
-                       this_read = cnt;
-               }
-
-               if (this_read == 0) {
-                       break;
-               }
-
-               this_read = min(cnt,this_read);
-
-               if (_playlist->read (buf+offset, mixdown_buffer, gain_buffer, workbuf, start, this_read, channel) != this_read) {
-                       error << string_compose(_("DiskStream %1: cannot read %2 from playlist at frame %3"), _id, this_read, 
-                                        start) << endmsg;
-                       return -1;
-               }
-
-               _read_data_count = _playlist->read_data_count();
-               
-               if (reversed) {
-
-                       /* don't adjust start, since caller has already done that
-                        */
-
-                       swap_by_ptr (buf, buf + this_read - 1);
-                       
-               } else {
-                       
-                       /* if we read to the end of the loop, go back to the beginning */
-                       
-                       if (reloop) {
-                               start = loop_start;
-                       } else {
-                               start += this_read;
-                       }
-               } 
-
-               cnt -= this_read;
-               offset += this_read;
-       }
-
-       return 0;
-}
-
-int
-DiskStream::do_refill (Sample* mixdown_buffer, float* gain_buffer, char * workbuf)
-{
-       int32_t ret = 0;
-       jack_nframes_t to_read;
-       RingBufferNPT<Sample>::rw_vector vector;
-       bool free_mixdown;
-       bool free_gain;
-       bool free_workbuf;
-       bool reversed = (_visible_speed * _session.transport_speed()) < 0.0f;
-       jack_nframes_t total_space;
-       jack_nframes_t zero_fill;
-       uint32_t chan_n;
-       ChannelList::iterator i;
-       jack_nframes_t ts;
-
-       channels.front().playback_buf->get_write_vector (&vector);
-       
-       if ((total_space = vector.len[0] + vector.len[1]) == 0) {
-               return 0;
-       }
-       
-       /* if there are 2+ chunks of disk i/o possible for
-          this track, let the caller know so that it can arrange
-          for us to be called again, ASAP.
-       */
-       
-       if (total_space >= (_slaved?3:2) * disk_io_chunk_frames) {
-               ret = 1;
-       }
-       
-       /* if we're running close to normal speed and there isn't enough 
-          space to do disk_io_chunk_frames of I/O, then don't bother.  
-          
-          at higher speeds, just do it because the sync between butler
-          and audio thread may not be good enough.
-       */
-       
-       if ((total_space < disk_io_chunk_frames) && fabs (_actual_speed) < 2.0f) {
-               return 0;
-       }
-       
-       /* when slaved, don't try to get too close to the read pointer. this
-          leaves space for the buffer reversal to have something useful to
-          work with.
-       */
-       
-       if (_slaved && total_space < (channels.front().playback_buf->bufsize() / 2)) {
-               return 0;
-       }
-
-       total_space = min (disk_io_chunk_frames, total_space);
-
-       if (reversed) {
-
-               if (file_frame == 0) {
-
-                       /* at start: nothing to do but fill with silence */
-
-                       for (chan_n = 0, i = channels.begin(); i != channels.end(); ++i, ++chan_n) {
-                                       
-                               ChannelInfo& chan (*i);
-                               chan.playback_buf->get_write_vector (&vector);
-                               memset (vector.buf[0], 0, sizeof(Sample) * vector.len[0]);
-                               if (vector.len[1]) {
-                                       memset (vector.buf[1], 0, sizeof(Sample) * vector.len[1]);
-                               }
-                               chan.playback_buf->increment_write_ptr (vector.len[0] + vector.len[1]);
-                       }
-                       return 0;
-               }
-
-               if (file_frame < total_space) {
-
-                       /* too close to the start: read what we can, 
-                          and then zero fill the rest 
-                       */
-
-                       zero_fill = total_space - file_frame;
-                       total_space = file_frame;
-                       file_frame = 0;
-
-               } else {
-                       
-                       /* move read position backwards because we are going
-                          to reverse the data.
-                       */
-                       
-                       file_frame -= total_space;
-                       zero_fill = 0;
-               }
-
-       } else {
-
-               if (file_frame == max_frames) {
-
-                       /* at end: nothing to do but fill with silence */
-                       
-                       for (chan_n = 0, i = channels.begin(); i != channels.end(); ++i, ++chan_n) {
-                                       
-                               ChannelInfo& chan (*i);
-                               chan.playback_buf->get_write_vector (&vector);
-                               memset (vector.buf[0], 0, sizeof(Sample) * vector.len[0]);
-                               if (vector.len[1]) {
-                                       memset (vector.buf[1], 0, sizeof(Sample) * vector.len[1]);
-                               }
-                               chan.playback_buf->increment_write_ptr (vector.len[0] + vector.len[1]);
-                       }
-                       return 0;
-               }
-               
-               if (file_frame > max_frames - total_space) {
-
-                       /* to close to the end: read what we can, and zero fill the rest */
-
-                       zero_fill = total_space - (max_frames - file_frame);
-                       total_space = max_frames - file_frame;
-
-               } else {
-                       zero_fill = 0;
-               }
-       }
-
-       /* Please note: the code to allocate buffers isn't run
-          during normal butler thread operation. Its there
-          for other times when we need to call do_refill()
-          from somewhere other than the butler thread.
-       */
-
-       if (mixdown_buffer == 0) {
-               mixdown_buffer = new Sample[disk_io_chunk_frames];
-               free_mixdown = true;
-       } else {
-               free_mixdown = false;
-       }
-
-       if (gain_buffer == 0) {
-               gain_buffer = new float[disk_io_chunk_frames];
-               free_gain = true;
-       } else {
-               free_gain = false;
-       }
-
-       if (workbuf == 0) {
-               workbuf = new char[disk_io_chunk_frames * 4];
-               free_workbuf = true;
-       } else {
-               free_workbuf = false;
-       }
-       
-       jack_nframes_t file_frame_tmp = 0;
-
-       for (chan_n = 0, i = channels.begin(); i != channels.end(); ++i, ++chan_n) {
-
-               ChannelInfo& chan (*i);
-               Sample* buf1;
-               Sample* buf2;
-               jack_nframes_t len1, len2;
-
-               chan.playback_buf->get_write_vector (&vector);
-
-               ts = total_space;
-               file_frame_tmp = file_frame;
-
-               if (reversed) {
-                       buf1 = vector.buf[1];
-                       len1 = vector.len[1];
-                       buf2 = vector.buf[0];
-                       len2 = vector.len[0];
-               } else {
-                       buf1 = vector.buf[0];
-                       len1 = vector.len[0];
-                       buf2 = vector.buf[1];
-                       len2 = vector.len[1];
-               }
-
-
-               to_read = min (ts, len1);
-               to_read = min (to_read, disk_io_chunk_frames);
-
-               if (to_read) {
-
-                       if (read (buf1, mixdown_buffer, gain_buffer, workbuf, file_frame_tmp, to_read, chan, chan_n, reversed)) {
-                               ret = -1;
-                               goto out;
-                       }
-                       
-                       chan.playback_buf->increment_write_ptr (to_read);
-                       ts -= to_read;
-               }
-
-               to_read = min (ts, len2);
-
-               if (to_read) {
-
-                       
-                       /* we read all of vector.len[0], but it wasn't an entire disk_io_chunk_frames of data,
-                          so read some or all of vector.len[1] as well.
-                       */
-
-                       if (read (buf2, mixdown_buffer, gain_buffer, workbuf, file_frame_tmp, to_read, chan, chan_n, reversed)) {
-                               ret = -1;
-                               goto out;
-                       }
-               
-                       chan.playback_buf->increment_write_ptr (to_read);
-               }
-
-               if (zero_fill) {
-                       /* do something */
-               }
-
-       }
-       
-       file_frame = file_frame_tmp;
-
-  out:
-       if (free_mixdown) {
-               delete [] mixdown_buffer;
-       }
-       if (free_gain) {
-               delete [] gain_buffer;
-       }
-       if (free_workbuf) {
-               delete [] workbuf;
-       }
-
-       return ret;
-}      
-
-int
-DiskStream::do_flush (char * workbuf, bool force_flush)
-{
-       uint32_t to_write;
-       int32_t ret = 0;
-       RingBufferNPT<Sample>::rw_vector vector;
-       RingBufferNPT<CaptureTransition>::rw_vector transvec;
-       jack_nframes_t total;
-       
-       /* important note: this function will write *AT MOST* 
-          disk_io_chunk_frames of data to disk. it will never 
-          write more than that. if its writes that much and there 
-          is more than that waiting to be written, it will return 1,
-          otherwise 0 on success or -1 on failure.
-
-          if there is less than disk_io_chunk_frames to be written, 
-          no data will be written at all unless `force_flush' is true.  
-       */
-
-       _write_data_count = 0;
-
-       for (ChannelList::iterator chan = channels.begin(); chan != channels.end(); ++chan) {
-       
-               (*chan).capture_buf->get_read_vector (&vector);
-
-               total = vector.len[0] + vector.len[1];
-
-               
-               if (total == 0 || (total < disk_io_chunk_frames && !force_flush && was_recording)) {
-                       goto out;
-               }
-
-               
-               /* if there are 2+ chunks of disk i/o possible for
-                  this track, let the caller know so that it can arrange
-                  for us to be called again, ASAP.
-                  
-                  if we are forcing a flush, then if there is* any* extra
-                  work, let the caller know.
-
-                  if we are no longer recording and there is any extra work,
-                  let the caller know too.
-               */
-
-               if (total >= 2 * disk_io_chunk_frames || ((force_flush || !was_recording) && total > disk_io_chunk_frames)) {
-                       ret = 1;
-               } 
-
-               to_write = min (disk_io_chunk_frames, (jack_nframes_t) vector.len[0]);
-               
-               
-               // check the transition buffer when recording destructive
-               // important that we get this after the capture buf
-
-               if (destructive()) {
-                       (*chan).capture_transition_buf->get_read_vector(&transvec);
-                       size_t transcount = transvec.len[0] + transvec.len[1];
-                       bool have_start = false;
-                       size_t ti;
-
-                       for (ti=0; ti < transcount; ++ti) {
-                               CaptureTransition & captrans = (ti < transvec.len[0]) ? transvec.buf[0][ti] : transvec.buf[1][ti-transvec.len[0]];
-                               
-                               if (captrans.type == CaptureStart) {
-                                       // by definition, the first data we got above represents the given capture pos
-
-                                       (*chan).write_source->mark_capture_start (captrans.capture_val);
-                                       (*chan).curr_capture_cnt = 0;
-
-                                       have_start = true;
-                               }
-                               else if (captrans.type == CaptureEnd) {
-
-                                       // capture end, the capture_val represents total frames in capture
-
-                                       if (captrans.capture_val <= (*chan).curr_capture_cnt + to_write) {
-
-                                               // shorten to make the write a perfect fit
-                                               uint32_t nto_write = (captrans.capture_val - (*chan).curr_capture_cnt); 
-
-                                               if (nto_write < to_write) {
-                                                       ret = 1; // should we?
-                                               }
-                                               to_write = nto_write;
-
-                                               (*chan).write_source->mark_capture_end ();
-                                               
-                                               // increment past this transition, but go no further
-                                               ++ti;
-                                               break;
-                                       }
-                                       else {
-                                               // actually ends just beyond this chunk, so force more work
-                                               ret = 1;
-                                               break;
-                                       }
-                               }
-                       }
-
-                       if (ti > 0) {
-                               (*chan).capture_transition_buf->increment_read_ptr(ti);
-                       }
-               }
-
-               if ((!(*chan).write_source) || (*chan).write_source->write (vector.buf[0], to_write, workbuf) != to_write) {
-                       error << string_compose(_("DiskStream %1: cannot write to disk"), _id) << endmsg;
-                       return -1;
-               }
-
-               (*chan).capture_buf->increment_read_ptr (to_write);
-               (*chan).curr_capture_cnt += to_write;
-               
-               if ((to_write == vector.len[0]) && (total > to_write) && (to_write < disk_io_chunk_frames) && !destructive()) {
-               
-                       /* we wrote all of vector.len[0] but it wasn't an entire
-                          disk_io_chunk_frames of data, so arrange for some part 
-                          of vector.len[1] to be flushed to disk as well.
-                       */
-               
-                       to_write = min ((jack_nframes_t)(disk_io_chunk_frames - to_write), (jack_nframes_t) vector.len[1]);
-               
-                       if ((*chan).write_source->write (vector.buf[1], to_write, workbuf) != to_write) {
-                               error << string_compose(_("DiskStream %1: cannot write to disk"), _id) << endmsg;
-                               return -1;
-                       }
-
-                       _write_data_count += (*chan).write_source->write_data_count();
-       
-                       (*chan).capture_buf->increment_read_ptr (to_write);
-                       (*chan).curr_capture_cnt += to_write;
-               }
-       }
-
-  out:
-       return ret;
-}
-
-void
-DiskStream::playlist_changed (Change ignored)
-{
-       playlist_modified ();
-}
-
-void
-DiskStream::playlist_modified ()
-{
-       if (!i_am_the_modifier && !overwrite_queued) {
-               _session.request_overwrite_buffer (this);
-               overwrite_queued = true;
-       } 
-}
-
-void
-DiskStream::transport_stopped (struct tm& when, time_t twhen, bool abort_capture)
-{
-       uint32_t buffer_position;
-       bool more_work = true;
-       int err = 0;
-       AudioRegion* region = 0;
-       jack_nframes_t total_capture;
-       AudioRegion::SourceList srcs;
-       AudioRegion::SourceList::iterator src;
-       ChannelList::iterator chan;
-       vector<CaptureInfo*>::iterator ci;
-       uint32_t n = 0; 
-       list<Source*>* deletion_list;
-       bool mark_write_completed = false;
-
-       finish_capture (true);
-
-       /* butler is already stopped, but there may be work to do 
-          to flush remaining data to disk.
-       */
-
-       while (more_work && !err) {
-               switch (do_flush ( _session.conversion_buffer(Session::TransportContext), true)) {
-               case 0:
-                       more_work = false;
-                       break;
-               case 1:
-                       break;
-               case -1:
-                       error << string_compose(_("DiskStream \"%1\": cannot flush captured data to disk!"), _name) << endmsg;
-                       err++;
-               }
-       }
-
-       /* XXX is there anything we can do if err != 0 ? */
-       Glib::Mutex::Lock lm (capture_info_lock);
-       
-       if (capture_info.empty()) {
-               return;
-       }
-
-       if (abort_capture) {
-               
-               ChannelList::iterator chan;
-               
-               deletion_list = new list<Source*>;
-
-               for ( chan = channels.begin(); chan != channels.end(); ++chan) {
-
-                       if ((*chan).write_source) {
-                               
-                               (*chan).write_source->mark_for_remove ();
-                               (*chan).write_source->release ();
-                               
-                               deletion_list->push_back ((*chan).write_source);
-
-                               (*chan).write_source = 0;
-                       }
-                       
-                       /* new source set up in "out" below */
-               }
-               
-               if (!deletion_list->empty()) {
-                       DeleteSources (deletion_list);
-               } else {
-                       delete deletion_list;
-               }
-
-               goto out;
-       } 
-
-       for (total_capture = 0, ci = capture_info.begin(); ci != capture_info.end(); ++ci) {
-               total_capture += (*ci)->frames;
-       }
-
-       /* figure out the name for this take */
-
-       for (n = 0, chan = channels.begin(); chan != channels.end(); ++chan, ++n) {
-
-               Source* s = (*chan).write_source;
-               
-               if (s) {
-
-                       FileSource* fsrc;
-
-                       srcs.push_back (s);
-
-                       if ((fsrc = dynamic_cast<FileSource *>(s)) != 0) {
-                               fsrc->update_header (capture_info.front()->start, when, twhen);
-                       }
-
-                       s->set_captured_for (_name);
-                       
-               }
-       }
-
-       /* destructive tracks have a single, never changing region */
-
-       if (destructive()) {
-
-               /* send a signal that any UI can pick up to do the right thing. there is 
-                  a small problem here in that a UI may need the peak data to be ready
-                  for the data that was recorded and this isn't interlocked with that
-                  process. this problem is deferred to the UI.
-                */
-               
-               _playlist->Modified();
-
-       } else {
-
-               /* Register a new region with the Session that
-                  describes the entire source. Do this first
-                  so that any sub-regions will obviously be
-                  children of this one (later!)
-               */
-               
-               try {
-                       region = new AudioRegion (srcs, channels[0].write_source->last_capture_start_frame(), total_capture, 
-                                                 region_name_from_path (channels[0].write_source->name()), 
-                                                 0, AudioRegion::Flag (AudioRegion::DefaultFlags|AudioRegion::Automatic|AudioRegion::WholeFile));
-                       
-                       region->special_set_position (capture_info.front()->start);
-               }
-               
-               
-               catch (failed_constructor& err) {
-                       error << string_compose(_("%1: could not create region for complete audio file"), _name) << endmsg;
-                       /* XXX what now? */
-               }
-               
-               _last_capture_regions.push_back (region);
-
-               // cerr << _name << ": there are " << capture_info.size() << " capture_info records\n";
-               
-               _session.add_undo (_playlist->get_memento());
-               _playlist->freeze ();
-               
-               for (buffer_position = channels[0].write_source->last_capture_start_frame(), ci = capture_info.begin(); ci != capture_info.end(); ++ci) {
-                       
-                       string region_name;
-                       _session.region_name (region_name, channels[0].write_source->name(), false);
-                       
-                       // cerr << _name << ": based on ci of " << (*ci)->start << " for " << (*ci)->frames << " add a region\n";
-                       
-                       try {
-                               region = new AudioRegion (srcs, buffer_position, (*ci)->frames, region_name);
-                       }
-                       
-                       catch (failed_constructor& err) {
-                               error << _("DiskStream: could not create region for captured audio!") << endmsg;
-                               continue; /* XXX is this OK? */
-                       }
-                       
-                       _last_capture_regions.push_back (region);
-                       
-                       // cerr << "add new region, buffer position = " << buffer_position << " @ " << (*ci)->start << endl;
-                       
-                       i_am_the_modifier++;
-                       _playlist->add_region (*region, (*ci)->start);
-                       i_am_the_modifier--;
-                       
-                       buffer_position += (*ci)->frames;
-               }
-
-               _playlist->thaw ();
-               _session.add_redo_no_execute (_playlist->get_memento());
-       }
-
-       mark_write_completed = true;
-
-       reset_write_sources (mark_write_completed);
-
-  out:
-       for (ci = capture_info.begin(); ci != capture_info.end(); ++ci) {
-               delete *ci;
-       }
-
-       capture_info.clear ();
-       capture_start_frame = 0;
-}
-
-void
-DiskStream::finish_capture (bool rec_monitors_input)
-{
-       was_recording = false;
-       
-       if (capture_captured == 0) {
-               return;
-       }
-
-       if (recordable() && destructive()) {
-               for (ChannelList::iterator chan = channels.begin(); chan != channels.end(); ++chan) {
-                       
-                       RingBufferNPT<CaptureTransition>::rw_vector transvec;
-                       (*chan).capture_transition_buf->get_write_vector(&transvec);
-                       
-                       
-                       if (transvec.len[0] > 0) {
-                               transvec.buf[0]->type = CaptureEnd;
-                               transvec.buf[0]->capture_val = capture_captured;
-                               (*chan).capture_transition_buf->increment_write_ptr(1);
-                       }
-                       else {
-                               // bad!
-                               fatal << string_compose (_("programmer error: %1"), X_("capture_transition_buf is full when stopping record!  inconceivable!")) << endmsg;
-                       }
-               }
-       }
-       
-       
-       CaptureInfo* ci = new CaptureInfo;
-       
-       ci->start =  capture_start_frame;
-       ci->frames = capture_captured;
-       
-       /* XXX theoretical race condition here. Need atomic exchange ? 
-          However, the circumstances when this is called right 
-          now (either on record-disable or transport_stopped)
-          mean that no actual race exists. I think ...
-          We now have a capture_info_lock, but it is only to be used
-          to synchronize in the transport_stop and the capture info
-          accessors, so that invalidation will not occur (both non-realtime).
-       */
-
-       // cerr << "Finish capture, add new CI, " << ci->start << '+' << ci->frames << endl;
-
-       capture_info.push_back (ci);
-       capture_captured = 0;
-}
-
-void
-DiskStream::set_record_enabled (bool yn, void* src)
-{
-        bool rolling = _session.transport_speed() != 0.0f;
-
-       if (!recordable() || !_session.record_enabling_legal()) {
-               return;
-       }
-       
-       /* if we're turning on rec-enable, there needs to be an
-          input connection.
-        */
-
-       if (yn && channels[0].source == 0) {
-
-               /* pick up connections not initiated *from* the IO object
-                  we're associated with.
-               */
-
-               get_input_sources ();
-       }
-
-       /* yes, i know that this not proof against race conditions, but its
-          good enough. i think.
-       */
-
-       if (record_enabled() != yn) {
-               if (yn) {
-                       g_atomic_int_set (&_record_enabled, 1);
-                       capturing_sources.clear ();
-                       if (Config->get_use_hardware_monitoring())  {
-                               for (ChannelList::iterator chan = channels.begin(); chan != channels.end(); ++chan) {
-                                       if ((*chan).source) {
-                                               (*chan).source->request_monitor_input (!(_session.get_auto_input() && rolling));
-                                       }
-                                       capturing_sources.push_back ((*chan).write_source);
-                               }
-                       } else {
-                               for (ChannelList::iterator chan = channels.begin(); chan != channels.end(); ++chan) {
-                                       capturing_sources.push_back ((*chan).write_source);
-                               }
-                       }
-
-               } else {
-                       g_atomic_int_set (&_record_enabled, 0);
-                       if (Config->get_use_hardware_monitoring()) {
-                               for (ChannelList::iterator chan = channels.begin(); chan != channels.end(); ++chan) {
-                                       if ((*chan).source) {
-                                               (*chan).source->request_monitor_input (false);
-                                       }
-                               }
-                       }
-                       capturing_sources.clear ();
-               }
-
-               record_enable_changed (src); /* EMIT SIGNAL */
-       }
-}
-
-XMLNode&
-DiskStream::get_state ()
-{
-       XMLNode* node = new XMLNode ("DiskStream");
-       char buf[64];
-       LocaleGuard lg (X_("POSIX"));
-
-       snprintf (buf, sizeof(buf), "0x%x", _flags);
-       node->add_property ("flags", buf);
-
-       snprintf (buf, sizeof(buf), "%zd", channels.size());
-       node->add_property ("channels", buf);
-
-       node->add_property ("playlist", _playlist->name());
-       
-       snprintf (buf, sizeof(buf), "%f", _visible_speed);
-       node->add_property ("speed", buf);
-
-       node->add_property("name", _name);
-       snprintf (buf, sizeof(buf), "%" PRIu64, id());
-       node->add_property("id", buf);
-
-       if (!capturing_sources.empty() && _session.get_record_enabled()) {
-
-               XMLNode* cs_child = new XMLNode (X_("CapturingSources"));
-               XMLNode* cs_grandchild;
-
-               for (vector<FileSource*>::iterator i = capturing_sources.begin(); i != capturing_sources.end(); ++i) {
-                       cs_grandchild = new XMLNode (X_("file"));
-                       cs_grandchild->add_property (X_("path"), (*i)->path());
-                       cs_child->add_child_nocopy (*cs_grandchild);
-               }
-
-               /* store the location where capture will start */
-
-               Location* pi;
-
-               if (_session.get_punch_in() && ((pi = _session.locations()->auto_punch_location()) != 0)) {
-                       snprintf (buf, sizeof (buf), "%" PRIu32, pi->start());
-               } else {
-                       snprintf (buf, sizeof (buf), "%" PRIu32, _session.transport_frame());
-               }
-
-               cs_child->add_property (X_("at"), buf);
-               node->add_child_nocopy (*cs_child);
-       }
-
-       if (_extra_xml) {
-               node->add_child_copy (*_extra_xml);
-       }
-
-       return* node;
-}
-
-int
-DiskStream::set_state (const XMLNode& node)
-{
-       const XMLProperty* prop;
-       XMLNodeList nlist = node.children();
-       XMLNodeIterator niter;
-       uint32_t nchans = 1;
-       XMLNode* capture_pending_node = 0;
-       LocaleGuard lg (X_("POSIX"));
-
-       in_set_state = true;
-
-       for (niter = nlist.begin(); niter != nlist.end(); ++niter) {
-               if ((*niter)->name() == IO::state_node_name) {
-                       deprecated_io_node = new XMLNode (**niter);
-               }
-
-               if ((*niter)->name() == X_("CapturingSources")) {
-                       capture_pending_node = *niter;
-               }
-       }
-
-       /* prevent write sources from being created */
-       
-       in_set_state = true;
-       
-       if ((prop = node.property ("name")) != 0) {
-               _name = prop->value();
-       } 
-
-       if (deprecated_io_node) {
-               if ((prop = deprecated_io_node->property ("id")) != 0) {
-                       sscanf (prop->value().c_str(), "%" PRIu64, &_id);
-               }
-       } else {
-               if ((prop = node.property ("id")) != 0) {
-                       sscanf (prop->value().c_str(), "%" PRIu64, &_id);
-               }
-       }
-
-       if ((prop = node.property ("flags")) != 0) {
-               _flags = strtol (prop->value().c_str(), 0, 0);
-       }
-
-       if ((prop = node.property ("channels")) != 0) {
-               nchans = atoi (prop->value().c_str());
-       }
-       
-       // create necessary extra channels
-       // we are always constructed with one
-       // and we always need one
-
-       if (nchans > _n_channels) {
-
-               // we need to add new channel infos
-               //LockMonitor lm (state_lock, __LINE__, __FILE__);
-
-               int diff = nchans - channels.size();
-
-               for (int i=0; i < diff; ++i) {
-                       add_channel ();
-               }
-
-       } else if (nchans < _n_channels) {
-
-               // we need to get rid of channels
-               //LockMonitor lm (state_lock, __LINE__, __FILE__);
-
-               int diff = channels.size() - nchans;
-               
-               for (int i = 0; i < diff; ++i) {
-                       remove_channel ();
-               }
-       }
-
-       if ((prop = node.property ("playlist")) == 0) {
-               return -1;
-       }
-
-       {
-               bool had_playlist = (_playlist != 0);
-       
-               if (find_and_use_playlist (prop->value())) {
-                       return -1;
-               }
-
-               if (!had_playlist) {
-                       _playlist->set_orig_diskstream_id (_id);
-               }
-               
-               if (!destructive() && capture_pending_node) {
-                       /* destructive streams have one and only one source per channel,
-                          and so they never end up in pending capture in any useful
-                          sense.
-                       */
-                       use_pending_capture_data (*capture_pending_node);
-               }
-
-       }
-
-       if ((prop = node.property ("speed")) != 0) {
-               double sp = atof (prop->value().c_str());
-
-               if (realtime_set_speed (sp, false)) {
-                       non_realtime_set_speed ();
-               }
-       }
-
-       _n_channels = channels.size();
-
-       in_set_state = false;
-
-       /* make sure this is clear before we do anything else */
-
-       capturing_sources.clear ();
-
-       /* write sources are handled when we handle the input set 
-          up of the IO that owns this DS (::non_realtime_input_change())
-       */
-               
-       in_set_state = false;
-
-       return 0;
-}
-
-int
-DiskStream::use_new_write_source (uint32_t n)
-{
-       if (!recordable()) {
-               return 1;
-       }
-
-       if (n >= channels.size()) {
-               error << string_compose (_("DiskStream: channel %1 out of range"), n) << endmsg;
-               return -1;
-       }
-
-       ChannelInfo &chan = channels[n];
-       
-       if (chan.write_source) {
-
-               if (FileSource::is_empty (chan.write_source->path())) {
-                       chan.write_source->mark_for_remove ();
-                       chan.write_source->release();
-                       delete chan.write_source;
-               } else {
-                       chan.write_source->release();
-                       chan.write_source = 0;
-               }
-       }
-
-       try {
-               if ((chan.write_source = _session.create_file_source (*this, n, destructive())) == 0) {
-                       throw failed_constructor();
-               }
-       } 
-
-       catch (failed_constructor &err) {
-               error << string_compose (_("%1:%2 new capture file not initialized correctly"), _name, n) << endmsg;
-               chan.write_source = 0;
-               return -1;
-       }
-
-       chan.write_source->use ();
-
-       /* do not remove destructive files even if they are empty */
-
-       chan.write_source->set_allow_remove_if_empty (!destructive());
-
-       return 0;
-}
-
-void
-DiskStream::reset_write_sources (bool mark_write_complete, bool force)
-{
-       ChannelList::iterator chan;
-       uint32_t n;
-
-       if (!recordable()) {
-               return;
-       }
-       
-       capturing_sources.clear ();
-       
-       for (chan = channels.begin(), n = 0; chan != channels.end(); ++chan, ++n) {
-               if (!destructive()) {
-
-                       if ((*chan).write_source && mark_write_complete) {
-                               (*chan).write_source->mark_streaming_write_completed ();
-                       }
-                       use_new_write_source (n);
-
-                       if (record_enabled()) {
-                               capturing_sources.push_back ((*chan).write_source);
-                       }
-
-               } else {
-                       if ((*chan).write_source == 0) {
-                               use_new_write_source (n);
-                       }
-               }
-       }
-
-       if (destructive()) {
-
-               /* we now have all our write sources set up, so create the
-                  playlist's single region.
-               */
-
-               if (_playlist->empty()) {
-                       setup_destructive_playlist ();
-               }
-       }
-}
-
-int
-DiskStream::rename_write_sources ()
-{
-       ChannelList::iterator chan;
-       uint32_t n;
-
-       for (chan = channels.begin(), n = 0; chan != channels.end(); ++chan, ++n) {
-               if ((*chan).write_source != 0) {
-                       (*chan).write_source->set_name (_name, destructive());
-                       /* XXX what to do if one of them fails ? */
-               }
-       }
-
-       return 0;
-}
-
-void
-DiskStream::set_block_size (jack_nframes_t nframes)
-{
-       if (_session.get_block_size() > speed_buffer_size) {
-               speed_buffer_size = _session.get_block_size();
-
-               for (ChannelList::iterator chan = channels.begin(); chan != channels.end(); ++chan) {
-                       if ((*chan).speed_buffer) delete [] (*chan).speed_buffer;
-                       (*chan).speed_buffer = new Sample[speed_buffer_size];
-               }
-       }
-       allocate_temporary_buffers ();
-}
-
-void
-DiskStream::allocate_temporary_buffers ()
-{
-       /* make sure the wrap buffer is at least large enough to deal
-          with the speeds up to 1.2, to allow for micro-variation
-          when slaving to MTC, SMPTE etc.
-       */
-
-       double sp = max (fabsf (_actual_speed), 1.2f);
-       jack_nframes_t required_wrap_size = (jack_nframes_t) floor (_session.get_block_size() * sp) + 1;
-
-       if (required_wrap_size > wrap_buffer_size) {
-
-               for (ChannelList::iterator chan = channels.begin(); chan != channels.end(); ++chan) {
-                       if ((*chan).playback_wrap_buffer) delete [] (*chan).playback_wrap_buffer;
-                       (*chan).playback_wrap_buffer = new Sample[required_wrap_size];  
-                       if ((*chan).capture_wrap_buffer) delete [] (*chan).capture_wrap_buffer;
-                       (*chan).capture_wrap_buffer = new Sample[required_wrap_size];   
-               }
-
-               wrap_buffer_size = required_wrap_size;
-       }
-}
-
-void
-DiskStream::monitor_input (bool yn)
-{
-       for (ChannelList::iterator chan = channels.begin(); chan != channels.end(); ++chan) {
-               
-               if ((*chan).source) {
-                       (*chan).source->request_monitor_input (yn);
-               }
-       }
-}
-
-void
-DiskStream::set_capture_offset ()
-{
-       if (_io == 0) {
-               /* can't capture, so forget it */
-               return;
-       }
-
-       _capture_offset = _io->input_latency();
-}
-
-void
-DiskStream::set_persistent_align_style (AlignStyle a)
-{
-       _persistent_alignment_style = a;
-}
-
-void
-DiskStream::set_align_style_from_io ()
-{
-       bool have_physical = false;
-
-       if (_io == 0) {
-               return;
-       }
-
-       get_input_sources ();
-       
-       for (ChannelList::iterator chan = channels.begin(); chan != channels.end(); ++chan) {
-               if ((*chan).source && (*chan).source->flags() & JackPortIsPhysical) {
-                       have_physical = true;
-                       break;
-               }
-       }
-
-       if (have_physical) {
-               set_align_style (ExistingMaterial);
-       } else {
-               set_align_style (CaptureTime);
-       }
-}
-
-void
-DiskStream::set_align_style (AlignStyle a)
-{
-       if (record_enabled() && _session.actively_recording()) {
-               return;
-       }
-
-
-       if (a != _alignment_style) {
-               _alignment_style = a;
-               AlignmentStyleChanged ();
-       }
-}
-
-int
-DiskStream::add_channel ()
-{
-       /* XXX need to take lock??? */
-
-       ChannelInfo chan;
-
-       init_channel (chan);
-
-       chan.speed_buffer = new Sample[speed_buffer_size];
-       chan.playback_wrap_buffer = new Sample[wrap_buffer_size];
-       chan.capture_wrap_buffer = new Sample[wrap_buffer_size];
-
-       channels.push_back (chan);
-
-       _n_channels = channels.size();
-
-       return 0;
-}
-
-int
-DiskStream::remove_channel ()
-{
-       if (channels.size() > 1) {
-               /* XXX need to take lock??? */
-               ChannelInfo & chan = channels.back();
-               destroy_channel (chan);
-               channels.pop_back();
-
-               _n_channels = channels.size();
-               return 0;
-       }
-
-       return -1;
-}
-
-float
-DiskStream::playback_buffer_load () const
-{
-       return (float) ((double) channels.front().playback_buf->read_space()/
-                       (double) channels.front().playback_buf->bufsize());
-}
-
-float
-DiskStream::capture_buffer_load () const
-{
-       return (float) ((double) channels.front().capture_buf->write_space()/
-                       (double) channels.front().capture_buf->bufsize());
-}
-
-int
-DiskStream::set_loop (Location *location)
-{
-       if (location) {
-               if (location->start() >= location->end()) {
-                       error << string_compose(_("Location \"%1\" not valid for track loop (start >= end)"), location->name()) << endl;
-                       return -1;
-               }
-       }
-
-       loop_location = location;
-
-        LoopSet (location); /* EMIT SIGNAL */
-       return 0;
-}
-
-jack_nframes_t
-DiskStream::get_capture_start_frame (uint32_t n)
-{
-       Glib::Mutex::Lock lm (capture_info_lock);
-
-       if (capture_info.size() > n) {
-               return capture_info[n]->start;
-       }
-       else {
-               return capture_start_frame;
-       }
-}
-
-jack_nframes_t
-DiskStream::get_captured_frames (uint32_t n)
-{
-       Glib::Mutex::Lock lm (capture_info_lock);
-
-       if (capture_info.size() > n) {
-               return capture_info[n]->frames;
-       }
-       else {
-               return capture_captured;
-       }
-}
-
-void
-DiskStream::punch_in ()
-{
-}
-
-void
-DiskStream::punch_out ()
-{
-}
-
-int
-DiskStream::use_pending_capture_data (XMLNode& node)
-{
-       const XMLProperty* prop;
-       XMLNodeList nlist = node.children();
-       XMLNodeIterator niter;
-       FileSource* fs;
-       FileSource* first_fs = 0;
-       AudioRegion::SourceList pending_sources;
-       jack_nframes_t position;
-
-       if ((prop = node.property (X_("at"))) == 0) {
-               return -1;
-       }
-
-       if (sscanf (prop->value().c_str(), "%" PRIu32, &position) != 1) {
-               return -1;
-       }
-
-       for (niter = nlist.begin(); niter != nlist.end(); ++niter) {
-               if ((*niter)->name() == X_("file")) {
-
-                       if ((prop = (*niter)->property (X_("path"))) == 0) {
-                               continue;
-                       }
-
-                       try {
-                               fs = new FileSource (prop->value(), _session.frame_rate(), true, Config->get_native_file_data_format());
-                       }
-
-                       catch (failed_constructor& err) {
-                               error << string_compose (_("%1: cannot restore pending capture source file %2"),
-                                                 _name, prop->value())
-                                     << endmsg;
-                               return -1;
-                       }
-
-                       pending_sources.push_back (fs);
-                       
-                       if (first_fs == 0) {
-                               first_fs = fs;
-                       }
-
-                       fs->set_captured_for (_name);
-               }
-       }
-
-       if (pending_sources.size() == 0) {
-               /* nothing can be done */
-               return 1;
-       }
-
-       if (pending_sources.size() != _n_channels) {
-               error << string_compose (_("%1: incorrect number of pending sources listed - ignoring them all"), _name)
-                     << endmsg;
-               return -1;
-       }
-
-       AudioRegion* region;
-       
-       try {
-               region = new AudioRegion (pending_sources, 0, first_fs->length(),
-                                         region_name_from_path (first_fs->name()), 
-                                         0, AudioRegion::Flag (AudioRegion::DefaultFlags|AudioRegion::Automatic|AudioRegion::WholeFile));
-               
-               region->special_set_position (0);
-       }
-
-       catch (failed_constructor& err) {
-               error << string_compose (_("%1: cannot create whole-file region from pending capture sources"),
-                                 _name)
-                     << endmsg;
-               
-               return -1;
-       }
-
-       try {
-               region = new AudioRegion (pending_sources, 0, first_fs->length(), region_name_from_path (first_fs->name()));
-       }
-
-       catch (failed_constructor& err) {
-               error << string_compose (_("%1: cannot create region from pending capture sources"),
-                                 _name)
-                     << endmsg;
-               
-               return -1;
-       }
-
-       _playlist->add_region (*region, position);
-
-       return 0;
-}
-
-void
-DiskStream::set_roll_delay (jack_nframes_t nframes)
-{
-       _roll_delay = nframes;
-}
-
-void
-DiskStream::set_destructive (bool yn)
-{
-       if (yn != destructive()) {
-               reset_write_sources (true, true);
-               if (yn) {
-                       _flags |= Destructive;
-               } else {
-                       _flags &= ~Destructive;
-               }
-       }
-}
diff --git a/libs/ardour/externalsource.cc b/libs/ardour/externalsource.cc
deleted file mode 100644 (file)
index 7f478b6..0000000
+++ /dev/null
@@ -1,246 +0,0 @@
-/*
-    Copyright (C) 2006 Paul Davis 
-
-    This program is free software; you can redistribute it and/or modify
-    it under the terms of the GNU General Public License as published by
-    the Free Software Foundation; either version 2 of the License, or
-    (at your option) any later version.
-
-    This program is distributed in the hope that it will be useful,
-    but WITHOUT ANY WARRANTY; without even the implied warranty of
-    MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
-    GNU General Public License for more details.
-
-    You should have received a copy of the GNU General Public License
-    along with this program; if not, write to the Free Software
-    Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
-
-*/
-
-#include <sys/stat.h>
-#include <unistd.h>
-#include <sys/time.h>
-
-#include <sndfile.h>
-
-#include <pbd/mountpoint.h>
-#include <ardour/externalsource.h>
-#include <ardour/sndfilesource.h>
-#include <ardour/sndfile_helpers.h>
-
-// if these headers come before sigc++ is included
-// the parser throws ObjC++ errors. (nil is a keyword)
-#ifdef HAVE_COREAUDIO 
-#include <ardour/coreaudio_source.h>
-#include <AudioToolbox/ExtendedAudioFile.h>
-#include <AudioToolbox/AudioFormat.h>
-#endif // HAVE_COREAUDIO
-
-#include "i18n.h"
-
-using namespace ARDOUR;
-
-string ExternalSource::peak_dir = "";
-
-ExternalSource::ExternalSource (const XMLNode& node)
-       : Source (node)
-{
-}
-
-ExternalSource::ExternalSource (const string& idstr, bool build_peak)
-       : Source(build_peak)
-{
-}
-
-ExternalSource::~ExternalSource ()
-{
-}
-
-jack_nframes_t
-ExternalSource::read_unlocked (Sample *dst, jack_nframes_t start, jack_nframes_t cnt, char * workbuf) const
-{
-       return read (dst, start, cnt, workbuf);
-}
-
-string
-ExternalSource::peak_path (string audio_path)
-{
-       /* XXX hardly bombproof! fix me */
-
-       struct stat stat_file;
-       struct stat stat_mount;
-
-       string mp = mountpoint (audio_path);
-
-       stat (audio_path.c_str(), &stat_file);
-       stat (mp.c_str(), &stat_mount);
-
-       char buf[32];
-#ifdef __APPLE__
-       snprintf (buf, sizeof (buf), "%u-%u-%d.peak", stat_mount.st_ino, stat_file.st_ino, channel);
-#else
-       snprintf (buf, sizeof (buf), "%ld-%ld-%d.peak", stat_mount.st_ino, stat_file.st_ino, channel);
-#endif
-
-       string res = peak_dir;
-       res += buf;
-
-       return res;
-}
-
-#ifdef HAVE_COREAUDIO
-
-ExternalSource*
-ExternalSource::create (const XMLNode& node)
-{
-       ExternalSource* es = 0;
-
-       try {
-               es = new CoreAudioSource (node);
-       } 
-       
-       catch (failed_constructor& err) {
-               es = new SndFileSource (node);
-       }
-
-       es = new SndFileSource (node);
-
-       return es;
-}
-
-#else
-
-ExternalSource*
-ExternalSource::create (const XMLNode& node)
-{
-       return new SndFileSource (node);
-}
-
-#endif // HAVE_COREAUDIO
-
-#ifdef HAVE_COREAUDIO
-ExternalSource*
-ExternalSource::create (const string& idstr, bool build_peak)
-{
-       ExternalSource* es = 0;
-
-       try {
-               es = new CoreAudioSource (idstr, build_peak);
-       }
-
-       catch (failed_constructor& err) {
-               es = new SndFileSource (idstr, build_peak);
-       }
-
-       return es;
-}
-
-#else
-
-ExternalSource*
-ExternalSource::create (const string& idstr, bool build_peak)
-{
-       return new SndFileSource (idstr, build_peak);
-}
-
-#endif // HAVE_COREAUDIO
-
-#ifdef HAVE_COREAUDIO
-std::string 
-CFStringRefToStdString(CFStringRef stringRef)
-{
-       CFIndex size = 
-               CFStringGetMaximumSizeForEncoding(CFStringGetLength(stringRef) , 
-               kCFStringEncodingASCII);
-           char *buf = new char[size];
-       
-       std::string result;
-
-       if(CFStringGetCString(stringRef, buf, size, kCFStringEncodingASCII)) {
-           result = buf;
-       }
-       delete [] buf;
-       return result;
-}
-#endif // HAVE_COREAUDIO
-
-bool
-ExternalSource::get_soundfile_info (string path, SoundFileInfo& _info, string& error_msg)
-{
-#ifdef HAVE_COREAUDIO
-       OSStatus err = noErr;
-    FSRef ref; 
-       ExtAudioFileRef af = 0;
-       size_t size;
-    CFStringRef name;
-
-    err = FSPathMakeRef ((UInt8*)path.c_str(), &ref, 0);
-       if (err != noErr) {
-        ExtAudioFileDispose (af);
-               goto libsndfile;
-       }
-
-       err = ExtAudioFileOpen(&ref, &af);
-       if (err != noErr) {
-        ExtAudioFileDispose (af);
-               goto libsndfile;
-       }
-
-       AudioStreamBasicDescription absd;
-       memset(&absd, 0, sizeof(absd));
-       size = sizeof(AudioStreamBasicDescription);
-       err = ExtAudioFileGetProperty(af,
-                       kExtAudioFileProperty_FileDataFormat, &size, &absd);
-       if (err != noErr) {
-        ExtAudioFileDispose (af);
-               goto libsndfile;
-       }
-
-       _info.samplerate = absd.mSampleRate;
-       _info.channels   = absd.mChannelsPerFrame;
-
-    size = sizeof(_info.length);
-    err = ExtAudioFileGetProperty(af, kExtAudioFileProperty_FileLengthFrames, &size, &_info.length);
-    if (err != noErr) {
-        ExtAudioFileDispose (af);
-               goto libsndfile;
-    }
-
-       size = sizeof(CFStringRef);
-       err = AudioFormatGetProperty(
-                       kAudioFormatProperty_FormatName, sizeof(absd), &absd, &size, &name);
-       if (err != noErr) {
-        ExtAudioFileDispose (af);
-               goto libsndfile;
-       }
-
-       _info.format_name = CFStringRefToStdString(name);
-
-    ExtAudioFileDispose (af);
-       return true;
-       
-libsndfile:
-#endif // HAVE_COREAUDIO
-
-       SNDFILE *sf;
-       SF_INFO sf_info;
-
-       sf_info.format = 0; // libsndfile says to clear this before sf_open().
-
-       if ((sf = sf_open ((char*) path.c_str(), SFM_READ, &sf_info)) == 0) { 
-               char errbuf[256];
-               error_msg = sf_error_str (0, errbuf, sizeof (errbuf) - 1);
-               return false;
-       }
-
-       sf_close (sf);
-
-       _info.samplerate  = sf_info.samplerate;
-       _info.channels    = sf_info.channels;
-       _info.length      = sf_info.frames;
-       _info.format_name = string_compose("Format: %1, %2",
-                       sndfile_major_format(sf_info.format),
-                       sndfile_minor_format(sf_info.format));
-
-       return true;
-}
index 63a9a3d014b6083dc0005dcb3d939bab0e1be081..0e0ef0bc1e134bf426e713ff6ea378a0d24c3ab3 100644 (file)
@@ -62,8 +62,7 @@
 
 #include <ardour/ardour.h>
 #include <ardour/version.h>
-#include <ardour/source.h>
-#include <ardour/filesource.h>
+#include <ardour/audiofilesource.h>
 #include <ardour/session.h>
 #include <ardour/cycle_timer.h>
 #include <ardour/pcm_utils.h>
index 8e36ca8074c4b1a61d27062bf43f7733e1d16b77..aa725d4bb3fe45151043cf2ff43b25baeb9c75a3 100644 (file)
@@ -43,7 +43,7 @@
 #include <ardour/audio_library.h>
 #include <ardour/configuration.h>
 #include <ardour/plugin_manager.h>
-#include <ardour/source.h>
+#include <ardour/audiosource.h>
 #include <ardour/utils.h>
 #include <ardour/session.h>
 #include <ardour/control_protocol_manager.h>
index c13816e648d077a23dc4c5752e44f5aeb165d23b..410171a590f36cfe2fc3c734ed0f5db03a72c3cd 100644 (file)
@@ -36,8 +36,8 @@
 
 #include <ardour/ardour.h>
 #include <ardour/session.h>
-#include <ardour/diskstream.h>
-#include <ardour/filesource.h>
+#include <ardour/audio_diskstream.h>
+#include <ardour/sndfilesource.h>
 #include <ardour/sndfile_helpers.h>
 #include <ardour/audioregion.h>
 
@@ -51,8 +51,8 @@ int
 Session::import_audiofile (import_status& status)
 {
        SNDFILE *in;
-       FileSource **newfiles = 0;
-       ARDOUR::AudioRegion::SourceList sources;
+       AudioFileSource **newfiles = 0;
+       AudioRegion::SourceList sources;
        SF_INFO info;
        float *data = 0;
        Sample **channel_data = 0;
@@ -94,7 +94,7 @@ Session::import_audiofile (import_status& status)
                }
        }
 
-       newfiles = new FileSource *[info.channels];
+       newfiles = new AudioFileSource *[info.channels];
        for (n = 0; n < info.channels; ++n) {
                newfiles[n] = 0;
        }
@@ -137,7 +137,10 @@ Session::import_audiofile (import_status& status)
 
                        
                try { 
-                       newfiles[n] = new FileSource (buf, frame_rate(), false, Config->get_native_file_data_format());
+                       newfiles[n] = new SndFileSource (buf, 
+                                                        Config->get_native_file_data_format(),
+                                                        Config->get_native_file_header_format(),
+                                                        frame_rate ());
                }
 
                catch (failed_constructor& err) {
index 67b70fba0ca6dd3cf61115e6dfe7ce196a7a7a7e..5aaf9d5591fad410a1ab5159cb5c52eddfe047a4 100644 (file)
@@ -309,7 +309,6 @@ OSC::osc_receiver()
                if ((ret = poll (pfd, nfds, timeout)) < 0) {
                        if (errno == EINTR) {
                                /* gdb at work, perhaps */
-                               cerr << "EINTR hit " << endl;
                                goto again;
                        }
                        
index 335dacad6ed1b6ec6711e47c611b447365c2ecfc..13dd531bac5dafc1eb0c427020deb1e852cf1b9d 100644 (file)
@@ -24,7 +24,7 @@
 
 #include <ardour/types.h>
 #include <ardour/reverse.h>
-#include <ardour/filesource.h>
+#include <ardour/audiofilesource.h>
 #include <ardour/session.h>
 #include <ardour/audioregion.h>
 
index ae807e66e15b3b8186fbeb401d0d2362067c1c65..57306237427ff581a17e352b615d29516ccf3bc0 100644 (file)
@@ -29,7 +29,7 @@
 
 #include <ardour/route_group.h>
 #include <ardour/audio_track.h>
-#include <ardour/diskstream.h>
+#include <ardour/audio_diskstream.h>
 #include <ardour/configuration.h>
 
 using namespace ARDOUR;
index 6c1dec8e81e3ca016f4bf37cd57435eecdfcd9fe..d7d7e290ed60945058968872f8c23520fdcb2242 100644 (file)
@@ -32,7 +32,8 @@
 #include <sigc++/bind.h>
 #include <sigc++/retype.h>
 
-#include <glibmm.h>
+#include <glibmm/thread.h>
+#include <glibmm/miscutils.h>
 
 #include <pbd/error.h>
 #include <glibmm/thread.h>
 #include <ardour/audioengine.h>
 #include <ardour/configuration.h>
 #include <ardour/session.h>
-#include <ardour/diskstream.h>
+#include <ardour/audio_diskstream.h>
 #include <ardour/utils.h>
 #include <ardour/audioplaylist.h>
 #include <ardour/audioregion.h>
-#include <ardour/source.h>
-#include <ardour/filesource.h>
+#include <ardour/audiofilesource.h>
 #include <ardour/destructive_filesource.h>
-#include <ardour/sndfilesource.h>
 #include <ardour/auditioner.h>
 #include <ardour/recent_sessions.h>
 #include <ardour/redirect.h>
@@ -90,6 +89,7 @@ Session::mix_buffers_with_gain_t      Session::mix_buffers_with_gain  = 0;
 Session::mix_buffers_no_gain_t         Session::mix_buffers_no_gain    = 0;
 
 sigc::signal<int> Session::AskAboutPendingState;
+sigc::signal<void> Session::SMPTEOffsetChanged;
 
 int
 Session::find_session (string str, string& path, string& snapshot, bool& isnew)
@@ -456,10 +456,10 @@ Session::~Session ()
        }
 
 #ifdef TRACK_DESTRUCTION
-       cerr << "delete diskstreams\n";
+       cerr << "delete audio_diskstreams\n";
 #endif /* TRACK_DESTRUCTION */
-       for (DiskStreamList::iterator i = diskstreams.begin(); i != diskstreams.end(); ) {
-               DiskStreamList::iterator tmp;
+       for (AudioDiskstreamList::iterator i = audio_diskstreams.begin(); i != audio_diskstreams.end(); ) {
+               AudioDiskstreamList::iterator tmp;
 
                tmp = i;
                ++tmp;
@@ -470,10 +470,10 @@ Session::~Session ()
        }
 
 #ifdef TRACK_DESTRUCTION
-       cerr << "delete sources\n";
+       cerr << "delete audio sources\n";
 #endif /* TRACK_DESTRUCTION */
-       for (SourceList::iterator i = sources.begin(); i != sources.end(); ) {
-               SourceList::iterator tmp;
+       for (AudioSourceList::iterator i = audio_sources.begin(); i != audio_sources.end(); ) {
+               AudioSourceList::iterator tmp;
 
                tmp = i;
                ++tmp;
@@ -882,7 +882,7 @@ Session::playlist_length_changed (Playlist* pl)
 }
 
 void
-Session::diskstream_playlist_changed (DiskStream* dstream)
+Session::diskstream_playlist_changed (AudioDiskstream* dstream)
 {
        Playlist *playlist;
 
@@ -962,7 +962,7 @@ Session::set_auto_input (bool yn)
                           The rarity and short potential lock duration makes this "OK"
                        */
                        Glib::RWLock::ReaderLock dsm (diskstream_lock);
-                       for (DiskStreamList::iterator i = diskstreams.begin(); i != diskstreams.end(); ++i) {
+                       for (AudioDiskstreamList::iterator i = audio_diskstreams.begin(); i != audio_diskstreams.end(); ++i) {
                                if ((*i)->record_enabled ()) {
                                        //cerr << "switching to input = " << !auto_input << __FILE__ << __LINE__ << endl << endl;
                                        (*i)->monitor_input (!auto_input);   
@@ -980,7 +980,7 @@ Session::reset_input_monitor_state ()
 {
        if (transport_rolling()) {
                Glib::RWLock::ReaderLock dsm (diskstream_lock);
-               for (DiskStreamList::iterator i = diskstreams.begin(); i != diskstreams.end(); ++i) {
+               for (AudioDiskstreamList::iterator i = audio_diskstreams.begin(); i != audio_diskstreams.end(); ++i) {
                        if ((*i)->record_enabled ()) {
                                //cerr << "switching to input = " << !auto_input << __FILE__ << __LINE__ << endl << endl;
                                (*i)->monitor_input (Config->get_use_hardware_monitoring() && !auto_input);
@@ -988,7 +988,7 @@ Session::reset_input_monitor_state ()
                }
        } else {
                Glib::RWLock::ReaderLock dsm (diskstream_lock);
-               for (DiskStreamList::iterator i = diskstreams.begin(); i != diskstreams.end(); ++i) {
+               for (AudioDiskstreamList::iterator i = audio_diskstreams.begin(); i != audio_diskstreams.end(); ++i) {
                        if ((*i)->record_enabled ()) {
                                //cerr << "switching to input = " << !auto_input << __FILE__ << __LINE__ << endl << endl;
                                (*i)->monitor_input (Config->get_use_hardware_monitoring());
@@ -1069,7 +1069,7 @@ Session::auto_loop_changed (Location* location)
                }
                else if (seamless_loop && !loop_changing) {
                        
-                       // schedule a locate-roll to refill the diskstreams at the
+                       // schedule a locate-roll to refill the audio_diskstreams at the
                        // previous loop end
                        loop_changing = true;
 
@@ -1257,7 +1257,7 @@ Session::enable_record ()
        if (g_atomic_int_get (&_record_status) != Recording) {
                g_atomic_int_set (&_record_status, Recording);
                _last_record_location = _transport_frame;
-               //send_mmc_in_another_thread (MIDI::MachineControl::cmdRecordStrobe);
+               deliver_mmc(MIDI::MachineControl::cmdRecordStrobe, _last_record_location);
 
                if (Config->get_use_hardware_monitoring() && auto_input) {
                        /* Even though this can be called from RT context we are using
@@ -1266,7 +1266,7 @@ Session::enable_record ()
                        */
                        Glib::RWLock::ReaderLock dsm (diskstream_lock);
                        
-                       for (DiskStreamList::iterator i = diskstreams.begin(); i != diskstreams.end(); ++i) {
+                       for (AudioDiskstreamList::iterator i = audio_diskstreams.begin(); i != audio_diskstreams.end(); ++i) {
                                if ((*i)->record_enabled ()) {
                                        (*i)->monitor_input (true);   
                                }
@@ -1292,7 +1292,11 @@ Session::disable_record (bool rt_context, bool force)
                        }
                }
 
-               //send_mmc_in_another_thread (MIDI::MachineControl::cmdRecordExit);
+               // FIXME: timestamp correct? [DR]
+               // FIXME FIXME FIXME: rt_context?  this must be called in the process thread.
+               // does this /need/ to be sent in all cases?
+               if (rt_context)
+                       deliver_mmc (MIDI::MachineControl::cmdRecordExit, _transport_frame);
 
                if (Config->get_use_hardware_monitoring() && auto_input) {
                        /* Even though this can be called from RT context we are using
@@ -1301,7 +1305,7 @@ Session::disable_record (bool rt_context, bool force)
                        */
                        Glib::RWLock::ReaderLock dsm (diskstream_lock);
                        
-                       for (DiskStreamList::iterator i = diskstreams.begin(); i != diskstreams.end(); ++i) {
+                       for (AudioDiskstreamList::iterator i = audio_diskstreams.begin(); i != audio_diskstreams.end(); ++i) {
                                if ((*i)->record_enabled ()) {
                                        (*i)->monitor_input (false);   
                                }
@@ -1328,7 +1332,7 @@ Session::step_back_from_record ()
                */
                Glib::RWLock::ReaderLock dsm (diskstream_lock);
                
-               for (DiskStreamList::iterator i = diskstreams.begin(); i != diskstreams.end(); ++i) {
+               for (AudioDiskstreamList::iterator i = audio_diskstreams.begin(); i != audio_diskstreams.end(); ++i) {
                        if (auto_input && (*i)->record_enabled ()) {
                                //cerr << "switching from input" << __FILE__ << __LINE__ << endl << endl;
                                (*i)->monitor_input (false);   
@@ -1353,8 +1357,7 @@ Session::maybe_enable_record ()
                        enable_record ();
                } 
        } else {
-               // FIXME
-               //send_mmc_in_another_thread (MIDI::MachineControl::cmdRecordPause);
+               deliver_mmc (MIDI::MachineControl::cmdRecordPause, _transport_frame);
                RecordStateChanged (); /* EMIT SIGNAL */
        }
 
@@ -1434,6 +1437,9 @@ Session::set_frame_rate (jack_nframes_t frames_per_second)
 
        Route::set_automation_interval ((jack_nframes_t) ceil ((double) frames_per_second * 0.25));
 
+       // XXX we need some equivalent to this, somehow
+       // DestructiveFileSource::setup_standard_crossfades (frames_per_second);
+
        set_dirty();
 
        /* XXX need to reset/reinstantiate all LADSPA plugins */
@@ -1495,7 +1501,7 @@ Session::set_block_size (jack_nframes_t nframes)
                        (*i)->set_block_size (nframes);
                }
                
-               for (DiskStreamList::iterator i = diskstreams.begin(); i != diskstreams.end(); ++i) {
+               for (AudioDiskstreamList::iterator i = audio_diskstreams.begin(); i != audio_diskstreams.end(); ++i) {
                        (*i)->set_block_size (nframes);
                }
 
@@ -1902,14 +1908,14 @@ Session::add_route (Route* route)
 }
 
 void
-Session::add_diskstream (DiskStream* dstream)
+Session::add_diskstream (AudioDiskstream* dstream)
 {
        /* need to do this in case we're rolling at the time, to prevent false underruns */
        dstream->do_refill(0, 0, 0);
        
        { 
                Glib::RWLock::WriterLock lm (diskstream_lock);
-               diskstreams.push_back (dstream);
+               audio_diskstreams.push_back (dstream);
        }
 
        /* take a reference to the diskstream, preventing it from
@@ -1929,7 +1935,7 @@ Session::add_diskstream (DiskStream* dstream)
        set_dirty();
        save_state (_current_snapshot_name);
 
-       DiskStreamAdded (dstream); /* EMIT SIGNAL */
+       AudioDiskstreamAdded (dstream); /* EMIT SIGNAL */
 }
 
 void
@@ -1963,18 +1969,24 @@ Session::remove_route (Route& route)
                update_route_solo_state ();
        }
 
-       {
-               Glib::RWLock::WriterLock lm (diskstream_lock);
-
-               AudioTrack* at;
+       AudioTrack* at;
+       AudioDiskstream* ds = 0;
+       
+       if ((at = dynamic_cast<AudioTrack*>(&route)) != 0) {
+               ds = &at->disk_stream();
+       }
+       
+       if (ds) {
 
-               if ((at = dynamic_cast<AudioTrack*>(&route)) != 0) {
-                       diskstreams.remove (&at->disk_stream());
-                       at->disk_stream().unref ();
+               {
+                       Glib::RWLock::WriterLock lm (diskstream_lock);
+                       audio_diskstreams.remove (ds);
                }
 
-               find_current_end ();
+               ds->unref ();
        }
+
+       find_current_end ();
        
        update_latency_compensation (false, false);
        set_dirty();
@@ -2257,7 +2269,7 @@ Session::get_maximum_extent () const
           ensure atomicity.
        */
 
-       for (DiskStreamList::const_iterator i = diskstreams.begin(); i != diskstreams.end(); ++i) {
+       for (AudioDiskstreamList::const_iterator i = audio_diskstreams.begin(); i != audio_diskstreams.end(); ++i) {
                Playlist* pl = (*i)->playlist();
                if ((me = pl->get_maximum_extent()) > max) {
                        max = me;
@@ -2267,12 +2279,12 @@ Session::get_maximum_extent () const
        return max;
 }
 
-DiskStream *
+AudioDiskstream *
 Session::diskstream_by_name (string name)
 {
        Glib::RWLock::ReaderLock lm (diskstream_lock);
 
-       for (DiskStreamList::iterator i = diskstreams.begin(); i != diskstreams.end(); ++i) {
+       for (AudioDiskstreamList::iterator i = audio_diskstreams.begin(); i != audio_diskstreams.end(); ++i) {
                if ((*i)->name() == name) {
                        return* i;
                }
@@ -2281,12 +2293,12 @@ Session::diskstream_by_name (string name)
        return 0;
 }
 
-DiskStream *
+AudioDiskstream *
 Session::diskstream_by_id (id_t id)
 {
        Glib::RWLock::ReaderLock lm (diskstream_lock);
 
-       for (DiskStreamList::iterator i = diskstreams.begin(); i != diskstreams.end(); ++i) {
+       for (AudioDiskstreamList::iterator i = audio_diskstreams.begin(); i != audio_diskstreams.end(); ++i) {
                if ((*i)->id() == id) {
                        return *i;
                }
@@ -2585,7 +2597,10 @@ Session::destroy_region (Region* region)
        for (vector<Source*>::iterator i = srcs.begin(); i != srcs.end(); ++i) {
                
                if ((*i)->use_cnt() == 0) {
-                       (*i)->mark_for_remove ();
+                       AudioFileSource* afs = dynamic_cast<AudioFileSource*>(*i);
+                       if (afs) {
+                               (afs)->mark_for_remove ();
+                       }
                        delete *i;
                }
        }
@@ -2609,7 +2624,7 @@ Session::remove_last_capture ()
 
        Glib::RWLock::ReaderLock lm (diskstream_lock);
        
-       for (DiskStreamList::iterator i = diskstreams.begin(); i != diskstreams.end(); ++i) {
+       for (AudioDiskstreamList::iterator i = audio_diskstreams.begin(); i != audio_diskstreams.end(); ++i) {
                list<Region*>& l = (*i)->last_capture_regions();
                
                if (!l.empty()) {
@@ -2632,15 +2647,15 @@ Session::remove_region_from_region_list (Region& r)
 /* Source Management */
 
 void
-Session::add_source (Source* source)
+Session::add_audio_source (AudioSource* source)
 {
-       pair<SourceList::key_type, SourceList::mapped_type> entry;
+       pair<AudioSourceList::key_type, AudioSourceList::mapped_type> entry;
 
        {
-               Glib::Mutex::Lock lm (source_lock);
+               Glib::Mutex::Lock lm (audio_source_lock);
                entry.first = source->id();
                entry.second = source;
-               sources.insert (entry);
+               audio_sources.insert (entry);
        }
        
        source->GoingAway.connect (mem_fun (this, &Session::remove_source));
@@ -2652,13 +2667,13 @@ Session::add_source (Source* source)
 void
 Session::remove_source (Source* source)
 {
-       SourceList::iterator i;
+       AudioSourceList::iterator i;
 
        { 
-               Glib::Mutex::Lock lm (source_lock);
+               Glib::Mutex::Lock lm (audio_source_lock);
 
-               if ((i = sources.find (source->id())) != sources.end()) {
-                       sources.erase (i);
+               if ((i = audio_sources.find (source->id())) != audio_sources.end()) {
+                       audio_sources.erase (i);
                }
        }
 
@@ -2677,15 +2692,21 @@ Session::remove_source (Source* source)
 Source *
 Session::get_source (ARDOUR::id_t id)
 {
-       Glib::Mutex::Lock lm (source_lock);
-       SourceList::iterator i;
+       Glib::Mutex::Lock lm (audio_source_lock);
+       AudioSourceList::iterator i;
        Source* source = 0;
 
-       if ((i = sources.find (id)) != sources.end()) {
+       if ((i = audio_sources.find (id)) != audio_sources.end()) {
                source = (*i).second;
        }
 
-       return source;
+       if (source) {
+               return source;
+       }
+
+       /* XXX search MIDI or other searches here */
+       
+       return 0;
 }
 
 string
@@ -2892,17 +2913,23 @@ Session::audio_path_from_name (string name, uint32_t nchan, uint32_t chan, bool
        return spath;
 }
 
-FileSource *
-Session::create_file_source (DiskStream& ds, int32_t chan, bool destructive)
+AudioFileSource *
+Session::create_audio_source_for_session (AudioDiskstream& ds, uint32_t chan, bool destructive)
 {
        string spath = audio_path_from_name (ds.name(), ds.n_channels(), chan, destructive);
 
        /* this might throw failed_constructor(), which is OK */
-
+       
        if (destructive) {
-               return new DestructiveFileSource (spath, frame_rate(), false, Config->get_native_file_data_format());
+               return new DestructiveFileSource (spath,
+                                                 Config->get_native_file_data_format(),
+                                                 Config->get_native_file_header_format(),
+                                                 frame_rate());
        } else {
-               return new FileSource (spath, frame_rate(), false, Config->get_native_file_data_format());
+               return new SndFileSource (spath, 
+                                         Config->get_native_file_data_format(),
+                                         Config->get_native_file_header_format(),
+                                         frame_rate());
        }
 }
 
@@ -3084,7 +3111,7 @@ Session::remove_empty_sounds ()
        
        for (vector<string *>::iterator i = possible_audiofiles->begin(); i != possible_audiofiles->end(); ++i) {
 
-               if (FileSource::is_empty (*(*i))) {
+               if (AudioFileSource::is_empty (*(*i))) {
 
                        unlink ((*i)->c_str());
                        
@@ -3142,12 +3169,12 @@ Session::set_all_mute (bool yn)
 }
                
 uint32_t
-Session::n_diskstreams () const
+Session::n_audio_diskstreams () const
 {
        Glib::RWLock::ReaderLock lm (diskstream_lock);
        uint32_t n = 0;
 
-       for (DiskStreamList::const_iterator i = diskstreams.begin(); i != diskstreams.end(); ++i) {
+       for (AudioDiskstreamList::const_iterator i = audio_diskstreams.begin(); i != audio_diskstreams.end(); ++i) {
                if (!(*i)->hidden()) {
                        n++;
                }
@@ -3156,10 +3183,10 @@ Session::n_diskstreams () const
 }
 
 void 
-Session::foreach_diskstream (void (DiskStream::*func)(void)) 
+Session::foreach_audio_diskstream (void (AudioDiskstream::*func)(void)) 
 {
        Glib::RWLock::ReaderLock lm (diskstream_lock);
-       for (DiskStreamList::iterator i = diskstreams.begin(); i != diskstreams.end(); ++i) {
+       for (AudioDiskstreamList::iterator i = audio_diskstreams.begin(); i != audio_diskstreams.end(); ++i) {
                if (!(*i)->hidden()) {
                        ((*i)->*func)();
                }
@@ -3186,7 +3213,7 @@ Session::graph_reordered ()
           reflect any changes in latencies within the graph.
        */
        
-       for (DiskStreamList::iterator i = diskstreams.begin(); i != diskstreams.end(); ++i) {
+       for (AudioDiskstreamList::iterator i = audio_diskstreams.begin(); i != audio_diskstreams.end(); ++i) {
                (*i)->set_capture_offset ();
        }
 }
@@ -3469,7 +3496,7 @@ Session::reset_native_file_format ()
        //RWLockMonitor lm1 (route_lock, true, __LINE__, __FILE__);
        Glib::RWLock::ReaderLock lm2 (diskstream_lock);
 
-       for (DiskStreamList::iterator i = diskstreams.begin(); i != diskstreams.end(); ++i) {
+       for (AudioDiskstreamList::iterator i = audio_diskstreams.begin(); i != audio_diskstreams.end(); ++i) {
                (*i)->reset_write_sources (false);
        }
 }
@@ -3489,7 +3516,7 @@ Session::route_name_unique (string n) const
 }
 
 int
-Session::remove_file_source (FileSource& fs)
+Session::cleanup_audio_file_source (AudioFileSource& fs)
 {
        return fs.move_to_trash (dead_sound_dir_name);
 }
@@ -3564,12 +3591,12 @@ Session::freeze (InterThreadInfo& itt)
 }
 
 int
-Session::write_one_track (AudioTrack& track, jack_nframes_t start, jack_nframes_t len,         bool overwrite, vector<Source*>& srcs,
-                         InterThreadInfo& itt)
+Session::write_one_audio_track (AudioTrack& track, jack_nframes_t start, jack_nframes_t len,   
+                              bool overwrite, vector<AudioSource*>& srcs, InterThreadInfo& itt)
 {
        int ret = -1;
        Playlist* playlist;
-       FileSource* fsource;
+       AudioFileSource* fsource;
        uint32_t x;
        char buf[PATH_MAX+1];
        string dir;
@@ -3614,7 +3641,11 @@ Session::write_one_track (AudioTrack& track, jack_nframes_t start, jack_nframes_
                }
                
                try {
-                       fsource = new FileSource (buf, frame_rate(), false, Config->get_native_file_data_format());
+                       fsource =  new SndFileSource (buf, 
+                                                     Config->get_native_file_data_format(),
+                                                     Config->get_native_file_header_format(),
+                                                     frame_rate());
+                                                           
                }
                
                catch (failed_constructor& err) {
@@ -3653,9 +3684,13 @@ Session::write_one_track (AudioTrack& track, jack_nframes_t start, jack_nframes_
                }
 
                uint32_t n = 0;
-               for (vector<Source*>::iterator src=srcs.begin(); src != srcs.end(); ++src, ++n) {
-                       if ((*src)->write (buffers[n], this_chunk, workbuf) != this_chunk) {
-                               goto out;
+               for (vector<AudioSource*>::iterator src=srcs.begin(); src != srcs.end(); ++src, ++n) {
+                       AudioFileSource* afs = dynamic_cast<AudioFileSource*>(*src);
+
+                       if (afs) {
+                               if (afs->write (buffers[n], this_chunk, workbuf) != this_chunk) {
+                                       goto out;
+                               }
                        }
                }
                
@@ -3673,14 +3708,20 @@ Session::write_one_track (AudioTrack& track, jack_nframes_t start, jack_nframes_
                time (&now);
                xnow = localtime (&now);
                
-               for (vector<Source*>::iterator src=srcs.begin(); src != srcs.end(); ++src) {
-                       dynamic_cast<FileSource*>((*src))->update_header (position, *xnow, now);
+               for (vector<AudioSource*>::iterator src=srcs.begin(); src != srcs.end(); ++src) {
+                       AudioFileSource* afs = dynamic_cast<AudioFileSource*>(*src);
+                       if (afs) {
+                               afs->update_header (position, *xnow, now);
+                       }
                }
                
                /* build peakfile for new source */
                
-               for (vector<Source*>::iterator src=srcs.begin(); src != srcs.end(); ++src) {
-                       dynamic_cast<FileSource*>(*src)->build_peaks ();
+               for (vector<AudioSource*>::iterator src=srcs.begin(); src != srcs.end(); ++src) {
+                       AudioFileSource* afs = dynamic_cast<AudioFileSource*>(*src);
+                       if (afs) {
+                               afs->build_peaks ();
+                       }
                }
                
                ret = 0;
@@ -3688,8 +3729,11 @@ Session::write_one_track (AudioTrack& track, jack_nframes_t start, jack_nframes_
                
   out:
        if (ret) {
-               for (vector<Source*>::iterator src=srcs.begin(); src != srcs.end(); ++src) {
-                       dynamic_cast<FileSource*>(*src)->mark_for_remove ();
+               for (vector<AudioSource*>::iterator src=srcs.begin(); src != srcs.end(); ++src) {
+                       AudioFileSource* afs = dynamic_cast<AudioFileSource*>(*src);
+                       if (afs) {
+                               afs->mark_for_remove ();
+                       }
                        delete *src;
                }
        }
index ebe0d645482d7620261980f70a6121fcaac68bd4..d29bf3937b67ed967cf7dcc248cf62a4f73acf9b 100644 (file)
@@ -34,7 +34,7 @@
 #include <ardour/configuration.h>
 #include <ardour/audioengine.h>
 #include <ardour/session.h>
-#include <ardour/diskstream.h>
+#include <ardour/audio_diskstream.h>
 #include <ardour/crossfade.h>
 #include <ardour/timestamps.h>
 
@@ -168,10 +168,10 @@ Session::butler_thread_work ()
        struct timeval begin, end;
        struct pollfd pfd[1];
        bool disk_work_outstanding = false;
-       DiskStreamList::iterator i;
+       AudioDiskstreamList::iterator i;
 
-       butler_mixdown_buffer = new Sample[DiskStream::disk_io_frames()];
-       butler_gain_buffer = new gain_t[DiskStream::disk_io_frames()];
+       butler_mixdown_buffer = new Sample[AudioDiskstream::disk_io_frames()];
+       butler_gain_buffer = new gain_t[AudioDiskstream::disk_io_frames()];
        // this buffer is used for temp conversion purposes in filesources
        char * conv_buffer = conversion_buffer(ButlerContext);
 
@@ -241,7 +241,7 @@ Session::butler_thread_work ()
                        }
                }
        
-               for (i = diskstreams.begin(); i != diskstreams.end(); ++i) {
+               for (i = audio_diskstreams.begin(); i != audio_diskstreams.end(); ++i) {
                        // cerr << "BEFORE " << (*i)->name() << ": pb = " << (*i)->playback_buffer_load() << " cp = " << (*i)->capture_buffer_load() << endl;
                }
 
@@ -257,7 +257,7 @@ Session::butler_thread_work ()
 
                Glib::RWLock::ReaderLock dsm (diskstream_lock);
                
-               for (i = diskstreams.begin(); !transport_work_requested() && butler_should_run && i != diskstreams.end(); ++i) {
+               for (i = audio_diskstreams.begin(); !transport_work_requested() && butler_should_run && i != audio_diskstreams.end(); ++i) {
                        
                        // cerr << "rah fondr " << (*i)->io()->name () << endl;
 
@@ -278,7 +278,7 @@ Session::butler_thread_work ()
 
                }
 
-               if (i != diskstreams.end()) {
+               if (i != audio_diskstreams.end()) {
                        /* we didn't get to all the streams */
                        disk_work_outstanding = true;
                }
@@ -300,7 +300,7 @@ Session::butler_thread_work ()
                compute_io = true;
                gettimeofday (&begin, 0);
                
-               for (i = diskstreams.begin(); !transport_work_requested() && butler_should_run && i != diskstreams.end(); ++i) {
+               for (i = audio_diskstreams.begin(); !transport_work_requested() && butler_should_run && i != audio_diskstreams.end(); ++i) {
                        
                        // cerr << "write behind for " << (*i)->name () << endl;
                        
@@ -330,7 +330,7 @@ Session::butler_thread_work ()
                        request_stop ();
                }
 
-               if (i != diskstreams.end()) {
+               if (i != audio_diskstreams.end()) {
                        /* we didn't get to all the streams */
                        disk_work_outstanding = true;
                }
@@ -357,7 +357,7 @@ Session::butler_thread_work ()
                        Glib::Mutex::Lock lm (butler_request_lock);
 
                        if (butler_should_run && (disk_work_outstanding || transport_work_requested())) {
-//                             for (DiskStreamList::iterator i = diskstreams.begin(); i != diskstreams.end(); ++i) {
+//                             for (AudioDiskstreamList::iterator i = audio_diskstreams.begin(); i != audio_diskstreams.end(); ++i) {
 //                                     cerr << "AFTER " << (*i)->name() << ": pb = " << (*i)->playback_buffer_load() << " cp = " << (*i)->capture_buffer_load() << endl;
 //                             }
 
@@ -375,7 +375,7 @@ Session::butler_thread_work ()
 
 
 void
-Session::request_overwrite_buffer (DiskStream* stream)
+Session::request_overwrite_buffer (AudioDiskstream* stream)
 {
        Event *ev = new Event (Event::Overwrite, Event::Add, Event::Immediate, 0, 0, 0.0);
        ev->set_ptr (stream);
@@ -383,7 +383,7 @@ Session::request_overwrite_buffer (DiskStream* stream)
 }
 
 void
-Session::overwrite_some_buffers (DiskStream* ds)
+Session::overwrite_some_buffers (AudioDiskstream* ds)
 {
        /* executed by the audio thread */
 
@@ -398,7 +398,7 @@ Session::overwrite_some_buffers (DiskStream* ds)
        } else {
 
                Glib::RWLock::ReaderLock dm (diskstream_lock);
-               for (DiskStreamList::iterator i = diskstreams.begin(); i != diskstreams.end(); ++i) {
+               for (AudioDiskstreamList::iterator i = audio_diskstreams.begin(); i != audio_diskstreams.end(); ++i) {
                        (*i)->set_pending_overwrite (true);
                }
        }
index c9b433968641061f06af6f9ee2b363a8b0b94c5a..586dea05a3aba59ffc32393f90be57a5669edc11 100644 (file)
@@ -28,7 +28,7 @@
 
 #include <ardour/ardour.h>
 #include <ardour/session.h>
-#include <ardour/diskstream.h>
+#include <ardour/audio_diskstream.h>
 
 #include "i18n.h"
 
@@ -393,11 +393,11 @@ Session::process_event (Event* ev)
                break;
 
        case Event::Overwrite:
-               overwrite_some_buffers (static_cast<DiskStream*>(ev->ptr));
+               overwrite_some_buffers (static_cast<AudioDiskstream*>(ev->ptr));
                break;
 
        case Event::SetDiskstreamSpeed:
-               set_diskstream_speed (static_cast<DiskStream*> (ev->ptr), ev->speed);
+               set_diskstream_speed (static_cast<AudioDiskstream*> (ev->ptr), ev->speed);
                break;
 
        case Event::SetSlaveSource:
index 183b6df2373a023fc9578c26cf059a81796913e8..f6ea0c9f3ff867a9e9e5db2f320514f873c501db 100644 (file)
@@ -47,7 +47,7 @@
 #include <ardour/sndfile_helpers.h>
 #include <ardour/port.h>
 #include <ardour/audioengine.h>
-#include <ardour/diskstream.h>
+#include <ardour/audio_diskstream.h>
 #include <ardour/panner.h>
 
 #include "i18n.h"
@@ -495,7 +495,7 @@ Session::prepare_to_export (AudioExportSpecification& spec)
 
        {
                Glib::RWLock::ReaderLock lm (diskstream_lock);
-               for (DiskStreamList::iterator i = diskstreams.begin(); i != diskstreams.end(); ++i) {
+               for (AudioDiskstreamList::iterator i = audio_diskstreams.begin(); i != audio_diskstreams.end(); ++i) {
                        if ((*i)-> seek (spec.start_frame, true)) {
                                error << string_compose (_("%1: cannot seek to %2 for export"),
                                                  (*i)->name(), spec.start_frame)
index ea8580b3c2023603d23be1cb6334d3adc2023b66..b409686ce75b3081edc21d82fa5e7e13bdfbe8e9 100644 (file)
@@ -38,7 +38,7 @@
 #include <ardour/audioengine.h>
 #include <ardour/session.h>
 #include <ardour/audio_track.h>
-#include <ardour/diskstream.h>
+#include <ardour/audio_diskstream.h>
 #include <ardour/control_protocol.h>
 
 #include "i18n.h"
index 9b6f0bf6bab5aaedc671698edb352595eff3a761..f1c4b1e84df76dfbd21be4afa08918411a28605a 100644 (file)
@@ -38,7 +38,7 @@
 #include <ardour/audioengine.h>
 #include <ardour/session.h>
 #include <ardour/audio_track.h>
-#include <ardour/diskstream.h>
+#include <ardour/audio_diskstream.h>
 #include <ardour/slave.h>
 #include <ardour/cycles.h>
 #include <ardour/smpte.h>
@@ -1016,10 +1016,15 @@ Session::send_mmc_in_another_thread (MIDI::MachineControl::Command cmd, jack_nfr
        poke_midi_thread ();
 }
 */
+
+/** Send an MMC command at the given absolute timestamp (@a where).
+ *
+ * This must be called in the process thread, and @a where must fall within
+ * this process cycle or horrible things will happen.
+ */
 void
 Session::deliver_mmc (MIDI::MachineControl::Command cmd, jack_nframes_t where)
 {
-#if 0
        using namespace MIDI;
        int nbytes = 4;
        SMPTE::Time smpte;
@@ -1030,7 +1035,7 @@ Session::deliver_mmc (MIDI::MachineControl::Command cmd, jack_nframes_t where)
 
        mmc_buffer[nbytes++] = cmd;
 
-       // cerr << "delivering MMC, cmd = " << hex << (int) cmd << dec << endl;
+       cerr << "delivering MMC, cmd = " << hex << (int) cmd << dec << endl;
        
        switch (cmd) {
        case MachineControl::cmdLocate:
@@ -1050,6 +1055,7 @@ Session::deliver_mmc (MIDI::MachineControl::Command cmd, jack_nframes_t where)
 
        case MachineControl::cmdPlay:
                /* always convert Play into Deferred Play */
+               /* Why? [DR] */
                mmc_buffer[4] = MachineControl::cmdDeferredPlay;
                break;
 
@@ -1073,14 +1079,13 @@ Session::deliver_mmc (MIDI::MachineControl::Command cmd, jack_nframes_t where)
 
                mmc_buffer[nbytes++] = 0xf7; // terminate SysEx/MMC message
 
-               Glib::Mutex::Lock lm (midi_lock);
+               //Glib::Mutex::Lock lm (midi_lock);
                
-               if (_mmc_port->write (mmc_buffer, nbytes) != nbytes) {
+               // FIXME: timestamp correct? [DR]
+               if (_mmc_port->write (mmc_buffer, nbytes, where - _transport_frame) != nbytes) {
                        error << string_compose(_("MMC: cannot send command %1%2%3"), &hex, cmd, &dec) << endmsg;
                }
        }
-#endif
-       cout << "MMC support broken." << endl;
 }
 
 bool
index 411c749ade67657dbc626d0ec1d2dc05142c0bb5..daa3a1d380a4493ea65da0e93325e08109c11857 100644 (file)
@@ -30,7 +30,7 @@
 #include <ardour/ardour.h>
 #include <ardour/session.h>
 #include <ardour/timestamps.h>
-#include <ardour/diskstream.h>
+#include <ardour/audio_diskstream.h>
 #include <ardour/audioengine.h>
 #include <ardour/slave.h>
 #include <ardour/auditioner.h>
@@ -74,7 +74,7 @@ Session::process (jack_nframes_t nframes)
 void
 Session::prepare_diskstreams ()
 {
-       for (DiskStreamList::iterator i = diskstreams.begin(); i != diskstreams.end(); ++i) {
+       for (AudioDiskstreamList::iterator i = audio_diskstreams.begin(); i != audio_diskstreams.end(); ++i) {
                (*i)->prepare ();
        }
 }
@@ -146,12 +146,12 @@ Session::process_routes (jack_nframes_t nframes, jack_nframes_t offset)
 
                if ((ret = (*i)->roll (nframes, _transport_frame, _transport_frame + nframes, offset, declick, record_active, rec_monitors)) < 0) {
 
-                       /* we have to do this here. Route::roll() for an AudioTrack will have called DiskStream::process(),
-                          and the DS will expect DiskStream::commit() to be called. but we're aborting from that
+                       /* we have to do this here. Route::roll() for an AudioTrack will have called AudioDiskstream::process(),
+                          and the DS will expect AudioDiskstream::commit() to be called. but we're aborting from that
                           call path, so make sure we release any outstanding locks here before we return failure.
                        */
 
-                       for (DiskStreamList::iterator ids = diskstreams.begin(); ids != diskstreams.end(); ++ids) {
+                       for (AudioDiskstreamList::iterator ids = audio_diskstreams.begin(); ids != audio_diskstreams.end(); ++ids) {
                                (*ids)->recover ();
                        }
 
@@ -185,12 +185,12 @@ Session::silent_process_routes (jack_nframes_t nframes, jack_nframes_t offset)
 
                if ((ret = (*i)->silent_roll (nframes, _transport_frame, _transport_frame + nframes, offset, record_active, rec_monitors)) < 0) {
                        
-                       /* we have to do this here. Route::roll() for an AudioTrack will have called DiskStream::process(),
-                          and the DS will expect DiskStream::commit() to be called. but we're aborting from that
+                       /* we have to do this here. Route::roll() for an AudioTrack will have called AudioDiskstream::process(),
+                          and the DS will expect AudioDiskstream::commit() to be called. but we're aborting from that
                           call path, so make sure we release any outstanding locks here before we return failure.
                        */
 
-                       for (DiskStreamList::iterator ids = diskstreams.begin(); ids != diskstreams.end(); ++ids) {
+                       for (AudioDiskstreamList::iterator ids = audio_diskstreams.begin(); ids != audio_diskstreams.end(); ++ids) {
                                (*ids)->recover ();
                        }
 
@@ -209,7 +209,7 @@ Session::commit_diskstreams (jack_nframes_t nframes, bool &needs_butler)
        float pworst = 1.0f;
        float cworst = 1.0f;
 
-       for (DiskStreamList::iterator i = diskstreams.begin(); i != diskstreams.end(); ++i) {
+       for (AudioDiskstreamList::iterator i = audio_diskstreams.begin(); i != audio_diskstreams.end(); ++i) {
 
                if ((*i)->hidden()) {
                        continue;
@@ -579,7 +579,7 @@ Session::follow_slave (jack_nframes_t nframes, jack_nframes_t offset)
                                bool ok = true;
                                jack_nframes_t frame_delta = slave_transport_frame - _transport_frame;
                                
-                               for (DiskStreamList::iterator i = diskstreams.begin(); i != diskstreams.end(); ++i) {
+                               for (AudioDiskstreamList::iterator i = audio_diskstreams.begin(); i != audio_diskstreams.end(); ++i) {
                                        if (!(*i)->can_internal_playback_seek (frame_delta)) {
                                                ok = false;
                                                break;
@@ -587,7 +587,7 @@ Session::follow_slave (jack_nframes_t nframes, jack_nframes_t offset)
                                }
 
                                if (ok) {
-                                       for (DiskStreamList::iterator i = diskstreams.begin(); i != diskstreams.end(); ++i) {
+                                       for (AudioDiskstreamList::iterator i = audio_diskstreams.begin(); i != audio_diskstreams.end(); ++i) {
                                                (*i)->internal_playback_seek (frame_delta);
                                        }
                                        _transport_frame += frame_delta;
index 466a546aeeb8a3e8bce87d66614b0d4f292d0a54..edcc52d729d12dff9f47445fb8dbe5e1c882da86 100644 (file)
 #include <ardour/audioengine.h>
 #include <ardour/configuration.h>
 #include <ardour/session.h>
-#include <ardour/diskstream.h>
+#include <ardour/audio_diskstream.h>
 #include <ardour/utils.h>
 #include <ardour/audioplaylist.h>
-#include <ardour/source.h>
-#include <ardour/filesource.h>
+#include <ardour/audiofilesource.h>
 #include <ardour/destructive_filesource.h>
-#include <ardour/sndfilesource.h>
 #include <ardour/sndfile_helpers.h>
 #include <ardour/auditioner.h>
 #include <ardour/export.h>
@@ -196,12 +194,13 @@ Session::first_stage_init (string fullpath, string snapshot_name)
        destructive_index = 0;
 
        /* allocate conversion buffers */
-       _conversion_buffers[ButlerContext] = new char[DiskStream::disk_io_frames() * 4];
-       _conversion_buffers[TransportContext] = new char[DiskStream::disk_io_frames() * 4];
+       _conversion_buffers[ButlerContext] = new char[AudioDiskstream::disk_io_frames() * 4];
+       _conversion_buffers[TransportContext] = new char[AudioDiskstream::disk_io_frames() * 4];
        
        /* default short fade = 15ms */
 
        Crossfade::set_short_xfade_length ((jack_nframes_t) floor ((15.0 * frame_rate()) / 1000.0));
+       DestructiveFileSource::setup_standard_crossfades (frame_rate());
 
        last_mmc_step.tv_sec = 0;
        last_mmc_step.tv_usec = 0;
@@ -267,10 +266,10 @@ Session::first_stage_init (string fullpath, string snapshot_name)
        /* These are all static "per-class" signals */
 
        Region::CheckNewRegion.connect (mem_fun (*this, &Session::add_region));
-       Source::SourceCreated.connect (mem_fun (*this, &Session::add_source));
+       AudioSource::AudioSourceCreated.connect (mem_fun (*this, &Session::add_audio_source));
        Playlist::PlaylistCreated.connect (mem_fun (*this, &Session::add_playlist));
        Redirect::RedirectCreated.connect (mem_fun (*this, &Session::add_redirect));
-       DiskStream::DiskStreamCreated.connect (mem_fun (*this, &Session::add_diskstream));
+       AudioDiskstream::AudioDiskstreamCreated.connect (mem_fun (*this, &Session::add_diskstream));
        NamedSelection::NamedSelectionCreated.connect (mem_fun (*this, &Session::add_named_selection));
 
        IO::MoreOutputs.connect (mem_fun (*this, &Session::ensure_passthru_buffers));
@@ -285,7 +284,7 @@ Session::first_stage_init (string fullpath, string snapshot_name)
 int
 Session::second_stage_init (bool new_session)
 {
-       ExternalSource::set_peak_dir (peak_dir());
+       AudioFileSource::set_peak_dir (peak_dir());
 
        if (!new_session) {
                if (load_state (_current_snapshot_name)) {
@@ -425,7 +424,7 @@ Session::setup_raid_path (string path)
                }
                fspath += tape_dir_name;
                
-               FileSource::set_search_path (fspath);
+               AudioFileSource::set_search_path (fspath);
 
                return;
        }
@@ -481,9 +480,9 @@ Session::setup_raid_path (string path)
                session_dirs.push_back (sp);
        }
 
-       /* set the FileSource search path */
+       /* set the AudioFileSource search path */
 
-       FileSource::set_search_path (fspath);
+       AudioFileSource::set_search_path (fspath);
 
        /* reset the round-robin soundfile path thingie */
 
@@ -625,11 +624,11 @@ Session::load_diskstreams (const XMLNode& node)
 
        for (citer = clist.begin(); citer != clist.end(); ++citer) {
                
-               DiskStream* dstream;
+               AudioDiskstream* dstream;
 
                try {
-                       dstream = new DiskStream (*this, **citer);
-                       /* added automatically by DiskStreamCreated handler */
+                       dstream = new AudioDiskstream (*this, **citer);
+                       /* added automatically by AudioDiskstreamCreated handler */
                } 
                
                catch (failed_constructor& err) {
@@ -1335,15 +1334,15 @@ Session::state(bool full_state)
        child = node->add_child ("Sources");
 
        if (full_state) {
-               Glib::Mutex::Lock sl (source_lock);
+               Glib::Mutex::Lock sl (audio_source_lock);
 
-               for (SourceList::iterator siter = sources.begin(); siter != sources.end(); ++siter) {
+               for (AudioSourceList::iterator siter = audio_sources.begin(); siter != audio_sources.end(); ++siter) {
                        
-                       /* Don't save information about FileSources that are empty */
+                       /* Don't save information about AudioFileSources that are empty */
                        
-                       FileSource* fs;
+                       AudioFileSource* fs;
 
-                       if ((fs = dynamic_cast<FileSource*> ((*siter).second)) != 0) {
+                       if ((fs = dynamic_cast<AudioFileSource*> ((*siter).second)) != 0) {
                                DestructiveFileSource* dfs = dynamic_cast<DestructiveFileSource*> (fs);
 
                                /* destructive file sources are OK if they are empty, because
@@ -1380,7 +1379,7 @@ Session::state(bool full_state)
 
        { 
                Glib::RWLock::ReaderLock dl (diskstream_lock);
-               for (DiskStreamList::iterator i = diskstreams.begin(); i != diskstreams.end(); ++i) {
+               for (AudioDiskstreamList::iterator i = audio_diskstreams.begin(); i != audio_diskstreams.end(); ++i) {
                        if (!(*i)->hidden()) {
                                child->add_child_nocopy ((*i)->get_state());
                        }
@@ -1511,7 +1510,7 @@ Session::set_state (const XMLNode& node)
        Options
        Sources
        AudioRegions
-       DiskStreams
+       AudioDiskstreams
        Connections
        Locations
        Routes
@@ -1745,6 +1744,7 @@ Session::XMLRegionFactory (const XMLNode& node, bool full)
        const XMLProperty* prop;
        id_t s_id;
        Source* source;
+       AudioSource* as;
        AudioRegion::SourceList sources;
        uint32_t nchans = 1;
        char buf[128];
@@ -1772,7 +1772,13 @@ Session::XMLRegionFactory (const XMLNode& node, bool full)
                return 0;
        }
 
-       sources.push_back(source);
+       as = dynamic_cast<AudioSource*>(source);
+       if (!as) {
+               error << string_compose(_("Session: XMLNode describing a AudioRegion references a non-audio source id =%1"), s_id) << endmsg;
+               return 0;
+       }
+
+       sources.push_back (as);
 
        /* pickup other channels */
 
@@ -1785,7 +1791,13 @@ Session::XMLRegionFactory (const XMLNode& node, bool full)
                                error << string_compose(_("Session: XMLNode describing a AudioRegion references an unknown source id =%1"), s_id) << endmsg;
                                return 0;
                        }
-                       sources.push_back(source);
+                       
+                       as = dynamic_cast<AudioSource*>(source);
+                       if (!as) {
+                               error << string_compose(_("Session: XMLNode describing a AudioRegion references a non-audio source id =%1"), s_id) << endmsg;
+                               return 0;
+                       }
+                       sources.push_back (as);
                }
        }
        
@@ -1804,12 +1816,14 @@ Session::get_sources_as_xml ()
 
 {
        XMLNode* node = new XMLNode (X_("Sources"));
-       Glib::Mutex::Lock lm (source_lock);
+       Glib::Mutex::Lock lm (audio_source_lock);
 
-       for (SourceList::iterator i = sources.begin(); i != sources.end(); ++i) {
+       for (AudioSourceList::iterator i = audio_sources.begin(); i != audio_sources.end(); ++i) {
                node->add_child_nocopy ((*i).second->get_state());
        }
 
+       /* XXX get MIDI and other sources here */
+
        return *node;
 }
 
@@ -1867,23 +1881,12 @@ Session::XMLSourceFactory (const XMLNode& node)
        }
 
        try {
-               if (node.property (X_("destructive")) != 0) {
-                       src = new DestructiveFileSource (node, frame_rate());
-               } else {
-                       src = new FileSource (node, frame_rate());
-               }
+               src = AudioFileSource::create (node);
        }
        
        catch (failed_constructor& err) {
-
-               try {
-                       src = ExternalSource::create (node);
-               }
-
-               catch (failed_constructor& err) {
-                       error << _("Found a sound file that cannot be used by Ardour. See the progammers.") << endmsg;
-                       return 0;
-               } 
+               error << _("Found a sound file that cannot be used by Ardour. Talk to the progammers.") << endmsg;
+               return 0;
        }
 
        return src;
@@ -2930,9 +2933,9 @@ Session::cleanup_sources (Session::cleanup_report& rep)
        rep.paths.clear ();
        rep.space = 0;
 
-       for (SourceList::iterator i = sources.begin(); i != sources.end(); ) {
+       for (AudioSourceList::iterator i = audio_sources.begin(); i != audio_sources.end(); ) {
 
-               SourceList::iterator tmp;
+               AudioSourceList::iterator tmp;
 
                tmp = i;
                ++tmp;
@@ -2949,7 +2952,7 @@ Session::cleanup_sources (Session::cleanup_report& rep)
                           adding it to the list of all sources below
                        */
 
-                       sources.erase (i);
+                       audio_sources.erase (i);
                }
 
                i = tmp;
@@ -3013,20 +3016,17 @@ Session::cleanup_sources (Session::cleanup_report& rep)
           state file on disk still references sources we may have already
           dropped.
        */
-
+       
        find_all_sources_across_snapshots (all_sources, true);
 
-       /* add our current source list
+       /*  add our current source list
         */
-
-       for (SourceList::iterator i = sources.begin(); i != sources.end(); ++i) {
-               FileSource* fs;
-               ExternalSource* sfs;
+       
+       for (AudioSourceList::iterator i = audio_sources.begin(); i != audio_sources.end(); ++i) {
+               AudioFileSource* fs;
                
-               if ((fs = dynamic_cast<FileSource*> ((*i).second)) != 0) {
+               if ((fs = dynamic_cast<AudioFileSource*> ((*i).second)) != 0) {
                        all_sources.insert (fs->path());
-               } else if ((sfs = dynamic_cast<ExternalSource*> ((*i).second)) != 0) {
-                       all_sources.insert (sfs->path());
                } 
        }
 
index 453f5d6d27452853a18c4d3b27d9e8c175dd8c54..d597860a5e799e9f53779b8d4e67cbff876bb571 100644 (file)
@@ -32,6 +32,7 @@
 #include <ardour/audioengine.h>
 #include <ardour/session.h>
 #include <ardour/tempo.h>
+#include <ardour/audiofilesource.h>
 
 #include "i18n.h"
 
@@ -95,6 +96,9 @@ Session::set_smpte_offset (jack_nframes_t off)
 {
        _smpte_offset = off;
        last_smpte_valid = false;
+
+       AudioFileSource::set_header_position_offset (_smpte_offset, _smpte_offset_negative);
+
        SMPTEOffsetChanged (); /* EMIT SIGNAL */
 }
 
@@ -103,6 +107,9 @@ Session::set_smpte_offset_negative (bool neg)
 {
        _smpte_offset_negative = neg;
        last_smpte_valid = false;
+
+       AudioFileSource::set_header_position_offset (_smpte_offset, _smpte_offset_negative);
+
        SMPTEOffsetChanged (); /* EMIT SIGNAL */
 }
 
@@ -194,7 +201,7 @@ void
 Session::sample_to_smpte( jack_nframes_t sample, SMPTE::Time& smpte, bool use_offset, bool use_subframes ) const
 {
        jack_nframes_t offset_sample;
-  
+
        if (!use_offset) {
                offset_sample = sample;
                smpte.negative = false;
@@ -326,7 +333,7 @@ Session::smpte_duration_string (char* buf, jack_nframes_t when) const
        SMPTE::Time smpte;
 
        smpte_duration (when, smpte);
-       snprintf (buf, sizeof (buf), "%02ld:%02ld:%02ld:%02ld", smpte.hours, smpte.minutes, smpte.seconds, smpte.frames);
+       snprintf (buf, sizeof (buf), "%02" PRIu32 ":%02" PRIu32 ":%02" PRIu32 ":%02" PRIu32, smpte.hours, smpte.minutes, smpte.seconds, smpte.frames);
 }
 
 void
index 6351aa9825924ab3854b9cdf65baa14346de9260..ee751b9af7c73aeb11ae1ebe97b1b54b8c5baba5 100644 (file)
@@ -27,7 +27,6 @@
 
 #include <ardour/session.h>
 #include <ardour/audioregion.h>
-#include <ardour/filesource.h>
 #include <ardour/sndfilesource.h>
 
 #include "i18n.h"
@@ -80,7 +79,10 @@ Session::tempoize_region (TimeStretchRequest& tsr)
                }
 
                try {
-                       sources.push_back(new FileSource (path, frame_rate(), false, Config->get_native_file_data_format()));
+                       sources.push_back (new SndFileSource (path, 
+                                                             Config->get_native_file_data_format(),
+                                                             Config->get_native_file_header_format(),
+                                                             frame_rate()));
                } catch (failed_constructor& err) {
                        error << string_compose (_("tempoize: error creating new audio file %1 (%2)"), path, strerror (errno)) << endmsg;
                        goto out;
@@ -150,13 +152,16 @@ Session::tempoize_region (TimeStretchRequest& tsr)
        xnow = localtime (&now);
 
        for (it = sources.begin(); it != sources.end(); ++it) {
-               dynamic_cast<FileSource*>(*it)->update_header (tsr.region->position(), *xnow, now);
+               AudioFileSource* afs = dynamic_cast<AudioFileSource*>(*it);
+               if (afs) {
+                       afs->update_header (tsr.region->position(), *xnow, now);
+               }
        }
 
        region_name = tsr.region->name() + X_(".t");
 
        r = new AudioRegion (sources, 0, sources.front()->length(), region_name,
-                       0, AudioRegion::Flag (AudioRegion::DefaultFlags | AudioRegion::WholeFile));
+                            0, AudioRegion::Flag (AudioRegion::DefaultFlags | AudioRegion::WholeFile));
 
 
   out:
index fafaf2a4754fbb415280390f69074d2a7d35aaea..c05f8f40546119b0e57c2df13ecaf2fecceef86e 100644 (file)
@@ -36,7 +36,7 @@
 #include <ardour/ardour.h>
 #include <ardour/audioengine.h>
 #include <ardour/session.h>
-#include <ardour/diskstream.h>
+#include <ardour/audio_diskstream.h>
 #include <ardour/auditioner.h>
 #include <ardour/slave.h>
 #include <ardour/location.h>
@@ -78,7 +78,7 @@ Session::request_transport_speed (float speed)
 }
 
 void
-Session::request_diskstream_speed (DiskStream& ds, float speed)
+Session::request_diskstream_speed (AudioDiskstream& ds, float speed)
 {
        Event* ev = new Event (Event::SetDiskstreamSpeed, Event::Add, Event::Immediate, 0, speed);
        ev->set_ptr (&ds);
@@ -200,7 +200,7 @@ Session::butler_transport_work ()
        }
 
        if (post_transport_work & PostTransportInputChange) {
-               for (DiskStreamList::iterator i = diskstreams.begin(); i != diskstreams.end(); ++i) {
+               for (AudioDiskstreamList::iterator i = audio_diskstreams.begin(); i != audio_diskstreams.end(); ++i) {
                        (*i)->non_realtime_input_change ();
                }
        }
@@ -216,7 +216,7 @@ Session::butler_transport_work ()
                cumulative_rf_motion = 0;
                reset_rf_scale (0);
 
-               for (DiskStreamList::iterator i = diskstreams.begin(); i != diskstreams.end(); ++i) {
+               for (AudioDiskstreamList::iterator i = audio_diskstreams.begin(); i != audio_diskstreams.end(); ++i) {
                        if (!(*i)->hidden()) {
                                if ((*i)->speed() != 1.0f || (*i)->speed() != -1.0f) {
                                        (*i)->seek ((jack_nframes_t) (_transport_frame * (double) (*i)->speed()));
@@ -248,7 +248,7 @@ Session::non_realtime_set_speed ()
 {
        Glib::RWLock::ReaderLock lm (diskstream_lock);
 
-       for (DiskStreamList::iterator i = diskstreams.begin(); i != diskstreams.end(); ++i) {
+       for (AudioDiskstreamList::iterator i = audio_diskstreams.begin(); i != audio_diskstreams.end(); ++i) {
                (*i)->non_realtime_set_speed ();
        }
 }
@@ -258,7 +258,7 @@ Session::non_realtime_overwrite ()
 {
        Glib::RWLock::ReaderLock lm (diskstream_lock);
 
-       for (DiskStreamList::iterator i = diskstreams.begin(); i != diskstreams.end(); ++i) {
+       for (AudioDiskstreamList::iterator i = audio_diskstreams.begin(); i != audio_diskstreams.end(); ++i) {
                if ((*i)->pending_overwrite) {
                        (*i)->overwrite_existing_buffers ();
                }
@@ -274,7 +274,7 @@ Session::non_realtime_stop (bool abort)
        
        did_record = false;
        
-       for (DiskStreamList::iterator i = diskstreams.begin(); i != diskstreams.end(); ++i) {
+       for (AudioDiskstreamList::iterator i = audio_diskstreams.begin(); i != audio_diskstreams.end(); ++i) {
                if ((*i)->get_captured_frames () != 0) {
                        did_record = true;
                        break;
@@ -327,7 +327,7 @@ Session::non_realtime_stop (bool abort)
                _have_captured = true;
        }
 
-       for (DiskStreamList::iterator i = diskstreams.begin(); i != diskstreams.end(); ++i) {
+       for (AudioDiskstreamList::iterator i = audio_diskstreams.begin(); i != audio_diskstreams.end(); ++i) {
                (*i)->transport_stopped (*now, xnow, abort);
        }
        
@@ -364,7 +364,7 @@ Session::non_realtime_stop (bool abort)
        }
 #endif
 
-               for (DiskStreamList::iterator i = diskstreams.begin(); i != diskstreams.end(); ++i) {
+               for (AudioDiskstreamList::iterator i = audio_diskstreams.begin(); i != audio_diskstreams.end(); ++i) {
                        if (!(*i)->hidden()) {
                                if ((*i)->speed() != 1.0f || (*i)->speed() != -1.0f) {
                                        (*i)->seek ((jack_nframes_t) (_transport_frame * (double) (*i)->speed()));
@@ -494,7 +494,7 @@ Session::set_auto_loop (bool yn)
 
                        if (seamless_loop) {
                                // set all diskstreams to use internal looping
-                               for (DiskStreamList::iterator i = diskstreams.begin(); i != diskstreams.end(); ++i) {
+                               for (AudioDiskstreamList::iterator i = audio_diskstreams.begin(); i != audio_diskstreams.end(); ++i) {
                                        if (!(*i)->hidden()) {
                                                (*i)->set_loop (loc);
                                        }
@@ -502,7 +502,7 @@ Session::set_auto_loop (bool yn)
                        }
                        else {
                                // set all diskstreams to NOT use internal looping
-                               for (DiskStreamList::iterator i = diskstreams.begin(); i != diskstreams.end(); ++i) {
+                               for (AudioDiskstreamList::iterator i = audio_diskstreams.begin(); i != audio_diskstreams.end(); ++i) {
                                        if (!(*i)->hidden()) {
                                                (*i)->set_loop (0);
                                        }
@@ -532,7 +532,7 @@ Session::set_auto_loop (bool yn)
                clear_events (Event::AutoLoop);
 
                // set all diskstreams to NOT use internal looping
-               for (DiskStreamList::iterator i = diskstreams.begin(); i != diskstreams.end(); ++i) {
+               for (AudioDiskstreamList::iterator i = audio_diskstreams.begin(); i != audio_diskstreams.end(); ++i) {
                        if (!(*i)->hidden()) {
                                (*i)->set_loop (0);
                        }
@@ -653,7 +653,7 @@ Session::locate (jack_nframes_t target_frame, bool with_roll, bool with_flush, b
                           The rarity and short potential lock duration makes this "OK"
                        */
                        Glib::RWLock::ReaderLock dsm (diskstream_lock);
-                       for (DiskStreamList::iterator i = diskstreams.begin(); i != diskstreams.end(); ++i) {
+                       for (AudioDiskstreamList::iterator i = audio_diskstreams.begin(); i != audio_diskstreams.end(); ++i) {
                                if ((*i)->record_enabled ()) {
                                        //cerr << "switching from input" << __FILE__ << __LINE__ << endl << endl;
                                        (*i)->monitor_input (!auto_input);
@@ -668,7 +668,7 @@ Session::locate (jack_nframes_t target_frame, bool with_roll, bool with_flush, b
                           The rarity and short potential lock duration makes this "OK"
                        */
                        Glib::RWLock::ReaderLock dsm (diskstream_lock);
-                       for (DiskStreamList::iterator i = diskstreams.begin(); i != diskstreams.end(); ++i) {
+                       for (AudioDiskstreamList::iterator i = audio_diskstreams.begin(); i != audio_diskstreams.end(); ++i) {
                                if ((*i)->record_enabled ()) {
                                        //cerr << "switching to input" << __FILE__ << __LINE__ << endl << endl;
                                        (*i)->monitor_input (true);
@@ -714,7 +714,7 @@ Session::set_transport_speed (float speed, bool abort)
                           The rarity and short potential lock duration makes this "OK"
                        */
                        Glib::RWLock::ReaderLock dsm (diskstream_lock);
-                       for (DiskStreamList::iterator i = diskstreams.begin(); i != diskstreams.end(); ++i) {
+                       for (AudioDiskstreamList::iterator i = audio_diskstreams.begin(); i != audio_diskstreams.end(); ++i) {
                                if ((*i)->record_enabled ()) {
                                        //cerr << "switching to input" << __FILE__ << __LINE__ << endl << endl;
                                        (*i)->monitor_input (true);     
@@ -740,7 +740,7 @@ Session::set_transport_speed (float speed, bool abort)
                           The rarity and short potential lock duration makes this "OK"
                        */
                        Glib::RWLock::ReaderLock dsm (diskstream_lock);
-                       for (DiskStreamList::iterator i = diskstreams.begin(); i != diskstreams.end(); ++i) {
+                       for (AudioDiskstreamList::iterator i = audio_diskstreams.begin(); i != audio_diskstreams.end(); ++i) {
                                if (auto_input && (*i)->record_enabled ()) {
                                        //cerr << "switching from input" << __FILE__ << __LINE__ << endl << endl;
                                        (*i)->monitor_input (false);    
@@ -791,7 +791,7 @@ Session::set_transport_speed (float speed, bool abort)
                _last_transport_speed = _transport_speed;
                _transport_speed = speed;
                
-               for (DiskStreamList::iterator i = diskstreams.begin(); i != diskstreams.end(); ++i) {
+               for (AudioDiskstreamList::iterator i = audio_diskstreams.begin(); i != audio_diskstreams.end(); ++i) {
                        if ((*i)->realtime_set_speed ((*i)->speed(), true)) {
                                post_transport_work = PostTransportWork (post_transport_work | PostTransportSpeed);
                        }
@@ -881,7 +881,7 @@ Session::actually_start_transport ()
        transport_sub_state |= PendingDeclickIn;
        _transport_speed = 1.0;
        
-       for (DiskStreamList::iterator i = diskstreams.begin(); i != diskstreams.end(); ++i) {
+       for (AudioDiskstreamList::iterator i = audio_diskstreams.begin(); i != audio_diskstreams.end(); ++i) {
                (*i)->realtime_set_speed ((*i)->speed(), true);
        }
 
@@ -1016,7 +1016,7 @@ Session::set_slave_source (SlaveSource src, jack_nframes_t frame)
        
        _slave_type = src;
 
-       for (DiskStreamList::iterator i = diskstreams.begin(); i != diskstreams.end(); ++i) {
+       for (AudioDiskstreamList::iterator i = audio_diskstreams.begin(); i != audio_diskstreams.end(); ++i) {
                if (!(*i)->hidden()) {
                        if ((*i)->realtime_set_speed ((*i)->speed(), true)) {
                                non_rt_required = true;
@@ -1048,7 +1048,7 @@ Session::reverse_diskstream_buffers ()
 }
 
 void
-Session::set_diskstream_speed (DiskStream* stream, float speed)
+Session::set_diskstream_speed (AudioDiskstream* stream, float speed)
 {
        if (stream->realtime_set_speed (speed, false)) {
                post_transport_work = PostTransportWork (post_transport_work | PostTransportSpeed);
@@ -1244,7 +1244,7 @@ Session::update_latency_compensation (bool with_stop, bool abort)
        /* reflect any changes in latencies into capture offsets
        */
        
-       for (DiskStreamList::iterator i = diskstreams.begin(); i != diskstreams.end(); ++i) {
+       for (AudioDiskstreamList::iterator i = audio_diskstreams.begin(); i != audio_diskstreams.end(); ++i) {
                (*i)->set_capture_offset ();
        }
 }
index 87f7faf423dff8330f8c83f4a8976233044e2276..692938514181edf328aa5a873570726ad6f1046d 100644 (file)
     $Id$
 */
 
+#include <cerrno>
+#include <climits>
+
+#include <pwd.h>
+#include <sys/utsname.h>
+
+#include <glibmm/miscutils.h>
+
 #include <ardour/sndfilesource.h>
 
 #include "i18n.h"
 
+using namespace std;
 using namespace ARDOUR;
 
 SndFileSource::SndFileSource (const XMLNode& node)
-       : ExternalSource (node)
+       : AudioFileSource (node)
 {
-       init (_name, true);
-       SourceCreated (this); /* EMIT SIGNAL */
+       init (_name);
+
+       if (open()) {
+               throw failed_constructor ();
+       }
+
+       if (_build_peakfiles) {
+               if (initialize_peakfile (false, _path)) {
+                       sf_close (sf);
+                       sf = 0;
+                       throw failed_constructor ();
+               }
+       }
+
+       AudioSourceCreated (this); /* EMIT SIGNAL */
 }
 
-SndFileSource::SndFileSource (const string& idstr, bool build_peak)
-       : ExternalSource(idstr, build_peak)
+SndFileSource::SndFileSource (string idstr, Flag flags)
+       : AudioFileSource (idstr, Flag (flags & ~(Writable|Removable|RemovableIfEmpty|RemoveAtDestroy)))
 {
-       init (idstr, build_peak);
+       init (idstr);
 
-       if (build_peak) {
-                SourceCreated (this); /* EMIT SIGNAL */
+       if (open()) {
+               throw failed_constructor ();
        }
+
+       if (_build_peakfiles) {
+               if (initialize_peakfile (false, _path)) {
+                       sf_close (sf);
+                       sf = 0;
+                       throw failed_constructor ();
+               }
+       }
+
+
+       AudioSourceCreated (this); /* EMIT SIGNAL */
+}
+
+SndFileSource::SndFileSource (string idstr, SampleFormat sfmt, HeaderFormat hf, jack_nframes_t rate, Flag flags)
+       : AudioFileSource(idstr, flags, sfmt, hf)
+{
+       int fmt = 0;
+
+       init (idstr);
+
+       cerr << "creating " << idstr << " hf = " << hf << endl;
+
+       switch (hf) {
+       case CAF:
+               fmt = SF_FORMAT_CAF;
+               _flags = Flag (_flags & ~Broadcast);
+               break;
+
+       case AIFF:
+               fmt = SF_FORMAT_AIFF;
+               _flags = Flag (_flags & ~Broadcast);
+               break;
+
+       case BWF:
+               fmt = SF_FORMAT_WAV;
+               _flags = Flag (_flags | Broadcast);
+               break;
+
+       case WAVE:
+               fmt = SF_FORMAT_WAV;
+               _flags = Flag (_flags & ~Broadcast);
+               break;
+
+       case WAVE64:
+               fmt = SF_FORMAT_W64;
+               _flags = Flag (_flags & ~Broadcast);
+               break;
+
+       default:
+               fatal << string_compose (_("programming error: %1"), X_("unsupported audio header format requested")) << endmsg;
+               /*NOTREACHED*/
+               break;
+
+       }
+
+       switch (sfmt) {
+       case FormatFloat:
+               fmt |= SF_FORMAT_FLOAT;
+               break;
+
+       case FormatInt24:
+               fmt |= SF_FORMAT_PCM_24;
+               break;
+       }
+       
+       _info.channels = 1;
+       _info.samplerate = rate;
+       _info.format = fmt;
+
+       if (open()) {
+               throw failed_constructor();
+       }
+
+       if (writable() && (_flags & Broadcast)) {
+
+               _broadcast_info = new SF_BROADCAST_INFO;
+               memset (_broadcast_info, 0, sizeof (*_broadcast_info));
+               
+               snprintf (_broadcast_info->description, sizeof (_broadcast_info->description), "BWF %s", _name.c_str());
+               
+               struct utsname utsinfo;
+
+               if (uname (&utsinfo)) {
+                       error << string_compose(_("FileSource: cannot get host information for BWF header (%1)"), strerror(errno)) << endmsg;
+                       return;
+               }
+               
+               snprintf (_broadcast_info->originator, sizeof (_broadcast_info->originator), "ardour:%s:%s:%s:%s:%s)", 
+                         Glib::get_real_name().c_str(),
+                         utsinfo.nodename,
+                         utsinfo.sysname,
+                         utsinfo.release,
+                         utsinfo.version);
+               
+               _broadcast_info->version = 1;  
+               
+               /* XXX do something about this field */
+               
+               snprintf (_broadcast_info->umid, sizeof (_broadcast_info->umid), "%s", "fnord");
+               
+               /* coding history is added by libsndfile */
+
+               if (sf_command (sf, SFC_SET_BROADCAST_INFO, _broadcast_info, sizeof (_broadcast_info)) != SF_TRUE) {
+                       char errbuf[256];
+                       sf_error_str (0, errbuf, sizeof (errbuf) - 1);
+                       error << string_compose (_("cannot set broadcast info for audio file %1 (%2); dropping broadcast info for this file"), _path, errbuf) << endmsg;
+                       _flags = Flag (_flags & ~Broadcast);
+                       delete _broadcast_info;
+                       _broadcast_info = 0;
+               }
+       }
+       
+       if (_build_peakfiles) {
+               if (initialize_peakfile (false, _path)) {
+                       sf_close (sf);
+                       sf = 0;
+                       throw failed_constructor ();
+               }
+       }
+
+       /* since SndFileSource's constructed with this constructor can be writable, make sure we update if the header info changes */
+
+       if (writable()) {
+               HeaderPositionOffsetChanged.connect (mem_fun (*this, &AudioFileSource::handle_header_position_change));
+       }
+
+       if (_build_peakfiles) {
+               if (initialize_peakfile (false, _path)) {
+                       sf_close (sf);
+                       sf = 0;
+                       throw failed_constructor ();
+               }
+       }
+
+       AudioSourceCreated (this); /* EMIT SIGNAL */
 }
 
 void 
-SndFileSource::init (const string& idstr, bool build_peak)
+SndFileSource::init (const string& idstr)
 {
        string::size_type pos;
        string file;
 
-       tmpbuf = 0;
-       tmpbufsize = 0;
+       interleave_buf = 0;
+       interleave_bufsize = 0;
        sf = 0;
-
-       _name = idstr;
+       _broadcast_info = 0;
 
        if ((pos = idstr.find_last_of (':')) == string::npos) {
                channel = 0;
-               file = idstr;
+               _name = Glib::path_get_basename (idstr);
        } else {
                channel = atoi (idstr.substr (pos+1).c_str());
-               file = idstr.substr (0, pos);
+               _name = Glib::path_get_basename (idstr.substr (0, pos));
        }
 
        /* although libsndfile says we don't need to set this,
@@ -66,46 +222,56 @@ SndFileSource::init (const string& idstr, bool build_peak)
        */
 
        memset (&_info, 0, sizeof(_info));
+}
 
-       /* note that we temporarily truncated _id at the colon */
-       
-       if ((sf = sf_open (file.c_str(), SFM_READ, &_info)) == 0) {
+int
+SndFileSource::open ()
+{
+       if ((sf = sf_open (_path.c_str(), (writable() ? SFM_RDWR : SFM_READ), &_info)) == 0) {
                char errbuf[256];
                sf_error_str (0, errbuf, sizeof (errbuf) - 1);
-               error << string_compose(_("SndFileSource: cannot open file \"%1\" (%2)"), file, errbuf) << endmsg;
-               throw failed_constructor();
+               error << string_compose(_("SndFileSource: cannot open file \"%1\" for %2 (%3)"), 
+                                       _path, (writable() ? "read+write" : "reading"), errbuf) << endmsg;
+               return -1;
        }
 
        if (channel >= _info.channels) {
                error << string_compose(_("SndFileSource: file only contains %1 channels; %2 is invalid as a channel number"), _info.channels, channel) << endmsg;
                sf_close (sf);
                sf = 0;
-               throw failed_constructor();
+               return -1;
        }
 
        _length = _info.frames;
-       _path = file;
 
-       if (build_peak) {
-               if (initialize_peakfile (false, _path)) {
-                       sf_close (sf);
-                       sf = 0;
-                       throw failed_constructor ();
-               }
+       if (writable()) {
+               sf_command (sf, SFC_SET_UPDATE_HEADER_AUTO, 0, SF_FALSE);
+       }
+
+       return 0;
+}
+
+void
+SndFileSource::close ()
+{
+       if (sf) {
+               sf_close (sf);
+               sf = 0;
        }
 }
 
 SndFileSource::~SndFileSource ()
-
 {
        GoingAway (this); /* EMIT SIGNAL */
 
-       if (sf) {
-               sf_close (sf);
+       close ();
+
+       if (interleave_buf) {
+               delete [] interleave_buf;
        }
 
-       if (tmpbuf) {
-               delete [] tmpbuf;
+       if (_broadcast_info) {
+               delete [] _broadcast_info;
        }
 }
 
@@ -116,49 +282,73 @@ SndFileSource::sample_rate () const
 }
 
 jack_nframes_t
-SndFileSource::read (Sample *dst, jack_nframes_t start, jack_nframes_t cnt, char * workbuf) const
+SndFileSource::read_unlocked (Sample *dst, jack_nframes_t start, jack_nframes_t cnt, char * workbuf) const
 {
        int32_t nread;
        float *ptr;
        uint32_t real_cnt;
+       jack_nframes_t file_cnt;
 
-       if (sf_seek (sf, (off_t) start, SEEK_SET) < 0) {
-               char errbuf[256];
-               sf_error_str (0, errbuf, sizeof (errbuf) - 1);
-               error << string_compose(_("SndFileSource: could not seek to frame %1 within %2 (%3)"), start, _name.substr (1), errbuf) << endmsg;
-               return 0;
-       }
+       if (start > _length) {
 
-       if (_info.channels == 1) {
-               jack_nframes_t ret = sf_read_float (sf, dst, cnt);
-               _read_data_count = cnt * sizeof(float);
-               return ret;
-       }
+               /* read starts beyond end of data, just memset to zero */
+               
+               file_cnt = 0;
 
-       real_cnt = cnt * _info.channels;
+       } else if (start + cnt > _length) {
+               
+               /* read ends beyond end of data, read some, memset the rest */
+               
+               file_cnt = _length - start;
 
-       {
-               Glib::Mutex::Lock lm (_tmpbuf_lock);
+       } else {
                
-               if (tmpbufsize < real_cnt) {
-                       
-                       if (tmpbuf) {
-                               delete [] tmpbuf;
-                       }
-                       tmpbufsize = real_cnt;
-                       tmpbuf = new float[tmpbufsize];
+               /* read is entirely within data */
+
+               file_cnt = cnt;
+       }
+       
+       if (file_cnt) {
+
+               if (sf_seek (sf, (off_t) start, SEEK_SET) < 0) {
+                       char errbuf[256];
+                       sf_error_str (0, errbuf, sizeof (errbuf) - 1);
+                       error << string_compose(_("SndFileSource: could not seek to frame %1 within %2 (%3)"), start, _name.substr (1), errbuf) << endmsg;
+                       return 0;
                }
                
-               nread = sf_read_float (sf, tmpbuf, real_cnt);
-               ptr = tmpbuf + channel;
-               nread /= _info.channels;
-               
-               /* stride through the interleaved data */
+               if (_info.channels == 1) {
+                       jack_nframes_t ret = sf_read_float (sf, dst, file_cnt);
+                       _read_data_count = cnt * sizeof(float);
+                       return ret;
+               }
+       }
+
+       if (file_cnt != cnt) {
+               jack_nframes_t delta = cnt - file_cnt;
+               memset (dst+file_cnt, 0, sizeof (Sample) * delta);
+       }
+
+       real_cnt = cnt * _info.channels;
+
+       if (interleave_bufsize < real_cnt) {
                
-               for (int32_t n = 0; n < nread; ++n) {
-                       dst[n] = *ptr;
-                       ptr += _info.channels;
+               if (interleave_buf) {
+                       delete [] interleave_buf;
                }
+               interleave_bufsize = real_cnt;
+               interleave_buf = new float[interleave_bufsize];
+       }
+       
+       nread = sf_read_float (sf, interleave_buf, real_cnt);
+       ptr = interleave_buf + channel;
+       nread /= _info.channels;
+       
+       /* stride through the interleaved data */
+       
+       for (int32_t n = 0; n < nread; ++n) {
+               dst[n] = *ptr;
+               ptr += _info.channels;
        }
 
        _read_data_count = cnt * sizeof(float);
@@ -166,3 +356,163 @@ SndFileSource::read (Sample *dst, jack_nframes_t start, jack_nframes_t cnt, char
        return nread;
 }
 
+jack_nframes_t 
+SndFileSource::write_unlocked (Sample *data, jack_nframes_t cnt, char * workbuf)
+{
+       if (!writable()) {
+               return 0;
+       }
+
+       if (_info.channels != 1) {
+               fatal << string_compose (_("programming error: %1 %2"), X_("SndFileSource::write called on non-mono file"), _path) << endmsg;
+               /*NOTREACHED*/
+               return 0;
+       }
+       
+       jack_nframes_t oldlen;
+       int32_t frame_pos = _length;
+       
+       if (write_float (data, frame_pos, cnt) != cnt) {
+               return 0;
+       }
+
+       oldlen = _length;
+       update_length (oldlen, cnt);
+
+       if (_build_peakfiles) {
+               PeakBuildRecord *pbr = 0;
+               
+               if (pending_peak_builds.size()) {
+                               pbr = pending_peak_builds.back();
+                       }
+                       
+                       if (pbr && pbr->frame + pbr->cnt == oldlen) {
+                               
+                               /* the last PBR extended to the start of the current write,
+                                  so just extend it again.
+                               */
+
+                               pbr->cnt += cnt;
+                       } else {
+                               pending_peak_builds.push_back (new PeakBuildRecord (oldlen, cnt));
+                       }
+                       
+                       _peaks_built = false;
+       }
+       
+       
+       if (_build_peakfiles) {
+               queue_for_peaks (*this);
+       }
+
+       _write_data_count = cnt;
+       
+       return cnt;
+}
+
+int
+SndFileSource::update_header (jack_nframes_t when, struct tm& now, time_t tnow)
+{      
+       /* allow derived classes to override how this is done */
+
+       set_timeline_position (when);
+
+       if (_flags & Broadcast) {
+               /* this will flush the header implicitly */
+               return setup_broadcast_info (when, now, tnow);
+       } else {
+               return flush_header ();
+       }
+}
+
+int
+SndFileSource::flush_header ()
+{
+       return (sf_command (sf, SFC_UPDATE_HEADER_NOW, 0, 0) != SF_TRUE);
+}
+
+int
+SndFileSource::setup_broadcast_info (jack_nframes_t when, struct tm& now, time_t tnow)
+{
+       /* random code is 9 digits */
+       
+       int random_code = random() % 999999999;
+       
+       snprintf (_broadcast_info->originator_reference, sizeof (_broadcast_info->originator_reference), "%2s%3s%12s%02d%02d%02d%9d",
+                 bwf_country_code,
+                 bwf_organization_code,
+                 bwf_serial_number,
+                 now.tm_hour,
+                 now.tm_min,
+                 now.tm_sec,
+                 random_code);
+       
+       snprintf (_broadcast_info->origination_date, sizeof (_broadcast_info->origination_date), "%4d-%02d-%02d",
+                 1900 + now.tm_year,
+                 now.tm_mon,
+                 now.tm_mday);
+       
+       snprintf (_broadcast_info->origination_time, sizeof (_broadcast_info->origination_time), "%02d-%02d-%02d",
+                 now.tm_hour,
+                 now.tm_min,
+                 now.tm_sec);
+
+       /* now update header position taking header offset into account */
+       
+       set_header_timeline_position ();
+
+       /* note that libsndfile flushes the header to disk when resetting the broadcast info */
+
+       if (sf_command (sf, SFC_SET_BROADCAST_INFO, _broadcast_info, sizeof (*_broadcast_info)) != SF_TRUE) {
+               error << string_compose (_("cannot set broadcast info for audio file %1; Dropping broadcast info for this file"), _path) << endmsg;
+               _flags = Flag (_flags & ~Broadcast);
+               delete _broadcast_info;
+               _broadcast_info = 0;
+               return -1;
+       }
+
+       return 0;
+}
+
+void
+SndFileSource::set_header_timeline_position ()
+{
+       uint64_t pos;
+
+       _broadcast_info->time_reference_high = 0;
+
+       if (header_position_negative) {
+
+               if (ULONG_LONG_MAX - header_position_offset < timeline_position) {
+                       pos = ULONG_LONG_MAX; // impossible
+               } else {
+                       pos = timeline_position + header_position_offset;
+               }
+
+       } else {
+
+               if (timeline_position < header_position_offset) {
+                       pos = 0;
+               } else {
+                       pos = timeline_position - header_position_offset;
+               }
+       }
+
+       _broadcast_info->time_reference_high = (pos >> 32);
+       _broadcast_info->time_reference_low = (pos & 0xffffffff);
+}
+
+jack_nframes_t
+SndFileSource::write_float (Sample* data, jack_nframes_t frame_pos, jack_nframes_t cnt)
+{
+       if (sf_seek (sf, frame_pos, SEEK_SET) != frame_pos) {
+               error << string_compose (_("%1: cannot seek to %2"), _path, frame_pos) << endmsg;
+               return 0;
+       }
+       
+       if (sf_writef_float (sf, data, cnt) != (ssize_t) cnt) {
+               return 0;
+       }
+       
+       return cnt;
+}
index 7d790a036d7f24c6a345872bb36925076a7cc543..0d32ea4a216ec6134dbb93281819747bd24ec8c5 100644 (file)
@@ -42,35 +42,18 @@ using std::max;
 
 using namespace ARDOUR;
 
-sigc::signal<void,Source *>  Source::SourceCreated;
-pthread_t                    Source::peak_thread;
-bool                         Source::have_peak_thread = false;
-vector<Source*>              Source::pending_peak_sources;
-Glib::StaticMutex            Source::pending_peak_sources_lock = GLIBMM_STATIC_MUTEX_INIT;
-int                          Source::peak_request_pipe[2];
-
-bool Source::_build_missing_peakfiles = false;
-bool Source::_build_peakfiles = false;
-
-Source::Source (bool announce)
+Source::Source (string name)
 {
+       _name = name;
        _id = ARDOUR::new_id();
        _use_cnt = 0;
-       _peaks_built = false;
-       next_peak_clear_should_notify = true;
        _timestamp = 0;
-       _read_data_count = 0;
-       _write_data_count = 0;
 }
 
 Source::Source (const XMLNode& node) 
 {
        _use_cnt = 0;
-       _peaks_built = false;
-       next_peak_clear_should_notify = true;
        _timestamp = 0;
-       _read_data_count = 0;
-       _write_data_count = 0;
 
        if (set_state (node)) {
                throw failed_constructor();
@@ -96,10 +79,6 @@ Source::get_state ()
                node->add_property ("timestamp", buf);
        }
 
-       if (_captured_for.length()) {
-               node->add_property ("captured-for", _captured_for);
-       }
-
        return *node;
 }
 
@@ -124,734 +103,9 @@ Source::set_state (const XMLNode& node)
                sscanf (prop->value().c_str(), "%ld", &_timestamp);
        }
 
-       if ((prop = node.property ("captured-for")) != 0) {
-               _captured_for = prop->value();
-       }
-
-       return 0;
-}
-
-/***********************************************************************
-  PEAK FILE STUFF
- ***********************************************************************/
-
-void*
-Source::peak_thread_work (void* arg)
-{
-       PBD::ThreadCreated (pthread_self(), X_("Peak"));
-       struct pollfd pfd[1];
-
-       Glib::Mutex::Lock lm (pending_peak_sources_lock);
-
-       while (true) {
-
-               pfd[0].fd = peak_request_pipe[0];
-               pfd[0].events = POLLIN|POLLERR|POLLHUP;
-
-               pending_peak_sources_lock.unlock();
-
-               if (poll (pfd, 1, -1) < 0) {
-
-                       if (errno == EINTR) {
-                               pending_peak_sources_lock.lock();
-                               continue;
-                       }
-                       
-                       error << string_compose (_("poll on peak request pipe failed (%1)"),
-                                         strerror (errno))
-                             << endmsg;
-                       break;
-               }
-
-               if (pfd[0].revents & ~POLLIN) {
-                       error << _("Error on peak thread request pipe") << endmsg;
-                       break;
-               }
-
-               if (pfd[0].revents & POLLIN) {
-
-                       char req;
-                       
-                       /* empty the pipe of all current requests */
-
-                       while (1) {
-                               size_t nread = ::read (peak_request_pipe[0], &req, sizeof (req));
-
-                               if (nread == 1) {
-                                       switch ((PeakRequest::Type) req) {
-                                       
-                                       case PeakRequest::Build:
-                                               break;
-                                               
-                                       case PeakRequest::Quit:
-                                               pthread_exit_pbd (0);
-                                               /*NOTREACHED*/
-                                               break;
-                                               
-                                       default:
-                                               break;
-                                       }
-
-                               } else if (nread == 0) {
-                                       break;
-                               } else if (errno == EAGAIN) {
-                                       break;
-                               } else {
-                                       fatal << _("Error reading from peak request pipe") << endmsg;
-                                       /*NOTREACHED*/
-                               }
-                       }
-               }
-
-               pending_peak_sources_lock.lock();
-
-               while (!pending_peak_sources.empty()) {
-
-                       Source* s = pending_peak_sources.front();
-                       pending_peak_sources.erase (pending_peak_sources.begin());
-
-                       pending_peak_sources_lock.unlock();
-                       s->build_peaks();
-                       pending_peak_sources_lock.lock();
-               }
-       }
-
-       pthread_exit_pbd (0);
-       /*NOTREACHED*/
-       return 0;
-}
-
-int
-Source::start_peak_thread ()
-{
-       if (!_build_peakfiles) {
-               return 0;
-       }
-
-       if (pipe (peak_request_pipe)) {
-               error << string_compose(_("Cannot create transport request signal pipe (%1)"), strerror (errno)) << endmsg;
-               return -1;
-       }
-
-       if (fcntl (peak_request_pipe[0], F_SETFL, O_NONBLOCK)) {
-               error << string_compose(_("UI: cannot set O_NONBLOCK on peak request pipe (%1)"), strerror (errno)) << endmsg;
-               return -1;
-       }
-
-       if (fcntl (peak_request_pipe[1], F_SETFL, O_NONBLOCK)) {
-               error << string_compose(_("UI: cannot set O_NONBLOCK on peak request pipe (%1)"), strerror (errno)) << endmsg;
-               return -1;
-       }
-
-       if (pthread_create_and_store ("peak file builder", &peak_thread, 0, peak_thread_work, 0)) {
-               error << _("Source: could not create peak thread") << endmsg;
-               return -1;
-       }
-
-       have_peak_thread = true;
        return 0;
 }
 
-void
-Source::stop_peak_thread ()
-{
-       if (!have_peak_thread) {
-               return;
-       }
-
-       void* status;
-
-       char c = (char) PeakRequest::Quit;
-       ::write (peak_request_pipe[1], &c, 1);
-       pthread_join (peak_thread, &status);
-}
-
-void 
-Source::queue_for_peaks (Source& source)
-{
-       if (have_peak_thread) {
-
-               Glib::Mutex::Lock lm (pending_peak_sources_lock);
-
-               source.next_peak_clear_should_notify = true;
-
-               if (find (pending_peak_sources.begin(),
-                         pending_peak_sources.end(),
-                         &source) == pending_peak_sources.end()) {
-                       pending_peak_sources.push_back (&source);
-               }
-
-               char c = (char) PeakRequest::Build;
-               ::write (peak_request_pipe[1], &c, 1);
-       }
-}
-
-void Source::clear_queue_for_peaks ()
-{
-       /* this is done to cancel a group of running peak builds */
-       if (have_peak_thread) {
-               Glib::Mutex::Lock lm (pending_peak_sources_lock);
-               pending_peak_sources.clear ();
-       }
-}
-
-
-bool
-Source::peaks_ready (sigc::slot<void> the_slot, sigc::connection& conn) const
-{
-       bool ret;
-       Glib::Mutex::Lock lm (_lock);
-
-       /* check to see if the peak data is ready. if not
-          connect the slot while still holding the lock.
-       */
-
-       if (!(ret = _peaks_built)) {
-               conn = PeaksReady.connect (the_slot);
-       }
-
-       return ret;
-}
-
-int
-Source::rename_peakfile (string newpath)
-{
-       /* caller must hold _lock */
-
-       string oldpath = peakpath;
-
-       if (access (oldpath.c_str(), F_OK) == 0) {
-               if (rename (oldpath.c_str(), newpath.c_str()) != 0) {
-                       error << string_compose (_("cannot rename peakfile for %1 from %2 to %3 (%4)"), _name, oldpath, newpath, strerror (errno)) << endmsg;
-                       return -1;
-               }
-       }
-
-       peakpath = newpath;
-
-       return 0;
-}
-
-int
-Source::initialize_peakfile (bool newfile, string audio_path)
-{
-       struct stat statbuf;
-
-       peakpath = peak_path (audio_path);
-
-       if (newfile) {
-
-               if (!_build_peakfiles) {
-                       return 0;
-               }
-
-               _peaks_built = false;
-
-       } else {
-
-               if (stat (peakpath.c_str(), &statbuf)) {
-                       if (errno != ENOENT) {
-                               /* it exists in the peaks dir, but there is some kind of error */
-                               
-                               error << string_compose(_("Source: cannot stat peakfile \"%1\""), peakpath) << endmsg;
-                               return -1;
-                       }
-
-               } else {
-                       
-                       /* we found it in the peaks dir */
-               }
-               
-               if (statbuf.st_size == 0) {
-                       _peaks_built = false;
-               } else {
-                       // Check if the audio file has changed since the peakfile was built.
-                       struct stat stat_file;
-                       int err = stat (audio_path.c_str(), &stat_file);
-                       
-                       if (!err && stat_file.st_mtime > statbuf.st_mtime){
-                               _peaks_built = false;
-                       } else {
-                               _peaks_built = true;
-                       }
-               }
-       }
-
-       if (!newfile && !_peaks_built && _build_missing_peakfiles && _build_peakfiles) {
-               build_peaks_from_scratch ();
-       } 
-
-       return 0;
-}
-
-int 
-Source::read_peaks (PeakData *peaks, jack_nframes_t npeaks, jack_nframes_t start, jack_nframes_t cnt, double samples_per_visual_peak) const
-{
-       Glib::Mutex::Lock lm (_lock);
-       double scale;
-       double expected_peaks;
-       PeakData::PeakDatum xmax;
-       PeakData::PeakDatum xmin;
-       int32_t to_read;
-       uint32_t nread;
-       jack_nframes_t zero_fill = 0;
-       int ret = -1;
-       PeakData* staging = 0;
-       Sample* raw_staging = 0;
-       char * workbuf = 0;
-       int peakfile = -1;
-
-       expected_peaks = (cnt / (double) frames_per_peak);
-       scale = npeaks/expected_peaks;
-
-#if 0
-       cerr << "======>RP: npeaks = " << npeaks 
-            << " start = " << start 
-            << " cnt = " << cnt 
-            << " len = " << _length 
-            << "   samples_per_visual_peak =" << samples_per_visual_peak 
-            << " expected was " << expected_peaks << " ... scale = " << scale
-            << " PD ptr = " << peaks
-            <<endl;
-       
-#endif
-
-       /* fix for near-end-of-file conditions */
-
-       if (cnt > _length - start) {
-               // cerr << "too close to end @ " << _length << " given " << start << " + " << cnt << endl;
-               cnt = _length - start;
-               jack_nframes_t old = npeaks;
-               npeaks = min ((jack_nframes_t) floor (cnt / samples_per_visual_peak), npeaks);
-               zero_fill = old - npeaks;
-       }
-
-       // cerr << "actual npeaks = " << npeaks << " zf = " << zero_fill << endl;
-       
-       if (npeaks == cnt) {
-
-               // cerr << "RAW DATA\n";
-               
-               /* no scaling at all, just get the sample data and duplicate it for
-                  both max and min peak values.
-               */
-
-               Sample* raw_staging = new Sample[cnt];
-               workbuf = new char[cnt*4];
-               
-               if (read_unlocked (raw_staging, start, cnt, workbuf) != cnt) {
-                       error << _("cannot read sample data for unscaled peak computation") << endmsg;
-                       return -1;
-               }
-
-               for (jack_nframes_t i = 0; i < npeaks; ++i) {
-                       peaks[i].max = raw_staging[i];
-                       peaks[i].min = raw_staging[i];
-               }
-
-               delete [] raw_staging;
-               delete [] workbuf;
-               return 0;
-       }
-
-       if (scale == 1.0) {
-
-               off_t first_peak_byte = (start / frames_per_peak) * sizeof (PeakData);
-
-               /* open, read, close */
-
-               if ((peakfile = ::open (peakpath.c_str(), O_RDWR|O_CREAT, 0664)) < 0) {
-                       error << string_compose(_("Source: cannot open peakpath \"%1\" (%2)"), peakpath, strerror (errno)) << endmsg;
-                       return -1;
-               }
-
-               // cerr << "DIRECT PEAKS\n";
-               
-               nread = ::pread (peakfile, peaks, sizeof (PeakData)* npeaks, first_peak_byte);
-               close (peakfile);
-
-               if (nread != sizeof (PeakData) * npeaks) {
-                       cerr << "Source["
-                            << _name
-                            << "]: cannot read peaks from peakfile! (read only " 
-                            << nread
-                            << " not " 
-                            << npeaks
-                             << "at sample " 
-                            << start
-                            << " = byte "
-                            << first_peak_byte
-                            << ')'
-                            << endl;
-                       return -1;
-               }
-
-               if (zero_fill) {
-                       memset (&peaks[npeaks], 0, sizeof (PeakData) * zero_fill);
-               }
-
-               return 0;
-       }
-
-
-       jack_nframes_t tnp;
-
-       if (scale < 1.0) {
-
-               // cerr << "DOWNSAMPLE\n";
-
-               /* the caller wants:
-
-                   - more frames-per-peak (lower resolution) than the peakfile, or to put it another way,
-                    - less peaks than the peakfile holds for the same range
-
-                   So, read a block into a staging area, and then downsample from there.
-
-                   to avoid confusion, I'll refer to the requested peaks as visual_peaks and the peakfile peaks as stored_peaks  
-               */
-
-               const uint32_t chunksize = (uint32_t) min (expected_peaks, 4096.0);
-               
-               staging = new PeakData[chunksize];
-               
-               /* compute the rounded up frame position  */
-       
-               jack_nframes_t current_frame = start;
-               jack_nframes_t current_stored_peak = (jack_nframes_t) ceil (current_frame / (double) frames_per_peak);
-               uint32_t       next_visual_peak  = (uint32_t) ceil (current_frame / samples_per_visual_peak);
-               double         next_visual_peak_frame = next_visual_peak * samples_per_visual_peak;
-               uint32_t       stored_peak_before_next_visual_peak = (jack_nframes_t) next_visual_peak_frame / frames_per_peak;
-               uint32_t       nvisual_peaks = 0;
-               uint32_t       stored_peaks_read = 0;
-               uint32_t       i = 0;
-
-               /* handle the case where the initial visual peak is on a pixel boundary */
-
-               current_stored_peak = min (current_stored_peak, stored_peak_before_next_visual_peak);
-
-               /* open ... close during out: handling */
-
-               if ((peakfile = ::open (peakpath.c_str(), O_RDWR|O_CREAT, 0664)) < 0) {
-                       error << string_compose(_("Source: cannot open peakpath \"%1\" (%2)"), peakpath, strerror (errno)) << endmsg;
-                       return 0;
-               }
-
-               while (nvisual_peaks < npeaks) {
-
-                       if (i == stored_peaks_read) {
-
-                               uint32_t       start_byte = current_stored_peak * sizeof(PeakData);
-                               tnp = min ((_length/frames_per_peak - current_stored_peak), (jack_nframes_t) expected_peaks);
-                               to_read = min (chunksize, tnp);
-                               
-                               off_t fend = lseek (peakfile, 0, SEEK_END);
-                               
-                               if ((nread = ::pread (peakfile, staging, sizeof (PeakData) * to_read, start_byte))
-                                   != sizeof (PeakData) * to_read) {
-                                       cerr << "Source["
-                                            << _name
-                                            << "]: cannot read peak data from peakfile ("
-                                            << (nread / sizeof(PeakData))
-                                            << " peaks instead of "
-                                            << to_read
-                                            << ") ("
-                                            << strerror (errno)
-                                            << ')'
-                                            << " at start_byte = " << start_byte 
-                                            << " _length = " << _length << " versus len = " << fend
-                                            << " expected maxpeaks = " << (_length - current_frame)/frames_per_peak
-                                            << " npeaks was " << npeaks
-                                            << endl;
-                                       goto out;
-                               }
-
-                               i = 0;
-                               stored_peaks_read = nread / sizeof(PeakData);
-                       }
-
-                       xmax = -1.0;
-                       xmin = 1.0;
-
-                       while ((i < stored_peaks_read) && (current_stored_peak <= stored_peak_before_next_visual_peak)) {
-
-                               xmax = max (xmax, staging[i].max);
-                               xmin = min (xmin, staging[i].min);
-                               ++i;
-                               ++current_stored_peak;
-                               --expected_peaks;
-                       }
-
-                       peaks[nvisual_peaks].max = xmax;
-                       peaks[nvisual_peaks].min = xmin;
-                       ++nvisual_peaks;
-                       ++next_visual_peak;
-
-                       //next_visual_peak_frame = min ((next_visual_peak * samples_per_visual_peak), (next_visual_peak_frame+samples_per_visual_peak) );
-                       next_visual_peak_frame =  min ((double) start+cnt, (next_visual_peak_frame+samples_per_visual_peak) );
-                       stored_peak_before_next_visual_peak = (uint32_t) next_visual_peak_frame / frames_per_peak; 
-               }
-
-               if (zero_fill) {
-                       memset (&peaks[npeaks], 0, sizeof (PeakData) * zero_fill);
-               }
-               
-               ret = 0;
-
-       } else {
-               
-               // cerr << "UPSAMPLE\n";
-
-               /* the caller wants 
-
-                    - less frames-per-peak (more resolution)
-                    - more peaks than stored in the Peakfile
-
-                  So, fetch data from the raw source, and generate peak
-                  data on the fly.
-               */
-
-               jack_nframes_t frames_read = 0;
-               jack_nframes_t current_frame = start;
-               jack_nframes_t i = 0;
-               jack_nframes_t nvisual_peaks = 0;
-               jack_nframes_t chunksize = (jack_nframes_t) min (cnt, (jack_nframes_t) 4096);
-               raw_staging = new Sample[chunksize];
-               workbuf = new char[chunksize *4];
-               
-               jack_nframes_t frame_pos = start;
-               double pixel_pos = floor (frame_pos / samples_per_visual_peak);
-               double next_pixel_pos = ceil (frame_pos / samples_per_visual_peak);
-               double pixels_per_frame = 1.0 / samples_per_visual_peak;
-
-               xmin = 1.0;
-               xmax = -1.0;
-
-               while (nvisual_peaks < npeaks) {
-
-                       if (i == frames_read) {
-                               
-                               to_read = min (chunksize, (_length - current_frame));
-                               
-                               if ((frames_read = read_unlocked (raw_staging, current_frame, to_read, workbuf)) < 0) {
-                                       error << string_compose(_("Source[%1]: peak read - cannot read %2 samples at offset %3")
-                                                        , _name, to_read, current_frame) 
-                                             << endmsg;
-                                       goto out;
-                               }
-
-                               i = 0;
-                       }
-                       
-                       xmax = max (xmax, raw_staging[i]);
-                       xmin = min (xmin, raw_staging[i]);
-                       ++i;
-                       ++current_frame;
-                       pixel_pos += pixels_per_frame;
-
-                       if (pixel_pos >= next_pixel_pos) {
-
-                               peaks[nvisual_peaks].max = xmax;
-                               peaks[nvisual_peaks].min = xmin;
-                               ++nvisual_peaks;
-                               xmin = 1.0;
-                               xmax = -1.0;
-
-                               next_pixel_pos = ceil (pixel_pos + 0.5);
-                       }
-               }
-               
-               if (zero_fill) {
-                       memset (&peaks[npeaks], 0, sizeof (PeakData) * zero_fill);
-               }
-
-               ret = 0;
-       }
-
-  out:
-       if (peakfile >= 0) {
-               close (peakfile);
-       }
-
-       if (staging) {
-               delete [] staging;
-       } 
-
-       if (raw_staging) {
-               delete [] raw_staging;
-       }
-
-       if (workbuf) {
-               delete [] workbuf;
-       }
-       
-       return ret;
-}
-
-#undef DEBUG_PEAK_BUILD
-
-int
-Source::build_peaks ()
-{
-       vector<PeakBuildRecord*> built;
-       int status = -1;
-       bool pr_signal = false;
-       list<PeakBuildRecord*> copy;
-
-       {
-               Glib::Mutex::Lock lm (_lock);
-               copy = pending_peak_builds;
-               pending_peak_builds.clear ();
-       }
-               
-#ifdef DEBUG_PEAK_BUILD
-       cerr << "build peaks with " << copy.size() << " requests pending\n";
-#endif         
-
-       for (list<PeakBuildRecord *>::iterator i = copy.begin(); i != copy.end(); ++i) {
-               
-               if ((status = do_build_peak ((*i)->frame, (*i)->cnt)) != 0) { 
-                       unlink (peakpath.c_str());
-                       break;
-               }
-               built.push_back (new PeakBuildRecord (*(*i)));
-               delete *i;
-       }
-
-       { 
-               Glib::Mutex::Lock lm (_lock);
-
-               if (status == 0) {
-                       _peaks_built = true;
-                       
-                       if (next_peak_clear_should_notify) {
-                               next_peak_clear_should_notify = false;
-                               pr_signal = true;
-                       }
-               }
-       }
-
-       if (status == 0) {
-               for (vector<PeakBuildRecord *>::iterator i = built.begin(); i != built.end(); ++i) {
-                       PeakRangeReady ((*i)->frame, (*i)->cnt); /* EMIT SIGNAL */
-                       delete *i;
-               }
-
-               if (pr_signal) {
-                       PeaksReady (); /* EMIT SIGNAL */
-               }
-       }
-
-       return status;
-}
-
-int
-Source::do_build_peak (jack_nframes_t first_frame, jack_nframes_t cnt)
-{
-       jack_nframes_t current_frame;
-       Sample buf[frames_per_peak];
-       Sample xmin, xmax;
-       uint32_t  peaki;
-       PeakData* peakbuf;
-       char * workbuf = 0;
-       jack_nframes_t frames_read;
-       jack_nframes_t frames_to_read;
-       off_t first_peak_byte;
-       int peakfile = -1;
-       int ret = -1;
-
-#ifdef DEBUG_PEAK_BUILD
-       cerr << pthread_self() << ": " << _name << ": building peaks for " << first_frame << " to " << first_frame + cnt - 1 << endl;
-#endif
-
-       first_peak_byte = (first_frame / frames_per_peak) * sizeof (PeakData);
-
-#ifdef DEBUG_PEAK_BUILD
-       cerr << "seeking to " << first_peak_byte << " before writing new peak data\n";
-#endif
-
-       current_frame = first_frame;
-       peakbuf = new PeakData[(cnt/frames_per_peak)+1];
-       peaki = 0;
-
-       workbuf = new char[max(frames_per_peak, cnt) * 4];
-       
-       if ((peakfile = ::open (peakpath.c_str(), O_RDWR|O_CREAT, 0664)) < 0) {
-               error << string_compose(_("Source: cannot open peakpath \"%1\" (%2)"), peakpath, strerror (errno)) << endmsg;
-               return -1;
-       }
-       
-       while (cnt) {
-
-               frames_to_read = min (frames_per_peak, cnt);
-
-               if ((frames_read = read_unlocked (buf, current_frame, frames_to_read, workbuf)) != frames_to_read) {
-                       error << string_compose(_("%1: could not write read raw data for peak computation (%2)"), _name, strerror (errno)) << endmsg;
-                       goto out;
-               }
-
-               xmin = buf[0];
-               xmax = buf[0];
-
-               for (jack_nframes_t n = 1; n < frames_read; ++n) {
-                       xmax = max (xmax, buf[n]);
-                       xmin = min (xmin, buf[n]);
-
-//                     if (current_frame < frames_read) {
-//                             cerr << "sample = " << buf[n] << " max = " << xmax << " min = " << xmin << " max of 2 = " << max (xmax, buf[n]) << endl;
-//                     }
-               }
-
-               peakbuf[peaki].max = xmax;
-               peakbuf[peaki].min = xmin;
-               peaki++;
-
-               current_frame += frames_read;
-               cnt -= frames_read;
-       }
-
-       if (::pwrite (peakfile, peakbuf, sizeof (PeakData) * peaki, first_peak_byte) != (ssize_t) (sizeof (PeakData) * peaki)) {
-               error << string_compose(_("%1: could not write peak file data (%2)"), _name, strerror (errno)) << endmsg;
-               goto out;
-       }
-
-       ret = 0;
-
-  out:
-       delete [] peakbuf;
-       if (peakfile >= 0) {
-               close (peakfile);
-       }
-       if (workbuf)
-               delete [] workbuf;
-       return ret;
-}
-
-void
-Source::build_peaks_from_scratch ()
-{
-       Glib::Mutex::Lock lp (_lock); 
-
-       next_peak_clear_should_notify = true;
-       pending_peak_builds.push_back (new PeakBuildRecord (0, _length));
-       queue_for_peaks (*this);
-}
-
-bool
-Source::file_changed (string path)
-{
-       struct stat stat_file;
-       struct stat stat_peak;
-
-       int e1 = stat (path.c_str(), &stat_file);
-       int e2 = stat (peak_path(path).c_str(), &stat_peak);
-       
-       if (!e1 && !e2 && stat_file.st_mtime > stat_peak.st_mtime){
-               return true;
-       } else {
-               return false;
-       }
-}
-
 void
 Source::use ()
 {
@@ -864,30 +118,3 @@ Source::release ()
        if (_use_cnt) --_use_cnt;
 }
 
-jack_nframes_t
-Source::available_peaks (double zoom_factor) const
-{
-       int peakfile;
-       off_t end;
-
-       if (zoom_factor < frames_per_peak) {
-               return length(); // peak data will come from the audio file
-       } 
-       
-       /* peak data comes from peakfile */
-
-       if ((peakfile = ::open (peakpath.c_str(), O_RDONLY)) < 0) {
-               error << string_compose(_("Source: cannot open peakpath \"%1\" (%2)"), peakpath, strerror (errno)) << endmsg;
-               return 0;
-       }
-
-       { 
-               Glib::Mutex::Lock lm (_lock);
-               end = lseek (peakfile, 0, SEEK_END);
-       }
-
-       close (peakfile);
-
-       return (end/sizeof(PeakData)) * frames_per_peak;
-}
-
diff --git a/libs/libsndfile/AUTHORS b/libs/libsndfile/AUTHORS
new file mode 100644 (file)
index 0000000..95770ab
--- /dev/null
@@ -0,0 +1,14 @@
+The main author of libsndfile is Erik de Castro Lopo <erikd@mega-nerd.com>.
+
+The code in the src/GSM610 directory was written by Jutta Degener 
+<jutta@cs.tu-berlin.de> and Carsten Bormann <cabo@cs.tu-berlin.de>.
+They should not be contacted in relation to libsndfile or the GSM 6.10 code 
+that is part of libsndfile. Their original code can be found at:
+
+    http://kbs.cs.tu-berlin.de/~jutta/toast.html
+
+Code in the src/G72x directory was released by Sun Microsystems, Inc. to the 
+public domain. Minor modifications were required to integrate these files 
+into libsndfile. The changes are listed in src/G72x/ChangeLog.
+
+
diff --git a/libs/libsndfile/ChangeLog b/libs/libsndfile/ChangeLog
new file mode 100644 (file)
index 0000000..df89771
--- /dev/null
@@ -0,0 +1,6107 @@
+2006-04-29 Erik de Castro Lopo  <erikd AT mega-nerd DOT com>
+
+    * tests/util.tpl
+    Add function testing function exit_if_true().
+
+    * tests/floating_point_test.tpl
+    Fix a problem where the test program was not exiting when the test failed.
+
+2006-04-15 Erik de Castro Lopo  <erikd AT mega-nerd DOT com>
+
+    * src/sndfile.h.in src/sndfile.c src/common.h src/command.c
+    Implement new commands SFC_GET_SIGNAL_MAX and SFC_GET_MAX_ALL_CHANNELS.
+
+    * doc/commands.html
+    Document new commands. Other minor updates.
+
+    * tests/peak_chunk_test.c
+    Update tests for new commands.
+
+2006-04-02 Erik de Castro Lopo  <erikd AT mega-nerd DOT com>
+
+    * tests/peak_chunk_test.c
+    Add test for RIFX and WAVEX files.
+    Try and confuse the PEAK chunk writing by enabling and disabling it.
+
+    * src/sndfile.c
+    Fix a bug where enabling and disabling PEAK chunk was screwing up.
+
+2006-03-31 Erik de Castro Lopo  <erikd AT mega-nerd DOT com>
+
+    * src/sndfile.h.in
+    Add the block of 190 reserved bytes into this struct to allow for
+    future expansion.
+
+    * src/wav.c src/sndfile.c src/broadcast.c
+    Significant cleanup of broadcast wave stuff.
+
+    * examples/sndfile-info.c
+    Fix print message.
+
+    * tests/command_test.c tests/Makefile.am
+    Complete bext tests, hook test in test suite.
+
+2006-03-30 Erik de Castro Lopo  <erikd AT mega-nerd DOT com>
+
+    * src/sndfile.h.in
+    Make coding_history field of SF_BROADCAST_INFO struct a char array instead
+    of a char pointer.
+
+    * src/sndfile.c src/common.h src/wav.c
+    Clean up knock on effects of above chnage.
+
+    * examples/sndfile-info.c
+    Add -b command line option to usage message.
+    Clean up output of broadcast wave info.
+
+    * src/wav.c
+    Ignore and skip the 'levl' chunk.
+
+2006-03-26 Erik de Castro Lopo  <erikd AT mega-nerd DOT com>
+
+    * configure.ac
+    Fix handling of --enable and --disable configure args. Thanks to Diego
+    'Flameeyes' Petten� who sent the patch.
+
+2006-03-22 Erik de Castro Lopo  <erikd AT mega-nerd DOT com>
+
+    * doc/win32.html
+    Make it really clear that although the MSVC++ cannot compile libsndfile,
+    the precompiled DLL can be used in C++ programs compiled with MSVC++.
+
+2006-03-18 Erik de Castro Lopo  <erikd AT mega-nerd DOT com>
+
+    * src/aiff.c
+    Fix bug in writing of INST chunk in AIFF files.
+    Fix potential bug in writing MARK chunks.
+
+    * src/sndfile.c
+    Make sure the instrument chunk can only be written at the start of the file.
+
+    * tests/command_test.c
+    Add check of log buffer.
+
+    * tests/utils.tpl
+    Add usage of space character to psf_binheader_writef.
+
+2006-03-17 Erik de Castro Lopo  <erikd AT mega-nerd DOT com>
+
+    * src/Makefile.am tests/Makefile.am
+    Remove --source-time argument from autogen command lines.
+
+    * src/broadcast.c
+    New file for EBU Broadcast chunk in WAV files.
+
+    * src/sndfile.c src/sndfile.h.in src/wav.c src/common.h
+    Add patch from Paul Davis implementing read/write of the BEXT chunk.
+
+2006-03-16 Erik de Castro Lopo  <erikd AT mega-nerd DOT com>
+
+    * Win32/README-precompiled-dll.txt
+    New file descibing how to use the precompiled DLL.
+
+    * Win32/Makefile.am
+    Add Win32/README-precompiled-dll.txt to EXTRA_DIST files.
+
+    * configure.ac
+    Bump version to 1.0.15.
+
+2006-03-11 Erik de Castro Lopo  <erikd AT mega-nerd DOT com>
+
+    * src/wav.c
+    On read, only add the endian flag if the file is big endian.
+
+    * src/ms_adpcm.c
+    Fixed writing of APDCM coeffs in RIFX files.
+
+    * tests/write_read_test.tpl tests/lossy_comp_test.c
+    Add tests for RIFX files.
+
+2006-03-10 Erik de Castro Lopo  <erikd AT mega-nerd DOT com>
+
+    * Mingw-make-dist.sh
+    Bunch of improvements.
+
+    * doc/win32.html
+    Update MinGW program versions.
+
+2006-03-09 Erik de Castro Lopo  <erikd AT mega-nerd DOT com>
+
+    * src/create_symbols_file.py
+    Fix the library name in created win32 DEF file. Add correct DLL name for
+    Cygwin DLL.
+
+    * Win32/Makefile.am tests/Makefile.am
+    Remove redundant files, add win32_ordinal_test to test suite.
+
+    * tests/win32_ordinal_test.c
+    Update to do test in cygsndfile-1.dll as well.
+
+    * doc/win32.html
+    Fix typo, mention that -mno-cygwin with the Cygwin compiler does not work.
+
+    * src/wav.c src/wav_w64.c src/sndfile.c src/sndfile.h.in
+    Apply large patch from Jesse Chappell which adds support for RIFX files.
+
+2006-03-08 Erik de Castro Lopo  <erikd AT mega-nerd DOT com>
+
+    * Makefile.am
+    Add Mingw-make-dist.sh to the extra dist files.
+
+    * configure.ac
+    Fix setting SHLIB_VERSION_ARG for MinGW.
+
+    * tests/win32_ordinal_test.c
+    New test program to test that the win32 DLL ordinals agree with the DEF
+    file.
+
+2006-03-04 Erik de Castro Lopo  <erikd AT mega-nerd DOT com>
+
+    * src/common.h
+    Add a static inline function to convert an int to a size_t. This will be
+    a compile to nothing on 32 bit CPUs and a sign extension on 64 bit CPUs.
+
+    * src/aiff.c src/avr.c src/common.c src/xi.c src/gsm610.c
+    Fix an ia64 problem where a varargs function was being passed an int in
+    some places and a size_t in other places.
+
+    * src/sd2.c
+    Add a workaround for situations where OSX seems to add an extra 0x52 bytes
+    to the start of the resource fork.
+
+2006-02-19 Erik de Castro Lopo  <erikd AT mega-nerd DOT com>
+
+    * Mingw-make-dist.sh
+    Add a shell script to build the windows binary/source ZIP file.
+
+    * doc/index.html
+    Add download link for windows binary/source ZIP file. Add links for GPG
+    signatures.
+
+    * doc/win32.html
+    Remove info about building using microsoft compiler.
+
+    * configure.ac
+    Bump version to 1.0.14.
+
+2006-02-11 Erik de Castro Lopo  <erikd AT mega-nerd DOT com>
+
+    * src/sd2.c
+    Improve logging of errors in resource fork parser.
+
+2006-01-31 Erik de Castro Lopo  <erikd AT mega-nerd DOT com>
+
+    * Win32/Makefile.msvc
+    Replace au_g72x.* with g72x.*. Thanks to ussell Borogove.
+
+2006-01-29 Erik de Castro Lopo  <erikd AT mega-nerd DOT com>
+
+    * src/common.c
+    Make sure return values are initialised header buffer is full.
+
+    * src/wav.c
+    Add workarounds for messed up WAV files.
+
+2006-01-21 Erik de Castro Lopo  <erikd AT mega-nerd DOT com>
+
+    * Win32/config.h
+    Undef HAVE_INTTYPES_H for win32.
+
+    * tests/command_test.c
+    Don't exit on error in instrument test for XI files.
+
+    * configure.ac
+    Bump version to 1.0.13.
+
+    * doc/*.html NEWS README
+    Update version numbers.
+
+2006-01-19 Erik de Castro Lopo  <erikd AT mega-nerd DOT com>
+
+    * src/xi.c
+    Start work on add read/write of instrument chunks.
+
+    * src/command_test.c
+    Add tests for XI instrument chunk.
+
+    * tests/largefile_test.c tests/Makefile.am
+    Add new test and hook it into the build system. This test will not be run
+    automatically because it requires 3 Gig of disk space and takes 3 minutes
+    to run.
+
+2006-01-10 Erik de Castro Lopo  <erikd AT mega-nerd DOT com>
+
+    * examples/sndfile-play.c
+    Fix calculation of samples remaining in win32 code. Thanks Axel Roebel.
+
+    * src/common.h
+    Make sure length of header buffer can hold header plus strings. Thanks Axel
+    Roebel.
+
+2006-01-09 Erik de Castro Lopo  <erikd AT mega-nerd DOT com>
+
+    * src/sndfile.h.in src/aiff.c src/wav.c
+    Apply a patch from John Fitch (Csound project).
+    Add detune field to SF_INSTRUMENT struct.
+    Add reading/writing instrument chunks to WAV files.
+
+    * tests/command_test.c
+    Update SF_INSTRUMENT tests.
+
+    * tests/Makefile.am
+    Hook instrument tests into test suite.
+
+2006-01-05 Erik de Castro Lopo  <erikd AT mega-nerd DOT com>
+
+    * configure.ac
+    Check for <inttypes.h> because some broken systems (like Solaris) don't have
+    <stdint.h> which is the 1999 ISO C standard file containing int64_t.
+
+    * src/sfendian.h src/common.h
+    Use <inttypes.h> if <stdint.h> is not available.
+
+2005-12-30 Erik de Castro Lopo  <erikd AT mega-nerd DOT com>
+
+    * tests/peak_chunk_test.c
+    Extend and clean up tests.
+
+    * src/sndfile.c
+    Fix a bug that prevented the turning off of PEAK chunks.
+
+2005-12-29 Erik de Castro Lopo  <erikd AT mega-nerd DOT com>
+
+    * tests/error_test.c
+    Make the test distclean correct.
+
+    * src/file_io.c
+    Fix an SD2 MacOSX bug (reported by vince schwarzinger).
+
+2005-12-28 Erik de Castro Lopo  <erikd AT mega-nerd DOT com>
+
+    * src/aiff.c tests/command_test.c
+    Apply a big patch from John ffitch (Csound project) to add reading and
+    writing of instrument chunks to AIFF files. Also update the test.
+
+2005-12-10 Erik de Castro Lopo  <erikd AT mega-nerd DOT com>
+
+    * tests/aiff_rw_test.c tests/virtual_io_test.c tests/utils.tpl
+    Move test function dump_data_to_file() to utils.tpl.
+
+    * tests/error_test.c tests/Makefile.am
+    Updates, including a new test to test that sf_error() returns a valid error
+    number.
+
+2005-12-07 Erik de Castro Lopo  <erikd AT mega-nerd DOT com>
+
+    * examples/list_formats.c
+    Make sure the SF_INFO struct is memset to all zero before being used.
+    Thanks to Stephen F. Booth.
+
+    * src/sndfile.c
+    Make the return value of sf_error() match the API documentation.
+
+2005-11-19 Erik de Castro Lopo  <erikd AT mega-nerd DOT com>
+
+    * examples/sndfile-convert.c
+    Allow conversion to raw gsm610.
+
+    * src/common.h src/sndfile.c src/au.c
+    Remove au_nh_open() and all references to it (wasn't working anyway).
+
+    * tests/headerless_test.c
+    Add new test for file extension based detection.
+
+    * src/sndfile.c
+    Rejig file extension based file type detection.
+
+2005-11-16 Erik de Castro Lopo  <erikd AT mega-nerd DOT com>
+
+    * src/sndfile.c
+    Add "gsm" as a recognised file extension when no magic number can be found.
+
+    * tests/lossy_comp_test.c tests/Makefile.am
+    Test headerless GSM610.
+
+2005-11-13 Erik de Castro Lopo  <erikd AT mega-nerd DOT com>
+
+    * doc/api.html
+    Fix a minor typo and a minor error. Thanks Christoph Kobe and John Pavel.
+
+2005-10-30 Erik de Castro Lopo  <erikd AT mega-nerd DOT com>
+
+    * src/wav_w64.c
+    Add more reporting of 'fmt ' chunk for G721 encoded files.
+
+    * src/wav.c
+    Gernerate a more correct 20 byte 'fmt ' chunk rather than a 16 byte one.
+
+2005-10-29 Erik de Castro Lopo  <erikd AT mega-nerd DOT com>
+
+    * src/G72x/g72x.[ch]
+    Minor cleanup of interface.
+
+2005-10-28 Erik de Castro Lopo  <erikd AT mega-nerd DOT com>
+
+    * src/ogg.c
+    Removed the horribly broken and non-functional OGG implementation when
+    --enable-experimental was enabled. When OGG does finally work it will be
+    merged.
+
+    * src/caf.c
+    Fix a memory leak.
+
+2005-10-27 Erik de Castro Lopo  <erikd AT mega-nerd DOT com>
+
+    * src/g72x.c src/G72x/*.(c|h) src/common.h src/sndfile.c src/wav.c src/au.c
+    Add support for G721 encoded WAV files.
+
+    * doc/index.html
+    Update support matrix.
+
+    * tests/lossy_comp_test.c
+    For file formats that support it, add string data after the audio data and
+    make sure it isn't treated as audio data on read.
+
+    * src/gsm610.c
+    Add code to ensure that the container close function (ie for WAV files) gets
+    called after the codec's close function. This allows GSM610 encoded WAV files
+    to have string data following the audio data.
+    Add an AIFF specific check on psf->datalength.
+
+    * src/wav.c
+    Simplify wav_close function.
+
+    * src/aiff.c
+    Make sure the tailer data gets written at an even file offset. Pad if
+    necessary.
+
+    * src/common.h
+    Replace the close function pointer in SF_PRIVATE with separate functions
+    codec_close and container_close. The former is always called first.
+
+    *  src/*.c
+    Fix knock on effects of above.
+
+2005-10-26 Erik de Castro Lopo  <erikd AT mega-nerd DOT com>
+
+    * examples/sndfile-info.c
+    Complete dumping SF_INSTRUMENT data.
+
+    * src/dwvw.c src/ima_adpcm.c src/gsm610.c src/ms_adpcm.c
+    Add extra checks in *_init function.
+
+    * tests/lossy_comp_test.c
+    Add a string comment to the end of the files to make sure that the decoder
+    doesn't decode beyond the end of the audio data section.
+
+2005-10-25 Erik de Castro Lopo  <erikd AT mega-nerd DOT com>
+
+    * examples/sndfile-info.c
+    Minor code cleanup.
+    Start work on dumping SF_INSTRUMENT data.
+
+2005-10-23 Erik de Castro Lopo  <erikd AT mega-nerd DOT com>
+
+    * src/sndfile.h.in src/common.h src/common.c
+    Update definition of SF_INSTRUMENT struct and create a function to allocate
+    and initialize the struct (input from David Viens).
+    Clean up definition of SF_INSTRUMENT struct.
+
+    * src/wav.c src/wav_w64.c
+    Add support for Ambisoncs B WAVEX files (David Viens).
+
+    * src/aiff.c src/wav.c src/wav_w64.c
+    Start work on reading/writing the SF_INSTRUMENT data.
+
+    * src/sndfile.c
+    Add code to get and set SF_INSTRUMENT data.
+
+    * tests/command_test.* tests/Makefile.am
+    Add test for set and getof SF_INSTRUMENT data.
+    The file command_test.c is no longer autogen generated.
+
+2005-10-15 Erik de Castro Lopo  <erikd AT mega-nerd DOT com>
+
+    * src/gsm610.c
+    Minor cleanup.
+
+2005-10-14 Erik de Castro Lopo  <erikd AT mega-nerd DOT com>
+
+    * tests/lossy_comp_test.c
+    Minor cleanup.
+
+2005-10-13 Erik de Castro Lopo  <erikd AT mega-nerd DOT com>
+
+    * src/*.c
+    Ensure sfconfig.h is included before any other header file.
+
+    * src/file_io.c
+    Add comments documenting the three sections of the file.
+
+    * src/gsm610.c
+    Make sure SF_FORMAT_WAVEX are handled correctly.
+
+2005-10-07 Erik de Castro Lopo  <erikd AT mega-nerd DOT com>
+
+    * configure.ac
+    Add options to allow disabling of FLAC and ALSA. Suggested by Ben Greear.
+
+2005-09-30 Erik de Castro Lopo  <erikd AT mega-nerd DOT com>
+
+    * tests/locale_test.c
+    Modify the way the unicode strings were encoded so that older compilers
+    do not complain. Thanks Axel Roebel.
+
+    * configure.ac
+    Bump the version to 1.0.12 for release.
+
+    * NEWS README Win32/config.h doc/(FAQ|index.html|command|api).html
+    Update version numbers.
+
+2005-09-26 Erik de Castro Lopo  <erikd AT mega-nerd DOT com>
+
+    * src/flac.c
+    Fix valgrind error and minor cleanup.
+
+2005-09-25 Erik de Castro Lopo  <erikd AT mega-nerd DOT com>
+
+    * src/(au|paf|aiff|w64|wav|svx).c
+    Make sure structs are initialised.
+
+2005-09-24 Erik de Castro Lopo  <erikd AT mega-nerd DOT com>
+
+    * configure.ac
+    Make -Wdeclaration-after-statement work with --enable-gcc-werror configure
+    option.
+    Add -std=gnu99 (C99 plus posix style stuff like gmtime_r) to CFLAGS if the
+    compiler supports it.
+
+2005-09-23 Erik de Castro Lopo  <erikd AT mega-nerd DOT com>
+
+    * configure.ac acinclude.m4
+    Add -Wdeclaration-after-statement to CFLAGS if the compilers supports it.
+
+2005-09-22 Erik de Castro Lopo  <erikd AT mega-nerd DOT com>
+
+    * tests/util.(tpl|def)
+    Make the test_write_*_or_die() functions const safe.
+
+2005-09-21 Erik de Castro Lopo  <erikd AT mega-nerd DOT com>
+
+    * src/nist.c
+    Make sure the data offset is read from the file header. Thanks to
+    David A. van Leeuwen for a patch.
+
+2005-09-20 Erik de Castro Lopo  <erikd AT mega-nerd DOT com>
+
+    * configure.ac src/sfconfig.h
+    Check for <locale.h> and the function setlocale().
+    Set config variables to zero if not found.
+
+    * tests/locale_test.c tests/Makefile.am
+    Add new test program and hook into build/test system.
+
+2005-09-18 Erik de Castro Lopo  <erikd AT mega-nerd DOT com>
+
+    * src/common.h src/file_io.c
+    On windows, use windows specific types for file handles.
+    Add functions psf_init_files() and psf_use_rsrc().
+
+    * src/sd2.c
+    Make resource fork handling independant of file desciptor/handles.
+
+    * src/sndfile.c src/test_file_io.c
+    Fix knock on effects.
+
+2005-09-06 Erik de Castro Lopo  <erikd AT mega-nerd DOT com>
+
+    * src/float_cast.h
+    The lrint and lrintf implementations in Cygwin are both buggy and slow.
+    Add replacements which were pulled from the Public Domain MinGW math.h
+    header file.
+
+2005-09-05 Erik de Castro Lopo  <erikd AT mega-nerd DOT com>
+
+    * tests/(lossy_comp_test|virtual_io_test).c
+    More Valgrind fixups.
+
+    * configure.ac
+    Simplify and correct configuring for Cygwin.
+
+    * Win32/config.h Win32/sndfile.h Win32/Makefile.msvc
+    Update build for MSVC.
+
+2005-09-04 Erik de Castro Lopo  <erikd AT mega-nerd DOT com>
+
+    * tests/lossy_comp_test.c
+    Make sure to close SNDFILE when exiting test when file format is not seekable.
+
+    * tests/(aiff_rw_test|virtual_io_test).c
+    Do a few valgrind fix ups.
+
+2005-09-03 Erik de Castro Lopo  <erikd AT mega-nerd DOT com>
+
+    * src/float32.c src/double64.c
+    Replace floating point equality comparisons with greater/less comparisons.
+    Found by John Pavel using the Intel compiler.
+
+    * src/sfconfig.h
+    New file to clean up issues surrounding autoconf generated preprocessor
+    symbols.
+
+    * src/*.(c|h) tests/*.(c|tpl) examples/*.c
+    Fixed a bunch of other stuff found by John Pavel using the Intel compiler.
+
+    * src/file_io.c
+    Remove Mac OS9 Metrowerks compiler specific hacks.
+
+2005-08-31 Erik de Castro Lopo  <erikd AT mega-nerd DOT com>
+
+    * src/w64.c
+    Cast integer literal to sf_count_t in call to psf_binheader_writef() to
+    prevent Valgrind error.
+
+2005-08-30 Erik de Castro Lopo  <erikd AT mega-nerd DOT com>
+
+    * doc/command.html
+    Improve documentation of SF_GET_FORMAT_SUBTYPE.
+
+2005-08-26 Erik de Castro Lopo  <erikd AT mega-nerd DOT com>
+
+    * examples/sndfile-convert.c
+    Allow files to be converted to SD2 format.
+
+    * src/sd2.c
+    Fix a bug in reading and writing of SD2 files on little endian CPUs.
+    Thanks to Matthew Willis for finding this.
+
+2005-08-25 Erik de Castro Lopo  <erikd AT mega-nerd DOT com>
+
+    * doc/api.html
+    Update Note2 to point to SFC_SET_SCALE_FLOAT_INT_READ.
+
+2005-08-16 Erik de Castro Lopo  <erikd AT mega-nerd DOT com>
+
+    * configure.ac
+    Use $host_os instead of $target_os (thanks to Mo De Jong).
+
+2005-08-15 Erik de Castro Lopo  <erikd AT mega-nerd DOT com>
+
+    * src/Makefile.am
+    Apply a patch from Mo DeJong to allow building outside of the source dir.
+
+    * src/file_io.c
+    Fix psf_fsync() for win32.
+
+    * src/wav.c src/wav_w64.(c|h)
+    Move some code from wav.c to wav_w64.c to improve the log output of files of
+    type WAVE_FORMAT_EXTENSIBLE.
+
+2005-08-10 Erik de Castro Lopo  <erikd AT mega-nerd DOT com>
+
+    * src/create_symbols_file.py
+    Make sure sf_write_fsync is an exported symbol.
+
+    * examples/sndfile-convert.c
+    Add support for writing VOX adpcm files.
+
+2005-07-31 Erik de Castro Lopo  <erikd AT mega-nerd DOT com>
+
+    * doc/api.html
+    Document the new function sf_write_sync().
+
+    * doc/FAQ.html
+    Do you plan to support XYZ codec.
+
+2005-07-28 Erik de Castro Lopo  <erikd AT mega-nerd DOT com>
+
+    * src/sndfile.h.in src/sndfile.c
+    Add function sf_write_sync() to the API.
+
+    * src/common.h src/file_io.c
+    Low level implementation (win32 not done yet).
+
+    * tests/write_read_test.tpl
+    Use the new function in the tests.
+
+2005-07-24 Erik de Castro Lopo  <erikd AT mega-nerd DOT com>
+
+    * src/common.h src/double64.c src/float32.c src/sndfile.c
+    Change the way PEAK chunk info is stored. Peaks now stored as an sf_count_t
+    for position and a double as the value.
+
+    * src/aiff.c src/caf.c src/wav.c
+    Fix knock on effects of above changes.
+
+    * src/caf.c
+    Implement 'peak' chunk for file wuth data in SF_FORMAT_FLOAT or
+    SF_FORMAT_DOUBLE format.
+
+2005-07-23 Erik de Castro Lopo  <erikd AT mega-nerd DOT com>
+
+    * src/nist.c
+    Fix a bug where a variable was being used without being initialized.
+
+    * src/flac.c
+    Add extra debug in sf_flac_meta_callback.
+    Make a bunch of private functions static.
+
+    * src/aiff.c src/wav.c
+    Fix allocation for PEAK_CHUNK (bug found using valgrind).
+
+2005-07-21 Erik de Castro Lopo  <erikd AT mega-nerd DOT com>
+
+    * src/common.h
+    Move the peak_loc field of SF_PRIVATE to the PEAK_CHUNK struct.
+    Remove had_peak field of SF_PRIVATE, use pchunk != NULL instead.
+    Rename PEAK_CHUNK and PEAK_POS to PEAK_CHUNK_32 and PEAK_POS_32.
+
+    * src/aiff.c src/caf.c src/wav.c src/float32.c src/double64.c
+    Fix knock on effects from above.
+
+2005-07-19 Erik de Castro Lopo  <erikd AT mega-nerd DOT com>
+
+    * src/wav.c
+    Prevent files with unknown chunks from being opened read/write.
+
+2005-07-14 Erik de Castro Lopo  <erikd AT mega-nerd DOT com>
+
+    * src/flac.c
+    Do not use psf->end_of_file because it never gets set to anything.
+
+    * src/common.h
+    Remove unused SF_PRIVATE field end_of_file.
+
+2005-07-12 Erik de Castro Lopo  <erikd AT mega-nerd DOT com>
+
+    * src/common.c
+    Change the 'S' format specifier of psf_binheader_writef() to write AIFF
+    style strings (no terminating character).
+
+    * src/aiff.c
+    Move to new (correct) AIFF string style. Thanks to Axel Roebel for being
+    so persistent on this issue.
+
+2005-07-11 Erik de Castro Lopo  <erikd AT mega-nerd DOT com>
+
+    * src/sndfile.c
+    Allow SFE_UNSUPPORTED_FORMAT as an error from sf_open().
+
+    * doc/api.html doc/command.html
+    Documentation updates (thanks to Kyroz for promoting these updates).
+
+    * src/mat5.c
+    Modify the way the header is written.
+
+2005-07-10 Erik de Castro Lopo  <erikd AT mega-nerd DOT com>
+
+    * src/caf.c
+    Add a 'free' chunk to the written file so that the audio data starts at
+    an offset of 0x1000.
+
+    * src/sndfile.c
+    Allow SFE_UNSUPPORTED_FORMAT as an error from sf_open().
+
+2005-07-09 Erik de Castro Lopo  <erikd AT mega-nerd DOT com>
+
+    * src/caf.c src/sndfile.c
+    Add support for signed 8 bit integers.
+
+    * tests/write_read_test.tpl
+    Add test for signed 8 bit integers in CAF files.
+
+    * doc/index.html
+    Update matrix for signed 8 bit integers in CAF files.
+
+2005-07-08 Erik de Castro Lopo  <erikd AT mega-nerd DOT com>
+
+    * src/sndfile.c
+    Update sf_check_format() to support CAF.
+
+    * examples/sndfile-convert.c
+    Add support for ".caf" file extension.
+
+    * doc/index.html
+    Add Apple CAF to the support matrix.
+
+    * src/caf.c
+    Add file write support.
+
+    * src/common.c
+    Fix printing of Frames.
+
+    * tests/Makefile.am tests/write_read_test.tpl tests/lossy_comp_test.c
+        tests/header_test.tpl misc_test.c
+    Add tests for CAF files.
+
+2005-07-07 Erik de Castro Lopo  <erikd AT mega-nerd DOT com>
+
+    * doc/FAQ.html
+    Fix Q/A about reading/writing memory buffers.
+
+    * src/caf.c
+    Bunch of work to support reading of CAF files.
+
+2005-07-04 Erik de Castro Lopo  <erikd AT mega-nerd DOT com>
+
+    * src/(aiff|ima_adpcm|mat4|mat5|ms_adpcm).c examples/sndfile-play.c
+    Fix sign conversion errors reported by gcc-4.0.
+
+    * src/caf.c
+    New file for Apple's Core Audio File format.
+
+    * src/sndfile.c src/common.h src/sndfile.h.in src/Makefile.am
+    Hook new file into build system.
+
+2005-06-21 Erik de Castro Lopo  <erikd AT mega-nerd DOT com>
+
+    * src_wav_w64.c
+    Fix handling of stupidly large 'fmt ' chunks. Thanks to Vadim Berezniker
+    for supplying an example file.
+
+    * src/common.h src/sndfile.c
+    Remove redundant error code SFE_WAV_FMT_TOO_BIG.
+
+2005-06-20 Erik de Castro Lopo  <erikd AT mega-nerd DOT com>
+
+    * src/sndfile.h.in src/common.h src/sndfile.c
+    Add public error value SF_ERR_MALFORMED_FILE.
+
+    * src/sndfile.c
+    When parsing a file header fails and we don't have a system error, then set
+    the error number to SF_ERR_MALFORMED_FILE (suggested by Kyroz).
+
+    * configure.ac
+    Allow sqlite support to be disabled in configure script.
+
+    * regtest/database.c regtest/sndfile-regtest.c
+    Fix compiling when sqlite is missing.
+
+2005-06-11 Erik de Castro Lopo  <erikd AT mega-nerd DOT com>
+
+    * src/file_io.c
+    Fix psf_is_pipe() and return value of psf_fread() when using virtual i/o.
+
+    * src/sndfile.c
+    Fix VALIDATE_AND_ASSIGN_PSF macro for virtual i/o.
+
+    * tests/virtual_io_test.c
+    Fill in skeleton test program.
+
+    * tests/Makefile.am
+    Move virtual i/o tests to end of tests with stdio/pipe tests.
+
+    * src/(sndfile.h.in|file_io.c|common.h|sndfile.c) tests/virtual_io_test.c
+    Rename some of the virtual i/o functions and data types.
+
+2005-06-10 Erik de Castro Lopo  <erikd AT mega-nerd DOT com>
+
+    * src/sndfile.c
+    Fix the return values of sf_commands : SFC_SET_NORM_DOUBLE,
+    SFC_SET_NORM_FLOAT, SFC_GET_LIB_VERSION and SFC_GET_LOG_INFO. Thanks to
+    Kyroz for pointing out these errors.
+
+    * doc/command.html
+    Correct documented return values for SFC_SET_NORM_DOUBLE and
+    SFC_SET_NORM_FLOAT. Thanks to Kyroz again.
+
+2005-05-17 Erik de Castro Lopo  <erikd AT mega-nerd DOT com>
+
+    * regtest/*
+    Add new files for sndfile-regtest program.
+
+    * configure.ac Makefile.am
+    Hook regetest into build.
+
+    * src/wav.c src/common.c
+    Fix a regression where long ICMT chunks were causing the WAV parser
+    to exit.
+
+2005-05-15 Erik de Castro Lopo  <erikd AT mega-nerd DOT com>
+
+    * libsndfile.spec.in
+    Add html docs to the files section as suggested by Karsten Jeppesen.
+
+    * src/aiff.c
+    Fix parsing of odd length ANNO chunks.
+
+2005-05-13 Erik de Castro Lopo  <erikd AT mega-nerd DOT com>
+
+    * src/common.h
+    Change the include guard to prevent clashes with other code.
+
+2005-05-12 Erik de Castro Lopo  <erikd AT mega-nerd DOT com>
+
+    * examples/sndfile-play.c
+    Improve error handling in code for playback under Linux/ALSA.
+
+2005-05-10 Erik de Castro Lopo  <erikd AT mega-nerd DOT com>
+
+    * src/ircam.c
+    Fix writing of IRCAM files on big endian systems (thanks to Axel Roebel).
+
+    * src/wav.c
+    Add workaround for files created by the Peak audio editor on Mac which can
+    produce files with very short LIST chunks (thanks to Jonathan Segel who
+    supplied the file).
+
+2005-04-30 Erik de Castro Lopo  <erikd AT mega-nerd DOT com>
+
+    * src/aiff.c
+    Apply a patch From David Viens to make the parsing of basc chunks more
+    robust.
+
+    * src/wav.c
+    Another patch from David Viens to write correct wavex channel masks for
+    the most common channel configurations.
+
+2005-04-08 Erik de Castro Lopo  <erikd AT mega-nerd DOT com>
+
+    * src/command.c
+    Only allow FLAC in the format arrays if FLAC is enabled. Thanks to
+    Leigh Smith.
+
+2005-03-09 Erik de Castro Lopo  <erikd AT mega-nerd DOT com>
+
+    * src/common.h
+    Add a directory field for storing the file directory to the SF_PRIVATE
+    struct.
+
+    * src/sndfile.c
+    Grab the directory name when copying the file path.
+
+    * src/file_io.c
+    Cleanup psf_open_rsrc() and also check for resource fork in
+    .AppleDouble/filename.
+
+2005-03-01 Erik de Castro Lopo  <erikd AT mega-nerd DOT com>
+
+    * src/svx.c
+    Fix a bug in the printing of the channel count. Bug reported by Michael
+    Schwendt. Thanks.
+
+2005-01-26 Erik de Castro Lopo  <erikd AT mega-nerd DOT com>
+
+    * src/paf.c
+    Fix a seek bug for 24 bit PAF files.
+
+    * tests/write_read_test.tpl
+    Update write_read_test to trigger the previously hidden PAF seek bug.
+
+2005-01-25 Erik de Castro Lopo  <erikd AT mega-nerd DOT com>
+
+    * src/aiff.c src/w64.c src/wav.c
+    Do not return a header parse error when the log buffer overflows.
+    Continuing parsing works even on files where the log buffer does overflow.
+    This avoids a bug on some weirdo WAV (and other) files.
+
+    * src/common.h src/sndfile.c
+    Remove SFE_LOG_OVERRIN error and its associated error message.
+
+    * src/file_io.c
+    Fix a rsrc fork problem on MacOSX.
+
+2004-12-31  Erik de Castro Lopo  <erikd AT mega-nerd DOT com>
+
+    * src/sndfile-play.c
+    In the ALSA output code, added call to snd_pcm_drain() just before
+    snd_pcm_close() as suggested by Thomas Kaeding.
+    In the OSS output code, added two ioctls (SNDCTL_DSP_POST and
+    SNDCTL_DSP_SYNC) just before the close of the audio device.
+
+    * tests/virtual_io_test.c tests/Makefile.am
+    Add a new test program (currently empty) and add it to the build.
+
+2004-12-29  Erik de Castro Lopo  <erikd AT mega-nerd DOT com>
+
+    * src/sndfile.h.in src/sndfile.h src/common.h src/file_io.c
+      src/create_symbols_file.py
+    Apply patch from Steve Baker which is the beginnings of a virtual
+    I/O interface.
+
+2004-12-23  Erik de Castro Lopo  <erikd AT mega-nerd DOT com>
+
+    * src/*.c src/sndfile.h.in
+    Const-ify the write path throughout the library.
+
+2004-12-14  Erik de Castro Lopo  <erikd AT mega-nerd DOT com>
+
+    * doc/development.html
+    Minor improvements.
+
+2004-11-29  Erik de Castro Lopo  <erikd AT mega-nerd DOT com>
+
+    * doc/bugs.html
+    Minor improvements.
+
+2004-11-18  Erik de Castro Lopo  <erikd AT mega-nerd DOT com>
+
+    * src/aiff.c
+    Add workaround for Logic Platinum AIFF files with broken COMT chunks.
+
+2004-11-16  Erik de Castro Lopo  <erikd AT mega-nerd DOT com>
+
+    * doc/FAQ.html
+    Remove some ambiguities in the SD2 FAQ answer.
+
+2004-11-15  Erik de Castro Lopo  <erikd AT mega-nerd DOT com>
+
+    * Win32/sndfile.h Win32/config.h MacOS9/sndfile.h MacOS9/config.h
+    Updates from autoconfig versions.
+
+2004-11-13  Erik de Castro Lopo  <erikd AT mega-nerd DOT com>
+
+    * src/aiff.c
+    Fix parsing of COMT chunks. Store SF_STR_COMMENT data in ANNO chunks
+    instead of COMT chunk.
+
+2004-11-07  Erik de Castro Lopo  <erikd AT mega-nerd DOT com>
+
+    * src/file_io.c src/common.h
+    Change the ptr argument to psf_write() from "void*" to a "const void*".
+    Thanks to Tobias Gehrig for suggesting this.
+
+2004-10-31  Erik de Castro Lopo  <erikd AT mega-nerd DOT com>
+
+    * src/file_io.c src/common.h
+    Add functions psf_close_rsrc() and read length of resourse fork into
+    rsrclength field of SF_PRIVATE.
+
+    * src/sd2.c
+    Make sure resource fork gets closed.
+
+    * tests/util.tpl
+    Add functions to check for file descriptor leakage.
+
+    * src/write_read_test.tpl
+    Use the file descriptor leak checks.
+
+    * src/sndfile.h.in
+    Add SFC_GET_LOOP_INFO and SF_LOOP_INFO struct.
+
+    * src/common.h
+    Add SF_LOOP_INFO pointer to SF_PRIVATE.
+
+    * src/wav.c src/aiff.c
+    Improve and add parsing of 'ACID' and 'basc' chunks, filling in
+    SF_LOOP_INFO data in SF_PRIVATE.
+
+2004-10-30  Erik de Castro Lopo  <erikd AT mega-nerd DOT com>
+
+    * src/sd2.c
+    Further cleanup: remove printfs, change snprintf to LSF_SNPRINTF.
+
+    * Win32/config.h Win32/sndfile.h
+    Updates.
+
+    * tests/util.tpl
+    Add win32 macro for snprintf.
+
+2004-10-29  Erik de Castro Lopo  <erikd AT mega-nerd DOT com>
+
+    * src/sfendian.h
+    Add macros : H2BE_SHORT, H2BE_INT, H2LE_SHORT and H2LE_INT.
+
+    * src/sd2.c
+    Use macros to make sure writing SD2 files on little endian machines works
+    correctly.
+
+    * tests/util.tpl
+    Add a delete_file() function which also deletes the resource fork of SD2
+    files.
+
+    * tests/write_read_test.tpl
+    Use delete_file() so that "make distcheck" works.
+
+2004-10-28  Erik de Castro Lopo  <erikd AT mega-nerd DOT com>
+
+    * src/sndfile.c src/file_io.c
+    Move resource filename construction and testing to psf_open_rsrc().
+
+    * src/common.h src/sndfile.c
+    Add error SFE_SD2_FD_DISALLOWED.
+
+    * tests/util.tpl tests/*.(c|tpl)
+    Add and allow_fd parameter to test_open_file_or_die() so that use of
+    sf_open_fd() can be avoided when opening SD2 files.
+
+2004-10-27  Erik de Castro Lopo  <erikd AT mega-nerd DOT com>
+
+    * src/wav.c
+    Update ACID chunk parsing.
+
+    * src/sd2.c
+    More fixes for files with large resource forks.
+
+2004-10-23  Erik de Castro Lopo  <erikd AT mega-nerd DOT com>
+
+    * src/common.h src/sndfile.c
+    Add error numbers and messages for sd2 files.
+
+    * src/sd2.c
+    Reading of sd2 (resource fork version) now seems to be working.
+
+2004-10-17  Erik de Castro Lopo  <erikd AT mega-nerd DOT com>
+
+    * src/file_io.h
+    Update file_io.c to include win32 psf_rsrc_open().
+
+    * tests/floating_point_test.tpl
+    Remove use of __func__ in test programs (MSVC++ doesn't grok this).
+
+    * Win32/(config|sndfile).h MacOS9/(config|sndfile).h
+    Updates.
+
+2004-10-13  Erik de Castro Lopo  <erikd AT mega-nerd DOT com>
+
+    * src/sfendian.h
+    Fix endswap_int64_t_(array|copy).
+
+    * src/test_endswap.(tpl|def)
+    Add tests for above and inprove all tests.
+
+2004-10-12  Erik de Castro Lopo  <erikd AT mega-nerd DOT com>
+
+    * src/sfendian.h
+    Improve type safety, add endswap_double_array().
+
+    * src/double64.c
+    Use endswap_double_array() instead of endswap_long_array().
+
+    * src/test_endswap.(tpl|def) src/Makefile.am
+    Add preliminary endswap tests and hook into build system.
+
+2004-10-06  Erik de Castro Lopo  <erikd AT mega-nerd DOT com>
+
+    * src/configure.ac src/makefile.am
+    Finally fix the bulding of DLLs on Win32/MinGW.
+
+    * tests/makefile.am
+    Fix running of tests on Win32/MinGW.
+
+2004-10-01  Erik de Castro Lopo  <erikd AT mega-nerd DOT com>
+
+    * src/sndfile.h.in src/sndfile.c tests/floating_point_test.tpl
+    Rename SFC_SET_FLOAT_INT_MULTIPLIER to SFC_SET_SCALE_FLOAT_INT_READ.
+
+    * doc/command.html
+    Document SFC_SET_SCALE_FLOAT_INT_READ.
+
+2004-09-30  Erik de Castro Lopo  <erikd AT mega-nerd DOT com>
+
+    * tests/floating_point_test.(tpl|def)
+    Derived from floating_point_test.c.
+    Add (float|double)_(short|int)_test functions.
+
+    * tests/util.(tpl|def)
+    Make separate float and double versions of gen_windowed_sine().
+
+    * tests/write_read_test.tpl
+    Fix after changes to gen_windowed_sine().
+
+    * src/(float32|double64).c
+    Implement SFC_SET_FLOAT_INT_MULTIPPLIER.
+
+2004-09-29  Erik de Castro Lopo  <erikd AT mega-nerd DOT com>
+
+    * acinclude.m4
+    Fix warnings from automake 1.8 and later.
+
+    * examples/sndfile-info.c
+    Add a "fflush (stdout)" after printing Win32 message.
+
+2004-09-28  Erik de Castro Lopo  <erikd AT mega-nerd DOT com>
+
+    * Win32/Makefile.mingw.in
+    Add a "make install" target.
+
+2004-09-24  Erik de Castro Lopo  <erikd AT mega-nerd DOT com>
+
+    * src/sndfile.h.in src/common.h src/sndfile.c src/command.c
+    Start work on adding command SFC_SET_FLOAT_INT_MULTIPLIER.
+
+2004-09-22  Erik de Castro Lopo  <erikd AT mega-nerd DOT com>
+
+    * examples/sndfile-convert.c
+    Fix a bug converting stereo integer PCM files to float.
+
+2004-09-22  Erik de Castro Lopo  <erikd AT mega-nerd DOT com>
+
+    * examples/sndfile-play.c
+    Appy patch from Conrad Parker to make Mac OSX error messages more
+    consistent and informative.
+
+    * doc/api.html
+    Fix a HTML HREF which was wrong.
+
+    * doc/win32.html
+    Add information about when nmake fails.
+
+2004-09-05  Erik de Castro Lopo  <erikd AT mega-nerd DOT com>
+
+    * examples/sndfile-play.c
+    Another patch from Denis Cote to prevent race conditions.
+
+2004-09-02  Erik de Castro Lopo  <erikd AT mega-nerd DOT com>
+
+    * src/common.h src/ms_adpcm.c src/ima_adpcm.c
+    Fix alternative to ISO standard flexible struct array feature for broken
+    compilers.
+
+2004-08-31  Erik de Castro Lopo  <erikd AT mega-nerd DOT com>
+
+    * src/common.h src/string.c src/sndfile.c
+    Make sf_set_string() return an error if trying to set a string when in
+    read mode.
+
+2004-08-29  Erik de Castro Lopo  <erikd AT mega-nerd DOT com>
+
+    * src/common.h
+    Change the unnamed union into a named union so gcc-2.95 will compile it.
+
+    * src/*.c
+    Fixes to allow for the above change.
+
+2004-08-20  Erik de Castro Lopo  <erikd AT mega-nerd DOT com>
+
+    * examples/sndfile-play.c
+    Fixes for Win32. Thanks to Denis Cote.
+
+    * Win32/Win32/Makefile.(msvc|mingw.in)
+    Fix build system after removal of sfendian.h.
+    Build sndfile-convert.
+
+    * src/Makefile.am
+    Remove sfendian.c from dependancies.
+
+2004-08-10  Erik de Castro Lopo  <erikd AT mega-nerd DOT com>
+
+    * src/sndfile.h.in
+    Fix typo in comments (thanks Tommi Sakari Uimonen).
+
+2004-07-31  Erik de Castro Lopo  <erikd AT mega-nerd DOT com>
+
+    * tests/(a|u)law_test.c
+    Minor cleanup.
+
+2004-07-29  Erik de Castro Lopo  <erikd AT mega-nerd DOT com>
+
+    * src/(pcm|float|double64|ulaw|alaw|xi).c
+    Optimise read/write loops by removing a redundant variable.
+
+2004-07-24  Erik de Castro Lopo  <erikd AT mega-nerd DOT com>
+
+    * src/file_io.c
+    Remove call to fsync() in psf_close().
+
+2004-07-19  Erik de Castro Lopo  <erikd AT mega-nerd DOT com>
+
+    * src/pcm.c
+    Inline x2y_array() functions where possible.
+
+    * configure.ac
+    Detect presence of type int64_t.
+
+    * src/sfendian.c src/sfendian.h
+    Move functions in the first file to the sfendian.h as static inline
+    functions.
+    Improve endswap_long_*() where possible.
+
+2004-07-17  Erik de Castro Lopo  <erikd AT mega-nerd DOT com>
+
+    * src/pcm.c
+    When converting from unsigned char to float or double, subtract 128 before
+    converting to float/double rather than after to save a floating point
+    operation as suggested by Stefan Briesenick.
+
+    * src/(pcm|sfendian|alaw|ulaw|double64|float32).c
+    Optimize inner loops by changing the loop counting slightly as suggested
+    by Stefan Briesenick.
+
+    * configure.ac
+    Detect presence of <byteswap.h>.
+
+    * src/sfendian.h
+    Use <byteswap.h> if present as suggested by Stefan Briesenick.
+
+    * src/pcm.c
+    Update bytewapping.
+
+2004-07-02  Erik de Castro Lopo  <erikd AT mega-nerd DOT com>
+
+    * src/common.h src/*.c
+    Change the psf->buffer field of SF_PRIVATE into a more type safe union with
+    double, float, int etc elements.
+
+2004-06-28  Erik de Castro Lopo  <erikd AT mega-nerd DOT com>
+
+    * examples/sndfile-play.c
+    Merge slightly modifed patch from Stanko Juzbasic which allows playback of
+    mono files on MacOSX.
+
+2004-06-25  Erik de Castro Lopo  <erikd AT mega-nerd DOT com>
+
+    * examples/sndfile-convert.c
+    Move copy_metadata() after the second sf_open().
+
+2004-06-21  Erik de Castro Lopo  <erikd AT mega-nerd DOT com>
+
+    * examples/sndfile-convert.c
+    Fix a bug which caused the program to go into an infinite loop if the source
+    file has no meta-data. Thanks to Ron Parker for reporting this.
+
+    * src/sndfile.h.in
+    Add SF_STR_FIRST and SF_STR_LAST to allow enumeration of string types.
+
+    * Win32/sndfile.h MacOS9/sndfile.h
+    Update these as per the above file.
+
+2004-06-17  Erik de Castro Lopo  <erikd AT mega-nerd DOT com>
+
+    * configure.ac src/common.h src/ogg.c src/sndfile.c src/sndfile.h.in
+      src/Makefile.am
+    Apply large patch from Conrad Parker implementing Ogg Vorbis, Ogg Speex and
+    Annodex support via liboggz and libfishsound. Thanks Conrad.
+
+2004-06-15  Erik de Castro Lopo  <erikd AT mega-nerd DOT com>
+
+    * src/avr.c src/ircam.c src/nist.c src/paf.c src/xi.c
+    Add cast to size_t for some parameters passed to psf_binheader_writef. This
+    is Debian bug number 253490. Thanks to Anand Kumria and Andreas Jochens.
+
+    * src/w64.c
+    Found and fixed a bug resulting from use of size_t when writing W64 'fmt '
+    chunk.
+
+2004-06-14  Erik de Castro Lopo  <erikd AT mega-nerd DOT com>
+
+    * configure.ac
+    Bump version to 1.0.10 ready for release.
+
+    * Makefile.am
+    Remove redundant files (check_libsndfile.py libsndfile_version_convert.py)
+    from distribution tarball.
+
+    * tests/header_test.tpl
+    Fix uninitialised variable.
+
+    * src/GSM610/short_term.c
+    Fix compiler warning on MSVC++.
+
+2004-05-23  Erik de Castro Lopo  <erikd AT mega-nerd DOT com>
+
+    * src/wav.c
+    Improve record keeping of chunks seen and return an error if a file with
+    unusual chunks is opened in mode SFM_RDWR.
+
+    * src/mmreg.h
+    This file not needed so remove it.
+
+2004-05-22  Erik de Castro Lopo  <erikd AT mega-nerd DOT com>
+
+    * tests/header_test.tpl
+    Add extra_header_test().
+
+    * src/common.h src/sndfile.c
+    Add SFE_RDWR_BAD_HEADER error number and string.
+
+2004-05-21  Erik de Castro Lopo  <erikd AT mega-nerd DOT com>
+
+    * tests/utils.tpl tests/*.c tests/*.tpl
+    Add a line number argument to check_log_buffer_or_die() and update all
+    files that use that function.
+
+    * tests/header_test.tpl
+    Modify/update tests for files opened SFM_RDWR and SFC_UPDATE_HEADER_AUTO.
+
+    * src/aiff.c src/wav.c
+    Fix another bug in AIFF and WAV files opened in SFM_RDWR and using
+    SFC_UPDATE_HEADER_AUTO.
+
+    * src/test_file_io.c
+    Add a test for psf_ftruncate() function.
+
+2004-05-19  Erik de Castro Lopo  <erikd AT mega-nerd DOT com>
+
+    * src/sndfile.c
+    Fix another  weird corner case bug found by Martin Rumori. Thanks.
+
+    * tests/header_test.(tpl|def)
+    Two new files to test for the absence of the above bug and include tests
+    moved from tests/misc_test.c.
+
+    * tests/Makefile.am
+    Hook new tests into build/test system.
+
+    * tests/misc_test.c
+    Remove update_header_test() which has been moved to the new files above.
+
+2004-05-16  Erik de Castro Lopo  <erikd AT mega-nerd DOT com>
+
+    * src/aiff.c
+    Fixed a bug reported by Martin Rumori on the LAD list. If a file created
+    with a format of SF_FORMAT_FLOAT and then closed before any data is written
+    to it, the header can get screwed up (PEAK chunk gets overwritten).
+
+    * tests/write_read_test.tpl
+    Add a test (empty_file_test) for the above bug.
+
+2004-05-13  Erik de Castro Lopo  <erikd AT mega-nerd DOT com>
+
+    * Win32/Makefile.mingw.in
+    Added a Makefile for MinGW (needs to be processed by configure).
+
+    * src/mmsystem.h src/mmreg.h
+    Add files from the Wine project (under the LGPL) to allow build of
+    sndfile-play.exe under MinGW.
+
+2004-05-12  Erik de Castro Lopo  <erikd AT mega-nerd DOT com>
+
+    * src/GSM610/gsm610_priv.h
+    Replace ugly macros with inline functions.
+
+    * src/GSM610/*.c
+    Remove temporary variables used by macros and other minor fixes required by
+    above change.
+
+2004-05-10  Erik de Castro Lopo  <erikd AT mega-nerd DOT com>
+
+    * tests/pipe_test.tpl tests/stdio_test.c Win32/Makefile.msvc
+    Make sure these programs compile (even though they do nothing) on Win32
+    and add them to the "make check" target.
+
+    * src/sfendian.h
+    Fix warning on Sparc CPU and code cleanup.
+
+2004-05-09  Erik de Castro Lopo  <erikd AT mega-nerd DOT com>
+
+    * src/file_io.c
+    Fix warning messages when compiling under MinGW.
+
+2004-05-01  Erik de Castro Lopo  <erikd AT mega-nerd DOT com>
+
+    * configure.ac
+    Set HAVE_FLEXIBLE_ARRAY in src/config.h depending on whether the compiler
+    accepts the flexible array struct member as per 1999 ISO C standard.
+
+    * src/common.h src/ima_adpcm.c src/paf.c src/ms_adpcm.c
+    Added ugly #if HAVE_FLEXIBLE_ARRAY and provided a non-standards compliant
+    hack for non 1999 ISO C compliant compilers.
+
+2004-04-26  Erik de Castro Lopo  <erikd AT mega-nerd DOT com>
+
+    * src/strings.c
+    If adding an SF_STR_SOFTWARE string, only append libsndfile-X.Y.Z if the
+    string does not already have libsndfile in the string. Thanks to Conrad
+    Parker.
+
+    * tests/string_test.c
+    Add test to verify the above.
+
+    * examples/sndfile-convert.c
+    Add ability to transcode meta data as well (Conrad Parker).
+
+2004-04-25  Erik de Castro Lopo  <erikd AT mega-nerd DOT com>
+
+    * doc/command.html
+    Fix minor error. Thanks to Simon Burton.
+
+    * doc/win32.html
+    Started adding instructions for compiling libsndfile under MinGW.
+
+    * configure.ac
+    Add --enable-bow-docs to enable black text on a white background HTML docs.
+
+    * doc/libsndfile.css.in
+    This is now a template file for configure which sets the foreground and
+    background colours.
+
+2004-04-20  Erik de Castro Lopo  <erikd AT mega-nerd DOT com>
+
+    * configure.ac
+    Do some MinGW fixes.
+
+    * configure.ac doc/Makefile.am
+    Install HTML docs when doing make install.
+
+2004-04-19  Erik de Castro Lopo  <erikd AT mega-nerd DOT com>
+
+    * examples/sndfile-info.c
+    Print out the dB level with the signal max.
+
+2004-04-15  Erik de Castro Lopo  <erikd AT mega-nerd DOT com>
+
+    * src/file_io.c
+    Define S_ISSOCK in src/file_io.c if required.
+
+2004-04-03  Erik de Castro Lopo  <erikd AT mega-nerd DOT com>
+
+    * configure.ac
+    Improve printout configuration summary (as suggested by Axel R�bel).
+
+    * doc/index.html
+    Add link to pre-release location.
+
+    * src/sndfile.h.in
+    Remove comma after last element of enum.
+
+    * src/float32.c src/double64.c
+    Fix read/write of float/double encoded raw files to/from pipes.
+
+    * tests/pipe_test.c tests/pipe_test.tpl tests/pipe_test.def
+    Turn pipe_test.c into an autogenerated file and add tests for reading/
+    writing floats and doubles.
+
+    * tests/Makefile.am
+    Hook tests/pipe_test.* into build system.
+
+2004-04-02  Erik de Castro Lopo  <erikd AT mega-nerd DOT com>
+
+    * configure.ac acinclude.m4
+    Rename AC_C_STRUCT_HACK macro to AC_C99_FLEXIBLE_ARRAY.
+
+2004-03-31  Erik de Castro Lopo  <erikd AT mega-nerd DOT com>
+
+    * tests/misc_test.c
+    Perform update_header_test in RDWR mode as well.
+
+    * src/aiff.c
+    Fix problems when updating header in RDWR mode.
+
+2004-03-30  Erik de Castro Lopo  <erikd AT mega-nerd DOT com>
+
+    * src/wav.c src/w64.c src/wav_w64.c
+    Integrate code supplied by David Viens for supporting microsoft's
+    WAVEFORMATEXTENSIBLE stuff. Thanks David for supplying this.
+
+    * configure.ac doc/*.html
+    Bump version to 1.0.9.
+
+2004-03-28  Erik de Castro Lopo  <erikd AT mega-nerd DOT com>
+
+    * src/command.c src/sndfile.c src/sndfile.h.in src/wav.c
+    Started work on supporting microsoft's WAVEFORMATEXTENSIBLE gunk.
+
+2004-03-26  Erik de Castro Lopo  <erikd AT mega-nerd DOT com>
+
+    * src/avr.c
+    New file to handle Audio Visual Resaerch files.
+
+    * src/sndfile.h.in src/common.h src/sndfile.c src/command.c
+    Hook AVR into everything else.
+
+    * tests/Makefile.am tests/write_read_test.tpl tests/misc_test.c
+    Add testing for AVR files.
+
+2004-03-22  Erik de Castro Lopo  <erikd AT mega-nerd DOT com>
+
+    * src/file_io.c
+    Fix psf_set_file() for win32. Thanks to Vincent Trussart (Plogue Art et
+    Technologie) for coming up with the solution.
+
+2004-03-21  Erik de Castro Lopo  <erikd AT mega-nerd DOT com>
+
+    * tests/write_read_test.tpl
+    Fixed a bug that was causing valgrind to report a memory leak. The bug was
+    in the test code itself, not the library.
+
+2004-03-20  Erik de Castro Lopo  <erikd AT mega-nerd DOT com>
+
+    * examples/generate.cs
+    An example showing how to use libsndfile from C#. Thanks to James Robson
+    for providing this.
+
+2004-03-19  Erik de Castro Lopo  <erikd AT mega-nerd DOT com>
+
+    * src/common.c
+    Fix problems with WAV files containing large chunks after the 'data'
+    chunk. Thanks to Koen Tanghe for providing a sample file.
+
+2004-03-17  Erik de Castro Lopo  <erikd AT mega-nerd DOT com>
+
+    * configure.ac
+    Detect presense of ALSA (Advanced Linux Sound Architecture).
+
+    * examples/sndfile-play.c
+    Add ALSA output support.
+
+    * examples/Makefile.am
+    Add ALSA_LIBS to link line of sndfile-play.c.
+
+2004-03-15  Erik de Castro Lopo  <erikd AT mega-nerd DOT com>
+
+    * acinclude.m4
+    Add new macro (AC_C_STRUCT_HACK) to detect whether the C compiler allows
+    the use of the what is known as the struct hack introduced by the 1999 ISO
+    C Standard.
+
+    * configure.ac
+    The last release would not compile with gcc-2.95 due to the use of features
+    (ie struct hack) introduced by the 1999 ISO C Standard.
+    Add check to make sure compiler handles this and bomb out if it doesn't.
+
+2004-03-14  Erik de Castro Lopo  <erikd AT mega-nerd DOT com>
+
+    * tests/write_read_test.tpl
+    Fix compiler warning on Win32.
+
+    * src/file_io.c
+    Fix use of an un-initialised variable in Win32 stuff.
+
+    * Win32/config.h examples/sndfile-play.c
+    Win32 fixes.
+
+2004-03-10  Erik de Castro Lopo  <erikd AT mega-nerd DOT com>
+
+    * configure.ac
+    Fix bug which occurres when configuring for MinGW.
+    If compiler is gcc and cross compiling use -nostdinc.
+
+2004-03-09  Erik de Castro Lopo  <erikd AT mega-nerd DOT com>
+
+    * src/common.h src/aiff.c src/wav.c src/float32.c src/double64.c
+      src/sndfile.c
+    Fix a bug with PEAK chunk handling for files with more than 16 channels.
+    Thanks to Remy Bruno for finding this.
+
+2004-03-08  Erik de Castro Lopo  <erikd AT mega-nerd DOT com>
+
+    * src/common.c
+    Fix a bug which was preventing WAV files being openned correctly if the
+    file had a very large header. Thanks to Eldad Zack for finding this.
+
+2004-03-04  Erik de Castro Lopo  <erikd AT mega-nerd DOT com>
+
+    * configure.ac src/file_io.c
+    Fix cross-compiling from Linux to Win32 using the MinGW tools.
+
+2004-03-01  Erik de Castro Lopo  <erikd AT mega-nerd DOT com>
+
+    * src/create_symbols_file.sh
+    Christian Weisgerber pointed out that the shell script did not run on a
+    real Bourne shell although it did run under Bash in Bourne shell mode.
+
+    * src/create_symbols_file.py
+    Rewrite of above in Python. Also add support for writing Win32 .def files.
+    The Python script generates Symbols.linux, Symbols.darwin and
+    libsndfile.def (Win32 version). These files get shipped with the tarball
+    so there should not be necessary to run the Python script when building
+    the code from the tarball.
+
+    * configure.ac src/Makefile.am Win32/Makefile.am
+    Hook new Python script into the build system.
+
+2004-02-25  Erik de Castro Lopo  <erikd AT mega-nerd DOT com>
+
+    * src/configure.ac
+    Add --enable-gcc-werror option and move GCC specific stuff down.
+
+2004-02-24  Erik de Castro Lopo  <erikd AT mega-nerd DOT com>
+
+    * acinclude.m4 configure.ac
+    Fix clip mode detection (tested in one of HP's testdrive Itanium II boxes).
+
+    * src/file_io.c
+    Added check for sizeof (off_t) != sizeof (sf_count_t) to prevent recurrence
+    of missing large file support on Linux and Solaris.
+
+2004-02-19  Erik de Castro Lopo  <erikd AT mega-nerd DOT com>
+
+    * examples/sndfile-play.c
+    Fix a MacOSX specific bug which was caused by a space being inserted in
+    the middle of a file name.
+
+    * configure.ac src/Makefile.am examples/Makefile.am
+    Fix a couple of MacOSX build issues.
+
+2004-02-17  Erik de Castro Lopo  <erikd AT mega-nerd DOT com>
+
+    * doc/command.html
+    Document SFC_SET_CLIPPING and SFC_GET_CLIPPING.
+
+2004-02-14  Erik de Castro Lopo  <erikd AT mega-nerd DOT com>
+
+    * doc/*.html
+    Applied patch from Frank Neumann (author of lakai) which fixes many minor
+    typos in documentation. Thanks Frank.
+
+2004-02-13  Erik de Castro Lopo  <erikd AT mega-nerd DOT com>
+
+    * ChangeLog
+    Changed my email address throughout source and docs.
+
+2004-02-08  Erik de Castro Lopo  <erikd AT mega-nerd DOT com>
+
+    * src/file_io.c
+    Make sure config.h is included before stdio.h to make sure large file
+    support is enabled on Linux (and Solaris).
+
+    * tests/misc_test.c
+    Disable update_header test on Win32. This should work but doesn't and
+    I'm not sure why.
+
+    * Make.bat Win32/Makefile.msvc
+    Updates.
+
+2004-01-07  Erik de Castro Lopo  <erikd AT mega-nerd DOT com>
+
+    * src/common.h
+    Changed logindex, headindex and headend files of SF_PRIVATE from unsigned
+    int to int to prevent weird arithmetic bugs.
+
+    * src/common.c src/aiff.c src/wav.c src/w64.c
+    Fixed compiler warnings resulting from above change.
+
+2004-01-06  Erik de Castro Lopo  <erikd AT mega-nerd DOT com>
+
+    * src/common.c
+    Fixed a bug in header reader for some files with data after the sample data.
+
+2003-12-29  Erik de Castro Lopo  <erikd AT mega-nerd DOT com>
+
+    * tests/lossy_comp_test.c tests/Makefile.am
+    Add tests for AIFF/IMA files.
+
+2003-12-26  Erik de Castro Lopo  <erikd AT mega-nerd DOT com>
+
+    * src/macbinary3.c src/macos.c
+    Two new files required for handling SD2 files.
+
+    * src/common.h
+    Add prototypes for functions in above two files.
+
+    * src/Makefile.am
+    Hook new files into build system.
+
+2003-12-21  Erik de Castro Lopo  <erikd AT mega-nerd DOT com>
+
+    * configure.ac
+    Add checks for mmap() and getpagesize() which might be used at some time
+    for faster file reads.
+    Add detection of MacOSX.
+
+2003-12-13  Erik de Castro Lopo  <erikd AT mega-nerd DOT com>
+
+    * doc/FAQ.html
+    Minor mods to pkg-config section.
+
+2003-12-12  Erik de Castro Lopo  <erikd AT mega-nerd DOT com>
+
+    * src/create_symbols_file.sh
+    Andre Pang (also known as Ozone) pointed out that on MacOSX, all non
+    static symbols are exported causing troubles when trying to link
+    libsndfile with another library which has any of the same symbols.
+    He fixed this by supplying the MacOSX linker with a file containing
+    all the public symbols so that only they would be exported and then
+    supplied a patch for libsndfile.
+    This wasn't quite ideal, because I would have to maintain two (3 if
+    you include Win32) separate files containing the exported symbols.
+    A better solution was to create this script which can generate a
+    Symbols file for Linux, MacoSX and any other OS that supports
+    minimising the number of exported symbols.
+
+    * configure.ac src/Makefile.am
+    Hook the new script into the build process.
+
+2003-12-10  Erik de Castro Lopo  <erikd AT mega-nerd DOT com>
+
+    * doc/index.html
+    Added comments about Steve Dekorte's SoundConverter scam.
+
+2003-12-07  Erik de Castro Lopo  <erikd AT mega-nerd DOT com>
+
+    * src/file_io.c
+    Axel Roebel pointed out that on Mac OSX a pipe is not considered a fifo
+    (S_ISFIFO (st.st_mode) is false) but a socket (S_ISSOCK (st.st_mode) is
+    true). The test has therefore been changed to is S_ISREG and anything
+    which which does not return true for S_ISREG is considered a pipe.
+
+2003-11-25  Erik de Castro Lopo  <erikd AT mega-nerd DOT com>
+
+    * tests/misc_test.c
+    Fix update_header_test to pass SDS.
+
+    * src/sds.c
+    More minor fixes.
+
+    * tests/floating_point_test.c
+    Add test for SDS files.
+
+    * src/command.c
+    Add SDS to major_formats array.
+
+2003-11-24  Erik de Castro Lopo  <erikd AT mega-nerd DOT com>
+
+    * tests/write_read_test.tpl tests/misc_test.c
+    Add tests for SDS files.
+
+    * src/sds.c
+    Fix a bug in header update code.
+
+2003-11-23  Erik de Castro Lopo  <erikd AT mega-nerd DOT com>
+
+    * src/sds.c
+    Get file write working.
+
+    * src/paf.c
+    Fix a potential bug in paf24_seek().
+
+2003-11-04  Erik de Castro Lopo  <erikd AT mega-nerd DOT com>
+
+    * doc/FAQ.html
+    Add Q/A about u-law encoded WAV files.
+
+    * Win32/*.h
+    Updated so it compiles on Win32.
+
+2003-11-03  Erik de Castro Lopo  <erikd AT mega-nerd DOT com>
+
+    * examples/sndfile-convert.c
+    Add -alaw and -ulaw command line arguments.
+
+    * configure.ac
+    Add library versioning comments.
+    Add arguments to AC_INIT.
+
+2003-10-28  Erik de Castro Lopo  <erikd AT mega-nerd DOT com>
+
+    * src/file_io.c
+    Ross Bencina has contributed code to replace all of the (mostly broken)
+    Win32 POSIX emulation calls with calls the native Win32 file I/O API.
+    This code still needs testing but is likely to be a huge improvemnt
+    of support for Win32. Thanks Ross.
+
+2003-10-27  Erik de Castro Lopo  <erikd AT mega-nerd DOT com>
+
+    * src/dwvw.c
+    Removed filedes field from the DWVW_PRIVATE struct.
+
+    * src/file_io.c
+    Change psf_fopen() so it returns psf->error instead of the file descriptor.
+    Add new functions psf_set_stdio() and psf_set_file().
+
+    * src/sndfile.c
+    Change these to work with changed psf_fopen() return value.
+    Remove all uses of psf->filedes from sndfile, making it easier to slot native
+    Win32 API file handling functions.
+
+    * src/test_file_io.c
+    Minor changes to make it compile with new file_io.c stuff.
+
+2003-10-26  Erik de Castro Lopo  <erikd AT mega-nerd DOT com>
+
+    * src/gsm610.h
+    Rename a variable from true to true_flag. As Ross Bencina points out,
+    true is defined in the C99 header <stdbool.h>.
+
+    * src/file_io.c
+    If fstat() fails, return SF_TRUE instead of -1 (Ross Bencina).
+
+2003-10-09  Erik de Castro Lopo  <erikd AT mega-nerd DOT com>
+
+    * src/common.h
+    Increase the size of SF_BUFFER_LEN and SF_HEADER_LEN.
+
+    * src/sndfile.c
+    Fix sf_read/write_raw which were dividing by psf->bytwidth and
+    psf->blockwidth which can both be zero.
+
+    * examples/sndfile-info.c
+    Increase size of BUFFER_LEN.
+
+2003-09-21  Erik de Castro Lopo  <erikd AT mega-nerd DOT com>
+
+    * configure.ac
+    Add checks for <sys/wait.h> and ssize_t.
+    Other Win32/MinGW checks.
+
+    * src/aiff.c src/au_g72x.c src/file_io.c src/gsm610.c src/interleave.c
+      src/paf.c src/sds.c src/svx.c src/voc.c src/w64.c src/wav.c src/xi.c
+    Fix compiler warnings.
+
+2003-09-20  Erik de Castro Lopo  <erikd AT mega-nerd DOT com>
+
+    * tests/scale_clip_test.tpl
+    Add definition of M_PI if needed.
+
+2003-09-19  Erik de Castro Lopo  <erikd AT mega-nerd DOT com>
+
+    * configure.ac
+    Detect if S_IRGRP is declared in <unistd.h>.
+
+    * src/file_io.c tests/*.tpl tests/*.c
+    More fixes for Win32/MSVC++ and MinGW. MinGW does have <unistd.h> but that
+    file doesn't declare S_IRGRP.
+
+2003-10-18  Erik de Castro Lopo  <erikd AT mega-nerd DOT com>
+
+    * src/config.h.in
+    Add comment stating that the sf_count_t typedef is determined when
+    libsndfile is being compiled.
+
+    * tests/utils.tpl
+    Modified so that utils.c gets one copy of the GPL and not two.
+
+
+2003-09-17  Erik de Castro Lopo  <erikd AT mega-nerd DOT com>
+
+    * Win32/unistd.h src/sf_unistd.h
+    Move first file to the second. This will help for Win32/MSVC++ and MinGW.
+
+    * Win32/Makefile.am src/Makefile.am
+    Changed in line with above.
+
+    * Win32/Makefile.msvc
+    Removed "/I Win32" which is no longer required.
+
+    * src/file_io.c src/test_file_io.c tests/*.tpl tests/*.c
+    If HAVE_UNISTD_H include <unistd.h> else include <sf_unistd.h>. This should
+    work for Win32, MinGW and other fakes Unix-like OSes.
+
+    * src/*.c
+    Removed #include <unistd.h> from files which didn't need it.
+
+2003-09-16  Erik de Castro Lopo  <erikd AT mega-nerd DOT com>
+
+    * libsndfile.spec.in
+    Apply fix from Andrew Schultz.
+
+2003-09-07  Erik de Castro Lopo  <erikd AT mega-nerd DOT com>
+
+    * src/vox_adpcm.c
+    Only set psf->sf.samplerate if the existing value is invalid.
+
+2003-09-06  Erik de Castro Lopo  <erikd AT mega-nerd DOT com>
+
+    * examples/sndfile-play.c
+    Started adding support for ALSA output.
+
+2003-09-04  Erik de Castro Lopo  <erikd AT mega-nerd DOT com>
+
+    * src/sndfile.h.in
+    Removed <stdlib.h> from sndfile.h.
+
+    * src/*.c examples/*.c tests/*.c tests/*.tpl
+    Added <stdlib.h> where needed.
+
+2003-09-02  Erik de Castro Lopo  <erikd AT mega-nerd DOT com>
+
+    * src/common.h
+    Added ARRAY_LEN, SF_MAX and SF_MIN macros.
+
+2003-08-19  Erik de Castro Lopo  <erikd AT mega-nerd DOT com>
+
+    * doc/index.html
+    Remove statements about alternative licensing arrangements.
+
+2003-08-17  Erik de Castro Lopo  <erikd AT mega-nerd DOT com>
+
+    * MacOS MacOS9 Makefile.am configure.ac
+    Change directory name from MacOS to MacOS9
+
+    * MacOS9/MacOS9-readme.txt
+    Change name to make it really obvious, add text to top of file to make it
+    still more obvious again.
+
+2003-08-16  Erik de Castro Lopo  <erikd AT mega-nerd DOT com>
+
+    * src/test_log_printf.c
+    Add tests for %u conversions.
+
+    * src/common.c
+    Fix psf_log_printf() %u conversions.
+
+2003-08-15  Erik de Castro Lopo  <erikd AT mega-nerd DOT com>
+
+    * src/aiff.c
+    Fixed a bug where opening a file with a non-trival header in SFM_RDWR mode
+    would over-write part of the header. Thanks to Axel Roebel for pointing
+    this out. Axel also provided a patch to fix this but I came up with a
+    neater and more general solution.
+    Return error when openning an AIFF file with data after the SSND chunk
+    (Thanks Axel Roebel).
+
+    * tests/aiff_rw_test.c
+    Improvements to test program which will later allow it to be generalised to
+    test WAV, SVX and others as required.
+
+2003-08-14  Erik de Castro Lopo  <erikd AT mega-nerd DOT com>
+
+    * tests/pipe_test.c
+    Add useek_pipe_rw_test() submitted by Russell Francis.
+
+    * src/sndfile.c
+    In sf_open_fd(), check if input file descriptor is a pipe.
+
+    * src/sndfile.[ch]
+    Fix typo in variable name do_not_close_descriptor.
+
+2003-08-13  Erik de Castro Lopo  <erikd AT mega-nerd DOT com>
+
+    * src/test_log_printf.c
+    Improve the tests for %d and %s conversions.
+
+    * src/common.c
+    Fixed a few problems in psf_log_printf() found using new tests.
+
+2003-08-06  Erik de Castro Lopo  <erikd AT mega-nerd DOT com>
+
+    * configure.ac
+    Add -Wwrite-strings warning to CFLAGS if the compiler is GCC. Thanks to
+    Peter Miller (Aegis author) for suggesting this and supplying a patch.
+
+    * src/*.c examples/*.c tests/*.c
+    Fix all compiler warnings arising from the above.
+
+2003-08-02
+
+    * tests/aiff_rw_test.c tests/Makefile.am
+    New test program to check for errors re-writing the headers of AIFC files
+    opened in mode SFM_RDWR.
+
+2003-07-21  Erik de Castro Lopo  <erikd AT mega-nerd DOT com>
+
+    * examples/sndfile-play.c
+    Applied a patch from Tero Pelander to allow this program to run on systems
+    using devfs which used /dev/sound/dsp instead of /dev/dsp.
+
+2003-07-11  Erik de Castro Lopo  <erikd AT mega-nerd DOT com>
+
+    * doc/new_file_type.HOWTO
+    Updated document. Still incomplete.
+
+2003-06-29  Erik de Castro Lopo  <erikd AT mega-nerd DOT com>
+
+    * src/sndfile.c
+    Fix VALIDATE_SNDFILE_AND_ASSIGN_PSF which was returning an error rather
+    than saving it and returning zero.
+
+2003-06-25  Erik de Castro Lopo  <erikd AT mega-nerd DOT com>
+
+    * src/file_io.c
+    Two fixes for Mac OS9.
+    Fix all casts from sf_count_t to ssize_t (not size_t).
+
+2003-06-22  Erik de Castro Lopo  <erikd AT mega-nerd DOT com>
+
+    * src/wav.c
+    Fix for reading files with RIFF length of 8 and data length of 0.
+
+2003-06-14  Erik de Castro Lopo  <erikd AT mega-nerd DOT com>
+
+    * src/*.c tests/*.c tests/*.tpl
+    Added comments to mark code for removal when make Lite version of
+    libsndfile.
+
+2003-06-09  Erik de Castro Lopo  <erikd AT mega-nerd DOT com>
+
+    * examples/sndfile-convert.c
+    Add extra error checking for unrecognised arguments.
+
+2003-06-08  Erik de Castro Lopo  <erikd AT mega-nerd DOT com>
+
+    * src/ima_adpcm.c
+    Started adding code to write IMA ADPCM encoded AIFF files.
+
+    * src/test_log_printf.c src/Makefile.am
+    New file to test psf_log_printf() function and add hooks into build system.
+
+    * src/common.c
+    Move psf_log_printf() function to top of the file and only compile the rest
+    of the file if if PSF_LOG_PRINTF_ONLY is not defined.
+
+2003-06-03  Erik de Castro Lopo  <erikd AT mega-nerd DOT com>
+
+    * Win32/config.h Win32/sndfile.h
+    Updated with new config variables.
+
+    * Win32/unistd.h src/file_io.c
+    Added implementation of S_ISFIFO macro which Win32 seems to lack and is
+    used in src/file_io.c.
+
+    * tests/utils.tpl
+    Added #include <unitstd.h> to pull in Win32/unistd.h so it compiles for
+    Win32.
+
+    * src/Makefile.msvc
+    Added src\test_file_io.exe build target and run this as the very first
+    test.
+
+    * tests/win32_test.c
+    Add support for testing Cygwin32.
+
+    * configure.ac
+    Detect POSIX fsync() and fdatasync() functions.
+
+    * src/file_io.c
+    If compiling for Cygwin, call fsync() before calling fstat() to retrieve
+    file length.
+
+    * tests/pcm_test.tpl
+    Add a test for lrintf() function. This was required to detect a really
+    broken lrint() and lrintf() on Cygwin.
+
+    * tests/misc_test.c
+    Don't run permission test when compiling under Cygwin.
+
+    * src/float_cast.h
+    Fix fallback macro for lrint() and lrintf() to cast to long instead of int
+    to match official function prototypes.
+
+2003-06-02  Erik de Castro Lopo  <erikd AT mega-nerd DOT com>
+
+    * examples/sndfile-convert.c
+    Modifications to improve accuracy of conversions; use double data for
+    floating point and int for everything else.
+
+    * src/ima_apdcm.c
+    Completed work on decoding IMA ADPCM encoded AIFF files. Still need to
+    get encoding working.
+
+2003-05-28  Erik de Castro Lopo  <erikd AT mega-nerd DOT com>
+
+    * src/aiff.c src/ima_adpcm.c
+    Start working on getting IMA ADPCM encoded AIFF files working.
+
+2003-05-27  Erik de Castro Lopo  <erikd AT mega-nerd DOT com>
+
+    * configure.ac
+    Fixed the touch command for when the autogen program is not found (Matt
+    Flax).
+
+    * src/ulaw.c src/alaw.c
+    Made these pipe-able.
+
+2003-05-24  Erik de Castro Lopo  <erikd AT mega-nerd DOT com>
+
+    * src/paf.c src/ircam.c
+    Fixed writing to pipe.
+
+    * src/wav.c src/aiff.c src/nist.c src/mat*.c src/svx.c src/w64.c
+    Return SFE_NO_PIPE_WRITE if an attempt is made to write to a pipe.
+
+2003-05-23  Erik de Castro Lopo  <erikd AT mega-nerd DOT com>
+
+    * examples/sndfile-info.c
+    Modified to detect unknown file lengths.
+
+    * src/mat4.c
+    Fix reading from a pipe.
+
+2003-05-22  Erik de Castro Lopo  <erikd AT mega-nerd DOT com>
+
+    * tests/pipe_test.c
+    Add more file types to tests.
+
+    * src/mat4.c
+    Removed explicit setting of psf->sf.seekable to SF_TRUE.
+
+    * tests/utils.tpl
+    Add macro for generating and check data in the stdio and pipe tests.
+
+    * tests/stdout_test.c tests/stdin_test.c
+    Use the above macro to generate known data on output and check data on
+    input.
+
+    * src/voc.c src/htk.c common.h sndfile.c
+    Disallow reading/writing VOC and HTK files from/to pipes be returning new
+    error values.
+
+    * src/w64.c
+    Fixes to allow reading from a pipe.
+
+2003-05-21  Erik de Castro Lopo  <erikd AT mega-nerd DOT com>
+
+    * configure.ac src/sndfile.h.in
+    When the configure script determines the sizeof (sf_count_t), also set the
+    value of SF_COUNT_MAX in sndfile.h.
+
+    * configure.ac
+    Remove -pedantic flag from default GCC compiler flags.
+
+    * tests/pipe_test.c
+    Add a pipe_read_test() before doing pipe_write_test().
+
+    * tests/scale_clip_test.c
+    Add test to make sure non-normalized values also clip in the right way.
+
+2003-05-18  Erik de Castro Lopo  <erikd AT mega-nerd DOT com>
+
+    * configure.ac
+    Add test to detect processor clipping capabilities.
+
+    * tests/stdin_test.c tests/stdout_test.c
+    Fix a pair of compiler warnings.
+
+    * src/common.h
+    Add new pipeoffset field to SF_PRIVATE. This will contain the current file
+    offset when operating on a pipe.
+
+    * src/common.c
+    Removed direct calls to psf_fread()/psf_fseek()/psf_fgets() etc from
+    psf_binheader_readf and redirect them to new buffered versions
+    header_read(), header_seek() and header_gets().
+    Add "G" format specifier to emulate fgets() functionality with buffering.
+    This will allow reading some file types from pipes.
+
+    * src/file_io.c
+    When the file descriptor is a pipe, manintain psf->pipeoffset.
+
+    * src/pvf.c
+    Change use of psf_fgets() to psf_binheader_readf() as required but changes to header re
+
+    * src/au.c
+    Fix reading from a pipe.
+
+2003-05-17  Erik de Castro Lopo  <erikd AT mega-nerd DOT com>
+
+    * src/pcm.c
+    Add clipping versions of the f2XXX_array() functions to allow option of
+    clipping data that would otherwise overflow.
+
+    * tests/scale_clip_test.tpl tests/scale_clip_test.def
+    New files test that clipping option does actually work.
+
+2003-05-14  Erik de Castro Lopo  <erikd AT mega-nerd DOT com>
+
+    * doc/index.html
+    Fixed a typo ("OS(" instead of "OS9").
+
+2003-05-13  Erik de Castro Lopo  <erikd AT mega-nerd DOT com>
+
+    * tests/open_fail_test.c
+    Include <string.h> to prevent warning message of missing declaration of
+    memset().
+
+2003-05-12  Erik de Castro Lopo  <erikd AT mega-nerd DOT com>
+
+    * src/common.h
+    Add new "add_clipping" field to SF_PRIVATE.
+
+    * src/sndfile.h.in src/sndfile.c
+    Add command SFC_SET_CLIPPING which sets/resets add_clipping field.
+
+2003-05-11  Erik de Castro Lopo  <erikd AT mega-nerd DOT com>
+
+    * doc/api.html
+    Add docs for sf_set_string() and sf_get_string().
+
+    * src/common.h src/sndfile.c
+    Add new SFE_STR_BAD_STRING error.
+
+    * tests/stdin_test.c tests/stdout_test.c
+    Removed all non-error print statements.
+
+    * tests/stdio_test.c tests/pipe_test.c tests/Makefile.am
+    Add print statements removed from two files above.
+
+2003-05-10  Erik de Castro Lopo  <erikd AT mega-nerd DOT com>
+
+    * libsndfile.spec.in
+    Fixed a coulpe of minor errors discovered by someone calling themselves
+    Agent Smith.
+
+    * src/common.c src/common.h src/file_io.h
+    Added is_pipe field to SF_PRIVATE and declaration of psf_is_pipe()
+    function. (Axel Roebel)
+
+    * src/sndfile.c
+    Fixed determination of whether the file is a pipe. (Axel Roebel)
+
+    * src/paf.c
+    Force paf24 to start with undefined mode. (Axel Roebel)
+
+    * tests/pipe_test.c
+    Mods to make this test work and actually do the test on RAW files. (Axel
+    Roebel).
+
+2003-05-05  Erik de Castro Lopo  <erikd AT mega-nerd DOT com>
+
+    * src/sndfile.c
+    Fixed a potential bug where psf->sf.seekable was being set to FALSE when
+    operating on stdin or stdout but then the default initialiser was reseting
+    it to TRUE. Thanks to Axel Roebel.
+
+    * src/aiff.c
+    Fixed a bug in the header parser where it was not handling an odd length
+    COMM chunk correctly. Thanks to Axel Roebel.
+
+    * src/test_file_io.c
+    Add more tests.
+
+    * tests/win32_test.c
+    New file for showing the bugs in the Win32 implementation of the POSIX API.
+    It also runs on Linux for sanity checking.
+
+    * tests/Makefile.am Win32/Makefile.msvc
+    Hook the new test program into the build system.
+
+2003-05-04  Erik de Castro Lopo  <erikd AT mega-nerd DOT com>
+
+    * src/test_file_io.c
+    New test program to test operation of functions defined in file_io.c. This
+    should make supporting win32 significantly easier.
+
+    * src/Makefile.am
+    Hook new test program into the build system.
+
+    * src/file_io.c
+    Add compile/run time check that sizeof statbuf.st_size and sf_count_t are
+    the same.
+
+    * src/common.h src/sndfile.c
+    Added new error code and error message for new check.
+
+    * tests/benchmark.tpl
+    Fix to use frames instead of samples in SF_INFO.
+
+2003-05-03  Erik de Castro Lopo  <erikd AT mega-nerd DOT com>
+
+    * src/file_io.c
+    More stuffing about working around PLAIN OLD-FASHIONED **BUGS** in Win32.
+
+    * examples/sndfile-info.c
+    Applied patch from Conrad Parker to add "--help" and "-h" options as
+    well as an improved usage message.
+
+2003-05-02  Erik de Castro Lopo  <erikd AT mega-nerd DOT com>
+
+    * src/au.c
+    Added embedded file support.
+
+    * tests/multi_file_test.c
+    Added tests for embedded AU files.
+    Added verbose testing mode.
+
+    * src/common.h src/sndfile.c
+    Added an embedded AU specific error code and message.
+
+    * src/wav.c
+    Added patch from Conrad Parker which filled in a little more information
+    about ACIDized WAV files.
+
+2003-04-30  Erik de Castro Lopo  <erikd AT mega-nerd DOT com>
+
+    * src/file_io.c
+    Fixed Win32 version of psf_fseek() which was calling psf_get_filelen()
+    which was in turn calling psf_fseek() which in the end blew the stack.
+    Now of course this would have been easy to find on Linux, but this blow
+    up was happening in kernel32.dll and the fscking MSVC++ debugger couldn't
+    figure out what call caused this (it couldn't even tell me the stack had
+    overflowed) and was absolutley useless for this debugging exercise.
+    On top of that, the reason I got into this mess was that windoze doesn't
+    have a working fstat() function which can return file lengths > 2 Gig. It
+    HAS a fscking _fstati64() but the file length value is only updated AFTER
+    the bloody file is closed. That makes it completely useless.
+    How the hell do people stand working on this crap excuse of an OS?
+
+2003-04-29  Erik de Castro Lopo  <erikd AT mega-nerd DOT com>
+
+    * Win32/unistd.h src/file_io.c
+    Moved definitions of S_IGRP etc from file_io.c to unistd.h so that these
+    can be used in the test programs.
+
+    * Win32/libsndfile.def
+    Added sf_open_fd.
+
+    * Win32/sndfile.h
+    Updated to match src/sndfile.h.in.
+
+    * Win32/Makefile.msvc
+    Added dither.c and htk.c to libsndfile.dll target.
+
+2003-04-28  Erik de Castro Lopo  <erikd AT mega-nerd DOT com>
+
+    * src/file_io.c
+    First attempt at getting the Win32 versions of the these functions working.
+    They still need to be tested.
+
+2003-04-27  Erik de Castro Lopo  <erikd AT mega-nerd DOT com>
+
+    * src/strings.c
+    Found and fixed a bug which was causing psf_store_string() to fail on
+    Motorola 68k processors. Many thanks fo Joshua Haberman (Debian maintainer
+    of libsndfile) for compiling and running debug code to help me debug the
+    problem.
+
+2003-04-26  Erik de Castro Lopo  <erikd AT mega-nerd DOT com>
+
+    * src/sndfile.c src/file_io.c src/wav.c src/aiff.c
+    Much hacking to get reading and writing of embedded files working (ie sound
+    files at a non-zero files offset).
+
+    * doc/embedded_files.html
+    First pass atempt at documenting reading/writing embedded files.
+
+2003-04-21  Erik de Castro Lopo  <erikd AT mega-nerd DOT com>
+
+    * doc/FAQ.html
+    Updated answer to "Why doesn't libsndfile do interleaving/de-interleaving?"
+
+2003-04-19  Erik de Castro Lopo  <erikd AT mega-nerd DOT com>
+
+    * src/wav.c src/aiff.c
+    Fix retrieving and storing of string data from files. Need to be careful
+    about using psf->buffer for strings.
+
+2003-04-18  Erik de Castro Lopo  <erikd AT mega-nerd DOT com>
+
+    * src/file_io.c
+    Fix psf_fseek() for seeks withing embedded files.
+
+2003-04-15  Erik de Castro Lopo  <erikd AT mega-nerd DOT com>
+
+    * src/sndfile.h.in
+    Changed the definition of SNDFILE slightly to produce warnings when it isn't
+    used correctly. This should have zero affect in code which uses the SNDFILE
+    type correctly.
+
+    * src/sndfile.c
+    Fixed a few compiler warnings cause by the changes to the SNDFILE type.
+
+2003-04-12  Erik de Castro Lopo  <erikd AT mega-nerd DOT com>
+
+    * doc/FAQ.html
+    Added question and answer to the question "How about adding the ability
+    to write/read sound files to/from memory buffers?".
+
+2003-04-08  Erik de Castro Lopo  <erikd AT mega-nerd DOT com>
+
+    * tests/write_read_test.tpl
+    Removed un-needed enums declaring TRUE and FALSE and replaced usage of
+    these with SF_TRUE and SF_FALSE.
+
+    * tests/multi_file_test.c
+    New test program to test sf_open_fd() on files containing data other than
+    a single sound file.
+
+2003-04-06  Erik de Castro Lopo  <erikd AT mega-nerd DOT com>
+
+    * src/file_io.c
+    When creating files, set the readable by others flag. This still allows
+    further restrictions to be enforced by use of the user's umask. Fix
+    suggested by Eric Lyon.
+
+2003-04-05  Erik de Castro Lopo  <erikd AT mega-nerd DOT com>
+
+    * src/sndfile.h.in src/sndfile.c
+    Changed sf_open_fd(). Dropped offset parameter and added a close_desc
+    parameter. If close desc is TRUE, the file descritpor passed into the
+    library will be closed when sf_close() is called.
+
+    * tests/utils.tpl
+    Modified call to sf_open_fd() to set close_desc parameter to SF_TRUE.
+
+2003-04-04  Erik de Castro Lopo  <erikd AT mega-nerd DOT com>
+
+    * tests/write_read_test.tpl
+    Add a string (using sf_set_string() function) before and after data section
+    of all files. This will make sure that if string data can be added, it
+    doesn't overwrite real audio data.
+
+2003-04-02  Erik de Castro Lopo  <erikd AT mega-nerd DOT com>
+
+    * src/sndfile.c
+    Started work on supporting a non-zero offset parameter for sf_open_fd ().
+
+    * src/<file header parsers>.c
+    Removed many uses of psf_fseek (SEEK_END) which to allow for future use of
+    sf_open_fd() with non-zero offset.
+    Associated refactoring.
+
+    * src/aiff.c
+    Implemented functionality required to get sf_get_string() and
+    sf_set_string() working for AIFF files.
+
+2003-04-01  Erik de Castro Lopo  <erikd AT mega-nerd DOT com>
+
+    * tests/utils.tpl
+    Modified test_open_file_or_die() to alternately use sf_open() and
+    sf_open_fd().
+
+    * src/svx.c
+    Fixed a bug which occurred when openning an existing file for read/write
+    using sf_open_fd(). In this case, the existing NAME chunk needs to be
+    read into psf->filename.
+    Fixed printing of sf_count_t types to logbuffer.
+
+2003-03-31  Erik de Castro Lopo  <erikd AT mega-nerd DOT com>
+
+    * src/sndfile.h.in
+    Added prototype for new function sf_open_fd().
+
+    * src/sndfile.c
+    Moved most of the code in sf_open() to a new function psf_open_file().
+    Created new function sf_open_fd() which also uses psf_open_file() but
+    does not currently support the offset parameter.
+
+    * doc/api.html
+    Document sf_open_fd().
+
+2003-03-09  Erik de Castro Lopo  <erikd AT mega-nerd DOT com>
+
+    * src/sndfile.c
+    Fixed a memory leak reported by Evgeny Karpov. Memory leak only occurred
+    when an attempt was made to read and the open() call fails.
+
+2003-03-08  Erik de Castro Lopo  <erikd AT mega-nerd DOT com>
+
+    * tests/open_fail_test.c
+    New test program to check for memory leaks when sf_open fails on a valid
+    file. Currently this must be run manually under valgrid.
+
+    * tests/Makefile.am
+    Hook new test program into build.
+
+2003-03-03  Erik de Castro Lopo  <erikd AT mega-nerd DOT com>
+
+    * Octave/sndfile_save.m Octave/sndfile_play.m
+    Added a -mat-binary option to the octave save command to force the output
+    to binary mode even if the user has set ascii data as the default. Found
+    by Christopher Moore.
+
+2003-02-27  Erik de Castro Lopo  <erikd AT mega-nerd DOT com>
+
+    * doc/dither.html
+    New file which will document the interface which allows the addition of
+    audio dither when sample word sizes are being reduced.
+
+    * src/dither.c
+    More work.
+
+2003-02-26  Erik de Castro Lopo  <erikd AT mega-nerd DOT com>
+
+    * tests/misc_test.c
+    In update_header_test(), make HTK files a special case.
+
+    * doc/index.html
+    Added HTK to the feature matrix.
+
+2003-02-25  Erik de Castro Lopo  <erikd AT mega-nerd DOT com>
+
+    * src/htk.c
+    New file for reading/writing HMM Tool Kit files.
+
+    * src/sndfile.h.in src/sndfile.c src/command.c src/Makefile.am
+    Hook in htk.c
+
+    * tests/write_read_test.tpl tests/misc_test.c tests/Makefile.am
+    Add tests for HTK files.
+
+2003-02-22  Erik de Castro Lopo  <erikd AT mega-nerd DOT com>
+
+    * src/wav.c
+    Fixed a bug where the LIST chunk length was being written incorrectly.
+
+    * tests/string_test.c
+    Added call to check_log_buffer().
+    Minor cleanups.
+
+2003-02-10  Erik de Castro Lopo  <erikd AT mega-nerd DOT com>
+
+    * src/wav_w64.h
+    Applied patch from Antoine Mathys to add extra WAV format definitions and
+    a G72x_ADPCM_WAV_FMT struct definition.
+
+    * src/wav_w64.c
+    Applied patch from Antoine Mathys which converts wav_w64_format_str() from
+    one huge inefficient switch statement to a binary search.
+
+    * tests/string_test.c
+    Dump log buffer if tests fail.
+
+2003-02-07  Erik de Castro Lopo  <erikd AT mega-nerd DOT com>
+
+    * tests/string_test.c
+    David Viens supplied some modifications to this file which showed up a bug
+    when using sf_set_string() and the sf_writef_float() functions.
+
+    * src/sndfile.c
+    Fixed the above bug.
+
+2003-02-06  Erik de Castro Lopo  <erikd AT mega-nerd DOT com>
+
+    * doc/FAQ.html
+    Added Q and A on how to detect libsndfile in configure.in (at the suggestion
+    of Davy Durham).
+
+2003-02-05  Erik de Castro Lopo  <erikd AT mega-nerd DOT com>
+
+    * src/sndfile.h.in
+    Add enums and typedefs for dither.
+    Deprecate SFC_SET_ADD_DITHER_ON_WRITE and SFC_SET_ADD_DITHER_ON_READ, to be
+    replaced with SFC_SET_DITHER_ON_WRITE and SFC_SET_DITHER_ON_READ which will
+    allow different dither algorithms to be enabled.
+    Added SFC_GET_DITHER_INFO_COUNT and SFC_GET_DITHER_INFO.
+
+    * src/sndfile.h.in src/Version_script.in Win32/libsndfile.def.
+    Added public sf_dither_*() functions.
+
+    * src/sndfile.c
+    Implement commands above.
+
+    * src/dither.c
+    More work. Framework and external hooks into dither algorithms complete.
+
+2003-02-03  Erik de Castro Lopo  <erikd AT mega-nerd DOT com>
+
+    * doc/version-1.html libsndfile_version_convert.py
+    Remove redundant files.
+
+    * doc/index.html doc/api.html
+    Remove links to version-1.html.
+
+    * src/dither.c
+    New file to allow the addition of audio dither on input and output.
+
+    * src/common.h
+    Add prototype for dither_init() function.
+
+    * Makefile.am doc/Makefile.am
+    Changes for added and removed files.
+
+2003-02-02  Erik de Castro Lopo  <erikd AT mega-nerd DOT com>
+
+    * Win32/Makefile.msvc
+    Changes to force example binaries to be placed in the top level directory
+    instead of the examples/ directory.
+    Add src/strings.c and src/xi.c to the build.
+    Add string_test to build and to tests on WAV files.
+
+    * doc/index.html
+    Added XI to support matrix.
+
+2003-01-27  Erik de Castro Lopo  <erikd AT mega-nerd DOT com>
+
+    * src/sndfile.h.in
+    Added prototypes for sf_get_string() and sf_set_string() and SF_STR_*
+    enum values.
+
+    * src/sndfile.c
+    Added public interface to sf_get_string() and sf_set_string().
+
+    * src/wav.c
+    Added code for setting and getting strings in WAV files.
+
+    * tests/string_test.c
+    New test program for sf_get_string() and sf_set_string() functionality.
+
+    * tests/Makefile.am
+    Hook new test program into build and test framework.
+
+2003-01-26  Erik de Castro Lopo  <erikd AT mega-nerd DOT com>
+
+    * src/common.h
+    Added fields to SF_PRIVATE for string data needed to implement
+    sf_get_string() and sf_set_string().
+
+    * src/strings.c
+    New file for storing and retrieving strings to/from files.
+
+    * src/Makefile.am
+    Added strings.c to build.
+
+2003-01-25  Erik de Castro Lopo  <erikd AT mega-nerd DOT com>
+
+    * src/xi.c
+    Read seems to be working so looking at write.
+
+    * src/sndfile.h.in
+    Added SF_FORMAT_XI, SF_FORMAT_DPCM_8 and SF_FORMAT_DPCM_16 enum values.
+
+    * tests/floating_point_test.c tests/lossy_comp_test.c tests/Makefile.am
+    Added test for 8 and 16 bit XI format files.
+
+2003-01-24  Erik de Castro Lopo  <erikd AT mega-nerd DOT com>
+
+    * doc/index.html
+    Added a non-lawyer readable summary of the licensing provisions as
+    suggested by Steve Dekorte.
+
+2003-01-23  Erik de Castro Lopo  <erikd AT mega-nerd DOT com>
+
+    * src/wav.c
+    Fixed a compiler warning found by Alexander Lerch.
+
+2003-01-18  Erik de Castro Lopo  <erikd AT mega-nerd DOT com>
+
+    * configure.ac
+    Fixed the multiple linking of libm.
+
+2003-01-17  Erik de Castro Lopo  <erikd AT mega-nerd DOT com>
+
+    * Win32/Makefile.mcvs
+    Added comments on the correct way to set up the MSVCDir environment
+    variable.
+
+    * doc/win32.html
+    Add on how to set up the MSVCDir environment variable.
+
+2003-01-15  Erik de Castro Lopo  <erikd AT mega-nerd DOT com>
+
+    * examples/sndfile-play.c examples/sndfile-info.c
+    When run on Win32 without any command line parameters print a message and
+    then sleep for 5 seconds. This means the when somebody double clicks on
+    these programs in explorer the user will actually see the message.
+
+2003-01-14  Erik de Castro Lopo  <erikd AT mega-nerd DOT com>
+
+    * tests/misc_test.c
+    Bypass permission test if running as root because root is allowed to open
+    a readonly file for write.
+
+2003-01-08  Erik de Castro Lopo  <erikd AT mega-nerd DOT com>
+
+    * Win32/Makefile.msvc
+    Added pvf.c and xi.c source files to project.
+
+    * src/sndfile.h
+    Updated for PVF files.
+
+2003-01-07  Erik de Castro Lopo  <erikd AT mega-nerd DOT com>
+
+    * src/sndfile.c
+    Modified validate_sfinfo() to force samplerate, channels and sections
+    to be >= 1.
+    In format_from_extension() replaced calls to does_extension_match()
+    with strcmp().
+
+    * src/xi.c
+    More work.
+
+2003-01-06  Erik de Castro Lopo  <erikd AT mega-nerd DOT com>
+
+    * doc/Makefile.am
+    Added octave.html which had been left out. Found by Jan Weil.
+
+2003-01-05  Erik de Castro Lopo  <erikd AT mega-nerd DOT com>
+
+    * src/pvf.c src/common.h src/sndfile.c
+    Fixed error handling for PVF files.
+
+    * src/xi.c
+    New file for handling Fasttracker 2 Extended Instrument files. Not working
+    yet and included when configured with --enable-experimental.
+
+    * src/sndfile.c src/common.h
+    Hooked in new file xi.c.
+
+2002-12-30  Erik de Castro Lopo  <erikd AT mega-nerd DOT com>
+
+    * src/rx2.c
+    Added a patch from Marek Peteraj which sheds a little more light on the
+    slices within an RX2 file. Still need to find out data encoding.
+
+2002-12-20  Erik de Castro Lopo  <erikd AT mega-nerd DOT com>
+
+    * src/wav.c
+    Started work on decoding 'acid' and 'strc' chunks.
+
+2002-12-14  Erik de Castro Lopo  <erikd AT mega-nerd DOT com>
+
+    * tests/peak_check_test.c
+    Minor cleanup.
+
+2002-12-12  Erik de Castro Lopo  <erikd AT mega-nerd DOT com>
+
+    * tests/write_read_test.tpl
+    Added check to make sure no error was generated when an attempt was made to
+    read past the end of the file.
+
+2002-12-11  Erik de Castro Lopo  <erikd AT mega-nerd DOT com>
+
+    * doc/lists.html
+    Added "mailto" links for all three lists.
+
+    * src/pvf.c
+    New file for Portable Voice Format files.
+
+    * src/sndfile.h.in src/sndfile.c src/common.h src/command.c src/Makefile.am
+    Added hooks for SF_FORMAT_PVF format files.
+
+    * tests/write_read_test.tpl tests/std*.c
+    Add tests for SF_FORMAT_PVF.
+
+    * doc/index.html
+    Add PVF to the compatibility matrix.
+
+    * src/pcm.c src/alaw.c src/ulaw.c src/float32.c src/double64.c
+    Previously, attempts to read beyond the end of a file would set psf->error
+    to SFE_SHORT_ERROR. This behaviour diverged from the behaviour of the POSIX
+    read() call but has now been fixed.
+    Attempts to read beyond the end of the file will return a short read count
+    but will not longer set any error.
+
+2002-12-09  Erik de Castro Lopo  <erikd AT mega-nerd DOT com>
+
+    * src/sndfile.c
+    Add more sanity checking when opening a RAW file for read. When format is
+    not RAW, zero out all members of the SF_INFO struct.
+
+    * tests/raw_test.c
+    Add bad_raw_test() to check for above problem.
+
+    * tests/stdin_test.c examples/sndfile-info.c
+    Set the format field of the SF_INFO struct to zero before calling
+    sf_open().
+
+    * doc/api.html
+    Add information about the need to set the format field of the SF_INFO struct
+    to zero when opening non-RAW files for read.
+
+    * configure.ac
+    Removed use of conversion script on Solaris. Not all Solaris versions
+    support it.
+
+    * doc/lists.html
+    New file containg details of the mailing lists.
+
+    * doc/index.html
+    Add a link to the above new file.
+
+2002-12-04  Erik de Castro Lopo  <erikd AT mega-nerd DOT com>
+
+    * tests/dft_cmp.c
+    Fixed a SIGFPE on Alpha caused by a log10 (0.0). Thanks to Joshua Haberman
+    for providing the gdb traceback.
+
+2002-11-28  Erik de Castro Lopo  <erikd AT mega-nerd DOT com>
+
+    * src/wav.c
+    Added more capabilities to 'smpl' chunk parser.
+
+    * src/sndfile.c
+    Fixed some (not all) possible problems found with Flawfinder.
+
+2002-11-24  Erik de Castro Lopo  <erikd AT mega-nerd DOT com>
+
+    * src/sndfile.c
+    Fixed a bug in sf_seek(). This bug could only occur when an attempt was
+    made to read beyond the end and then sf_seek() was called with a whence
+    parameter of SEEK_CUR.
+
+    * src/file_io.c
+    Win32's _fstati64() does not work, it returns BS. Re-implemented
+    psf_get_filelen() in terms of psf_fseek().
+
+    * tests/write_read_test.tpl
+    Add a test to detect above bug.
+
+    * src/float_cast.h
+    Modification to prevent compiler warnings on Mac OS X.
+
+    * src/file_io.c
+    Fixes for windows (what a f**ked OS).
+
+2002-11-08  Erik de Castro Lopo  <erikd AT mega-nerd DOT com>
+
+    * configure.ac
+    Disable use of native lrint()/lrintf() on Mac OSX. These functions exist on
+    Mac OSX 10.2 but not on 10.1. Forcing the use of the versions in
+    src/float_cast.h means that a library compiled on 10.2 will still work on
+    10.1.
+
+2002-11-06  Erik de Castro Lopo  <erikd AT mega-nerd DOT com>
+
+    * configure.in configure.ac
+    Renamed configure.in to configure.ac as expected by later versions of
+    autoconf.
+    Slight hacking of configure.ac to work with version 2.54 of autoconf.
+    Changed to using -dumpversion instead of --version for determining GCC
+    version numer as suggested by Anand Kumria.
+
+    * src/G72x/Makefile.am
+    Slight hacking required for operation with automake 1.6.3.
+
+2002-11-05  Erik de Castro Lopo  <erikd AT mega-nerd DOT com>
+
+    * src/common.c
+    In psf_binheader_readf() changed type parameter type "b" type from size_t
+    to int to prevent errors on IA64 CPU where sizeof (size_t) != sizeof (int).
+    Thanks to Enrique Robledo Arnuncio for debugging this.
+
+2002-11-04  Erik de Castro Lopo  <erikd AT mega-nerd DOT com>
+
+    * test/command_test.tpl
+    Changed test value so test would pass on Solaris.
+
+    * src/Version_script.in
+    Modified version numbering so that later versions of 1.0.X can replace
+    earlier versions without recompilation.
+
+    * src/vox_adpcm.c
+    Fixed bug causing short reads.
+
+2002-11-03  Erik de Castro Lopo  <erikd AT mega-nerd DOT com>
+
+    * test/floating_point_test.c
+    Code cleanup using functions from util.c.
+    Add test for IEEE replacement floats and doubles.
+
+2002-11-01  Erik de Castro Lopo  <erikd AT mega-nerd DOT com>
+
+    * src/wav.c
+    Fixed a possible divide by zero error when read the 'smpl' chunk. Thanks to
+    Serg Repalov for the example file.
+
+    * tests/pcm_test.tpl
+    Used sf_command (SFC_TEST_IEEE_FLOAT_REPLACE) to test IEEE replacement code.
+    Clean up pcm_double_test().
+
+    * src/float32.c src/double64.c
+    Force use of IEEE replacement code using psf->ieee_replace is TRUE,
+    Print message to log_buffer as well.
+    Rename all broken_read_* and broken_write* functions to replace_read_* and
+    replace_write_*.
+
+    * tests/util.tpl
+    Added string_in_log_buffer().
+
+    * tests/pcm_test.tpl
+    Use string_in_log_buffer() to ensure that IEEE replacement code has been
+    used.
+
+    * configure.in
+    Removed --enable-force-broken-float option. IEEE replacement code is now
+    always tested.
+
+2002-10-31  Erik de Castro Lopo  <erikd AT mega-nerd DOT com>
+
+    * src/double64.c
+    Implement code for read/writing IEEE doubles on platforms where the native
+    double format is not IEEE.
+
+    * src/float32.c src/common.h
+    Remove float32_read() and float32_write(). Replace with float32_le_read(),
+    float32_be_read(), float32_le_write() and float32_be_write() to match stuff
+    in src/double64.c.
+
+    * src/common.c
+    Fix all usage of float32_write().
+
+    * src/sndfile.h.in
+    Added SFC_TEST_IEEE_FLOAT_REPLACE command (testing only).
+
+    * src/common.h
+    Added SF_PRIVATE field ieee_replace.
+
+    * src/sndfile.c
+    In sf_command() set/reset psf->ieee_replace.
+
+2002-10-26  Erik de Castro Lopo  <erikd AT mega-nerd DOT com>
+
+    * tests/pcm_test.tpl
+    Fixed a problem when testing with --enable-force-broken-float. The test was
+    generating a value of negative zero and the broken float code is not able
+    to write negative zero. Removing the negative zero fixed the test.
+
+2002-10-25  Erik de Castro Lopo  <erikd AT mega-nerd DOT com>
+
+    * src/file_io.c
+    Added fix for Cygwin (suggested by Maros Michalik).
+
+2002-10-23  Erik de Castro Lopo  <erikd AT mega-nerd DOT com>
+
+    * src/file_io.c
+    Improved error detection and handling.
+
+    * src/file_io.c src/common.h
+    Removed functions psf_ferror() and psf_clearerr() which were redundant
+    after above improvements.
+
+    * src/aiff.c src/svx.c src/w64.c src/wav.c
+    Removed all use of psf_ferror() and psf_clearerr().
+
+    * src/sndfile.c
+    Removed #include of <stdio.h>, <unistd.h>, <fcntl.h> and <math.h> which
+    are no longer needed.
+
+    * tests/misc_test.c
+    Added test to make sure the correct error message is returned with an
+    existing read-only file is openned for write.
+
+2002-10-21  Erik de Castro Lopo  <erikd AT mega-nerd DOT com>
+
+    * doc/index.html doc/api.html
+    Updated for OKI Dialogic ADPCM files.
+
+    * src/command.c
+    Added VOX ADPCM to sub_fomats.
+
+2002-10-20  Erik de Castro Lopo  <erikd AT mega-nerd DOT com>
+
+    * src/vox_adpcm.c src/Makefile.am
+    New file for handling OKI Dialogic ADPCM files.
+
+    * src/sndfile.h
+    Add new subtype SF_FORMAT_VOX_ADPCM.
+
+    * src/sndfile.c
+    Renamed function is_au_snd_file () to format_from_extenstion () and expanded
+    its functionality to detect headerless VOX files.
+
+    * src/raw.c
+    Added hooks for SF_FORMAT_VOX_ADPCM.
+
+    * examples/sndfile-info.c
+    Print out file duration (suggested by Conrad Parker).
+
+    * libsndfile.spec.in
+    Force installation of sndfile.pc file (found by John Thompson).
+
+    * tests/Makefile.am tests/lossy_comp_test.c tests/floating_point_test.c
+    Add tests for SF_FORMAT_VOX_ADPCM.
+
+2002-10-18  Erik de Castro Lopo  <erikd AT mega-nerd DOT com>
+
+    * tests/misc_test.c
+    Add test which attempts to write to /dev/full (on Linux anyway) to check
+    for correct handling of writing to a full filesystem.
+
+    * src/sndfile.c
+    Return correct error message if the header cannot be written because the
+    filesystem is full.
+
+    * tests/util.tpl
+    Corrected printing of file mode in error reporting.
+
+    * src/mat5.c
+    Fixed a bug where a MAT5 file written by libsndfile could not be opened by
+    Octave 2.1.36.
+
+2002-10-13  Erik de Castro Lopo  <erikd AT mega-nerd DOT com>
+
+    * src/common.h src/file_io.c
+    All low level file I/O have been modified to be better able to report
+    system errors resulting from calling system level open/read/write etc.
+
+    * src/*.c
+    Updated for compatibility with above changes.
+
+    * examples/cooledit-fixer.c
+    New example program which fixes badly broken file created by Syntrillium's
+    Cooledit which are marked as containing PCM samples but actually contain
+    floating point data.
+
+    * examples/Makefile.am
+    Hooked cooledit-fixer into the build system.
+
+2002-10-10  Erik de Castro Lopo  <erikd AT mega-nerd DOT com>
+
+    * doc/command.html
+    Document SFC_GET_FORMAT_INFO.
+
+2002-10-09  Erik de Castro Lopo  <erikd AT mega-nerd DOT com>
+
+    * examples/wav32_aiff24.c examples/sndfile2oct.c examples/sfhexdump.c
+        examples/sfdump.c
+    Removed these files because they weren't interesting.
+
+    * examples/sfconvert.c examples/sndfile-convert.c
+    Renamed the first to the latter.
+
+    * examples/Makefile.am
+    Added sndfile-convert to the bin_PROGRAMS, so it is installed when the lib
+    is installed.
+    Removed old programs wav32_aiff24 and sndfile2oct.
+
+    * man/sndfile-convert.1
+    New man page.
+
+    * examples/sndfile-convert.c
+    Added some gloss now that sndfile-convert.c is an installed program.
+
+    * src/sndfile.h.in src/sndfile.c src/common.h src/command.h
+    Added command SFC_GET_FORMAT_INFO.
+
+    * tests/command_test.c
+    Added tests form SFC_GET_FORMAT_INFO.
+
+2002-10-08  Erik de Castro Lopo  <erikd AT mega-nerd DOT com>
+
+    * src/sndfile.c
+    In sf_format_check() return error if samplerate < 0.
+
+2002-10-07  Erik de Castro Lopo  <erikd AT mega-nerd DOT com>
+
+    * src/aiff.c
+    Fixed bug in handling of COMM chunks with a 4 byte encoding byte but no
+    encoding string.
+
+2002-10-06  Erik de Castro Lopo  <erikd AT mega-nerd DOT com>
+
+    * src/sndfile.c
+    Fixed repeated word in an error message.
+
+2002-10-05  Erik de Castro Lopo  <erikd AT mega-nerd DOT com>
+
+    * doc/index.html
+    Improved advertising in Features section.
+
+2002-10-04  Erik de Castro Lopo  <erikd AT mega-nerd DOT com>
+
+    * src/wav.c
+    Added decoding of 'labl' chunks within 'LIST' chunks.
+
+    * src/common.h
+    Added (experimental only) SF_FORMAT_OGG and SF_FORMAT_VORBIS and definition
+    of ogg_open(). This is nowhere near working yet.
+
+    * src/sndfile.c
+    Added detection of 'OggS' file marker and added call to ogg_open() to
+    switch statement.
+
+    * src/ogg.c
+    New file. Very early start of Ogg Vorbis support.
+
+    * src/wav.c
+    Added handling of brain-damaged and broken Cooledit "32 bit 24.0 float
+    type 1" files. These files are marked as being 24 bit WAVE_FORMAT_PCM with
+    a block alignment of 4 times the numbers of channels but are in fact 32 bit
+    floating point.
+
+2002-10-02  Erik de Castro Lopo  <erikd AT mega-nerd DOT com>
+
+    * configure.in
+    Modified option --enable-experimental to set ENABLE_EXPERIMENTAL_CODE in
+    config.h to either 0 or 1.
+
+    * src/sndfile.c
+    Modify sf_command (SFC_GET_LIB_VERSION) to append "-exp" to the version
+    string if experimental code has been enabled.
+
+2002-10-01  Erik de Castro Lopo  <erikd AT mega-nerd DOT com>
+
+    * src/Makefile.am
+    Added -lm to libsndfile_la_LIBADD. This means that -lm is not longer needed
+    in the link line when linking something to libsndfile.
+
+    * tests/Makefile.am examples/Makefile.am
+    Removed -lm from all link lines.
+
+    * sndfile.pc.in
+    Removed -lm from Libs line.
+
+2002-09-24  Erik de Castro Lopo  <erikd AT mega-nerd DOT com>
+
+    * src/file_io.c
+    Removed all perror() calls.
+
+    * src/nist.c
+    Removed calls to exit() function.
+    Added check to detect NIST files dammaged from Unix CR -> Win32 CRLF
+    conversion process.
+
+2002-09-24  Erik de Castro Lopo  <erikd AT mega-nerd DOT com>
+
+    * src/sndfile.h.in src/sndfile.c
+    New function sf_strerror() which will eventually replace functions
+    sf_perror() and sf_error_str().
+    Function sf_error_number() has also been changed, but this was documented
+    as being for testing only.
+
+    * doc/api.html
+    Documented above changes.
+
+    * tests/*.c examples/*.c
+    Changed to new error functions.
+
+2002-09-22  Erik de Castro Lopo  <erikd AT mega-nerd DOT com>
+
+    * configure.in
+    Detect GCC version, and print a warning message about writeable strings
+    it GCC major version number is less than 3.
+
+2002-09-21  Erik de Castro Lopo  <erikd AT mega-nerd DOT com>
+
+    * src/sndfile.h.in doc/api.html
+    Documentation fixes.
+
+2002-09-19  Erik de Castro Lopo  <erikd AT mega-nerd DOT com>
+
+    * src/Version_script.in src/Makefile.am configure.in
+    Use the version script to prevent the exporting of all non public symbols.
+    This currently only works with Linux. Will test on Solaris as well.
+
+    * src/float_cast.h
+    Added #ifndef to prevent the #warning directives killing the SGI MIPSpro
+    compiler.
+
+    * src/au_g72x.c src/double64.c src/float32.c src/gsm610.c src/ima_adpcm.c
+        src/ms_adpcm.c
+    Fix benign compiler warnings arising from previously added compiler
+    flags.
+
+2002-09-18  Erik de Castro Lopo  <erikd AT mega-nerd DOT com>
+
+    * src/sndfile.c
+    Fixed a bug in sf_error_str() where errnum was used as the index instead
+    of k. Found by Tim Hockin.
+
+    * examples/sndfile-play.c
+    Fixed a compiler warning resulting from a variable shadowing a previously
+    defined local.
+
+2002-09-17  Erik de Castro Lopo  <erikd AT mega-nerd DOT com>
+
+    * src/sndfile.h.in src/sndfile.c
+    Added command SFC_SET_RAW_START_OFFSET.
+
+    * doc/command.html
+    Document SFC_SET_RAW_START_OFFSET.
+
+    * tests/raw_test.c tests/Makefile.am
+    Add new file for for testing SF_FORMAT_RAW specific functionality.
+
+    * tests/dwvw_test.c
+    Updates.
+
+2002-09-16  Erik de Castro Lopo  <erikd AT mega-nerd DOT com>
+
+    * src/wav.c
+    Modified reading of 'smpl' chunk to take account of the sampler data field.
+
+    * tests/utils.tpl tests/utils.h
+    Added function print_test_name().
+
+    * tests/misc_test.c tests/write_read_test.tpl tests/lossy_comp_test.c
+        tests/pcm_test.tpl tests/command_test.tpl tests/floating_point_test.c
+    Convert to use function print_test_name().
+
+2002-09-15  Erik de Castro Lopo  <erikd AT mega-nerd DOT com>
+
+    * doc/octave.html
+    Added a link to some other Octave scripts for reading and writing sound
+    files.
+
+    * src/paf.c
+    Change type of dummy data field to int. This should fix a benign compiler
+    warning on some CPUs.
+    Removed superfluous casts resulting from the above change.
+
+    * src/rx2.c
+    More hacking.
+
+2002-09-14  Erik de Castro Lopo  <erikd AT mega-nerd DOT com>
+
+    * src/mat5.c src/common.c
+    Changed usage of snprintf() to LSF_SNPRINTF().
+
+    * Win32/Makefile.msvc
+    Updated to include new files and add new tests.
+
+    * Win32/config.h Win32/sndfile.h
+    Updated.
+
+    * doc/api.html
+    Added note about the possibility of "missing" features actually being
+    implemented as an sf_command().
+
+2002-09-13  Erik de Castro Lopo  <erikd AT mega-nerd DOT com>
+
+    * tests/misc_test.c
+    Added previously missing update_header_test and zero_data_tests for PAF,
+    MAT4 and MAT5 formats.
+
+    * src/paf.c src/mat4.c src/mat5.c
+    Fixed bugs uncovered by new tests above.
+
+    * src/mat5.c
+    Generalised parsing of name fields of MAT5 files.
+
+    * src/mat5.c src/sndfile.c
+    Added support for unsigned 8 bit PCM MAT5 files.
+
+    * tests/write_read_test.tpl
+    Added test for unsigned 8 bit PCM MAT5 files.
+
+    * doc/index.html
+    Added unsigned 8 bit PCM MAT5 to capabilities matrix.
+
+2002-09-12  Erik de Castro Lopo  <erikd AT mega-nerd DOT com>
+
+    * test/update_header_test.c tests/misc_test.c
+    Renamed update_header_test.c to misc_test.c.
+    Added zero_data_test() to check for case where file is opened for write and
+    closed immediately. The resulting file can be left in a state where
+    libsndfile cannot open it. Problem reported by Werner Schweer, the author
+    of Muse.
+
+    * src/aiff.c
+    Removed superfluous cast.
+
+    * src/wav.c src/svx.c
+    Fixed case of file generated with no data.
+    Removed superfluous cast.
+
+    * src/sndfile.c
+    Fixed error on IA64 platform caused by incorrect termination of
+    SndfileErrors struct array. This problem was found in the Debian buildd
+    logs (http://buildd.debian.org/).
+
+    * configure.in
+    Added Octave directory.
+
+    * Octave/Makefile.ma
+    New Makfile.am for Octave directory.
+
+    * Octave/sndfile_load.m Octave/sndfile_save.m Octave/sndfile_play.m
+    New files for working with Octave.
+
+    * doc/octave.html
+    Document explaining the use of the above three Octave scripts.
+
+2002-09-10  Erik de Castro Lopo  <erikd AT mega-nerd DOT com>
+
+    * src/sndfile.c
+    Fixed bug in RDWR mode.
+
+2002-09-09  Erik de Castro Lopo  <erikd AT mega-nerd DOT com>
+
+    * src/common.c
+    Fixed psf_get_date_str() for systems which don't have gmtime_r() or
+    gmtime().
+
+    * src/file_io.c
+    Added #include <io.h> for Win32. Reported by Koen Tanghe.
+
+2002-09-08  Erik de Castro Lopo  <erikd AT mega-nerd DOT com>
+
+    * src/common.c
+    Added 'S' format specifier for psf_binheader_writef() which writes a C
+    string, including single null terminator to the header.
+    Added 'j' format specifier to allow jumping forwards or backwards in the
+    header.
+    Added function psf_get_date_str().
+
+    * src/mat5.c
+    Complete read and write support.
+
+    * doc/index.html
+    Added entries for MAT4 and MAT5 in capabilities matrix.
+
+2002-09-06  Erik de Castro Lopo  <erikd AT mega-nerd DOT com>
+
+    * src/mat4.c
+    Completed read and write support.
+
+    * src/common.h src/sndfile.c
+    Added MAT4 and MAT5 specific error messages.
+
+    * tests/write_read_test.tpl tests/Makefile.am
+    Added tests for MAT4 and MAT5 files.
+
+    * tests/stdio_test.c tests/stdout_test.c tests/stdin_test.c
+    Added tests for MAT4 and MAT5 files.
+
+2002-09-05  Erik de Castro Lopo  <erikd AT mega-nerd DOT com>
+
+    * src/command.c
+    Added elements for SF_FORMAT_MAT4 and SF_FORMAT_MAT5 to major_formats
+    array.
+
+    * examples/sfconvert.c
+    Added mat4 and mat5 output targets.
+
+2002-09-04  Erik de Castro Lopo  <erikd AT mega-nerd DOT com>
+
+    * src/sndfile.c
+    Added check to prevent errors openning read only formats for read/write.
+
+    * src/interleave.c
+    New file for interleaving non-interleaved data. Non-interleaved data is
+    only supported on read.
+
+    * src/Makefile.am
+    Added src/interleave.c to build.
+
+2002-09-03  Erik de Castro Lopo  <erikd AT mega-nerd DOT com>
+
+    * src/double64.c src/common.h
+    Added double64_be_read(), double64_le_read(), double64_be_write() and
+    double64_le_write() which replace double64_read() and double64_write().
+
+    * src/common.c
+    Cleanup of psf_binheader_readf() and add ability to read big and little
+    endian doubles (required by mat4.c and mat5.c).
+    Add ability for psf_binheader_writef() to write doubles to sound file
+    headers.
+
+2002-09-01  Erik de Castro Lopo  <erikd AT mega-nerd DOT com>
+
+    * src/mat5.c
+    New file for reading Matlab (tm) version 5 data files. This is also the
+    native binary file format for version 2.1.X of GNU Octave which will be
+    used for testing.
+    Not complete yet.
+
+    * src/mat4.c
+    New file for reading Matlab (tm) version 4.2 data files. This is also the
+    native binary file format for version 2.0.X of GNU Octave which will be
+    used for testing.
+    Not complete yet.
+
+    * src/sndfile.h.in src/sndfile.c src/common.h src/command.c src/Makefile.am
+    Mods to add Matlab files.
+
+    * src/common.[ch]
+    Added readf_endian field to SF_PRIVATE struct allowing endianness to
+    remembered across calls to sf_binheader_readf().
+    Fixed bug in width_specifier behaviour for printing hex values.
+
+2002-08-31  Erik de Castro Lopo  <erikd AT mega-nerd DOT com>
+
+    * src/file_io.c
+    Check return value of close() call in psf_fclose().
+
+2002-08-24  Erik de Castro Lopo  <erikd AT mega-nerd DOT com>
+
+    * src/ms_adpcm.c
+    Commented out some code where 0x10000 was being subtracted from a short
+    and the result assigned to a short again. Andrew Zaja found this.
+
+2002-08-23  Erik de Castro Lopo  <erikd AT mega-nerd DOT com>
+
+    * doc/command.html
+    Fixed typo found by Tommi Ilmonen.
+
+    * src/ima_adpcm.c
+    Changed type of diff from short to int to prevent errors which can occur
+    during very rare circumstances. Thanks to FUWAFUWA.
+
+2002-08-16  Erik de Castro Lopo  <erikd AT mega-nerd DOT com>
+
+    * tests/floating_point_test.c
+    Disable testing on machines without lrintf().
+
+    * Win32/Makefile.msvc
+    Added dwd.c and wve.c to build.
+
+    * configure.in
+    Bumped version to 1.0.0.
+
+2002-08-15  Erik de Castro Lopo  <erikd AT mega-nerd DOT com>
+
+    * src/file_io.c
+    Add a #include for Mac OS 9. Thanks to Stephane Letz.
+
+    * src/wav.c
+    Changed an snprintf to LSF_SNPRINTF.
+
+    * doc/Makefile.am
+    Added version-1.html.
+
+2002-08-14  Erik de Castro Lopo  <erikd AT mega-nerd DOT com>
+
+    * configure.in
+    Bumped version to 1.0.rc6.
+
+    * src/*.c
+    Modified scaling of normalised floats and doubles to integers. Until now
+    this has been done by multiplying by 0x8000 for short output, 0x80000000
+    for 32 bit ints and so on. Unfortunately this can cause an overflow and
+    wrap around in the target value. All thes values have therefore been
+    reduced to 0x7FFF, 0x7FFFFFFF and so on. The conversion from ints to
+    normalised floats and doubles remains unchanged. This does mean that for
+    repeated conversions normalised float -> pcm16 -> normalised float would
+    result in a decrease in amplitude of 0x7FFF/0x8000 on every round trip.
+    This is undesirable but less undesireable than the wrap around I am trying
+    to avoid.
+
+    * tests/floating_point_test.c
+    Removed file hash checking because new float scaling procedure introduced
+    above prevented the ability to crate a has on both x86 and PowerPC systems.
+
+2002-08-13  Erik de Castro Lopo  <erikd AT mega-nerd DOT com>
+
+    * src/txw.c
+    Completed reading of TXW files. Seek doesn't work yet.
+
+    * src/file_io.c
+    Added a MacOS 9 replacement for ftruncate().
+
+    * MacOS/sndfile.h
+    Added MacOS 9 header file. This should be copied into src/ to compile
+    libsndfile for MacOS9.
+
+2002-08-12  Erik de Castro Lopo  <erikd AT mega-nerd DOT com>
+
+    * src/sndfile.c
+    Fixed commands SF_SET_NORM_DOUBLE and SFC_SET_NORM_FLOAT to return their
+    values after being set. Reported by Jussi Laako.
+
+    * configure.in
+    If autogen is not found, touch all .c and .h files in tests/.
+
+    * src/common.c
+    Added format width specifier to psf_log_printf() for %u, %d, %D and %X.
+
+    * src/dwd.c
+    Completed implementation of read only access to these files.
+
+    * src/common.h src/*.c src/pcm.c
+    Removed redundant field chars from SF_PRIVATE struct and modified
+    pcm_init() to do without it.
+
+2002-08-11  Erik de Castro Lopo  <erikd AT mega-nerd DOT com>
+
+    * src/wve.c
+    New file implementing read of Psion Alaw files. This will be a read only
+    format. Implementation complete.
+
+    * src/dwd/c
+    Started implementation of DiamondWare Digitized files. Also read only, not
+    complete.
+
+    * src/wav.c
+    Add parsing of 'smpl' chunk.
+
+    * src/paf.c
+    Fixed reading on un-normalized doubles and floats from 24 bit PAF files.
+    This brings it into line with the reading of 8 bit files into
+    un-normalized doubles which returns values in the range [-128, 127].
+
+    * src/common.c
+    Modified psf_log_printf() to accept the %% conversion specifier to allow
+    printing of a single '%'.
+
+    * src/sds.c
+    Read only of 16 bit samples is working. Need to build a test harness for
+    this and other read only formats.
+
+2002-08-10  Erik de Castro Lopo  <erikd AT mega-nerd DOT com>
+
+    * configure.in
+    Added --enable-experimental configure option.
+    Removed pkg-config message at the end of the configure process.
+
+    * src/sds.c src/txw.c src/rx2.c src/sd2.c
+    Moved all the code in these files inside #if ENABLE_EXPERIMENTAL_CODE
+    blocks and added new *_open() function for the case where experimental is
+    not enabled. These new functions just return SFE_UNIMPLMENTED.
+
+    * Win32/sndfile.h src/sndfile.h.in src/common.h
+    Removed un-necessary #pragma pack commands.
+
+    * src/file_io.c
+    Implemented psf_ftruncate() and much other hacking for Win32.
+
+    * Win32/Makefile.msvc
+    Updated.
+
+    * doc/win32.html
+    Updated to include the copying of the sndfile.h file from the Win32/
+    directory to the src/ directory.
+
+    * Make.bat
+    Batch file to make compiling on Wi32 a little easier. Implements "make" and
+    "make check".
+
+2002-08-09  Erik de Castro Lopo  <erikd AT mega-nerd DOT com>
+
+    * src/file_io.c
+    Add place holder for ftruncate() on Win32 which doesn't have ftruncate().
+    This will need to be fixed later.
+
+    * src/sndfile.h.in
+    New file (copy of sndfile.h) with sets up @TYPEOF_SF_COUNT_T@ which will be
+    replaced by the correct type during configure.
+
+    * configure.in
+    Modified to find a good type for TYPEOF_SF_COUNT_T.
+
+    * src/aiff.c
+    Fixed a bug when reading malformed headers.
+
+    * src/common.c
+    Set read values to zero before performing read.
+
+2002-08-08  Erik de Castro Lopo  <erikd AT mega-nerd DOT com>
+
+    * doc/command.html
+    Fixed some HTML tags which were not allowing jumps to links within the
+    page.
+
+    * src/sds.c
+    Massive hacking on this.
+
+    * src/wav.c
+    Added recognition of 'clm ' tag.
+
+2002-08-07  Erik de Castro Lopo  <erikd AT mega-nerd DOT com>
+
+    * doc/index.html
+    Added beginning of a capabilities list beyond simple file formats which
+    can be read/written.
+
+    * src/aiff.c
+    Added parsing of INST and MARK chunks of AIFF files. At the moment this
+    data is simply recorded in the log buffer. Later it will be possible to
+    read this data from an application using sf_command().
+
+    * src/wav.c
+    Added parsing of 'cue ' chunk which contains loop information in WAV files.
+
+    * exampes/sndfile-info.c
+    Changed reporting of Samples to Frames.
+
+    * src/wav.c src/w64.c src/aiff.c src/wav_w64.h
+    Moved from a samples to a frames nomenclature to avoid confusion.
+
+    * doc/FAQ.html
+    What's the best format for storing temporary files?
+
+    * src/sds.c
+    New file for reading/writing Midi Sample Dump Standard files.
+
+    * src/Makefile.am src/sndfile.c src/common.[ch]
+    Added hooks for sds.c.
+
+    * examples/sndfile-info.c
+    Changed from using sf_perror() to using sf_error_str().
+
+2002-08-06  Erik de Castro Lopo  <erikd AT mega-nerd DOT com>
+
+    * doc/api.html
+    Added explanation of mode parameter for sf_open().
+    Added explanation of usage of SFM_* values in sf_seek().
+
+    * src/sndfile.[ch] src/command.c src/file_io.c src/common.h
+    Implemented SFC_FILE_TRUNCATE to allow a file to be truncated. File
+    truncation was suggested by James McCartney.
+
+    * src/command.html
+    Documented SFC_FILE_TRUNCATE.
+
+    * tests/command_test.c
+    Add tests for SFC_FILE_TRUNCATE.
+
+    * src/sndfile.c
+    Added a thrid parameter to the VALIDATE_SNDFILE_AND_ASSIGN_PSF macro to
+    make resetting the error number optional. All uses of the macro other than
+    in error reporting functions were changed to reset the error number.
+
+    * src/pcm.c
+    Fixed a bug were sf_read_* was logging an SFE_SHORT_READ even when no error
+    occurred.
+
+    * tests/write_read_test.tpl
+    Added tests of internal error state.
+
+2002-08-05  Erik de Castro Lopo  <erikd AT mega-nerd DOT com>
+
+    * src/GSM610/private.h src/GSM610/*.c src/GSM610/Makefile.am
+    Renamed private.h to gsm610_priv.h to prevent clash with other headers
+    named private.h in other directories. (Probably only a problem on MacOS 9).
+
+    * src/G72x/private.h src/G72x/*.c src/G72x/Makefile.am
+    Renamed private.h to g72x_priv.h to prevent clash with other headers
+    named private.h in other directories. (Probably only a problem on MacOS 9).
+
+    * MacOS/config.h
+    Changed values of HAVE_LRINT and HAVE_LRINTF to force use of code in
+    float_cash.h.
+
+    * src/sndfile.h
+    Changes the name of samples field of the SF_INFO to frames. The old name
+    had caused too much confusion and it simply had to be changed. There will
+    be at least one more pre-release.
+
+2002-08-04  Erik de Castro Lopo  <erikd AT mega-nerd DOT com>
+
+    * doc/index.html
+    Updated formats matrix to include RAW (header-less) GSM 6.10.
+    Fix specificaltion of table and spelling mistakes.
+
+    * src/sndfile.c src/command.c
+    Fixed bug in SFC_CALC_MAX_SIGNAL family and psf_calc_signal_max ().
+
+    * tests/command.c
+    Removed cruft.
+    Added test for SFC_CALC_MAX_SIGNAL and SFC_CALC_NORM_MAX_SIGNAL.
+
+    * configure.in
+    Update version to 1.0.0rc5.
+
+    * sfendian.h
+    Removed inclusion of un-necessary header.
+
+2002-08-03  Erik de Castro Lopo  <erikd AT mega-nerd DOT com>
+
+    * src/aiff.c
+    Minor fixes of info written to log buffer.
+
+    * src/float_cast.h
+    Add definition of HAVE_LRINT_REPLACEMENT.
+
+    * tests/floating_point_test.c
+    Fix file hash check on systems without lrint/lrintf.
+
+    * tests/dft_cmp.c
+    Limit SNR to less than -500.0dB.
+
+    * examples/sndfile2oct.c
+    Fixed compiler warnings.
+
+    * doc/api.html
+    Fixed error where last parameter of sf_error_str() was sf_count_t instead
+    of size_t.
+
+2002-08-02  Erik de Castro Lopo  <erikd AT mega-nerd DOT com>
+
+    * doc/FAQ.html
+    Why doesn't libsndfile do interleaving/de-interleaving.
+
+    * tests/pcm_test.tpl
+    On Win32 do not perform hash check on files containing doubles.
+
+2002-08-01  Erik de Castro Lopo  <erikd AT mega-nerd DOT com>
+
+    * src/common.h
+    Defined SF_COUNT_MAX_POSITIVE() macro, a portable way of setting variables
+    of type sf_count_t to their maximum positive value.
+
+    * src/dwvw.c src/w64.c
+    Used SF_COUNT_MAX_POSITIVE().
+
+2002-07-31  Erik de Castro Lopo  <erikd AT mega-nerd DOT com>
+
+    * src/paf.c
+    Fixed bug in reading/writing of 24 bit PCM PAF files on big endian systems.
+
+    * tests/floating_point_tests.c
+    Fixed hash values for 24 bit PCM PAF files.
+    Disabled file has check if lrintf() function is not available and added
+    warning.
+    Decreased level of signal from a peak of 1.0 to a value of 0.95 to prevent
+    problems on platforms without lrintf() ie Solaris.
+
+2002-07-30  Erik de Castro Lopo  <erikd AT mega-nerd DOT com>
+
+    * src/wav.c
+    Fixed a problem with two different kinds of mal-formed WAV file header. The
+    first had the 'fact' chunk before the 'fmt ' chunk, the other had an
+    incomplete 'INFO' chunk at the end of the file.
+
+    * src/w64.c
+    Added fix to allow differentiation between W64 files and ACID files.
+
+    * src/au_g72x.c src/common.h src/sndfile.c
+    Added error for G72x encoded files with more than one channel.
+
+    * tests/pcm_test.tpl tests/utils.tpl
+    Moved function check_file_hash_or_die() to utils.tpl. Function was then
+    modified to calculate the has of the whole file.
+
+    * src/wav.c
+    Fixed problem writing the 'fact' chunk on big endian systems.
+
+    * tests/sfconvert.c
+    Fixed bug where .paf files were being written as Sphere NIST.
+
+2002-07-29  Erik de Castro Lopo  <erikd AT mega-nerd DOT com>
+
+    * src/voc.c
+    Fix for reading headers generated using SFC_UPDATE_HEADER_NOW.
+
+    * doc/command.html
+    Add docs for SFC_UPDATE_HEADER_NOW and SFC_SET_UPDATE_HEADER_AUTO.
+
+2002-07-28  Erik de Castro Lopo  <erikd AT mega-nerd DOT com>
+
+    * man/sndfile-info.1 man/sndfile-play.1
+    Added manpages supplied by Joshua Haberman the Debian maintainer for
+    libsndfile. Additional tweaks by me.
+
+    * configure.in man/Makefile.am
+    Hooked manpages into autoconf/automake system.
+
+    * src/sndfile.c
+    Added hooks for SFC_SET_UPDATE_HEADER_AUTO.
+
+    * tests/update_header_test.c
+    Improved rigor of testing.
+
+    * src/*.c
+    Fixed problem with *_write_header() functions.
+
+2002-07-27  Erik de Castro Lopo  <erikd AT mega-nerd DOT com>
+
+    * doc/*.html
+    Updates to documentation to fix problems found by wdg-html-validator.
+
+    * src/common.h src/command.c
+    Added normalize parameter to calls to psf_calc_signal_max() and
+    psf_calc_max_all_channels().
+
+    * src/sndfile.c
+    Added handling for commands SFC_CALC_NORM_SIGNAL_MAX and
+    SFC_CALC_NORM_MAX_ALL_CHANNELS.
+
+    * doc/command.html
+    Added entry for SFC_CALC_NORM_SIGNAL_MAX and SFC_CALC_NORM_MAX_ALL_CHANNELS.
+
+2002-07-26  Erik de Castro Lopo  <erikd AT mega-nerd DOT com>
+
+    * examples/sndfile-play.c Win32/Makefile.msvc
+    Get sndfile-play program working on Win32. The Win32 PCM sample I/O API
+    sucks. The sndfile-play program now works on Linux, MacOSX, Solaris and
+    Win32.
+
+2002-07-25  Erik de Castro Lopo  <erikd AT mega-nerd DOT com>
+
+    * doc/FAQ.html
+    New file for frequently asked questsions.
+
+2002-07-22  Erik de Castro Lopo  <erikd AT mega-nerd DOT com>
+
+    * doc/api.html
+    Documentation fixes.
+
+    * src/au.[ch] src/au_g72x.c src/G72x/g72x.h
+    Add support of 40kbps G723 ADPCM encoding.
+
+    * tests/lossy_comp_test.c tests/floating_point_test.c
+    Add tests for 40kbps G723 ADPCM encoding.
+
+    * doc/index.html
+    Update support matrix.
+
+2002-07-21  Erik de Castro Lopo  <erikd AT mega-nerd DOT com>
+
+    * doc/command.html
+    Documented SFC_GET_SIMPLE_FORMAT_COUNT, SFC_GET_SIMPLE_FORMAT,
+    SFC_GET_FORMAT_* and SFC_SET_ADD_PEAK_CHUNK.
+
+    * src/sndfile.c src/pcm.c
+    Add ability to turn on and off the addition of a PEAK chunk for floating
+    point WAV and AIFF files.
+
+    * src/sndfile.[ch] src/common.h src/command.c
+    Added sf_command SFC_CALC_MAX_ALL_CHANNELS. Implemented by Maurizio Umberto
+    Puxeddu.
+
+    * doc/command.html
+    Docs for SFC_CALC_MAX_ALL_CHANNELS (assisted by Maurizio Umberto Puxeddu).
+
+2002-07-18  Erik de Castro Lopo  <erikd AT mega-nerd DOT com>
+
+    * src/sndfile.c src/gsm610.c
+    Finalised support for GSM 6.10 AIFF files and added support for GSM 6.10
+    encoded RAW (header-less) files.
+
+    * src/wav.c
+    Add support for IBM_FORMAT_MULAW and IBM_FORMAT_ALAW encodings.
+
+    * src/api.html
+    Fixed more documentation bugs.
+
+2002-07-17  Erik de Castro Lopo  <erikd AT mega-nerd DOT com>
+
+    * src/sndfile.h src/common.h
+    Moved some yet-to-be-implelmented values for SF_FORMAT_* from the public
+    header file sndfile.h to the private header file common.h to avoid
+    confusion about the actual capabilities of libsndfile.
+
+2002-07-16  Erik de Castro Lopo  <erikd AT mega-nerd DOT com>
+
+    * src/aiff.c src/wav.c
+    Fixed file parsing for WAV and AIFF files containing non-audio data after
+    the data chunk.
+
+    * src/aiff.c src/sndfile.c
+    Add support for GSM 6.10 encoded AIFF files.
+
+    * tests/lossy_comp_test.c tests/Makefile.am
+    Add tests for GSM 6.10 encoded AIFF files.
+
+    * src/*.c
+    Fix compiler warnings.
+
+2002-07-15  Erik de Castro Lopo  <erikd AT mega-nerd DOT com>
+
+    * tests/command_test.c
+    For SFC_SET_NORM_* tests, change the file format from SF_FORMAT_WAV to
+    SF_FORMAT_RAW.
+
+    * src/sndfile.c
+    Added sf_command(SFC_TEST_ADD_TRAILING_DATA) to allow testing of reading
+    from AIFF and WAV files with non-audio data after the audio chunk.
+
+    * src/common.h
+    Add test commands SFC_TEST_WAV_ADD_INFO_CHUNK and
+    SFC_TEST_AIFF_ADD_INST_CHUNK. When these commands are working, they will be
+    moved to src/sndfile.h
+
+    * src/aiff.c src/wav.c
+    Begin implementation of XXXX_command() hook for sf_command().
+
+    * tests/write_read_test.tpl
+    Added sf_command (SFC_TEST_ADD_TRAILING_DATA) to ensure above new code was
+    working.
+
+2002-07-13  Erik de Castro Lopo  <erikd AT mega-nerd DOT com>
+
+    * tests/update_header_test.c
+    Allow read sample count == write sample count - 1 to fix problems with VOC
+    files.
+
+    * tests/write_read_test.tpl tests/pcm_test.tpl
+    Fixed some problems in the test suite discovered by using Valgrind.
+
+2002-07-12  Erik de Castro Lopo  <erikd AT mega-nerd DOT com>
+
+    * tests/utils.[ch] tests/*.c
+    Renamed check_log_buffer() to check_log_buffer_or_die().
+
+    * src/sndfile.c
+    SFC_UPDATE_HEADER_NOW and SFC_SETUPDATE_HEADER_AUTO almost finished. Works
+    for all file formats other than VOC.
+
+2002-07-11  Erik de Castro Lopo  <erikd AT mega-nerd DOT com>
+
+    * src/sndfile.[ch] src/common.h
+    Started adding functionality to allow the file header to be updated before
+    the file is closed on files open for SFM_WRITE. This was requested by
+    Maurizio Umberto Puxeddu who is using libsndfile for file I/O in iCSound.
+
+    * tests/update_header_test.c
+    New test program to test that the above functionality is working correctly.
+
+    * tests/peak_chunk_test.c tests/floating_point_test.c
+    Cleanups.
+
+2002-07-10  Erik de Castro Lopo  <erikd AT mega-nerd DOT com>
+
+    * src/sfendian.[ch]
+    Changed length count parameters for all endswap_XXX() functions from
+    sf_count_t (which can be 64 bit even on 32 bit architectures) to int. These
+    functions are only called frin inside the library, are always called with
+    integer parameters and doing the actual calculation on 64 bit values is
+    slow in comparision to doing it on ints.
+
+    * examples/sndfile-play.c
+    More playback hacking for Win32.
+
+2002-07-09  Erik de Castro Lopo  <erikd AT mega-nerd DOT com>
+
+    * src/common.c
+    In psf_log_printf(), changed %D format conversion specifier to %M (marker) and
+    added %D specifier for printing the sf_count_t type.
+
+    * src/*.c
+    Changed all usage of psf_log_printf() with %D format conversion specifiers
+    to use %M conversion instead.
+
+    * tests/pcm_test.tpl tests/pcm_test.def
+    New files to autogen pcm_test.c.
+
+    * src/pcm.c
+    Fixed bug in scaling floats and doubles to 24 bit PCM and vice versa.
+
+2002-07-08  Erik de Castro Lopo  <erikd AT mega-nerd DOT com>
+
+    * configure.in
+    Fix setup of $ac_cv_sys_largefile_CFLAGS so that sndfile.pc gets valid
+    values for CFLAGS.
+
+    * examples/sndfile-play.c
+    Start adding playback support for Win32.
+
+2002-07-07  Erik de Castro Lopo  <erikd AT mega-nerd DOT com>
+
+    * src/*.c
+    Worked to removed compiler warnings.
+    Extensive refactoring.
+
+    * src/common.[ch]
+    Added function psf_memset() which works like the standard C function memset
+    but takes and sf_count_t as the length parameter.
+
+    * src/sndfile.c
+    Replaced calls to memset(0 with calls to psf_memset() as required.
+
+2002-07-06  Erik de Castro Lopo  <erikd AT mega-nerd DOT com>
+
+    * src/sndfile.c
+    Added "libsndfile : " to the start of all error messages. This was suggested
+    by Conrad Parker author of Sweep ( http://sweep.sourceforge.net/ ).
+
+    * src/sfendian.[ch]
+    Added endswap_XXXX_copy() functions.
+
+    * src/pcm.c src/float32.c src/double64.c
+    Use endswap_XXXX_copy() functions and removed dead code.
+    Cleanups and optimisations.
+
+2002-07-05  Erik de Castro Lopo  <erikd AT mega-nerd DOT com>
+
+    * src/sndfile.c src/sndfile.h
+    Gave values to all the SFC_* enum values to allow better control of the
+    interface as commands are added and removed.
+    Added new command SFC_SET_ADD_PEAK_CHUNK.
+
+    * src/wav.c src/aiff.c
+    Modified wav_write_header and aiff_write_header to make addition of a PEAK
+    chunk optional, even on floating point files.
+
+    * tests/benchmark.tpl
+    Added call to sf_command(SFC_SET_ADD_PEAK_CHUNK) to turn off addition of a
+    PEAK chunk for the benchmark where we are trying to miximize speed.
+
+    * src.pcm.c
+    Changed tribyte typedef to something more sensible.
+    Further conversion speed ups.
+
+2002-07-03  Erik de Castro Lopo  <erikd AT mega-nerd DOT com>
+
+    * src/command.c
+    In major_formats rename "Sphere NIST" to "NIST Sphere".
+
+    * src/common.c src/sfendian.c
+    Moved all endswap_XXX_array() functions to sfendian.c. These functions will
+    be tweaked to provide maximum performance. Since maximum performance on one
+    platform does not guarantee maximum performance on another, a small set of
+    functions will be written and the optimal one chosen at compile time.
+
+    * src/common.h src/sfendian.h
+    Declarations of all endswap_XXX_array() functions moved to sfendian.h.
+
+    * src/Makefile.am
+    Add sfendian.c to build targets.
+
+2002-07-01  Erik de Castro Lopo  <erikd AT mega-nerd DOT com>
+
+    * src/pcm.c src/sfendian.h
+    Re-coded PCM encoders and decoders to match or better the speed of
+    libsndfile version 0.0.28.
+
+2002-06-30  Erik de Castro Lopo  <erikd AT mega-nerd DOT com>
+
+    * src/wav.c
+    Add checking for WAVPACK data in standard PCM WAV file. Return error if
+    found. This WAVPACK is *WAY* broken. It uses the same PCM WAV file header
+    and then stores non-PCM data.
+
+    * tests/benchmark.tpl
+    Added more tests.
+
+2002-06-29  Erik de Castro Lopo  <erikd AT mega-nerd DOT com>
+
+    * tests/benchmark.tpl
+    Added conditional definition of M_PI.
+    For Win32, set WRITE_PERMS to 0777.
+
+    * Win32/Makefile.msvc
+    Added target to make generate program on Win32.
+
+    * src/samplitude.c
+    Removed handler for Samplitude RAP file format. This file type seems rarer
+    than hens teeth and is completely undocumented.
+
+    * src/common.h src/sndfile.c src/Makefile.am Win32/Makefile.msvc
+    Removed references to sampltiude RAP format.
+
+    * tests/benchmark.tpl
+    Benchmark program now prints the libsndfile version number when run. This
+    program was also backported to version 0 to compare results. Version
+    1.0.0rc2 is faster than version 0.0.28 on most conversions but slower on
+    some. The slow ones need to be fixed before final release.
+
+2002-06-28  Erik de Castro Lopo  <erikd AT mega-nerd DOT com>
+
+    * tests/benchmark.def tests/benchmark.tpl
+    New files which generate tests/benchmark.c using Autogen. Added int ->
+    SF_FORMAT_PCM_24 test.
+
+    * tests/benchmark.c
+    Now and Autogen output file.
+
+    * tests/Makefile.am
+    Updated for above changes.
+
+2002-06-27  Erik de Castro Lopo  <erikd AT mega-nerd DOT com>
+
+    * tests/benchmark.c
+    Basic benchmark program complete. Need to convert it to Autogen.
+
+    * Win32/Makefile.msvc
+    Added benchmark.exe target.
+
+2002-06-26  Erik de Castro Lopo  <erikd AT mega-nerd DOT com>
+
+    * examples/generate.c
+    New program to generate a number of different output file formats from a
+    single input file. This allows testing of the created files.
+
+    * tests/benchmark.c
+    New test program to benchmark libsndfile. Nowhere near complete yet.
+
+    * examples/Makefile.am tests/Makefile.am
+    New make rules for the two new programs.
+
+2002-06-25  Erik de Castro Lopo  <erikd AT mega-nerd DOT com>
+
+    * Win32/libsndfile.def
+    Removed definition for sf_signal_max().
+
+    * src/sndfile.c
+    Removed cruft.
+
+    * doc/index.html
+    A number of documentation bugs were fixed. Thanks to Anand Kumria.
+
+    * doc/version-1.html
+    Minor doc updates.
+
+    * configure.in
+    Bumped version to 1.0.0rc2.
+
+    * src/sf_command.h src/Makefile.am
+    Removed the header file as it was no longer being used. Thanks to Anand
+    Kunria for spotting this.
+
+    * doc/index.html
+    A number of documentation bugs were fixed. Thanks to Anand Kumria.
+
+2002-06-24  Erik de Castro Lopo  <erikd AT mega-nerd DOT com>
+
+    * src/common.h
+    Test for Win32 before testing SIZEOF_OFF_T so that it works correctly
+    on Win32..
+
+    * src/file_io.c
+    Win32 fixes to ensure O_BINARY is used for file open.
+
+    * doc/win32.html
+    New file documenting the building libsndfile on Win32.
+
+    * doc/*.html
+    Updating of documentation.
+
+2002-06-23  Erik de Castro Lopo  <erikd AT mega-nerd DOT com>
+
+    * tests/pcm_test.c
+    Minor changes to allow easier determination of test file name.
+
+    * src/sndfile.[ch]
+    Removed function sf_signal_max().
+
+    * examples/sndfile-play.c
+    Changed call to sf_signal_max() to a call to sf_command().
+
+2002-06-22  Erik de Castro Lopo  <erikd AT mega-nerd DOT com>
+
+    * src/format.c src/command.c
+    Renamed format.c to command.c which will now include code for sf_command()
+    calls to perform operations other than format commands.
+
+    * src/sndfile.c src/sndfile.h
+    Removed function sf_get_signal_max() which is replaced by commands passed
+    to sf_command().
+
+    * src/command.c
+    Implement commands SFC_CALC_SIGNAL_MAX.
+
+    * doc/command.html
+    Documented SFC_CALC_SIGNAL_MAX.
+
+2002-06-21  Erik de Castro Lopo  <erikd AT mega-nerd DOT com>
+
+    * examples/sndfile-play.c
+    Mods to make sndfile-play work on Solaris. The program sndfile-play now
+    runs on Linux, MaxOSX and Solaris. Win32 to come.
+
+    * src/format.c
+    Added SF_FORMAT_DWVW_* to subtype_formats array.
+
+    * src/nist.c
+    Added support for 8 bit NIST Sphere files. Example file supplied by Anand
+    Kumria.
+
+2002-06-20  Erik de Castro Lopo  <erikd AT mega-nerd DOT com>
+
+    * examples/sndfile-info.c
+    Tidy up of output format.
+
+    * examnples/sndfile-play.c
+    Mods to make sndfile-play work on MacOSX using Apple's CoreAudio API.
+
+    * configure.in
+    Add new variables OS_SPECIFIC_INCLUDES and OS_SPECIFIC_LINKS which were
+    required to supply extra include paths and link parameters to get
+    sndfile-play working on MacOSX.
+
+    * examples/Makefile.am
+    Use OS_SPOECIFIC_INCLUDES and OS_SPECIFIC_LINKS to build commands for
+    sndfile-play.
+
+2002-06-19  Erik de Castro Lopo  <erikd AT mega-nerd DOT com>
+
+    * src/nist.c
+    Added ability to read/write new NIST Sphere file types (A-law, u-law).
+    Header parser was re-written from scratch. Example files supplied by Anand
+    Kumria.
+
+    * src/sndfile.c
+    Support for A-law and u-law NIST files.
+
+    * tests/Makefile.am tests/lossy_comp_test.c
+    Tests for A-law and u-law NIST files.
+
+2002-06-18  Erik de Castro Lopo  <erikd AT mega-nerd DOT com>
+
+    * tests/utils.c
+    Fixed an error in error string.
+
+2002-06-17  Erik de Castro Lopo  <erikd AT mega-nerd DOT com>
+
+    * acinclude.m4
+    Removed exit command to allow cross-compiling.
+
+    * Win32/unistd.h src/file_io.c
+    Moved contents of first file into the second file (enclosed in #ifdef).
+    Win32/unistd.h is now an empty file but still must be there for libsndfile
+    to compile on Win32.
+
+    * src/sd2.c, src/sndfile.c:
+    Fixes for Sound Designer II files on big endian systems.
+
+2002-06-16  Erik de Castro Lopo  <erikd AT mega-nerd DOT com>
+
+    * configure.in
+    Modified to work around problems with crappy MacOSX version of sed.
+    Added sanity check for proper values for CFLAGS.
+
+2002-06-14  Erik de Castro Lopo  <erikd AT mega-nerd DOT com>
+
+    * src/sndfile.c
+    Code clean up in sf_open ().
+
+    * Win32/Makefile.msvc
+    Michael Fink's contributed MSVC++ makefile was hacked to bits and put back
+    together in a new improved form.
+
+    * src/file_io.c
+    Fixes for Win32; _lseeki64() returns an invalid argument for calls like
+    _lseeki64(fd, 0, SEEK_CUR) so need to use _telli64 (fd) instead.
+
+    * src/common.h src/sndfile.c src/wav.c src/aiff.c
+    Added SFE_LOG_OVERRUN error.
+    Added termination for potential infinite loop when parsing file headers.
+
+    * src/wav.c src/w64.c
+    Fixed bug casuing incorrect header generation when opening file read/write.
+
+2002-06-12  Erik de Castro Lopo  <erikd AT mega-nerd DOT com>
+
+    * doc/api.html
+    Improved the documentation to make it clearer that the file read method
+    and the underlying file format are completely disconnected. Suggested
+    by Josh Green.
+
+    * doc/command.html
+    Started correcting docs to take into account changes made to the
+    operations of the sf_command () function. Not complete yet.
+
+    * src/sndfile.c
+    Reverted some changes which had broken the partially working SDII header
+    parsing. Now have access to an iBook with OS X so reading and writing SDII
+    files on all platforms should be a reality in the near future. On Mac this
+    will involve reading the resource fork via the standard MacOS API. To move
+    a file from Mac to another OS, the resource and data forks will need to be
+    combined before transfer. The combined file will be read on both Mac and
+    other OSes like any other file.
+
+2002-06-08  Erik de Castro Lopo  <erikd AT mega-nerd DOT com>
+
+    * ltmain.sh
+    Applied a patch from http://fink.sourceforge.net/doc/porting/libtool.php
+    which allows libsndfile to compile on MacOSX 10.1. This patch should not
+    interfere with compiling on other OSes.
+
+    * src/GSM610/private.h
+    Changes to fix compile problems on MacOSX (see src/GSM610/ChangeLog).
+
+    * src/float_cast.h
+    Added MacOSX replacements for lrint() and lrintf().
+
+2002-06-05  Erik de Castro Lopo  <erikd AT mega-nerd DOT com>
+
+    * src/sndfile.c
+    Replaced the code to print the filename to the log buffer when a file is
+    opened. This code seems to have been left out during the merge of
+    sf_open_read() and sf_open_write() to make a single  functions sf_open().
+
+2002-06-01  Erik de Castro Lopo  <erikd AT mega-nerd DOT com>
+
+    * src/wav.c
+    Fixed a bug where the WAV header parser was going into an infinite loop
+    on a badly formed LIST chunk. File supplied by David Viens.
+
+2002-05-25  Erik de Castro Lopo  <erikd AT mega-nerd DOT com>
+
+    * configure.in
+    Added a message at the end of the configuration process to warn about the
+    need for the use of pkg-config when linking programs against version 1 of
+    libsndfile.
+
+    * doc/pkg-config.html
+    New documentation file containing details of how to use pkg-config to
+    retrieve settings for CFLAGS and library locations for linking files
+    against version 1 of libsndfile.
+
+2002-05-17  Erik de Castro Lopo  <erikd AT mega-nerd DOT com>
+
+    * src/wav.c
+    Fixed minor bug in handling of so-called ACIDized WAV files.
+
+2002-05-16  Erik de Castro Lopo  <erikd AT mega-nerd DOT com>
+
+    * Win32/libsndfile.def Win32/Makefile.msvc
+    Two new files contributed by Michael Fink (from the winLAME project)
+    which allows libsndfile to be built on windows in a MSDOS box by doing
+    "nmake -f Makefile.msvc". Way cool!
+
+2002-05-15  Erik de Castro Lopo  <erikd AT mega-nerd DOT com>
+
+    * configure.in
+    MacOSX is SSSOOOOOOO screwed up!!! I can't believe how hard it is to
+    generate a tarball which will configure and compile on that platform.
+    Joined the libtool mailing list to try and get some answers.
+
+2002-05-13  Erik de Castro Lopo  <erikd AT mega-nerd DOT com>
+
+    * configure.in
+    Changed to autoconf version 2.50. MacOSX uses autoconf version 2.53 which
+    is incompatible with with version 2.13 which had been using until now.
+    The AC_SYS_LARGE_FILE macro distributed withe autoconf 2.50 is missing a
+    few features so AC_SYS_EXTRA_LARGE file was defined to replace it.
+
+    * configure.in
+    Changed to automake version 1.5 to try and make a tarball which will
+    work on MacOSX.
+
+2002-05-12  Erik de Castro Lopo  <erikd AT mega-nerd DOT com>
+
+    * src/wav_gsm610.c
+    Changed name to gsm610.c. Added reading/writing of headerless files.
+
+    * src/sndfile.c src/raw.c
+    Added ability to read/write headerless (SF_FORMAT_RAW) GSM 6.10 files.
+
+2002-05-11  Erik de Castro Lopo  <erikd AT mega-nerd DOT com>
+
+    * tests/lossy_comp_test.c
+    Clean up in preparation for Autogen-ing this file.
+
+    * src/GSM610/*.[ch]
+    Code cleanup and prepartion forgetting file seek working. Details in
+    src/GSM610/ChangeLog.
+
+    * sndfile.pc.in
+    Testing complete. Is sndfile.m4 still needed?
+
+2002-05-09  Erik de Castro Lopo  <erikd AT mega-nerd DOT com>
+
+    * tests/write_read_test.tpl tests/rdwr_test.tpl
+    Merged tests from these two programs into write_read_test.tpl and deleted
+    rdwr_test.tpl.
+
+2002-05-08  Erik de Castro Lopo  <erikd AT mega-nerd DOT com>
+
+    * src/w64.c src/svx.c src/paf.c
+    Fixed bugs in read/write mode.
+
+2002-05-07  Erik de Castro Lopo  <erikd AT mega-nerd DOT com>
+
+    * examples/Makefile.am
+    Renamed sfplay.c to sndfile-play.c and sndfile_info.c to sndfile-info.c for
+    consistency when these programs become part of the Debian package
+    sndfile-programs.
+
+    * sndfile.pc.in
+    New file to replace sndfile-config.in. Libsndfile now uses the pkg-config
+    model for providing installation parameters to dependant programs.
+
+    * src/sndfile.c
+    Cleanup of code in sf_open().
+
+2002-05-06  Erik de Castro Lopo  <erikd AT mega-nerd DOT com>
+
+    * tests/utils.tpl tests/write_read_test.tpl
+    More conversion to Autogen fixes and enchancements.
+
+    * src/*.c
+    Read/write mode is now working for 16, 24 and 32 bit PCM as well as 32
+    bit float and 64 bit double data. More tests still required.
+
+    * src/Makefile.am
+    Added DISTCLEANFILES target to remove config.status and config.last.
+
+    * Win32/Makefile.am MacOS/Makefile.am
+    Added DISTCLEANFILES target to remove Makefile.
+
+2002-05-05  Erik de Castro Lopo  <erikd AT mega-nerd DOT com>
+
+    * src/*.[ch] tests/rdwr_test.c
+    More verifying workings of read/write mode. Fixing bugs found.
+
+    * tests/utils.[ch]
+    Made these files Autogen generated files.
+
+    * tests/util.tpl tests/util.def
+    New Autogen files to generate utils.[ch]. Moved some generic test functions
+    into this file. Autogen is such a great tool!
+
+2002-05-03  Erik de Castro Lopo  <erikd AT mega-nerd DOT com>
+
+    * src/pcm.c src/float_cast.h Win32/config.h
+    Fixed a couple of Win32 specific bugs pointed out by Michael Fink
+    (maintainer of WinLAME) and David Viens.
+
+    * tests/check_log_buffer.[ch] tests/utils.[ch]
+    Moved check_log_buffer() to utils.[ch] and deleted old file.
+
+2002-05-02  Erik de Castro Lopo  <erikd AT mega-nerd DOT com>
+
+    * src/common.[ch] src/sndfile.c
+    New function psf_default_seek() which will be the default seek function
+    for things like PCM and floating point data. This default is set for
+    both read and write in sf_open() but can be over-ridden by any codec
+    during it's initialisation.
+
+2002-05-01  Erik de Castro Lopo  <erikd AT mega-nerd DOT com>
+
+    * src/au.c
+    AU files use a data size value of -1 to mean unknown. Fixed au_open_read()
+    to allow opening files like this.
+
+    * tests/rdwr_test .c
+    Added more tests.
+
+    * src/sndfile.c
+    Fixed bugs in read/write mode found due to improvements in the test
+    program.
+
+2002-04-30  Erik de Castro Lopo  <erikd AT mega-nerd DOT com>
+
+    * tests/rdwr_test .c
+    New file for testing read/write mode.
+
+2002-04-29  Erik de Castro Lopo  <erikd AT mega-nerd DOT com>
+
+    * m4/*
+    Removed all m4 macros from this directory as they get concatenated to form
+    the file aclocal.m4 anyway.
+
+    * sndfile.m4
+    Moved this from the m4 directory to the root directory asn this is part of
+    the distribution and is installed during "make install".
+
+2002-04-29  Erik de Castro Lopo  <erikd AT mega-nerd DOT com>
+
+    * src/float32.c
+    Removed logging of peaks for all file formats other than AIFF and WAV.
+
+    * tests/write_read_test.tpl tests/write_read_test.def
+    New files which autogen uses to generate write_read_test.c. Doing it this
+    way makes write_read_test.c far easier to maintain. Other test programs
+    will be converted to autogen in the near future.
+
+    * src/*.c
+    Fixed a few bugs found when testing on Sparc (bug endian) Solaris.
+
+2002-04-28  Erik de Castro Lopo  <erikd AT mega-nerd DOT com>
+
+    * doc/*.html
+    Fixed documention versioning.
+
+    * configure.in
+    Fixed a bug in the routines which search for Large File Support on systems
+    which have large file support by defualt.
+
+2002-04-27  Erik de Castro Lopo  <erikd AT mega-nerd DOT com>
+
+    * src/*.[ch]
+    Found and fixed an issue which can cause a bug in other software (I was
+    porting Conrad Parker's Sweep program from version 0 of the library to
+    version 1). When opening a file for write, the libsndfile code would
+    set the sfinfo.samples field to a maximum value.
+
+    * tests/write_read_test.c
+    Added tests to detect the above problem.
+
+2002-04-25  Erik de Castro Lopo  <erikd AT mega-nerd DOT com>
+
+    * src/*.[ch]
+    Finished base implementation of read/write mode. Much more testing still
+    needed.
+
+    * m4/largefile.m4
+    Macro for detecting Large File Standard capabilities. This macro was ripped
+    out of the aclocal.m4 file of GNU tar-1.13.
+
+    * configure.in
+    Added detection of large file support. Files larger than 2 Gigabytes should
+    now be supported on 64 bit platforms and many 32 bit platforms including
+    Linux (2.4 kernel, glibc-2.2), *BSD, MacOS, Win32.
+
+    * libsndfile_convert_version.py
+    A Python script which attempts to autoconvert code written to use version 0
+    to version 1.
+
+2002-04-24  Erik de Castro Lopo  <erikd AT mega-nerd DOT com>
+
+    * src/*.[ch]
+    Finished base implementation of read/write mode. Much more testing still
+    needed.
+
+    * tests/write_read_test.c
+    Preliminary tests for read/write mode added. More needed.
+
+2002-04-20  Erik de Castro Lopo  <erikd AT mega-nerd DOT com>
+
+    * src/sndfile.[ch]
+    Removed sf_open_read() and sf_open_write() functions,replacting them with
+    sf_open() which takes an extra mode parameter (SF_OPEN_READ, SF_OPEN_WRITE,
+    or SF_OPEN_RDWR). This new function sf_open can now be modified to allow
+    opening a file formodification (RDWR).
+
+2002-04-19  Erik de Castro Lopo  <erikd AT mega-nerd DOT com>
+
+    * src/*.c
+    Completed merging of separate xxx_open_read() and xxx_open_write()
+    functions. All tests pass.
+
+2002-04-18  Erik de Castro Lopo  <erikd AT mega-nerd DOT com>
+
+    * src/au.c
+    Massive refactoring required to merge au_open_read() with au_open_write()
+    to create au_open().
+
+2002-04-17  Erik de Castro Lopo  <erikd AT mega-nerd DOT com>
+
+    * src/*.c
+    Started changes required to allow a sound file to be opened in read/write
+    mode, with separate file pointers for read and write. This involves merging
+    of encoder/decoder functions like pcm_read_init() and pcm_write_init()
+    int a new function pcm_init() as well as doing something similar for all
+    the file type specific functions ie aiff_open_read() and aiff_open_write()
+    were merged to make the function aiff_open().
+
+2002-04-15  Erik de Castro Lopo  <erikd AT mega-nerd DOT com>
+
+    * src/file_io.c
+    New file containing psf_fopen(), psf_fread(), psf_fwrite(), psf_fseek() and
+    psf_ftell() functions. These function will replace use of fopen/fread/fwrite
+    etc and allow access to files larger than 2 gigabytes on a number of 32 bit
+    OSes (Linux on x86, 32 bit Solaris user space apps, Win32 and MacOS).
+
+    * src/*.c
+    Replaced all instances of fopen with psf_open, fread with psd_read, fwrite
+    with psf_write and so on.
+
+2002-03-11  Erik de Castro Lopo  <erikd AT mega-nerd DOT com>
+
+    * src/dwvw.c
+    Finally fixed all known problems with 12, 16 and 24 bit DWVW encoding.
+
+    * tests/floating_point_test.c
+    Added tests for 12, 16 and 24 bit DWVW encoding.
+
+2002-03-03  Erik de Castro Lopo  <erikd AT mega-nerd DOT com>
+
+    * m4/endian.m4
+    Defines a new m4 macro AC_C_FIND_ENDIAN, for determining the endian-ness of
+    the target CPU. It first checks for the definition of BYTE_ORDER in
+    <endian.h>, then in <sys/types.h> and <sys/param.h>. If none of these work
+    and the C compiler is not a cross compiler it compiles and runs a program
+    to test for endian-ness. If the compiler is a cross compiler it makes a
+    guess based on $target_cpu.
+
+    * configure.in
+    Modified to use AC_C_FIND_ENDIAN.
+
+    * src/sfendian.h
+    Simplified.
+
+2002-02-23  Erik de Castro Lopo  <erikd AT mega-nerd DOT com>
+
+    * tests/floating_point_test.c
+    Tests completely rewritten using the dft_cmp function. Now able to
+    calculate a quick guesstimate of the Signal to Noise Ratio of the encoder.
+
+2002-02-15  Erik de Castro Lopo  <erikd AT mega-nerd DOT com>
+
+    * tests/dft_cmp.[ch]
+    New files containing functions for comparing pre and post lossily
+    compressed data using a quickly hacked DFT.
+
+    * tests/utils.[ch]
+    New files containing functions for saving pre and post encoded data in a
+    file readable by the GNU Octave package.
+
+2002-02-13  Erik de Castro Lopo  <erikd AT mega-nerd DOT com>
+
+    * m4/lrint.m4 m4/lrintf.m4
+    Fixed m4 macros to define HAVE_LRINT and HAVE_LRINTF even when the test
+    is cached.
+
+2002-02-12  Erik de Castro Lopo  <erikd AT mega-nerd DOT com>
+
+    * tests/floating_point_test.c
+    Fixed improper use of strncat ().
+
+2002-02-11  Erik de Castro Lopo  <erikd AT mega-nerd DOT com>
+
+    * tests/headerless_test.c
+    New test program to test the ability to open and read a known file type as a
+    RAW header-less file.
+
+2002-02-07  Erik de Castro Lopo  <erikd AT mega-nerd DOT com>
+
+    * tests/losy_comp_test.c
+    Added a test to ensure that the data read from a file is not all zeros.
+
+    * examples/sfconvert.c
+    Added "-gsm610" encoding types.
+
+2002-01-29  Erik de Castro Lopo  <erikd AT mega-nerd DOT com>
+
+    * examples/sfconvert.c
+    Added "-dwvw12", "-dwvw16" and "-dwvw24" encoding types.
+
+    * tests/dwvw_test.c
+    New file for testing DWVW encoder/decoder.
+
+2002-01-28  Erik de Castro Lopo  <erikd AT mega-nerd DOT com>
+
+    * src/dwvw.c
+    Implemented writing of DWVW. 12 bit seems to work, 16 and 24 bit still broken.
+
+    * src/aiff.c
+    Improved reporting of encoding types.
+
+    * src/voc.c
+    Clean up.
+
+2002-01-27  Erik de Castro Lopo  <erikd AT mega-nerd DOT com>
+
+    * src/dwvw.c
+    New file implementing lossless Delta Word Variable Width (DWVW) encoding.
+    Reading 12 bit DWVW is now working.
+
+    * src/aiff.c common.h sndfile.c
+    Added hooks for DWVW encoded AIFF and RAW files.
+
+2002-01-15  Erik de Castro Lopo  <erikd AT mega-nerd DOT com>
+
+    * src/w64.c
+    Robustify header parsing.
+
+    * src/wav_w64.h
+    Header file wav.h was renamed to wav_w64.h to signify sharing of
+    definitions across the two file types.
+
+    * src/wav.c src/w64.c src/wav_w64.c
+    Refactoring.
+    Modified and moved functions with a high degree of similarity between
+    wav.c and w64.c to wav_w64.c.
+
+2002-01-14  Erik de Castro Lopo  <erikd AT mega-nerd DOT com>
+
+    * src/w64.c
+    Completed work on getting read and write working.
+
+    * examples/sfplay.c
+    Added code to scale floating point data so it plays at a reasonable volume.
+
+    * tests/Makefile.am tests/write_read_test.c
+    Added tests for W64 files.
+
+2002-01-13  Erik de Castro Lopo  <erikd AT mega-nerd DOT com>
+
+    * src/*.c
+    Modded all code in file header writing routines to use
+    psf_new_binheader_writef().
+    Removed psf_binheader_writef() from src/common.c.
+    Globally replaced psf_new_binheader_writef with psf_binheader_writef.
+
+2002-01-12  Erik de Castro Lopo  <erikd AT mega-nerd DOT com>
+
+    * src/*.c
+    Modded all code in file parsing routines to use psf_new_binheader_readf().
+    Removed psf_binheader_readf() from src/common.c.
+    Globally replaced psf_new_binheader_readf with psf_binheader_readf.
+
+    * src/common.[ch]
+    Added new function psf_new_binheader_writef () which will soon replace
+    psf_binheader_writef (). The new function has basically the same function
+    as the original but has a more flexible and capable interface. It also
+    allows the writing of 64 bit integer values for files contains 64 bit file
+    offsets.
+
+2002-01-11  Erik de Castro Lopo  <erikd AT mega-nerd DOT com>
+
+    * src/formats.c src/sndfile.c src/sndfile.h
+    Added code allowing full enumeration of supported file formats via the
+    sf_command () interface.
+    This feature will allow applications to avoid needing recompilation when
+    support for new file formats are added to libsndfile.
+
+    * tests/command_test.c
+    Added test code for the above feature.
+
+    * examples/list_formats.c
+    New file. An example of the use of the supported file enumeration
+    interface. This program lists all the major formats and for each major
+    format the supported subformats.
+
+2002-01-10  Erik de Castro Lopo  <erikd AT mega-nerd DOT com>
+
+    * src/*.[ch] tests/*.c
+    Changed command parameter of sf_command () function from a test string to
+    an int. The valid values for the command parameter begin with SFC_ and are
+    listed in src/sndfile.h.
+
+2001-12-20  Erik de Castro Lopo  <erikd AT mega-nerd DOT com>
+
+    * src/formats.c src/sndfile.c
+    Added an way of enumerating a set of common file formats using the
+    sf_command () interface. This interface was suggested by Dominic Mazzoni,
+    one of the main authors of Audacity (http://audacity.sourceforge.net/).
+
+2001-12-26  Erik de Castro Lopo  <erikd AT mega-nerd DOT com>
+
+    * src/sndfile.c
+    Added checking of filename parameter in sf_open_read (). Previousy, if a
+    NULL pointer was passed the library would segfault.
+
+2001-12-18  Erik de Castro Lopo  <erikd AT mega-nerd DOT com>
+
+    * src/common.c src/common.h
+    Changed the len parameter of the endswap_*_array () functions from type
+    int to type long.
+
+    * src/pcm.c
+    Fixed a problem which
+
+2001-12-15  Erik de Castro Lopo  <erikd AT mega-nerd DOT com>
+
+    * src/sndfile.c
+    Added conditional #include <sys/types.h> for EMX/gcc on OS/2. Thanks to
+    Paul Hartman for pointing this out.
+
+    * tests/lossy_comp_test.c tests/floating_point_test.c
+    Added definitions for M_PI for when it isn't defined in <math.h>.
+
+2001-11-30  Erik de Castro Lopo  <erikd AT mega-nerd DOT com>
+
+    * src/ircam.c
+    Re-implemented the header reader. Old version was making incorrect
+    assumptions about the endian-ness of the file from the magic number at the
+    start of the file. The new code looks at the integer which holds the
+    number of channels and determines the endian-ness from that.
+
+2001-11-30  Erik de Castro Lopo  <erikd AT mega-nerd DOT com>
+
+    * src/aiff.c
+    Added support for other AIFC types ('raw ', 'in32', '23ni').
+    Further work on IMA ADPCM encoding.
+
+2001-11-29  Erik de Castro Lopo  <erikd AT mega-nerd DOT com>
+
+    * src/ima_adpcm.c
+    Renamed from wav_ima_adpcm.c. This file will soon handle IMA ADPCM
+    encodings for both WAV and AIFF files.
+
+    * src/aiff.c
+    Started adding IMA ADPCM support.
+
+2001-11-28  Erik de Castro Lopo  <erikd AT mega-nerd DOT com>
+
+    * src/double.c
+    New file for handling double precision floating point (SF_FORMAT_DOUBLE)
+    data.
+
+    * src/wav.c src/aiff.c src/au.c src/raw.c
+    Added support for SF_FORMAT_DOUBLE data.
+
+    * src/common.[ch]
+    Addition of endswap_long_array () for endian swapping 64 bit integers. This
+    function will work correctly on processors with 32 bit and 64 bit longs.
+    Optimised endswap_short_array () and endswap_int_array ().
+
+    * tests/pcm_test.c
+    Added and extra check. After the first file of each type is written to disk
+    a checksum is performed of the first 64 bytes and checked against a pre-
+    calculated value. This will work whatever the endian-ness of the host
+    machine.
+
+2001-11-27  Erik de Castro Lopo  <erikd AT mega-nerd DOT com>
+
+    * src/aiff.c
+    Added handling of u-law, A-law encoded AIFF files. Thanks to Tom Erbe for
+    supplying example files.
+
+    * tests/lossy_comp_test.c
+    Added tests for above.
+
+    * src/common.h src/*.c
+    Removed function typedefs from common.h and function pointer casting in all
+    the other files. This allows the compiler to perform proper type checking.
+    Hopefully this will prevernt problems like the sf_seek bug for OpenBSD,
+    BeOS etc.
+
+    * src/common.[ch]
+    Added new function psf_new_binheader_readf () which will eventually replace
+    psf_binheader_readf (). The new function has basically the same function as
+    the original but has a more flexible and capable interface. It also allows
+    the reading of 64 bit integer values for files contains 64 bit file
+    offsets.
+
+2001-11-26  Erik de Castro Lopo  <erikd AT mega-nerd DOT com>
+
+    * src/voc.c
+    Completed implementation of VOC file handling. Can now handle 8 and 16 bit
+    PCM, u-law and A-law files with one or two channels.
+
+    * src/write_read_test.c tests/lossy_comp_test.c
+    Added tests for VOC files.
+
+2001-11-22  Erik de Castro Lopo  <erikd AT mega-nerd DOT com>
+
+    * src/float_cast.h
+    Added inline asm version of lrint/lrintf for MacOS. Solution provided by
+    Stephane Letz.
+
+    * src/voc.c
+    More work on this braindamaged format. The VOC files produced by SoX also
+    have a number of inconsistencies.
+
+2001-11-19  Erik de Castro Lopo  <erikd AT mega-nerd DOT com>
+
+    * src/paf.c
+    Added support for 8 bit PCM PAF files.
+
+    * tests/write_read_test.c
+    Added tests for 8 bit PAF files.
+
+2001-11-18  Erik de Castro Lopo  <erikd AT mega-nerd DOT com>
+
+    * tests/pcm_test.c
+    New test program to test for correct scaling of integer values between
+    different sized integer containers (ie short -> int).
+    The new specs for libsndfile state that when the source and destination
+    containers are of a different size, the most significant bit of the source
+    value becomes the most significant bit of the destination container.
+
+    * src/pcm.c src/paf.c
+    Modified to pass the above test program.
+
+    * tests/write_read_test.c tests/lossy_comp_test.c
+    Modified to work with the new scaling rules.
+
+2001-11-17  Erik de Castro Lopo  <erikd AT mega-nerd DOT com>
+
+    * src/raw.c tests/write_read_test.c tests/write_read_test.c
+    Added ability to do raw reads/writes of float, u-law and A-law files.
+
+    * src/*.[ch] examples/*.[ch] tests/*.[ch]
+    Removed dependance on pcmbitwidth field of SF_INFO struct and moved to new
+    SF_FORMAT_* types and use of SF_ENDIAN_BIG/LITTLE/CPU.
+
+2001-11-12  Erik de Castro Lopo  <erikd AT mega-nerd DOT com>
+
+    * src/*.[ch]
+    Started implmentation of major changes documented in doc/version1.html.
+
+    Removed all usage of off_t which is not part of the ISO C standard. All
+    places which were using it are now using type long which is the type of
+    the offset parameter for the fseek function.
+    This should fix problems on BeOS, MacOS and *BSD like systems which were
+    failing "make check" because sizeof (long) != sizeof (off_t).
+
+--------------------------------------------------------------------------------
+This is the boundary between version 1 of the library above and version 0 below.
+--------------------------------------------------------------------------------
+
+2001-11-11  Erik de Castro Lopo  <erikd AT mega-nerd DOT com>
+
+    * examples/sfplay_beos.cpp
+    Added BeOS version of sfplay.c. This needs to be compiled using a C++
+    compiler so is therefore not built by default. Thanks to Marcus Overhagen
+    for providing this.
+
+2001-11-10  Erik de Castro Lopo  <erikd AT mega-nerd DOT com>
+
+    * examples/sfplay.c
+    New example file showing how libsndfile can be used to read and play a
+    sound file.
+    At the moment on Linux is supported. Others will follow in the near future.
+
+2001-11-09  Erik de Castro Lopo  <erikd AT mega-nerd DOT com>
+
+    * src/pcm.c
+    Fixed problem with normalisation code where a value of 1.0 could map to
+    a value greater than MAX_SHORT or MAX_INT. Thanks to Roger Dannenberg for
+    pointing this out.
+
+2001-11-08  Erik de Castro Lopo  <erikd AT mega-nerd DOT com>
+
+    * src/pcm.c
+    Fixed scaling issue when reading/writing 8 bit files using
+    sf_read/sf_write_short ().
+    On read, values are scaled so that the most significant bit in the char
+    ends up in the most significant bit of the short. On write, values are
+    scaled so that most significant bit in the short ends up as the most
+    significant bit in the char.
+
+2001-11-07  Erik de Castro Lopo  <erikd AT mega-nerd DOT com>
+
+    * src/au.c src/sndfile.c
+    Added support for 32 bit float data in big and little endian AU files.
+
+    * tests/write_read_test.c
+    Added tests for 32 bit float data in AU files.
+
+2001-11-06  Erik de Castro Lopo  <erikd AT mega-nerd DOT com>
+
+    * tests/lossy_comp_test.c
+    Finalised testing of stereo files where possible.
+
+2001-11-05  Erik de Castro Lopo  <erikd AT mega-nerd DOT com>
+
+    * src/wav_ms_adpcm.c
+    Fixed bug in writing stereo MS ADPCM WAV files. Thanks to Xu Xin for
+    pointing out this problem.
+
+2001-10-24  Erik de Castro Lopo  <erikd AT mega-nerd DOT com>
+
+    * src/wav_ms_adpcm.c
+    Modified function srate2blocksize () to handle 44k1Hz stereo files.
+
+2001-10-21  Erik de Castro Lopo  <erikd AT mega-nerd DOT com>
+
+    * src/w64.c
+    Added support for Sonic Foundry 64 bit WAV format. As Linux (my main
+    development platform) does not yet support 64 bit file offsets by default,
+    current handling of this file format treats everything as 32 bit and fails
+    openning the file, if it finds anything that goes beyond 32 bit values.
+
+    * src/sndfile.[hc] src/common.h src/Makefile.am
+    Added hooks for W64 support.
+
+2001-10-21  Erik de Castro Lopo  <erikd AT mega-nerd DOT com>
+
+    * configure.in
+    Added more warnings options to CFLAGS when the gcc compiler is detected.
+
+    * src/*.[ch] tests/*.c examples/*.c
+    Started fixing the warning messages due to the new CFLASG.
+
+    * src/voc.c
+    More work on VOC file read/writing.
+
+    * src/paf.c
+    Found that PAF files were not checking the normalisation flag when reading
+    or writing floats and doubles. Fixed it.
+
+    * tests/floating_point_test.c
+    Added specific test for the above problem.
+
+    * src/float_cast.h src/pcm.c
+    Added a section for Win32 to define lrint () and lrintf () in the header
+    and implement it in the pcm.c
+
+2001-10-20  Erik de Castro Lopo  <erikd AT mega-nerd DOT com>
+
+    * sndfile-config.in m4/sndfile.m4
+    These files were donated by Conrad Parker who also provided instructions
+    on how to install them using autoconf/automake.
+
+    * src/float_cast.h
+    Fiddled around with this file some more. On Linux and other gcc supported
+    OSes use the C99 functions lrintf() and lrint() for casting from floating
+    point to int without incurring the huge perfromance penalty (particularly
+    on the i386 family) caused by the regular C cast from float to int.
+    These new C99 functions replace the FLOAT_TO_* and DOUBLE_TO_* macros which
+    I had been playing with.
+
+    * configure.in m4/lrint.m4 m4/lrintf.m4
+    Add detection of these functions.
+
+2001-10-17  Erik de Castro Lopo  <erikd AT mega-nerd DOT com>
+
+    * src/voc.c
+    Completed code for reading VOC files containing a single audio data
+    segment.
+    Started implementing code to handle files with multiple VOC_SOUND_DATA
+    segments but couldn't be bothered finishing it. Multiple segment files can
+    have different sample rates for different sections and other nasties like
+    silence and repeat segments.
+
+2001-10-16  Erik de Castro Lopo  <erikd AT mega-nerd DOT com>
+
+    * src/common.h src/*.c
+    Removed SF_PRIVATE struct field fdata and replaced it with extra_data.
+
+    * src/voc.c
+    Further development of the read part of this woefult file format.
+
+2001-10-04  Erik de Castro Lopo  <erikd AT mega-nerd DOT com>
+
+    * src/float_cast.h
+    Implemented gcc and i386 floating point to int cast macros. Standard cast
+    will be used when not on gcc for i385.
+
+    * src/pcm.c
+    Modified all uses of FLOAT/DOUBLE_TO_INT and FLOAT/DOUBLE_TO_SHORT casts to
+    comply with macros in float_cast.h.
+
+2001-10-04  Erik de Castro Lopo  <erikd AT mega-nerd DOT com>
+
+    * src/voc.c
+    Changed the TYPE_xxx enum names to VOC_TYPE_xxx to prevent name clashes
+    on MacOS with CodeWarrior 6.0.
+
+    * MacOS/MacOS-readme.txt
+    Updated the compile instructions. Probably still need work as I don't have
+    access to a Mac.
+
+2001-10-01  Erik de Castro Lopo  <erikd AT mega-nerd DOT com>
+
+    * src/wav.c src/aiff.c common.c
+    Changed all references to snprintf to LSF_SNPRINTF and all vsnprintf to
+    LSF_VSNPRINTF. LSF_VSNPRINTF and LSF_VSNPRINTF are defined in common.h.
+
+    * src/common.h
+    Added checking of HAVE_SNPRINTF and HAVE_VSNPRINTF and defining
+    LSF_VSNPRINTF and LSF_VSNPRINTF to appropriate values.
+
+    * src/missing.c
+    New file containing a minimal implementation of snprintf and vsnprintf
+    functions named missing_snprintf and missing_vsnprintf respectively. These
+    are only compliled into the binary if snprintf and/or vsnprintf are not
+    available.
+
+2001-09-29  Erik de Castro Lopo  <erikd AT mega-nerd DOT com>
+
+    * src/ircam.c
+    New file to handle Berkeley/IRCAM/CARL files.
+
+    * src/sndfile.c src/common.h
+    Modified for IRCAM handling.
+
+    * tests/*.c
+    Added tests for IRCAM files.
+
+2001-09-27  Erik de Castro Lopo  <erikd AT mega-nerd DOT com>
+
+    * src/wav.c
+    Apparently microsoft windows (tm) doesn't like ulaw and Alaw WAV files with
+    20 byte format chunks (contrary to ms's own documentation). Fixed the WAV
+    header writing code to generate smaller ms compliant ulaw and Alaw WAV
+    files.
+
+2001-09-17  Erik de Castro Lopo  <erikd AT mega-nerd DOT com>
+
+    * tests/stdio_test.sh tests/stdio_test.c
+    Shell script was rewritten as a C program due to incompatibilities of the
+    sh shell on Linux and Solaris.
+
+2001-09-16  Erik de Castro Lopo  <erikd AT mega-nerd DOT com>
+
+    * tests/stdio_test.sh tests/stdout_test.c tests/stdin_test.c
+    New test programs to verify the correct operation of reading from stdin and
+    writing to stdout.
+
+    * src/sndfile.c wav.c au.c nist.c paf.c
+    Fixed a bugs uncovered by the new test programs above.
+
+2001-09-15  Erik de Castro Lopo  <erikd AT mega-nerd DOT com>
+
+    * src/sndfile.c wav.c
+    Fixed a bug preventing reading a file from stdin. Found by T. Narita.
+
+2001-09-12  Erik de Castro Lopo  <erikd AT mega-nerd DOT com>
+
+    * src/common.h
+    Fixed a problem on OpenBSD 2.9 which was causing sf_seek() to fail on IMA
+    WAV files. Root cause was the declaration of the func_seek typedef not
+    matching the functions it was actually being used to point to. In OpenBSD
+    sizeof (off_t) != sizeof (int). Thanks to Heikki Korpela for allowing me
+    to log into his OpenBSD machine to debug this problem.
+
+2001-09-03  Erik de Castro Lopo  <erikd AT mega-nerd DOT com>
+
+    * src/sndfile.c
+    Implemented sf_command ("norm float").
+
+    * src/*.c
+    Implemented handling of sf_command ("set-norm-float"). Float normalization
+    can now be turned on and off.
+
+    * tests/double_test.c
+    Renamed to floating_point_test.c. Modified to include tests for all scaled
+    reads and writes of floats and doubles.
+
+    * src/au_g72x.c
+    Fixed bug in normalization code found with improved floating_point_test
+    program.
+
+    * src/wav.c
+    Added code for parsing 'INFO' and 'LIST' chunks. Will be used for extract
+    text annotations from WAV files.
+
+    * src/aiff.c
+    Added code for parsing '(c) ' and 'ANNO' chunks. Will be used for extract
+    text annotations from WAV files.
+
+2001-09-02  Erik de Castro Lopo  <erikd AT mega-nerd DOT com>
+
+    * examples/sf_info.c example/Makefile.am
+    Renamed to sndfile_info.c. The program sndfile_info will now be installed
+    when the library is installed.
+
+    * src/float_cast.h
+    New file defining floating point to short and int casts. These casts will
+    eventually replace all flot and double casts to short and int. See comments
+    at the top of the file for the reasoning.
+
+    * src/*.c
+    Changed all default float and double casts to short or int with macros
+    defined in floatcast.h. At the moment these casts do nothing. They will be
+    replaced with faster float to int cast operations in the near future.
+
+2001-08-31  Erik de Castro Lopo  <erikd AT mega-nerd DOT com>
+
+    * tests/command_test.c
+    New file for testing sf_command () functionality.
+
+    * src/sndfile.c
+    Revisiting of error return values of some functions.
+    Started implementing sf_command () a new function will allow on-the-fly
+    modification of library behaviour, or instance, sample value scaling.
+
+    * src/common.h
+    Added hook for format specific sf_command () calls to SNDFILE struct.
+
+    * doc/api.html
+    Updated and errors corrected.
+
+    * doc/command.html
+    New documentation file explaining new sf_command () function.
+
+2001-08-11  Erik de Castro Lopo  <erikd AT mega-nerd DOT com>
+
+    * src/sndfile.c
+    Fixed error return values from sf_read*() and sf_write*(). There were
+    numerous instances of -1 being returned through size_t. These now all set
+    error int the SF_PRIVATE struct and return 0. Thanks to David Viens for
+    spotting this.
+
+2001-08-01  Erik de Castro Lopo  <erikd AT mega-nerd DOT com>
+
+    * src/common.c
+    Fixed use of va_arg() calls that were causing warning messages with the
+    latest version of gcc (thanks Maurizio Umberto Puxeddu).
+
+2001-07-25  Erik de Castro Lopo  <erikd AT mega-nerd DOT com>
+
+    * src/*.c src/sfendian.h
+    Moved definition of MAKE_MARKER macro to sfendian.h
+
+2001-07-23  Erik de Castro Lopo  <erikd AT mega-nerd DOT com>
+
+    * src/sndfile.c
+    Modified sf_get_lib_version () so that version string will be visible using
+    the Unix strings command.
+
+    * examples/Makefile.am examples/sfinfo.c
+    Renamed sfinfo program and source code to sf_info. This prevents a name
+    clash with the program included with libaudiofile.
+
+2001-07-22  Erik de Castro Lopo  <erikd AT mega-nerd DOT com>
+
+    * tests/read_seek_test.c tests/lossy_comp_test.c
+    Added tests for sf_read_float () and sf_readf_float ().
+
+    * src/voc.c
+    New files for handling Creative Voice files (not complete).
+
+    * src/samplitude.c
+    New files for handling Samplitude files (not complete).
+
+2001-07-21  Erik de Castro Lopo  <erikd AT mega-nerd DOT com>
+
+    * src/aiff.c src/au.c src/paf.c src/svx.c src/wav.c
+    Converted these files to using psf_binheader_readf() function. Will soon be
+    ready to attempt to make reading writing from pipes work reliably.
+
+    * src/*.[ch]
+    Added code for sf_read_float () and sf_readf_float () methods of accessing
+    file data.
+
+2001-07-20  Erik de Castro Lopo  <erikd AT mega-nerd DOT com>
+
+    * src/paf.c src/wav_gsm610.c
+    Removed two printf()s which had escaped notice for some time (thanks
+    Sigbj�rn Skj�ret).
+
+2001-07-19  Erik de Castro Lopo  <erikd AT mega-nerd DOT com>
+
+    * src/wav_gsm610.c
+    Fixed a bug which prevented GSM 6.10 encoded WAV files generated by
+    libsndfile from being played in Windoze (thanks klay).
+
+2001-07-18  Erik de Castro Lopo  <erikd AT mega-nerd DOT com>
+
+    * src/common.[ch]
+    Implemented psf_binheader_readf() which will do for file header reading what
+    psf_binheader_writef() did for writing headers. Will eventually allow
+    libsndfile to read and write from pipes, including named pipes.
+
+2001-07-16  Erik de Castro Lopo  <erikd AT mega-nerd DOT com>
+
+    * MacOS/config.h Win32/config.h
+    Attempted to bring these two files uptodate with src/config.h. As I don't
+    have access to either of these systems support for them may be completely
+    broken.
+
+2001-06-18  Erik de Castro Lopo  <erikd AT mega-nerd DOT com>
+
+    * src/float32.c
+    Fixed bug for big endian processors that can't read 32 bit IEEE floats. Now
+    tested on Intel x86 and UltraSparc processors.
+
+2001-06-13  Erik de Castro Lopo  <erikd AT mega-nerd DOT com>
+
+    * src/aiff.c
+    Modified to allow REX files (from Propellorhead's Recycle and Reason
+    programs) to be read.
+    REX files are basically an AIFF file with slightly unusual sequence of
+    chunks (AIFF files are supposed to allow any sequence) and some extra
+    application specific information.
+    Not yet able to write a REX file as the details of the application specific
+    data is unknown.
+
+2001-06-12  Erik de Castro Lopo  <erikd AT mega-nerd DOT com>
+
+    * src/wav.c
+    Fixed endian bug when reading PEAK chunk on big endian machines.
+
+    * src/common.c
+    Fixed endian bug when reading PEAK chunk on big endian machines with
+    --enable-force-broken-float configure option.
+    Fix psf_binheader_writef for (FORCE_BROKEN_FLOAT ||______)
+
+2001-06-07  Erik de Castro Lopo  <erikd AT mega-nerd DOT com>
+
+    * configure.in src/config.h.in
+    Removed old CAN_READ_WRITE_x86_IEEE configure variable now that float
+    capabilities are detected at run time.
+    Added FORCE_BROKEN_FLOAT to allow testing of broken float code on machines
+    where the processor can in fact handle floats correctly.
+
+    * src/float32.c
+    Rejigged code reading and writing of floats on broken processors.
+
+    * m4/
+    Removed this directory and all its files as they are no longer needed.
+
+2001-06-05  Erik de Castro Lopo  <erikd AT mega-nerd DOT com>
+
+    * tests/peak_chunk_test.c
+    New test to validate reading and writing of peak chunk.
+
+    * examples/sfconvert
+    Added -float32 option.
+
+    * src/*.c
+    Changed all error return values to negative values (ie the negative of what
+    they were).
+
+    * src/sndfile.c tests/error_test.c
+    Modified to take account of the previous change.
+
+2001-06-04  Erik de Castro Lopo  <erikd AT mega-nerd DOT com>
+
+    * src/float32.c
+    File renamed from wav_float.c and renamed function to something more
+    general.
+    Added runtime detection of floating point capabilities.
+    Added recording of peaks during write for generation of PEAK chunk.
+
+    * src/wav.c src/aiff.c
+    Added handing for PEAK chunk for floating point files. PEAK is read when the
+    file headers are read and generated when the file is closed. Logic is in
+    place for adding PEAK chunk to end of file when writing to a pipe (reading
+    and writing from/to pipe to be implemented soon).
+
+    * src/sndfile.c
+    Modified sf_signal_max () to use PEAK values if present.
+
+2001-06-03  Erik de Castro Lopo  <erikd AT mega-nerd DOT com>
+
+    * src/*.c
+    Added pcm_read_init () and pcm_write_init () to src/pcm.c and removed all
+    other calls to functions in this file from the filetype specific files.
+
+    * src/*.c
+    Added alaw_read_init (), alaw_write_int (), ulaw_read_init () and
+    ulaw_write_init () and removed all other calls to functions in alaw.c and
+    ulaw.c from the filetype specific files.
+
+    * tests/write_read_test.c
+    Added tests to validate sf_seek () on all file types.
+
+    * src/raw.c
+    Implemented raw_seek () function to fix a bug where
+    sf_seek (file, 0, SEEK_SET) on a RAW file failed.
+
+    * src/paf.c
+    Fixed a bug in paf24_seek () found due to added seeks tests in
+    tests/write_read_test.c
+
+2001-06-01  Erik de Castro Lopo  <erikd AT mega-nerd DOT com>
+
+    * tests/read_seek_test.c
+    Fixed a couple of broken binary files.
+
+    * src/aiff.c src/wav.c
+    Added handling of PEAK chunks on file read.
+
+2001-05-31  Erik de Castro Lopo  <erikd AT mega-nerd DOT com>
+
+    * check_libsndfile.py
+    New file for the regression testing of libsndfile.
+    check_libsndfile.py is a Python script which reads in a file containing
+    filenames of audio files. Each file is checked by running the examples/sfinfo
+    program on them and checking for error or warning messages in the libsndfile
+    log buffer.
+
+    * check_libsndfile.list
+    This is an example list of audio files for use with check_libsndfile.py
+
+    * tests/lossy_comp_test.c
+    Changed the defined value of M_PI for math header files which don't have it.
+    This fixed validation test failures on MetroWerks compilers. Thanks to Lord
+    Praetor Satanus of Acheron for bringing this to my attention.
+
+2001-05-30  Erik de Castro Lopo  <erikd AT mega-nerd DOT com>
+
+    * src/common.[ch]
+    Removed psf_header_setf () which was no longer required after refactoring
+    and simplification of header writing.
+    Added 'z' format specifier to psf_binheader_writef () for zero filling header
+    with N bytes. Used by paf.c and nist.c
+
+    * tests/check_log_buffer.c
+    New file implementing check_log_buffer () which reads the log buffer of a
+    SNDFILE* object and searches for error and warning messages. Calls exit ()
+    if any are found.
+
+    * tests/*.c
+    Added calls to check_log_buffer () after each call to sf_open_XXX ().
+
+2001-05-29  Erik de Castro Lopo  <erikd AT mega-nerd DOT com>
+
+    * src/wav.c src/wav_ms_adpcm.c src/wav_gsm610.c
+    Major rehack of header writing using psf_binheader_writef ().
+
+2001-05-28  Erik de Castro Lopo  <erikd AT mega-nerd DOT com>
+
+    * src/wav.c src/wav_ima_adpcm.c
+    Major rehack of header writing using psf_binheader_writef ().
+
+2001-05-27  Erik de Castro Lopo  <erikd AT mega-nerd DOT com>
+
+    * src/wav.c
+    Changed return type of get_encoding_str () to prevent compiler warnings on
+    Mac OSX.
+
+    * src/aiff.c src/au.c
+    Major rehack of header writing using psf_binheader_writef ().
+
+2001-05-25  Erik de Castro Lopo  <erikd AT mega-nerd DOT com>
+
+    * src/common.h src/common.c
+    Added comments.
+    Name of log buffer changed from strbuffer to logbuffer.
+    Name of log buffer index variable changed from strindex to logindex.
+
+    * src/*.[ch]
+    Changed name of internal logging function from psf_sprintf () to
+    psf_log_printf ().
+    Changed name of internal header generation functions from
+    psf_[ab]h_printf () to psf_asciiheader_printf () and
+    psf_binheader_writef ().
+    Changed name of internal header manipulation function psf_hsetf () to
+    psf_header_setf ().
+
+2001-05-24  Erik de Castro Lopo  <erikd AT mega-nerd DOT com>
+
+    * src/nist.c
+    Fixed reading and writing of sample_byte_format header. "01" means little
+    endian and "10" means big endian regardless of bit width.
+
+    * configure.in
+    Detect Mac OSX and disable -Wall and -pedantic gcc options. Mac OSX is
+    way screwed up and spews out buckets of warning messages from the system
+    headers.
+    Added --disable-gcc-opt configure option (sets gcc optimisation to -O0 ) for
+    easier debugging.
+    Made decision to harmonise source code version number and .so library
+    version number. Future releases will stick to this rule.
+
+    * doc/new_file_type.HOWTO
+    New file to document the addition of new file types to libsndfile.
+
+2001-05-23  Erik de Castro Lopo  <erikd AT mega-nerd DOT com>
+
+    * src/nist.c
+    New file for reading/writing Sphere NIST audio file format.
+    Originally requested by Elis Pomales in 1999.
+    Retrieved from unstable (and untouched for 18 months) branch of libsndfile.
+    Some vital information gleaned from the source code to Bill Schottstaedt's
+    sndlib library : ftp://ccrma-ftp.stanford.edu/pub/Lisp/sndlib.tar.gz
+    Currently reading and writing 16, 24 and 32 bit, big-endian and little
+    endian, stereo and mono files.
+
+    * src/common.h src/common.c
+    Added psf_ah_printf () function to help construction of ASCII headers (ie NIST).
+
+    * configure.in
+    Added test for vsnprintf () required by psf_ah_printf ().
+
+    * tests/write_read_test.c
+    Added tests for supported NIST files.
+
+2001-05-22  Erik de Castro Lopo  <erikd AT mega-nerd DOT com>
+
+    * tests/write_read_test.c
+    Added tests for little endian AIFC files.
+
+    * src/aiff.c
+    Minor re-working of aiff_open_write ().
+    Added write support for little endian PCM encoded AIFC files.
+
+2001-05-13  Erik de Castro Lopo  <erikd AT mega-nerd DOT com>
+
+    * src/aiff.c
+    Minor re-working of aiff_open_read ().
+    Added read support for little endian PCM encoded AIFC files from the Mac
+    OSX CD ripper program. Guillaume Lessard provided a couple of sample files
+    and a working patch.
+    The patch was not used as is but gave a good guide as to what to do.
+
+2001-05-11  Erik de Castro Lopo  <erikd AT mega-nerd DOT com>
+
+    * src/sndfile.h
+    Fixed comments about endian-ness of WAV and AIFF files. Guillaume Lessard
+    pointed out the error.
+
+2001-04-23  Erik de Castro Lopo  <erikd AT mega-nerd DOT com>
+
+    * examples/make_sine.c
+    Re-write of this example using sample rate and required frequency in Hz.
+
+2001-02-11  Erik de Castro Lopo  <erikd AT mega-nerd DOT com>
+
+    * src/sndfile.c
+    Fixed bug that prevented known file types from being read as RAW PCM data.
+
+2000-12-16  Erik de Castro Lopo  <erikd AT mega-nerd DOT com>
+
+    * src/aiff.c
+    Added handing of COMT chunk.
+
+2000-11-16  Erik de Castro Lopo  <erikd AT mega-nerd DOT com>
+
+    * examples/sfconvert.c
+    Fixed bug in normalisatio code. Pointed out by Johnny Wu.
+
+2000-11-08  Erik de Castro Lopo  <erikd AT mega-nerd DOT com>
+
+    * Win32/config.h
+    Fixed the incorrect setting of HAVE_ENDIAN_H parameter. Win32 only issue.
+
+2000-10-27  Erik de Castro Lopo  <erikd AT mega-nerd DOT com>
+
+    * tests/Makefile.am
+    Added -lm for write_read_test_LDADD.
+
+2000-10-16  Erik de Castro Lopo  <erikd AT mega-nerd DOT com>
+
+    * src/sndfile.c src/au.c
+    Fixed bug which prevented writing of G723 24kbps AU files.
+
+    * tests/lossy_comp_test.c
+    Corrrection to options for G723 tests.
+
+    * configure.in
+    Added --disable-gcc-pipe option for DJGPP compiler (gcc on MS-DOS) which
+    doesn't allow gcc -pipe option.
+
+2000-09-03  Erik de Castro Lopo  <erikd AT mega-nerd DOT com>
+
+    * src/ulaw.c src/alaw.c src/wav_imaadpcm.c src/msadpcm.c src/wav_gsm610.c
+    Fixed normailsation bugs shown up by new double_test program.
+
+2000-08-31  Erik de Castro Lopo  <erikd AT mega-nerd DOT com>
+
+    * src/pcm.c
+    Fixed bug in normalisation code (spotted by Steve Lhomme).
+
+    * tests/double_test.c
+    New file to test scaled and unscaled sf_read_double() and sf_write_double()
+    functions.
+
+2000-08-28  Erik de Castro Lopo  <erikd AT mega-nerd DOT com>
+
+    * COPYING
+    Changed to the LGPL COPYING file (spotted by H. S. Teoh).
+
+2000-08-21  Erik de Castro Lopo  <erikd AT mega-nerd DOT com>
+
+    * src/sndfile.h
+    Removed prototype of unimplemented function sf_get_info(). Added prototype
+    for sf_error_number() Thanks to Sigbj�rn Skj�ret for spotting these.
+
+2000-08-18  Erik de Castro Lopo  <erikd AT mega-nerd DOT com>
+
+    * src/newpcm.h
+    New file to contain a complete rewrite of the PCM data handling.
+
+2000-08-15  Erik de Castro Lopo  <erikd AT mega-nerd DOT com>
+
+    * src/sndfile.c
+    Fixed a leak of FILE* pointers in sf_open_write(). Thanks to Sigbj�rn
+    Skj�ret for spotting this one.
+
+2000-08-13  Erik de Castro Lopo  <erikd AT mega-nerd DOT com>
+
+    * src/au_g72x.c src/G72x/g72x.c
+    Added G723 encoded AU file support.
+
+    * tests/lossy_comp_test.c
+    Added tests for G721 and G723 encoded AU files.
+
+2000-08-06  Erik de Castro Lopo  <erikd AT mega-nerd DOT com>
+
+    * all files
+    Changed the license to LGPL. Albert Faber who had copyright on
+    Win32/unistd.h gave his permission to change the license on that file. All
+    other files were either copyright erikd AT mega-nerd DOT com or copyright
+    under a GPL/LGPL compatible license.
+
+2000-08-06  Erik de Castro Lopo  <erikd AT mega-nerd DOT com>
+
+    * tests/lossy_comp_test.c
+    Fixed incorrect error message.
+
+    * src/au_g72x.c src/G72x/*
+    G721 encoded AU files now working.
+
+    * Win32/README-Win32.txt
+    Replaced this file with a new one which gives a full explanation
+    of how to build libsndfile under Win32. Thanks to Mike Ricos.
+
+2000-08-05  Erik de Castro Lopo  <erikd AT mega-nerd DOT com>
+
+    * src/*.[ch]
+    Removed double leading underscores from the start of all variable and
+    function names. Identifiers with a leading underscores are reserved
+    for use by the compiler.
+
+    * src/au_g72x.c src/G72x/*
+    Continued work on G721 encoded AU files.
+
+2000-07-12  Erik de Castro Lopo  <erikd AT mega-nerd DOT com>
+
+    * src/G72x/*
+    New files for reading/writing G721 and G723 ADPCM audio. These files
+    are from a Sun Microsystems reference implementation released under a
+    free software licence.
+    Extensive changes to this code to make it fit in with libsndfile.
+    See the ChangeLog in this directory for details.
+
+    * src/au_g72x.c
+    New file for G721 encoded AU files.
+
+2000-07-08  Erik de Castro Lopo  <erikd AT mega-nerd DOT com>
+
+    * libsndfile.spec.in
+    Added a spec file for making RPMs. Thanks to Josh Green for supplying this.
+
+2000-06-28  Erik de Castro Lopo  <erikd AT mega-nerd DOT com>
+
+    * src/sndfile.c src/sndfile.h
+    Add checking for and handling of header-less u-law encoded AU/SND files.
+    Any file with a ".au" or ".snd" file extension and without the normal
+    AU file header is treated as an 8kHz, u-law encoded file.
+
+    * src/au.h
+    New function for opening a headerless u-law encoded file for read.
+
+2000-06-04  Erik de Castro Lopo  <erikd AT mega-nerd DOT com>
+
+    * src/paf.c
+    Add checking for files shorter than minimal PAF file header length.
+
+2000-06-02  Erik de Castro Lopo  <erikd AT mega-nerd DOT com>
+
+    * tests/write_read_test.c
+    Added extra sf_perror() calls when sf_write_XXXX fails.
+
+2000-05-29  Erik de Castro Lopo  <erikd AT mega-nerd DOT com>
+
+    * src/common.c
+    Modified usage of va_arg() macro to work correctly on PowerPC
+    Linux. Thanks to Kyle Wheeler for giving me ssh access to his
+    machine while I was trying to track this down.
+
+    * configure.in src/*.[ch]
+    Sorted out some endian-ness issues brought up by PowerPC Linux.
+
+    * tests/read_seek_test.c
+    Added extra debugging for when tests fail.
+
+2000-05-18  Erik de Castro Lopo  <erikd AT mega-nerd DOT com>
+
+    * src/wav.c
+    Fixed bug in GSM 6.10 handling for big-endian machines. Thanks
+    to Sigbj�rn Skj�ret for reporting this.
+
+2000-04-25  Erik de Castro Lopo  <erikd AT mega-nerd DOT com>
+
+    * src/sndfile.c src/wav.c src/wav_gsm610.c
+    Finallised writing of GSM 6.10 WAV files.
+
+    * tests/lossy_comp_test.c
+    Wrote new test code for GSM 6.10 files.
+
+    * examples/sfinfo.c
+    Fixed incorrect format in printf() statement.
+
+2000-04-06  Erik de Castro Lopo  <erikd AT mega-nerd DOT com>
+
+    * src/sndfile.h.in
+    Fixed comments about sf_perror () and sf_error_str ().
+
+2000-03-14  Erik de Castro Lopo  <erikd AT mega-nerd DOT com>
+
+    * configure.in
+    Fixed --enable-justsrc option.
+
+2000-03-07  Erik de Castro Lopo  <erikd AT mega-nerd DOT com>
+
+    * wav.c
+    Fixed checking of bytespersec field of header. Still some weirdness
+    with some files.
+
+2000-03-05  Erik de Castro Lopo  <erikd AT mega-nerd DOT com>
+
+    * tests/lossy_comp_test.c
+    Added option to test PCM WAV files (sanity check).
+    Fixed bug in sf_seek() tests.
+
+2000-02-29  Erik de Castro Lopo  <erikd AT mega-nerd DOT com>
+
+    * src/sndfile.c src/wav.c
+    Minor changes to allow writing of GSM 6.10 WAV files.
+
+2000-02-28  Erik de Castro Lopo  <erikd AT mega-nerd DOT com>
+
+    * configure.in Makefile.am src/Makefile.am
+    Finally got around to figuring out how to build a single library from
+    multiple source directories.
+    Reading GSM 6.10 files now seems to work.
+
+2000-01-03  Erik de Castro Lopo  <erikd AT mega-nerd DOT com>
+
+    * src/wav.c
+    Added more error reporting in read_fmt_chunk().
+
+1999-12-21  Erik de Castro Lopo  <erikd AT mega-nerd DOT com>
+
+    * examples/sfinfo.c
+    Modified program to accept multiple filenames from the command line.
+
+1999-11-27  Erik de Castro Lopo  <erikd AT mega-nerd DOT com>
+
+    * src/wav_ima_adpcm.c
+    Moved code around in preparation to adding ability to read/write IMA ADPCM
+    encoded AIFF files.
+
+1999-11-16  Erik de Castro Lopo  <erikd AT mega-nerd DOT com>
+
+    * src/common.c
+    Fixed put_int() and put_short() macros used by _psf_hprintf() which were
+    causing seg. faults on Sparc Solaris.
+
+1999-11-15  Erik de Castro Lopo  <erikd AT mega-nerd DOT com>
+
+    * src/common.c
+    Added string.h to includes. Thanks to Sigbjxrn Skjfret.
+
+    * src/svx.c
+    Fixed __svx_close() function to ensure FORM and BODY chunks are correctly
+    set.
+
+1999-10-01  Erik de Castro Lopo  <erikd AT mega-nerd DOT com>
+
+    * src/au.c
+    Fixed handling of incorrect size field in AU header on read. Thanks to
+    Christoph Lauer for finding this problem.
+
+1999-09-28  Erik de Castro Lopo  <erikd AT mega-nerd DOT com>
+
+    * src/aiff.c
+    Fixed a bug with incorrect SSND chunk length being written. This also lead
+    to finding an minor error in AIFF header parsing. Thanks to Dan Timis for
+    pointing this out.
+
+1999-09-24  Erik de Castro Lopo  <erikd AT mega-nerd DOT com>
+
+    * src/paf.c
+    Fixed a bug with reading and writing 24 bit stereo PAF files. This problem
+    came to light when implementing tests for the new functions which operate
+    in terms of frames rather than items.
+
+1999-09-23  Erik de Castro Lopo  <erikd AT mega-nerd DOT com>
+
+    * src/sndfile.c
+    Modified file type detection to use first 12 bytes of file rather than
+    file name extension. Required this because NIST files use the same
+    filename extension as Microsoft WAV files.
+
+    * src/sndfile.c src/sndfile.h
+    Added short, int and double read/write functions which work in frames
+    rather than items. This was originally suggested by Maurizio Umberto
+    Puxeddu.
+
+1999-09-22  Erik de Castro Lopo  <erikd AT mega-nerd DOT com>
+
+    * src/svx.c
+    Finished off implementation of write using __psf_hprintf().
+
+1999-09-21  Erik de Castro Lopo  <erikd AT mega-nerd DOT com>
+
+    * src/common.h
+    Added a buffer to SF_PRIVATE for writing the header. This is required
+    to make generating headers for IFF/SVX files easier as well as making
+    it easier to do re-write the headers which will be required when
+    sf_rewrite_header() is implemented.
+
+    * src/common.c
+    Implemented __psf_hprintf() function. This is an internal function
+    which is documented briefly just above the code.
+
+1999-09-05  Erik de Castro Lopo  <erikd AT mega-nerd DOT com>
+
+    * src/sndfile.c
+    Fixed a bug in sf_write_raw() where it was returning incorrect values
+    (thanks to Richard Dobson for finding this one). Must put in a test
+    routine for sf_read_raw and sf_write_raw.
+
+    * src/aiff.c
+    Fixed default FORMsize in __aiff_open_write ().
+
+    * src/sndfile.c
+    Added copy of filename to internal data structure. IFF/SVX files
+    contain a NAME header chunk. Both sf_open_read() and sf_open_write()
+    copy the file name (less the leading path information) to the
+    filename field.
+
+    * src/svx.c
+    Started implementing writing of files.
+
+1999-08-04  Erik de Castro Lopo  <erikd AT mega-nerd DOT com>
+
+    * src/svx.c
+    New file for reading/writing 8SVX and 16SVX files.
+
+    * src/sndfile.[ch] src/common.h
+    Changes for SVX files.
+
+    * src/aiff.c
+    Fixed header parsing when unknown chunk is found.
+
+1999-08-01  Erik de Castro Lopo  <erikd AT mega-nerd DOT com>
+
+    * src/paf.c
+    New file for reading/writing Ensoniq PARIS audio file format.
+
+    * src/sndfile.[ch] src/common.h
+    Changes for PAF files.
+
+    * src/sndfile.[ch]
+    Added stuff for sf_get_lib_version() function.
+
+
+1999-07-31  Erik de Castro Lopo  <erikd AT mega-nerd DOT com>
+
+    * src/sndfile.h MacOS/config.h
+    Fixed minor MacOS configuration issues.
+
+1999-07-30  Erik de Castro Lopo  <erikd AT mega-nerd DOT com>
+
+    * MacOS/
+    Added a new directory for the MacOS config.h file and the
+    readme file.
+
+    * src/aiff.c
+    Fixed calculation of datalength when reading SSND chunk. Thanks to
+    Sigbj�rn Skj�ret for pointing out this error.
+
+1999-07-29  Erik de Castro Lopo  <erikd AT mega-nerd DOT com>
+
+    * src/sndfile.c src/sndfile.h src/raw.c
+    Further fixing of #includes for MacOS.
+
+1999-07-25  Erik de Castro Lopo  <erikd AT mega-nerd DOT com>
+
+    * src/wav.c src/aiff.c
+    Added call to ferror () in main header parsing loop of __XXX_open_read
+    functions. This should fix problems on platforms (MacOS, AmigaOS) where
+    fseek()ing or fread()ing beyond the end of the file puts the FILE*
+    stream in an error state until clearerr() is called.
+
+    * tests/write_read_test.c
+    Added tests for RAW header-less PCM files.
+
+    * src/common.h
+    Moved definition of struct tribyte to pcm.c which is the only place
+    which needs it.
+
+    * src/pcm.c
+    Modified all code which assumed sizeof (struct tribyte) == 3. This code
+    did not work on MacOS. Thanks to Ben "Jacobs" for pointing this out.
+
+    * src/au.c
+    Removed <sys/stat.h> from list of #includes (not being used).
+
+    * src/sndfile.c
+    Added MacOS specific #ifdef to replace <sys/stat.h>.
+
+    * src/sndfile.h
+    Added MacOS specific #ifdef to replace <sys/stat.h>.
+
+    * src/sndfile.h
+    Added MacOS specific typedef for off_t.
+
+    * MacOS-readme.txt
+    New file with instructions for building libsndfile under MacOS. Thanks
+    to Ben "Jacobs" for supplying these instructions.
+
+1999-07-24  Erik de Castro Lopo  <erikd AT mega-nerd DOT com>
+
+    * configure.in
+    Removed sndfile.h from generated file list as there were no longer
+    any autoconf substitutions being made.
+
+    * src/raw.c
+    New file for handling raw header-less PCM files. In order to open these
+    for read, the user must specify format, pcmbitwidth and channels in the
+    SF_INFO struct when calling sf_open_read ().
+
+    * src/sndfile.c
+    Added support for raw header-less PCM files.
+
+1999-07-22  Erik de Castro Lopo  <erikd AT mega-nerd DOT com>
+
+    * examples/sfinfo.c
+    Removed options so the sfinfo program always prints out all the information.
+
+1999-07-19  Erik de Castro Lopo  <erikd AT mega-nerd DOT com>
+
+    * src/alaw.c
+    New file for A-law encoding (similar to u-law).
+
+    * tests/alaw_test.c
+    New test program to test the A-law encode/decode lookup tables.
+
+    * tests/lossy_comp_test.c
+    Added tests for a-law encoded WAV, AU and AULE files.
+
+1999-07-18  Erik de Castro Lopo  <erikd AT mega-nerd DOT com>
+
+    * src/sndfile.c src/au.c
+    Removed second "#include <unistd.h>". Thanks to Ben "Jacobs" for pointing
+    this out.
+
+1999-07-18  Erik de Castro Lopo  <erikd AT mega-nerd DOT com>
+
+    * tests/ulaw_test.c
+    New test program to test the u-law encode/decode lookup tables.
+
+1999-07-16  Erik de Castro Lopo  <erikd AT mega-nerd DOT com>
+
+    * src/sndfile.h
+    Made corrections to comments on the return values from sf_seek ().
+
+    * src/sndfile.c
+    Fixed boundary condition checking bug and accounting bug in sf_read_raw ().
+
+1999-07-15  Erik de Castro Lopo  <erikd AT mega-nerd DOT com>
+
+    * src/au.c src/ulaw.c
+    Finished implementation of u-law encoded AU files.
+
+    * src/wav.c
+    Implemented reading and writing of u-law encoded WAV files.
+
+    * tests/
+    Changed name of adpcm_test.c to lossy_comp_test.c. This test program
+    will now be used to test Ulaw and Alaw encoding as well as APDCM.
+    Added tests for Ulaw encoded WAV files.
+
+1999-07-14  Erik de Castro Lopo  <erikd AT mega-nerd DOT com>
+
+    * tests/adpcm_test.c
+    Initialised amp variable in gen_signal() to remove compiler warning.
+
+1999-07-12  Erik de Castro Lopo  <erikd AT mega-nerd DOT com>
+
+    * src/aiff.c
+    In __aiff_open_read () prevented fseek()ing beyond end of file which
+    was causing trouble on MacOS with the MetroWerks compiler. Thanks to
+    Ben "Jacobs" for pointing this out.
+
+    *src/wav.c
+    Fixed as above in __wav_open_read ().
+
+1999-07-01    Erik de Castro Lopo  <erikd AT mega-nerd DOT com>
+
+    * src/wav_ms_adpcm.c
+    Implemented MS ADPCM encoding. Code cleanup of decoder.
+
+    * tests/adpcm_test.c
+    Added tests for MS ADPCM WAV files.
+
+    * src/wav_ima_adpcm.c
+    Fixed incorrect parameter in call to srate2blocksize () from
+    __ima_writer_init ().
+
+1999-06-23  Erik de Castro Lopo  <erikd AT mega-nerd DOT com>
+
+    * tests/read_seek_test.c
+    Added test for 8 bit AIFF files.
+
+1999-06-18  Erik de Castro Lopo  <erikd AT mega-nerd DOT com>
+
+    * tests/write_read_test.c
+    Removed test for IMA ADPCM WAV files which is now done in adpcm_test.c
+
+    * configure.in
+    Added -Wconversion to CFLAGS.
+
+    * src/*.c tests/*.c examples/*.c
+    Fixed all warnings resulting from use of -Wconversion.
+
+1999-06-17  Erik de Castro Lopo  <erikd AT mega-nerd DOT com>
+
+    * src/wav.c
+    Added fact chunk handling on read and write for all non WAVE_FORMAT_PCM
+    WAV files.
+
+    * src/wav_ima.c
+    Changed block alignment to be dependant on sample rate. This should make
+    WAV files created with libsndfile compatible with the MS Windows media
+    players.
+
+    * tests/adpcm_test.c
+    Reimplemented adpcm_test_short and implemented adpcm_test_int and
+    adpcm_test_double.
+    Now have full testing of IMA ADPCM WAV file read, write and seek.
+
+1999-06-15  Erik de Castro Lopo  <erikd AT mega-nerd DOT com>
+
+    * src/wav_float.c
+    Fixed function prototype for x86f2d_array () which was causing ocassional
+    seg. faults on Sparc Solaris machines.
+
+1999-06-14  Erik de Castro Lopo  <erikd AT mega-nerd DOT com>
+
+    * src/aiff.c
+    Fixed bug in __aiff_close where the length fields in the header were
+    not being correctly calculated before writing.
+
+    * tests/write_read_test.c
+    Modified to detect the above bug in WAV, AIFF and AU files.
+
+1999-06-12    Erik de Castro Lopo     <erikd AT mega-nerd DOT com>
+
+    * Win32/*
+    Added a contribution from Albert Faber to allow libsndfile to compile
+    under Win32 systems. libsndfile will now be used as part of LAME the
+    the MPEG 1 Layer 3 encoder (http://internet.roadrunner.com/~mt/mp3/).
+
+1999-06-11    Erik de Castro Lopo  <erikd AT mega-nerd DOT com>
+
+    * configure.in
+    Changed to reflect previous changes.
+
+    * src/wav_ima_adpcm.c
+    Fixed incorrect calculation of bytespersec header field (IMA ADPCM only).
+
+    Fixed bug when writing from int or double data to IMA ADPCM file. Will need
+    to write test code for this.
+
+    Fixed bug in __ima_write () whereby the length of the current block was
+    calculated incorrectly. Thanks to Jongcheon Park for pointing this out.
+
+1999-03-27  Erik de Castro Lopo  <erikd AT mega-nerd DOT com>
+
+    * src/*.c
+    Changed all read/write/lseek function calls to fread/fwrite/
+    fseek/ftell and added error checking of return values from
+    fread and fwrite in critical areas of the code.
+
+    * src/au.c
+    Fixed incorrect datasize element in AU header on write.
+
+    * tests/error_test.c
+    Add new test to check all error values have an associated error
+    string. This will avoid embarrassing real world core dumps.
+
+1999-03-23  Erik de Castro Lopo  <erikd AT mega-nerd DOT com>
+
+    * src/wav.c src/aiff.c
+    Added handling for unknown chunk markers in the file.
+
+1999-03-22  Erik de Castro Lopo  <erikd AT mega-nerd DOT com>
+
+    * src/sndfile.c
+    Filled in missing error strings in SndfileErrors array. Missing entries
+    can cause core dumps when calling sf_error-str (). Thanks to Sam
+    <mrsam at-sign geocities.com> for finding this problem.
+
+1999-03-21  Erik de Castro Lopo  <erikd AT mega-nerd DOT com>
+
+    * src/wav_ima_adpcm.c
+    Work on wav_ms_adpcm.c uncovered a bug in __ima_read () when reading
+    stereo files. Caused by not adjusting offset into buffer of decoded
+    samples for 2 channels. A similar bug existed in __ima_write ().
+    Need a test for stereo ADPCM files.
+
+    * src/wav_ms_adpcm.c
+    Decoder working correctly.
+
+1999-03-18  Erik de Castro Lopo  <erikd AT mega-nerd DOT com>
+
+    * configure.in Makefile.am
+    Added --enable-justsrc configuration variable sent by Sam
+    <mrsam at-sign geocities.com>.
+
+    * src/wav_ima_adpcm.c
+    Fixed bug when reading beyond end of data section due to not
+    checking pima->blockcount.
+    This uncovered __ima_seek () bug due to pima->blockcount being set
+    before calling __ima_init_block ().
+
+1999-03-17  Erik de Castro Lopo  <erikd AT mega-nerd DOT com>
+
+    * src/wav.c
+    Started implementing MS ADPCM decoder.
+    If file is WAVE_FORMAT_ADPCM and length of data chunk is odd, this
+    encoder seems to add an extra byte. Why not just give an even data
+    length?
+
+1999-03-16  Erik de Castro Lopo  <erikd AT mega-nerd DOT com>
+
+    * src/wav.c
+    Split code out of wav.c to create wav_float.c and wav_ima_adpcm.c.
+    This will make it easier to add and debug other kinds of WAV files
+    in future.
+
+1999-03-14  Erik de Castro Lopo  <erikd AT mega-nerd DOT com>
+
+    * tests/
+    Added adpcm_test.c which implements test functions for
+    IMA ADPCM reading/writing/seeking etc.
+
+    * src/wav.c
+    Fixed many bugs in IMA ADPCM encoder and decoder.
+
+1999-03-11  Erik de Castro Lopo  <erikd AT mega-nerd DOT com>
+
+    * src/wav.c
+    Finished implementing IMA ADPCM encoder and decoder (what a bitch!).
+
+1999-03-03  Erik de Castro Lopo  <erikd AT mega-nerd DOT com>
+
+    * src/wav.c
+    Started implementing IMA ADPCM decoder.
+
+1999-03-02  Erik de Castro Lopo  <erikd AT mega-nerd DOT com>
+
+    * src/sndfile.c
+    Fixed bug where the sf_read_XXX functions were returning a
+    incorrect read count when reading past end of file.
+    Fixed bug in sf_seek () when seeking backwards from end of file.
+
+    * tests/read_seek_test.c
+    Added multiple read test to short_test(), int_test () and
+    double_test ().
+    Added extra chunk to all test WAV files to test that reading
+    stops at end of 'data' chunk.
+
+1999-02-21  Erik de Castro Lopo  <erikd AT mega-nerd DOT com>
+
+    * tests/write_read_test.c
+    Added tests for little DEC endian AU files.
+
+    * src/au.c
+    Add handling for DEC format little endian AU files.
+
+1999-02-20  Erik de Castro Lopo  <erikd AT mega-nerd DOT com>
+
+    * src/aiff.c src/au.c src/wav.c
+    Add __psf_sprintf calls during header parsing.
+
+    * src/sndfile.c src/common.c
+    Implement sf_header_info (sndfile.c) function and __psf_sprintf (common.c).
+
+    * tests/write_read_test.c
+    Added tests for 8 bit PCM files (WAV, AIFF and AU).
+
+    * src/au.c src/aiff.c
+    Add handling of 8 bit PCM data format.
+
+    * src/aiff.c
+    On write, set blocksize in SSND chunk to zero like everybody else.
+
+1999-02-16  Erik de Castro Lopo  <erikd AT mega-nerd DOT com>
+
+    * src/pcm.c:
+    Fixed bug in let2s_array (cptr was not being initialised).
+
+    * src/sndfile.c:
+    Fixed bug in sf_read_raw and sf_write_raw. sf_seek should
+    now work when using these functions.
+
+1999-02-15  Erik de Castro Lopo  <erikd AT mega-nerd DOT com>
+
+    * tests/write_read_test.c:
+    Force test_buffer array to be double aligned. Sparc Solaris
+    requires this.
+
+1999-02-14  Erik de Castro Lopo  <erikd AT mega-nerd DOT com>
+
+    * src/pcm.c:
+    Fixed a bug which was causing errors in the reading
+    and writing of 24 bit PCM files.
+
+    * doc/api.html
+    Finished of preliminary documentaion.
+
+1999-02-13  Erik de Castro Lopo  <erikd AT mega-nerd DOT com>
+
+    * src/aiff.c:
+    Changed reading of 'COMM' chunk to avoid reading an int
+    which overlaps an int (4 byte) boundary.
+
diff --git a/libs/libsndfile/Mingw-make-dist.sh b/libs/libsndfile/Mingw-make-dist.sh
new file mode 100755 (executable)
index 0000000..fef4ba8
--- /dev/null
@@ -0,0 +1,113 @@
+#!/bin/sh
+
+# Copyright (C) 2006 Erik de Castro Lopo <erikd@mega-nerd.com>
+#
+# All rights reserved.
+#
+# 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 author nor the names of any 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 COPYRIGHT OWNER 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.
+
+set -e
+
+if [ $# -lt 1 ] || [ $# -gt 2 ]; then
+       echo "Usage : Mingw-make-dist.sh <source tarball>."
+       exit 1
+       fi
+
+TARGZ=$1
+if [ ! -f $TARGZ ]; then
+       echo "Can't find source tarball."
+       fi
+
+TARGZ=$1
+if [ ! -f $TARGZ.asc ]; then
+       echo "Can't find source tarball signature."
+       fi
+
+UNAME=`uname -s`
+if [ x$UNAME != "xMINGW32_NT-5.1" ]; then
+       echo "Not able to build Win32 binaries on this platform."
+       fi
+
+echo "Building MinGW binary/source zip file."
+
+VERSION=`pwd | sed -e "s#.*/##" | sed -e s/libsndfile-//`
+BUILD=`echo $VERSION | sed -e "s/\./_/g"`
+INSTALL="libsndfile-$BUILD"
+ZIPNAME="$INSTALL.zip"
+
+if [ -z "$BUILD" ]; then
+       echo "Bad BUILD variable : '$BUILD'"
+       exit 1
+       fi
+
+if [ ! -d $INSTALL/ ];  then
+       mkdir $INSTALL
+       fi
+
+if [ ! -f config.status ]; then
+       ./configure --prefix=`pwd`/$INSTALL/
+else
+       teststr=`grep "with options" config.status | grep -- --prefix=`
+       if [ -z "$teststr" ]; then
+               # --disable-static doesn't work.
+               ./configure --prefix=`pwd`/$INSTALL/
+               fi
+       fi
+
+if [ ! -f src/.libs/libsndfile-1.dll ]; then
+       make all check
+       fi
+
+if [ ! -f $INSTALL/bin/libsndfile-1.dll ]; then
+       make install
+       rm -f $INSTALL/bin/sndfile-regtest.exe
+       strip $INSTALL/bin/*.*
+       mv $INSTALL/bin/*.* $INSTALL/include/*.* $INSTALL/
+       rmdir $INSTALL/bin
+       rm -rf $INSTALL/lib
+       rmdir $INSTALL/include
+       cp src/libsndfile.def $INSTALL/
+       cp Win32/README-precompiled-dll.txt $INSTALL/
+       fi
+
+if [ ! -f $INSTALL/libsndfile-$VERSION.tar.gz ]; then
+       cp $TARGZ $INSTALL/
+       if [ -f $TARGZ.asc ]; then
+               cp $TARGZ.asc $INSTALL/
+               fi
+       fi
+
+if [ ! -f $ZIPNAME ]; then
+       zip -r $ZIPNAME $INSTALL/
+       fi
+
+
+# Do not edit or modify anything in this comment block.
+# The following line is a file identity tag for the GNU Arch
+# revision control system.
+#
+# arch-tag: 3f82cd8a-f800-48d7-9646-2cdcf03c81a0
diff --git a/libs/libsndfile/NEWS b/libs/libsndfile/NEWS
new file mode 100644 (file)
index 0000000..540a2d6
--- /dev/null
@@ -0,0 +1,126 @@
+Version 1.0.16 (2006-04-30)
+  * Add support for Broadcast (BEXT) chunks in WAV files.
+  * Implement new commands SFC_GET_SIGNAL_MAX and SFC_GET_MAX_ALL_CHANNELS.
+  * Add support for RIFX (big endian WAV variant).
+  * Fix configure script bugs.
+  * Fix bug in INST and MARK chunk writing for AIFF files.
+
+Version 1.0.15 (2006-03-16)
+  * Fix some ia64 issues.
+  * Fix precompiled DLL.
+  * Minor bug fixes.
+
+Version 1.0.14 (2006-02-19)
+  * Really fix MinGW compile problems.
+  * Minor bug fixes.
+
+Version 1.0.13 (2006-01-21)
+  * Fix for MinGW compiler problems.
+  * Allow readin/write of instrument chunks from WAV and AIFF files.
+  * Compile problem fix for Solaris compiler.
+  * Minor cleanups and bug fixes.
+
+Version 1.0.12 (2005-09-30)
+  * Add support for FLAC and Apple's Core Audio Format (CAF).
+  * Add virtual I/O interface (still needs docs).
+  * Cygwin and other Win32 fixes.
+  * Minor bug fixes and cleanups.
+
+Version 1.0.11 (2004-11-15)
+  * Add support for SD2 files.
+  * Add read support for loop info in WAV and AIFF files.
+  * Add more tests.
+  * Improve type safety.
+  * Minor optimisations and bug fixes.
+
+Version 1.0.10 (2004-06-15)
+  * Fix AIFF read/write mode bugs.
+  * Add support for compiling Win32 DLLS using MinGW.
+  * Fix problems resulting in failed compiles with gcc-2.95.
+  * Improve test suite.
+  * Minor bug fixes.
+
+Version 1.0.9 (2004-03-30)
+  * Add handling of AVR (Audio Visual Research) files.
+  * Improve handling of WAVEFORMATEXTENSIBLE WAV files.
+  * Fix for using pipes on Win32.
+
+Version 1.0.8 (2004-03-14)
+  * Correct peak chunk handing for files with > 16 tracks.
+  * Fix for WAV files with huge number of CUE chunks.
+
+Version 1.0.7 (2004-02-25)
+  * Fix clip mode detection on ia64, MIPS and other CPUs.
+  * Fix two MacOSX build problems.
+
+Version 1.0.6 (2004-02-08)
+  * Added support for native Win32 file access API (Ross Bencina).
+  * New mode to add clippling then a converting from float/double to integer
+    would otherwise wrap around.
+  * Fixed a bug in reading/writing files > 2Gig on Linux, Solaris and others.
+  * Many minor bug fixes.
+  * Other random fixes for Win32.
+
+Version 1.0.5 (2003-05-03)
+  * Added support for HTK files.
+  * Added new function sf_open_fd() to allow for secure opening of temporary
+    files as well as reading/writing sound files embedded within larger
+    container files.
+  * Added string support for AIFF files.
+  * Minor bug fixes and code cleanups.
+
+Version 1.0.4 (2003-02-02)
+  * Added suport of PVF and XI files.
+  * Added functionality for setting and retreiving strings from sound files.
+  * Minor code cleanups and bug fixes.
+
+Version 1.0.3 (2002-12-09)
+  * Minor bug fixes.
+
+Version 1.0.2 (2002-11-24)
+  * Added support for VOX ADPCM.
+  * Improved error reporting.
+  * Added version scripting on Linux and Solaris.
+  * Minor bug fixes.
+
+Version 1.0.1 (2002-09-14)
+  * Added MAT and MAT5 file formats.
+  * Minor bug fixes.
+
+Version 1.0.0 (2002-08-16)
+  * Final release for 1.0.0.
+
+Version 1.0.0rc6 (2002-08-14)
+  * Release candidate 6 for the 1.0.0 series.
+  * MacOS9 fixes.
+
+Version 1.0.0rc5 (2002-08-10)
+  * Release candidate 5 for the 1.0.0 series.
+  * Changed the definition of sf_count_t which was causing problems when
+    libsndfile was compiled with other libraries (ie WxWindows).
+  * Minor bug fixes.
+  * Documentation cleanup.
+
+Version 1.0.0rc4 (2002-08-03)
+  * Release candidate 4 for the 1.0.0 series.
+  * Minor bug fixes.
+  * Fix broken Win32 "make check".
+
+Version 1.0.0rc3 (2002-08-02)
+  * Release candidate 3 for the 1.0.0 series.
+  * Fix bug where libsndfile was reading beyond the end of the data chunk.
+  * Added on-the-fly header updates on write.
+  * Fix a couple of documentation issues.
+
+Version 1.0.0rc2 (2002-06-24)
+  * Release candidate 2 for the 1.0.0 series.
+  * Fix compile problem for Win32.
+
+Version 1.0.0rc1 (2002-06-24)
+  * Release candidate 1 for the 1.0.0 series.
+
+Version 0.0.28 (2002-04-27)
+  * Last offical release of 0.0.X series of the library.
+
+Version 0.0.8 (1999-02-16)
+  * First offical release.
diff --git a/libs/libsndfile/README b/libs/libsndfile/README
new file mode 100644 (file)
index 0000000..d93edfd
--- /dev/null
@@ -0,0 +1,71 @@
+This is libsndfile, 1.0.16
+
+libsndfile is a library of C routines for reading and writing 
+files containing sampled audio data. 
+
+The src/ directory contains the source code for library itself.
+
+The doc/ directory contains the libsndfile documentation.
+
+The examples/ directory contains examples of how to write code using
+libsndfile. 'wav32_aiff24' converts a WAV file containing 32 bit floating 
+point data into a 24 bit PCM AIFF file. 'sndfile2oct' dumps the audio
+data of a file in a human readable format. 'sfconvert' is the beginnings
+of a audio file format conversion utility. 'make_sine' generates a WAV
+file containing one cycle of a sine wave with 4096 sample points in
+32 bit floating point format. 'sfinfo' opens a sound file and prints
+out information about that file.
+
+The tests/ directory contains programs which link against libsndfile
+and test its functionality.
+
+The Win32/ directory contains files and documentation to allow libsndfile
+to compile under Win32 with the Microsoft Visual C++ compiler.
+
+The src/GSM610 directory contains code written by Jutta Degener and Carsten 
+Bormann. Their original code can be found at :
+    http://kbs.cs.tu-berlin.de/~jutta/toast.html
+
+The src/G72x directory contains code written and released by Sun Microsystems
+under a suitably free license.
+
+
+Win32
+-----
+There are detailed instructions for building libsndfile on Win32 in the file
+
+       doc/win32.html
+       
+
+MacOSX
+------
+Building on MacOSX should be the same as building it on any other Unix.
+
+
+OTHER PLATFORMS
+---------------
+To compile libsndfile on platforms which have a Bourne Shell compatible
+shell, an ANSI C compiler and a make utility should require no more that
+the following three commands :
+               ./configure
+               make
+               make install
+               
+For platforms without the required shell, it is usually sufficient to 
+create an approriate config.h file in the src/ directory with correct
+values for the following #defines  (this would work for AmigaOS) :
+
+#define HAVE_ENDIAN_H 0
+#define GUESS_BIG_ENDIAN 1
+#define GUESS_LITTLE_ENDIAN 0
+#define FORCE_BROKEN_FLOAT 0
+
+
+CONTACTS
+--------
+
+libsndfile was written by Erik de Castro Lopo (erikd AT mega-nerd DOT com).  
+The libsndfile home page is at :
+
+       http://www.mega-nerd.com/libsndfile/
+
diff --git a/libs/libsndfile/SConscript b/libs/libsndfile/SConscript
new file mode 100644 (file)
index 0000000..b7d35b9
--- /dev/null
@@ -0,0 +1,43 @@
+# -*- python -*-
+
+import os
+import os.path
+import glob
+
+sndfile_files = glob.glob('src/*.c') + glob.glob('src/GSM610/*.c') + glob.glob('src/G72x/*.c')
+
+Import('env install_prefix')
+sndfile = env.Copy()
+
+domain = 'libsndfile'
+
+sndfile.Append(CCFLAGS = "-DPACKAGE=\\\"" + domain + "\\\"")
+sndfile.Append(CCFLAGS = "-DVERSION=\\\"ardour-special\\\"")
+# mingw may need this
+#sndfile.Append(CCFLAGS="-no-undefined")
+sndfile.Append(PACKAGE = domain)
+sndfile.Append(POTFILE = domain + '.pot')
+
+conf = Configure(sndfile)
+
+if conf.CheckCHeader('/System/Library/Frameworks/CoreServices.framework/Headers/CoreServices.h'):
+    sndfile.Append(LINKFLAGS = "-framework CoreServices")
+
+sndfile = conf.Finish()
+
+libsndfile = sndfile.SharedLibrary('sndfile', sndfile_files)
+
+sndfile_h = sndfile.Command('src/sndfile.h', ['src/sndfile.h.in'], 'cd libs/libsndfile && ./configure && cd -', ENV=os.environ)
+
+Default([sndfile_h,libsndfile])
+
+env.Alias('install', env.Install(os.path.join(install_prefix, 'lib/ardour2'), libsndfile))
+
+env.Alias('tarball', env.Distribute (env['DISTTREE'],
+                                     [ 'NEWS', 'README', 'AUTHORS', 'ChangeLog',
+                                       'configure', 'SConscript',] +
+                                       sndfile_files +
+                                       glob.glob('src/*.h') +
+                                      [ 'src/sndfile.h.in', 'src/config.h.in', 'src/Symbols.linux', 'src/Symbols.darwin', 'src/libsndfile.def', 'src/cygsndfile.def' ]
+                                     ))
+                                     
diff --git a/libs/libsndfile/acinclude.m4 b/libs/libsndfile/acinclude.m4
new file mode 100644 (file)
index 0000000..37f8c0c
--- /dev/null
@@ -0,0 +1,579 @@
+dnl By default, many hosts won't let programs access large files;
+dnl one must use special compiler options to get large-file access to work.
+dnl For more details about this brain damage please see:
+dnl http://www.sas.com/standards/large.file/x_open.20Mar96.html
+
+dnl Written by Paul Eggert <eggert@twinsun.com>.
+
+dnl Internal subroutine of AC_SYS_EXTRA_LARGEFILE.
+dnl AC_SYS_EXTRA_LARGEFILE_FLAGS(FLAGSNAME)
+AC_DEFUN([AC_SYS_EXTRA_LARGEFILE_FLAGS],
+  [AC_CACHE_CHECK([for $1 value to request large file support],
+     ac_cv_sys_largefile_$1,
+     [ac_cv_sys_largefile_$1=`($GETCONF LFS_$1) 2>/dev/null` || {
+       ac_cv_sys_largefile_$1=no
+       ifelse($1, CFLAGS,
+         [case "$host_os" in
+          # IRIX 6.2 and later require cc -n32.
+changequote(, )dnl
+          irix6.[2-9]* | irix6.1[0-9]* | irix[7-9].* | irix[1-9][0-9]*)
+changequote([, ])dnl
+            if test "$GCC" != yes; then
+              ac_cv_sys_largefile_CFLAGS=-n32
+            fi
+            ac_save_CC="$CC"
+            CC="$CC $ac_cv_sys_largefile_CFLAGS"
+            AC_TRY_LINK(, , , ac_cv_sys_largefile_CFLAGS=no)
+            CC="$ac_save_CC"
+          esac])
+      }])])
+
+dnl Internal subroutine of AC_SYS_EXTRA_LARGEFILE.
+dnl AC_SYS_EXTRA_LARGEFILE_SPACE_APPEND(VAR, VAL)
+AC_DEFUN([AC_SYS_EXTRA_LARGEFILE_SPACE_APPEND],
+  [case $2 in
+   no) ;;
+   ?*)
+     case "[$]$1" in
+     '') $1=$2 ;;
+     *) $1=[$]$1' '$2 ;;
+     esac ;;
+   esac])
+
+dnl Internal subroutine of AC_SYS_EXTRA_LARGEFILE.
+dnl AC_SYS_EXTRA_LARGEFILE_MACRO_VALUE(C-MACRO, CACHE-VAR, COMMENT, CODE-TO-SET-DEFAULT)
+AC_DEFUN([AC_SYS_EXTRA_LARGEFILE_MACRO_VALUE],
+  [AC_CACHE_CHECK([for $1], $2,
+     [$2=no
+changequote(, )dnl
+      $4
+      for ac_flag in $ac_cv_sys_largefile_CFLAGS no; do
+       case "$ac_flag" in
+       -D$1)
+         $2=1 ;;
+       -D$1=*)
+         $2=`expr " $ac_flag" : '[^=]*=\(.*\)'` ;;
+       esac
+      done
+changequote([, ])dnl
+      ])
+   if test "[$]$2" != no; then
+     AC_DEFINE_UNQUOTED([$1], [$]$2, [$3])
+   fi])
+
+AC_DEFUN([AC_SYS_EXTRA_LARGEFILE],
+  [AC_REQUIRE([AC_CANONICAL_HOST])
+   AC_ARG_ENABLE(largefile,
+     [  --disable-largefile     omit support for large files])
+   if test "$enable_largefile" != no; then
+     AC_CHECK_TOOL(GETCONF, getconf)
+     AC_SYS_EXTRA_LARGEFILE_FLAGS(CFLAGS)
+     AC_SYS_EXTRA_LARGEFILE_FLAGS(LDFLAGS)
+     AC_SYS_EXTRA_LARGEFILE_FLAGS(LIBS)
+
+     for ac_flag in $ac_cv_sys_largefile_CFLAGS no; do
+       case "$ac_flag" in
+       no) ;;
+       -D_FILE_OFFSET_BITS=*) ;;
+       -D_LARGEFILE_SOURCE | -D_LARGEFILE_SOURCE=*) ;;
+       -D_LARGE_FILES | -D_LARGE_FILES=*) ;;
+       -D?* | -I?*)
+        AC_SYS_EXTRA_LARGEFILE_SPACE_APPEND(CPPFLAGS, "$ac_flag") ;;
+       *)
+        AC_SYS_EXTRA_LARGEFILE_SPACE_APPEND(CFLAGS, "$ac_flag") ;;
+       esac
+     done
+     AC_SYS_EXTRA_LARGEFILE_SPACE_APPEND(LDFLAGS, "$ac_cv_sys_largefile_LDFLAGS")
+     AC_SYS_EXTRA_LARGEFILE_SPACE_APPEND(LIBS, "$ac_cv_sys_largefile_LIBS")
+     AC_SYS_EXTRA_LARGEFILE_MACRO_VALUE(_FILE_OFFSET_BITS,
+       ac_cv_sys_file_offset_bits,
+       [Number of bits in a file offset, on hosts where this is settable.])
+       [case "$host_os" in
+       # HP-UX 10.20 and later
+       hpux10.[2-9][0-9]* | hpux1[1-9]* | hpux[2-9][0-9]*)
+         ac_cv_sys_file_offset_bits=64 ;;
+       esac]
+     AC_SYS_EXTRA_LARGEFILE_MACRO_VALUE(_LARGEFILE_SOURCE,
+       ac_cv_sys_largefile_source,
+       [Define to make fseeko etc. visible, on some hosts.],
+       [case "$host_os" in
+       # HP-UX 10.20 and later
+       hpux10.[2-9][0-9]* | hpux1[1-9]* | hpux[2-9][0-9]*)
+         ac_cv_sys_largefile_source=1 ;;
+       esac])
+     AC_SYS_EXTRA_LARGEFILE_MACRO_VALUE(_LARGE_FILES,
+       ac_cv_sys_large_files,
+       [Define for large files, on AIX-style hosts.],
+       [case "$host_os" in
+       # AIX 4.2 and later
+       aix4.[2-9]* | aix4.1[0-9]* | aix[5-9].* | aix[1-9][0-9]*)
+         ac_cv_sys_large_files=1 ;;
+       esac])
+   fi
+  ])
+
+
+
+
+
+
+dnl @synopsis AC_C_FIND_ENDIAN
+dnl
+dnl Determine endian-ness of target processor.
+dnl @version 1.1       Mar 03 2002
+dnl @author Erik de Castro Lopo <erikd AT mega-nerd DOT com>
+dnl
+dnl Majority written from scratch to replace the standard autoconf macro 
+dnl AC_C_BIGENDIAN. Only part remaining from the original it the invocation
+dnl of the AC_TRY_RUN macro.
+dnl
+dnl Permission to use, copy, modify, distribute, and sell this file for any 
+dnl purpose is hereby granted without fee, provided that the above copyright 
+dnl and this permission notice appear in all copies.  No representations are
+dnl made about the suitability of this software for any purpose.  It is 
+dnl provided "as is" without express or implied warranty.
+
+dnl Find endian-ness in the following way:
+dnl    1) Look in <endian.h>.
+dnl    2) If 1) fails, look in <sys/types.h> and <sys/param.h>.
+dnl    3) If 1) and 2) fails and not cross compiling run a test program.
+dnl    4) If 1) and 2) fails and cross compiling then guess based on target.
+
+AC_DEFUN([AC_C_FIND_ENDIAN],
+[AC_CACHE_CHECK(processor byte ordering, 
+       ac_cv_c_byte_order,
+
+# Initialize to unknown
+ac_cv_c_byte_order=unknown
+
+if test x$ac_cv_header_endian_h = xyes ; then
+
+       # First try <endian.h> which should set BYTE_ORDER.
+
+       [AC_TRY_LINK([
+               #include <endian.h>
+               #if BYTE_ORDER != LITTLE_ENDIAN
+                       not big endian
+               #endif
+               ], return 0 ;, 
+                       ac_cv_c_byte_order=little
+               )]
+                               
+       [AC_TRY_LINK([
+               #include <endian.h>
+               #if BYTE_ORDER != BIG_ENDIAN
+                       not big endian
+               #endif
+               ], return 0 ;, 
+                       ac_cv_c_byte_order=big
+               )]
+
+       fi
+
+if test $ac_cv_c_byte_order = unknown ; then
+
+       [AC_TRY_LINK([
+               #include <sys/types.h>
+               #include <sys/param.h>
+               #if !BYTE_ORDER || !BIG_ENDIAN || !LITTLE_ENDIAN
+                       bogus endian macros
+               #endif
+               ], return 0 ;, 
+
+               [AC_TRY_LINK([
+                       #include <sys/types.h>
+                       #include <sys/param.h>
+                       #if BYTE_ORDER != LITTLE_ENDIAN
+                               not big endian
+                       #endif
+                       ], return 0 ;, 
+                               ac_cv_c_byte_order=little
+                       )]
+                               
+               [AC_TRY_LINK([
+                       #include <sys/types.h>
+                       #include <sys/param.h>
+                       #if BYTE_ORDER != LITTLE_ENDIAN
+                               not big endian
+                       #endif
+                       ], return 0 ;, 
+                               ac_cv_c_byte_order=little
+                       )]
+
+               )]
+
+       fi
+
+if test $ac_cv_c_byte_order = unknown ; then
+       if test $cross_compiling = yes ; then
+               # This is the last resort. Try to guess the target processor endian-ness
+               # by looking at the target CPU type.    
+               [
+               case "$target_cpu" in
+                       alpha* | i?86* | mipsel* | ia64*)
+                               ac_cv_c_big_endian=0
+                               ac_cv_c_little_endian=1
+                               ;;
+                       
+                       m68* | mips* | powerpc* | hppa* | sparc*)
+                               ac_cv_c_big_endian=1
+                               ac_cv_c_little_endian=0
+                               ;;
+       
+                       esac
+               ]
+       else
+               AC_TRY_RUN(
+               [[
+               int main (void) 
+               {       /* Are we little or big endian?  From Harbison&Steele.  */
+                       union
+                       {       long l ;
+                               char c [sizeof (long)] ;
+                       } u ;
+                       u.l = 1 ;
+                       return (u.c [sizeof (long) - 1] == 1);
+                       }
+                       ]], , ac_cv_c_byte_order=big, 
+                       ac_cv_c_byte_order=unknown
+                       )
+
+               AC_TRY_RUN(
+               [[int main (void) 
+               {       /* Are we little or big endian?  From Harbison&Steele.  */
+                       union
+                       {       long l ;
+                               char c [sizeof (long)] ;
+                       } u ;
+                       u.l = 1 ;
+                       return (u.c [0] == 1);
+                       }]], , ac_cv_c_byte_order=little, 
+                       ac_cv_c_byte_order=unknown
+                       )
+               fi      
+       fi
+
+)
+]
+
+if test $ac_cv_c_byte_order = big ; then
+       ac_cv_c_big_endian=1
+       ac_cv_c_little_endian=0
+elif test $ac_cv_c_byte_order = little ; then
+       ac_cv_c_big_endian=0
+       ac_cv_c_little_endian=1
+else
+       ac_cv_c_big_endian=0
+       ac_cv_c_little_endian=0
+
+       AC_MSG_WARN([[*****************************************************************]])
+       AC_MSG_WARN([[*** Not able to determine endian-ness of target processor.       ]])
+       AC_MSG_WARN([[*** The constants CPU_IS_BIG_ENDIAN and CPU_IS_LITTLE_ENDIAN in  ]])
+       AC_MSG_WARN([[*** src/config.h may need to be hand editied.                    ]])
+       AC_MSG_WARN([[*****************************************************************]])
+       fi
+
+)# AC_C_FIND_ENDIAN
+
+
+
+
+
+dnl @synopsis AC_C99_FLEXIBLE_ARRAY
+dnl
+dnl Dose the compiler support the 1999 ISO C Standard "stuct hack".
+dnl @version 1.1       Mar 15 2004
+dnl @author Erik de Castro Lopo <erikd AT mega-nerd DOT com>
+dnl
+dnl Permission to use, copy, modify, distribute, and sell this file for any 
+dnl purpose is hereby granted without fee, provided that the above copyright 
+dnl and this permission notice appear in all copies.  No representations are
+dnl made about the suitability of this software for any purpose.  It is 
+dnl provided "as is" without express or implied warranty.
+
+AC_DEFUN([AC_C99_FLEXIBLE_ARRAY],
+[AC_CACHE_CHECK(C99 struct flexible array support, 
+       ac_cv_c99_flexible_array,
+
+# Initialize to unknown
+ac_cv_c99_flexible_array=no
+
+AC_TRY_LINK([[
+       #include <stdlib.h>
+       typedef struct {
+       int k;
+       char buffer [] ;
+       } MY_STRUCT ;
+       ]], 
+       [  MY_STRUCT *p = calloc (1, sizeof (MY_STRUCT) + 42); ],
+       ac_cv_c99_flexible_array=yes,
+       ac_cv_c99_flexible_array=no
+       ))]
+) # AC_C99_FLEXIBLE_ARRAY
+
+
+     
+
+
+dnl @synopsis AC_C99_FUNC_LRINT
+dnl
+dnl Check whether C99's lrint function is available.
+dnl @version 1.3       Feb 12 2002
+dnl @author Erik de Castro Lopo <erikd AT mega-nerd DOT com>
+dnl
+dnl Permission to use, copy, modify, distribute, and sell this file for any 
+dnl purpose is hereby granted without fee, provided that the above copyright 
+dnl and this permission notice appear in all copies.  No representations are
+dnl made about the suitability of this software for any purpose.  It is 
+dnl provided "as is" without express or implied warranty.
+dnl
+AC_DEFUN([AC_C99_FUNC_LRINT],
+[AC_CACHE_CHECK(for lrint,
+  ac_cv_c99_lrint,
+[
+lrint_save_CFLAGS=$CFLAGS
+CFLAGS="-O2 -lm"
+AC_TRY_LINK([
+#define                _ISOC9X_SOURCE  1
+#define        _ISOC99_SOURCE  1
+#define                __USE_ISOC99    1
+#define        __USE_ISOC9X    1
+
+#include <math.h>
+], if (!lrint(3.14159)) lrint(2.7183);, ac_cv_c99_lrint=yes, ac_cv_c99_lrint=no)
+
+CFLAGS=$lrint_save_CFLAGS
+
+])
+
+if test "$ac_cv_c99_lrint" = yes; then
+  AC_DEFINE(HAVE_LRINT, 1,
+            [Define if you have C99's lrint function.])
+fi
+])# AC_C99_FUNC_LRINT
+dnl @synopsis AC_C99_FUNC_LRINTF
+dnl
+dnl Check whether C99's lrintf function is available.
+dnl @version 1.3       Feb 12 2002
+dnl @author Erik de Castro Lopo <erikd AT mega-nerd DOT com>
+dnl
+dnl Permission to use, copy, modify, distribute, and sell this file for any 
+dnl purpose is hereby granted without fee, provided that the above copyright 
+dnl and this permission notice appear in all copies.  No representations are
+dnl made about the suitability of this software for any purpose.  It is 
+dnl provided "as is" without express or implied warranty.
+dnl
+AC_DEFUN([AC_C99_FUNC_LRINTF],
+[AC_CACHE_CHECK(for lrintf,
+  ac_cv_c99_lrintf,
+[
+lrintf_save_CFLAGS=$CFLAGS
+CFLAGS="-O2 -lm"
+AC_TRY_LINK([
+#define                _ISOC9X_SOURCE  1
+#define        _ISOC99_SOURCE  1
+#define                __USE_ISOC99    1
+#define        __USE_ISOC9X    1
+
+#include <math.h>
+], if (!lrintf(3.14159)) lrintf(2.7183);, ac_cv_c99_lrintf=yes, ac_cv_c99_lrintf=no)
+
+CFLAGS=$lrintf_save_CFLAGS
+
+])
+
+if test "$ac_cv_c99_lrintf" = yes; then
+  AC_DEFINE(HAVE_LRINTF, 1,
+            [Define if you have C99's lrintf function.])
+fi
+])# AC_C99_FUNC_LRINTF
+
+
+
+
+dnl @synopsis AC_C99_FUNC_LLRINT
+dnl
+dnl Check whether C99's llrint function is available.
+dnl @version 1.1       Sep 30 2002
+dnl @author Erik de Castro Lopo <erikd AT mega-nerd DOT com>
+dnl
+dnl Permission to use, copy, modify, distribute, and sell this file for any 
+dnl purpose is hereby granted without fee, provided that the above copyright 
+dnl and this permission notice appear in all copies.  No representations are
+dnl made about the suitability of this software for any purpose.  It is 
+dnl provided "as is" without express or implied warranty.
+dnl
+AC_DEFUN([AC_C99_FUNC_LLRINT],
+[AC_CACHE_CHECK(for llrint,
+  ac_cv_c99_llrint,
+[
+llrint_save_CFLAGS=$CFLAGS
+CFLAGS="-O2 -lm"
+AC_TRY_LINK([
+#define                _ISOC9X_SOURCE  1
+#define        _ISOC99_SOURCE  1
+#define                __USE_ISOC99    1
+#define        __USE_ISOC9X    1
+
+#include <math.h>
+#include <stdint.h>
+], int64_t     x ; x = llrint(3.14159) ;, ac_cv_c99_llrint=yes, ac_cv_c99_llrint=no)
+
+CFLAGS=$llrint_save_CFLAGS
+
+])
+
+if test "$ac_cv_c99_llrint" = yes; then
+  AC_DEFINE(HAVE_LLRINT, 1,
+            [Define if you have C99's llrint function.])
+fi
+])# AC_C99_FUNC_LLRINT
+
+
+
+dnl @synopsis AC_C_CLIP_MODE
+dnl
+dnl Determine the clipping mode when converting float to int.
+dnl @version 1.0       May 17 2003
+dnl @author Erik de Castro Lopo <erikd AT mega-nerd DOT com>
+dnl
+dnl Permission to use, copy, modify, distribute, and sell this file for any 
+dnl purpose is hereby granted without fee, provided that the above copyright 
+dnl and this permission notice appear in all copies.  No representations are
+dnl made about the suitability of this software for any purpose.  It is 
+dnl provided "as is" without express or implied warranty.
+
+
+
+dnl Find the clipping mode in the following way:
+dnl    1) If we are not cross compiling test it.
+dnl    2) IF we are cross compiling, assume that clipping isn't done correctly.
+
+AC_DEFUN([AC_C_CLIP_MODE],
+[AC_CACHE_CHECK(processor clipping capabilities, 
+       ac_cv_c_clip_type,
+
+# Initialize to unknown
+ac_cv_c_clip_positive=unknown
+ac_cv_c_clip_negative=unknown
+
+if test $ac_cv_c_clip_positive = unknown ; then
+       AC_TRY_RUN(
+       [[
+       #define _ISOC9X_SOURCE  1
+       #define _ISOC99_SOURCE  1
+       #define __USE_ISOC99    1
+       #define __USE_ISOC9X    1
+       #include <math.h>
+       int main (void)
+       {       double  fval ;
+               int k, ival ;
+
+               fval = 1.0 * 0x7FFFFFFF ;
+               for (k = 0 ; k < 100 ; k++)
+               {       ival = (lrint (fval)) >> 24 ;
+                       if (ival != 127)
+                               return 1 ;
+               
+                       fval *= 1.2499999 ;
+                       } ;
+               
+                       return 0 ;
+               }
+               ]],
+               ac_cv_c_clip_positive=yes,
+               ac_cv_c_clip_positive=no,
+               ac_cv_c_clip_positive=unknown
+               )
+
+       AC_TRY_RUN(
+       [[
+       #define _ISOC9X_SOURCE  1
+       #define _ISOC99_SOURCE  1
+       #define __USE_ISOC99    1
+       #define __USE_ISOC9X    1
+       #include <math.h>
+       int main (void)
+       {       double  fval ;
+               int k, ival ;
+
+               fval = -8.0 * 0x10000000 ;
+               for (k = 0 ; k < 100 ; k++)
+               {       ival = (lrint (fval)) >> 24 ;
+                       if (ival != -128)
+                               return 1 ;
+               
+                       fval *= 1.2499999 ;
+                       } ;
+               
+                       return 0 ;
+               }
+               ]],
+               ac_cv_c_clip_negative=yes,
+               ac_cv_c_clip_negative=no,
+               ac_cv_c_clip_negative=unknown
+               )
+       fi
+
+if test $ac_cv_c_clip_positive = yes ; then
+       ac_cv_c_clip_positive=1
+else
+       ac_cv_c_clip_positive=0
+       fi
+
+if test $ac_cv_c_clip_negative = yes ; then
+       ac_cv_c_clip_negative=1
+else
+       ac_cv_c_clip_negative=0
+       fi
+
+[[
+case "$ac_cv_c_clip_positive$ac_cv_c_clip_negative" in
+       "00")
+               ac_cv_c_clip_type="none"
+               ;;
+       "10")
+               ac_cv_c_clip_type="positive"
+               ;;
+       "01")
+               ac_cv_c_clip_type="negative"
+               ;;
+       "11")
+               ac_cv_c_clip_type="both"
+               ;;
+       esac
+       ]]
+
+)
+]
+
+)# AC_C_CLIP_MODE
+
+
+dnl @synopsis AC_ADD_CFLAGS
+dnl
+dnl Add the given option to CFLAGS, if it doesn't break the compiler
+
+AC_DEFUN([AC_ADD_CFLAGS],
+[AC_MSG_CHECKING([if $CC accepts $1])
+       ac_add_cflags__old_cflags="$CFLAGS"
+       CFLAGS="$CFLAGS $1"
+       AC_TRY_LINK([#include <stdio.h>],
+               [printf("Hello, World!\n"); return 0;],
+               AC_MSG_RESULT([yes]),
+               AC_MSG_RESULT([no])
+               CFLAGS="$ac_add_cflags__old_cflags")
+])
+
+
+
+
+ifelse(dnl     
+
+ Do not edit or modify anything in this comment block.
+ The arch-tag line is a file identity tag for the GNU Arch 
+ revision control system.
+
+ arch-tag: bc38294d-bb5c-42ad-90b9-779def5eaab7
+
+)dnl
diff --git a/libs/libsndfile/aclocal.m4 b/libs/libsndfile/aclocal.m4
new file mode 100644 (file)
index 0000000..e406d1a
--- /dev/null
@@ -0,0 +1,72 @@
+# generated automatically by aclocal 1.9.2 -*- Autoconf -*-
+
+# Copyright (C) 1996, 1997, 1998, 1999, 2000, 2001, 2002, 2003, 2004
+# Free Software Foundation, Inc.
+# This file is free software; the Free Software Foundation
+# gives unlimited permission to copy and/or distribute it,
+# with or without modifications, as long as this notice is preserved.
+
+# This program is distributed in the hope that it will be useful,
+# but WITHOUT ANY WARRANTY, to the extent permitted by law; without
+# even the implied warranty of MERCHANTABILITY or FITNESS FOR A
+# PARTICULAR PURPOSE.
+
+
+dnl PKG_CHECK_MODULES(GSTUFF, gtk+-2.0 >= 1.3 glib = 1.3.4, action-if, action-not)
+dnl defines GSTUFF_LIBS, GSTUFF_CFLAGS, see pkg-config man page
+dnl also defines GSTUFF_PKG_ERRORS on error
+AC_DEFUN([PKG_CHECK_MODULES], [
+  succeeded=no
+
+  if test -z "$PKG_CONFIG"; then
+    AC_PATH_PROG(PKG_CONFIG, pkg-config, no)
+  fi
+
+  if test "$PKG_CONFIG" = "no" ; then
+     echo "*** The pkg-config script could not be found. Make sure it is"
+     echo "*** in your path, or set the PKG_CONFIG environment variable"
+     echo "*** to the full path to pkg-config."
+     echo "*** Or see http://www.freedesktop.org/software/pkgconfig to get pkg-config."
+  else
+     PKG_CONFIG_MIN_VERSION=0.9.0
+     if $PKG_CONFIG --atleast-pkgconfig-version $PKG_CONFIG_MIN_VERSION; then
+        AC_MSG_CHECKING(for $2)
+
+        if $PKG_CONFIG --exists "$2" ; then
+            AC_MSG_RESULT(yes)
+            succeeded=yes
+
+            AC_MSG_CHECKING($1_CFLAGS)
+            $1_CFLAGS=`$PKG_CONFIG --cflags "$2"`
+            AC_MSG_RESULT($$1_CFLAGS)
+
+            AC_MSG_CHECKING($1_LIBS)
+            $1_LIBS=`$PKG_CONFIG --libs "$2"`
+            AC_MSG_RESULT($$1_LIBS)
+        else
+            $1_CFLAGS=""
+            $1_LIBS=""
+            ## If we have a custom action on failure, don't print errors, but 
+            ## do set a variable so people can do so.
+            $1_PKG_ERRORS=`$PKG_CONFIG --errors-to-stdout --print-errors "$2"`
+            ifelse([$4], ,echo $$1_PKG_ERRORS,)
+        fi
+
+        AC_SUBST($1_CFLAGS)
+        AC_SUBST($1_LIBS)
+     else
+        echo "*** Your version of pkg-config is too old. You need version $PKG_CONFIG_MIN_VERSION or newer."
+        echo "*** See http://www.freedesktop.org/software/pkgconfig"
+     fi
+  fi
+
+  if test $succeeded = yes; then
+     ifelse([$3], , :, [$3])
+  else
+     ifelse([$4], , AC_MSG_ERROR([Library requirements ($2) not met; consider adjusting the PKG_CONFIG_PATH environment variable if your libraries are in a nonstandard prefix so pkg-config can find them.]), [$4])
+  fi
+])
+
+
+
+m4_include([acinclude.m4])
diff --git a/libs/libsndfile/compile b/libs/libsndfile/compile
new file mode 100755 (executable)
index 0000000..ac07cc5
--- /dev/null
@@ -0,0 +1,107 @@
+#! /bin/sh
+
+# Wrapper for compilers which do not understand `-c -o'.
+
+# Copyright 1999, 2000 Free Software Foundation, Inc.
+# Written by Tom Tromey <tromey@cygnus.com>.
+#
+# This program is free software; you can redistribute it and/or modify
+# it under the terms of the GNU General Public License as published by
+# the Free Software Foundation; either version 2, or (at your option)
+# any later version.
+#
+# This program is distributed in the hope that it will be useful,
+# but WITHOUT ANY WARRANTY; without even the implied warranty of
+# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+# GNU General Public License for more details.
+#
+# You should have received a copy of the GNU General Public License
+# along with this program; if not, write to the Free Software
+# Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA.
+
+# As a special exception to the GNU General Public License, if you
+# distribute this file as part of a program that contains a
+# configuration script generated by Autoconf, you may include it under
+# the same distribution terms that you use for the rest of that program.
+
+# Usage:
+# compile PROGRAM [ARGS]...
+# `-o FOO.o' is removed from the args passed to the actual compile.
+
+# Usage statement added by Billy Biggs <vektor@dumbterm.net>.
+if [ -z $1 ]; then
+    echo "Wrapper for compilers which do not understand '-c -o'."
+    echo "usage: compile PROGRAM [ARGS]..."
+    echo "'-o FOO.o' is removed from the args passed to the actual compile."
+    exit 1
+fi
+
+prog=$1
+shift
+
+ofile=
+cfile=
+args=
+while test $# -gt 0; do
+   case "$1" in
+    -o)
+       # configure might choose to run compile as `compile cc -o foo foo.c'.
+       # So we do something ugly here.
+       ofile=$2
+       shift
+       case "$ofile" in
+       *.o | *.obj)
+          ;;
+       *)
+          args="$args -o $ofile"
+          ofile=
+          ;;
+       esac
+       ;;
+    *.c)
+       cfile=$1
+       args="$args $1"
+       ;;
+    *)
+       args="$args $1"
+       ;;
+   esac
+   shift
+done
+
+if test -z "$ofile" || test -z "$cfile"; then
+   # If no `-o' option was seen then we might have been invoked from a
+   # pattern rule where we don't need one.  That is ok -- this is a
+   # normal compilation that the losing compiler can handle.  If no
+   # `.c' file was seen then we are probably linking.  That is also
+   # ok.
+   exec "$prog" $args
+fi
+
+# Name of file we expect compiler to create.
+cofile=`echo $cfile | sed -e 's|^.*/||' -e 's/\.c$/.o/'`
+
+# Create the lock directory.
+# Note: use `[/.-]' here to ensure that we don't use the same name
+# that we are using for the .o file.  Also, base the name on the expected
+# object file name, since that is what matters with a parallel build.
+lockdir=`echo $cofile | sed -e 's|[/.-]|_|g'`.d
+while true; do
+   if mkdir $lockdir > /dev/null 2>&1; then
+      break
+   fi
+   sleep 1
+done
+# FIXME: race condition here if user kills between mkdir and trap.
+trap "rmdir $lockdir; exit 1" 1 2 15
+
+# Run the compile.
+"$prog" $args
+status=$?
+
+if test -f "$cofile"; then
+   mv "$cofile" "$ofile"
+fi
+
+rmdir $lockdir
+exit $status
diff --git a/libs/libsndfile/config.guess b/libs/libsndfile/config.guess
new file mode 100755 (executable)
index 0000000..c38553d
--- /dev/null
@@ -0,0 +1,1497 @@
+#! /bin/sh
+# Attempt to guess a canonical system name.
+#   Copyright (C) 1992, 1993, 1994, 1995, 1996, 1997, 1998, 1999,
+#   2000, 2001, 2002, 2003, 2004, 2005 Free Software Foundation, Inc.
+
+timestamp='2006-02-23'
+
+# This file is free software; you can redistribute it and/or modify it
+# under the terms of the GNU General Public License as published by
+# the Free Software Foundation; either version 2 of the License, or
+# (at your option) any later version.
+#
+# This program is distributed in the hope that it will be useful, but
+# WITHOUT ANY WARRANTY; without even the implied warranty of
+# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
+# General Public License for more details.
+#
+# You should have received a copy of the GNU General Public License
+# along with this program; if not, write to the Free Software
+# Foundation, Inc., 51 Franklin Street - Fifth Floor, Boston, MA
+# 02110-1301, USA.
+#
+# As a special exception to the GNU General Public License, if you
+# distribute this file as part of a program that contains a
+# configuration script generated by Autoconf, you may include it under
+# the same distribution terms that you use for the rest of that program.
+
+
+# Originally written by Per Bothner <per@bothner.com>.
+# Please send patches to <config-patches@gnu.org>.  Submit a context
+# diff and a properly formatted ChangeLog entry.
+#
+# This script attempts to guess a canonical system name similar to
+# config.sub.  If it succeeds, it prints the system name on stdout, and
+# exits with 0.  Otherwise, it exits with 1.
+#
+# The plan is that this can be called by configure scripts if you
+# don't specify an explicit build system type.
+
+me=`echo "$0" | sed -e 's,.*/,,'`
+
+usage="\
+Usage: $0 [OPTION]
+
+Output the configuration name of the system \`$me' is run on.
+
+Operation modes:
+  -h, --help         print this help, then exit
+  -t, --time-stamp   print date of last modification, then exit
+  -v, --version      print version number, then exit
+
+Report bugs and patches to <config-patches@gnu.org>."
+
+version="\
+GNU config.guess ($timestamp)
+
+Originally written by Per Bothner.
+Copyright (C) 1992, 1993, 1994, 1995, 1996, 1997, 1998, 1999, 2000, 2001, 2002, 2003, 2004, 2005
+Free Software Foundation, Inc.
+
+This is free software; see the source for copying conditions.  There is NO
+warranty; not even for MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE."
+
+help="
+Try \`$me --help' for more information."
+
+# Parse command line
+while test $# -gt 0 ; do
+  case $1 in
+    --time-stamp | --time* | -t )
+       echo "$timestamp" ; exit ;;
+    --version | -v )
+       echo "$version" ; exit ;;
+    --help | --h* | -h )
+       echo "$usage"; exit ;;
+    -- )     # Stop option processing
+       shift; break ;;
+    - )        # Use stdin as input.
+       break ;;
+    -* )
+       echo "$me: invalid option $1$help" >&2
+       exit 1 ;;
+    * )
+       break ;;
+  esac
+done
+
+if test $# != 0; then
+  echo "$me: too many arguments$help" >&2
+  exit 1
+fi
+
+trap 'exit 1' 1 2 15
+
+# CC_FOR_BUILD -- compiler used by this script. Note that the use of a
+# compiler to aid in system detection is discouraged as it requires
+# temporary files to be created and, as you can see below, it is a
+# headache to deal with in a portable fashion.
+
+# Historically, `CC_FOR_BUILD' used to be named `HOST_CC'. We still
+# use `HOST_CC' if defined, but it is deprecated.
+
+# Portable tmp directory creation inspired by the Autoconf team.
+
+set_cc_for_build='
+trap "exitcode=\$?; (rm -f \$tmpfiles 2>/dev/null; rmdir \$tmp 2>/dev/null) && exit \$exitcode" 0 ;
+trap "rm -f \$tmpfiles 2>/dev/null; rmdir \$tmp 2>/dev/null; exit 1" 1 2 13 15 ;
+: ${TMPDIR=/tmp} ;
+ { tmp=`(umask 077 && mktemp -d "$TMPDIR/cgXXXXXX") 2>/dev/null` && test -n "$tmp" && test -d "$tmp" ; } ||
+ { test -n "$RANDOM" && tmp=$TMPDIR/cg$$-$RANDOM && (umask 077 && mkdir $tmp) ; } ||
+ { tmp=$TMPDIR/cg-$$ && (umask 077 && mkdir $tmp) && echo "Warning: creating insecure temp directory" >&2 ; } ||
+ { echo "$me: cannot create a temporary directory in $TMPDIR" >&2 ; exit 1 ; } ;
+dummy=$tmp/dummy ;
+tmpfiles="$dummy.c $dummy.o $dummy.rel $dummy" ;
+case $CC_FOR_BUILD,$HOST_CC,$CC in
+ ,,)    echo "int x;" > $dummy.c ;
+       for c in cc gcc c89 c99 ; do
+         if ($c -c -o $dummy.o $dummy.c) >/dev/null 2>&1 ; then
+            CC_FOR_BUILD="$c"; break ;
+         fi ;
+       done ;
+       if test x"$CC_FOR_BUILD" = x ; then
+         CC_FOR_BUILD=no_compiler_found ;
+       fi
+       ;;
+ ,,*)   CC_FOR_BUILD=$CC ;;
+ ,*,*)  CC_FOR_BUILD=$HOST_CC ;;
+esac ; set_cc_for_build= ;'
+
+# This is needed to find uname on a Pyramid OSx when run in the BSD universe.
+# (ghazi@noc.rutgers.edu 1994-08-24)
+if (test -f /.attbin/uname) >/dev/null 2>&1 ; then
+       PATH=$PATH:/.attbin ; export PATH
+fi
+
+UNAME_MACHINE=`(uname -m) 2>/dev/null` || UNAME_MACHINE=unknown
+UNAME_RELEASE=`(uname -r) 2>/dev/null` || UNAME_RELEASE=unknown
+UNAME_SYSTEM=`(uname -s) 2>/dev/null`  || UNAME_SYSTEM=unknown
+UNAME_VERSION=`(uname -v) 2>/dev/null` || UNAME_VERSION=unknown
+
+# Note: order is significant - the case branches are not exclusive.
+
+case "${UNAME_MACHINE}:${UNAME_SYSTEM}:${UNAME_RELEASE}:${UNAME_VERSION}" in
+    *:NetBSD:*:*)
+       # NetBSD (nbsd) targets should (where applicable) match one or
+       # more of the tupples: *-*-netbsdelf*, *-*-netbsdaout*,
+       # *-*-netbsdecoff* and *-*-netbsd*.  For targets that recently
+       # switched to ELF, *-*-netbsd* would select the old
+       # object file format.  This provides both forward
+       # compatibility and a consistent mechanism for selecting the
+       # object file format.
+       #
+       # Note: NetBSD doesn't particularly care about the vendor
+       # portion of the name.  We always set it to "unknown".
+       sysctl="sysctl -n hw.machine_arch"
+       UNAME_MACHINE_ARCH=`(/sbin/$sysctl 2>/dev/null || \
+           /usr/sbin/$sysctl 2>/dev/null || echo unknown)`
+       case "${UNAME_MACHINE_ARCH}" in
+           armeb) machine=armeb-unknown ;;
+           arm*) machine=arm-unknown ;;
+           sh3el) machine=shl-unknown ;;
+           sh3eb) machine=sh-unknown ;;
+           *) machine=${UNAME_MACHINE_ARCH}-unknown ;;
+       esac
+       # The Operating System including object format, if it has switched
+       # to ELF recently, or will in the future.
+       case "${UNAME_MACHINE_ARCH}" in
+           arm*|i386|m68k|ns32k|sh3*|sparc|vax)
+               eval $set_cc_for_build
+               if echo __ELF__ | $CC_FOR_BUILD -E - 2>/dev/null \
+                       | grep __ELF__ >/dev/null
+               then
+                   # Once all utilities can be ECOFF (netbsdecoff) or a.out (netbsdaout).
+                   # Return netbsd for either.  FIX?
+                   os=netbsd
+               else
+                   os=netbsdelf
+               fi
+               ;;
+           *)
+               os=netbsd
+               ;;
+       esac
+       # The OS release
+       # Debian GNU/NetBSD machines have a different userland, and
+       # thus, need a distinct triplet. However, they do not need
+       # kernel version information, so it can be replaced with a
+       # suitable tag, in the style of linux-gnu.
+       case "${UNAME_VERSION}" in
+           Debian*)
+               release='-gnu'
+               ;;
+           *)
+               release=`echo ${UNAME_RELEASE}|sed -e 's/[-_].*/\./'`
+               ;;
+       esac
+       # Since CPU_TYPE-MANUFACTURER-KERNEL-OPERATING_SYSTEM:
+       # contains redundant information, the shorter form:
+       # CPU_TYPE-MANUFACTURER-OPERATING_SYSTEM is used.
+       echo "${machine}-${os}${release}"
+       exit ;;
+    *:OpenBSD:*:*)
+       UNAME_MACHINE_ARCH=`arch | sed 's/OpenBSD.//'`
+       echo ${UNAME_MACHINE_ARCH}-unknown-openbsd${UNAME_RELEASE}
+       exit ;;
+    *:ekkoBSD:*:*)
+       echo ${UNAME_MACHINE}-unknown-ekkobsd${UNAME_RELEASE}
+       exit ;;
+    *:SolidBSD:*:*)
+       echo ${UNAME_MACHINE}-unknown-solidbsd${UNAME_RELEASE}
+       exit ;;
+    macppc:MirBSD:*:*)
+       echo powerppc-unknown-mirbsd${UNAME_RELEASE}
+       exit ;;
+    *:MirBSD:*:*)
+       echo ${UNAME_MACHINE}-unknown-mirbsd${UNAME_RELEASE}
+       exit ;;
+    alpha:OSF1:*:*)
+       case $UNAME_RELEASE in
+       *4.0)
+               UNAME_RELEASE=`/usr/sbin/sizer -v | awk '{print $3}'`
+               ;;
+       *5.*)
+               UNAME_RELEASE=`/usr/sbin/sizer -v | awk '{print $4}'`
+               ;;
+       esac
+       # According to Compaq, /usr/sbin/psrinfo has been available on
+       # OSF/1 and Tru64 systems produced since 1995.  I hope that
+       # covers most systems running today.  This code pipes the CPU
+       # types through head -n 1, so we only detect the type of CPU 0.
+       ALPHA_CPU_TYPE=`/usr/sbin/psrinfo -v | sed -n -e 's/^  The alpha \(.*\) processor.*$/\1/p' | head -n 1`
+       case "$ALPHA_CPU_TYPE" in
+           "EV4 (21064)")
+               UNAME_MACHINE="alpha" ;;
+           "EV4.5 (21064)")
+               UNAME_MACHINE="alpha" ;;
+           "LCA4 (21066/21068)")
+               UNAME_MACHINE="alpha" ;;
+           "EV5 (21164)")
+               UNAME_MACHINE="alphaev5" ;;
+           "EV5.6 (21164A)")
+               UNAME_MACHINE="alphaev56" ;;
+           "EV5.6 (21164PC)")
+               UNAME_MACHINE="alphapca56" ;;
+           "EV5.7 (21164PC)")
+               UNAME_MACHINE="alphapca57" ;;
+           "EV6 (21264)")
+               UNAME_MACHINE="alphaev6" ;;
+           "EV6.7 (21264A)")
+               UNAME_MACHINE="alphaev67" ;;
+           "EV6.8CB (21264C)")
+               UNAME_MACHINE="alphaev68" ;;
+           "EV6.8AL (21264B)")
+               UNAME_MACHINE="alphaev68" ;;
+           "EV6.8CX (21264D)")
+               UNAME_MACHINE="alphaev68" ;;
+           "EV6.9A (21264/EV69A)")
+               UNAME_MACHINE="alphaev69" ;;
+           "EV7 (21364)")
+               UNAME_MACHINE="alphaev7" ;;
+           "EV7.9 (21364A)")
+               UNAME_MACHINE="alphaev79" ;;
+       esac
+       # A Pn.n version is a patched version.
+       # A Vn.n version is a released version.
+       # A Tn.n version is a released field test version.
+       # A Xn.n version is an unreleased experimental baselevel.
+       # 1.2 uses "1.2" for uname -r.
+       echo ${UNAME_MACHINE}-dec-osf`echo ${UNAME_RELEASE} | sed -e 's/^[PVTX]//' | tr 'ABCDEFGHIJKLMNOPQRSTUVWXYZ' 'abcdefghijklmnopqrstuvwxyz'`
+       exit ;;
+    Alpha\ *:Windows_NT*:*)
+       # How do we know it's Interix rather than the generic POSIX subsystem?
+       # Should we change UNAME_MACHINE based on the output of uname instead
+       # of the specific Alpha model?
+       echo alpha-pc-interix
+       exit ;;
+    21064:Windows_NT:50:3)
+       echo alpha-dec-winnt3.5
+       exit ;;
+    Amiga*:UNIX_System_V:4.0:*)
+       echo m68k-unknown-sysv4
+       exit ;;
+    *:[Aa]miga[Oo][Ss]:*:*)
+       echo ${UNAME_MACHINE}-unknown-amigaos
+       exit ;;
+    *:[Mm]orph[Oo][Ss]:*:*)
+       echo ${UNAME_MACHINE}-unknown-morphos
+       exit ;;
+    *:OS/390:*:*)
+       echo i370-ibm-openedition
+       exit ;;
+    *:z/VM:*:*)
+       echo s390-ibm-zvmoe
+       exit ;;
+    *:OS400:*:*)
+        echo powerpc-ibm-os400
+       exit ;;
+    arm:RISC*:1.[012]*:*|arm:riscix:1.[012]*:*)
+       echo arm-acorn-riscix${UNAME_RELEASE}
+       exit ;;
+    arm:riscos:*:*|arm:RISCOS:*:*)
+       echo arm-unknown-riscos
+       exit ;;
+    SR2?01:HI-UX/MPP:*:* | SR8000:HI-UX/MPP:*:*)
+       echo hppa1.1-hitachi-hiuxmpp
+       exit ;;
+    Pyramid*:OSx*:*:* | MIS*:OSx*:*:* | MIS*:SMP_DC-OSx*:*:*)
+       # akee@wpdis03.wpafb.af.mil (Earle F. Ake) contributed MIS and NILE.
+       if test "`(/bin/universe) 2>/dev/null`" = att ; then
+               echo pyramid-pyramid-sysv3
+       else
+               echo pyramid-pyramid-bsd
+       fi
+       exit ;;
+    NILE*:*:*:dcosx)
+       echo pyramid-pyramid-svr4
+       exit ;;
+    DRS?6000:unix:4.0:6*)
+       echo sparc-icl-nx6
+       exit ;;
+    DRS?6000:UNIX_SV:4.2*:7* | DRS?6000:isis:4.2*:7*)
+       case `/usr/bin/uname -p` in
+           sparc) echo sparc-icl-nx7; exit ;;
+       esac ;;
+    sun4H:SunOS:5.*:*)
+       echo sparc-hal-solaris2`echo ${UNAME_RELEASE}|sed -e 's/[^.]*//'`
+       exit ;;
+    sun4*:SunOS:5.*:* | tadpole*:SunOS:5.*:*)
+       echo sparc-sun-solaris2`echo ${UNAME_RELEASE}|sed -e 's/[^.]*//'`
+       exit ;;
+    i86pc:SunOS:5.*:*)
+       echo i386-pc-solaris2`echo ${UNAME_RELEASE}|sed -e 's/[^.]*//'`
+       exit ;;
+    sun4*:SunOS:6*:*)
+       # According to config.sub, this is the proper way to canonicalize
+       # SunOS6.  Hard to guess exactly what SunOS6 will be like, but
+       # it's likely to be more like Solaris than SunOS4.
+       echo sparc-sun-solaris3`echo ${UNAME_RELEASE}|sed -e 's/[^.]*//'`
+       exit ;;
+    sun4*:SunOS:*:*)
+       case "`/usr/bin/arch -k`" in
+           Series*|S4*)
+               UNAME_RELEASE=`uname -v`
+               ;;
+       esac
+       # Japanese Language versions have a version number like `4.1.3-JL'.
+       echo sparc-sun-sunos`echo ${UNAME_RELEASE}|sed -e 's/-/_/'`
+       exit ;;
+    sun3*:SunOS:*:*)
+       echo m68k-sun-sunos${UNAME_RELEASE}
+       exit ;;
+    sun*:*:4.2BSD:*)
+       UNAME_RELEASE=`(sed 1q /etc/motd | awk '{print substr($5,1,3)}') 2>/dev/null`
+       test "x${UNAME_RELEASE}" = "x" && UNAME_RELEASE=3
+       case "`/bin/arch`" in
+           sun3)
+               echo m68k-sun-sunos${UNAME_RELEASE}
+               ;;
+           sun4)
+               echo sparc-sun-sunos${UNAME_RELEASE}
+               ;;
+       esac
+       exit ;;
+    aushp:SunOS:*:*)
+       echo sparc-auspex-sunos${UNAME_RELEASE}
+       exit ;;
+    # The situation for MiNT is a little confusing.  The machine name
+    # can be virtually everything (everything which is not
+    # "atarist" or "atariste" at least should have a processor
+    # > m68000).  The system name ranges from "MiNT" over "FreeMiNT"
+    # to the lowercase version "mint" (or "freemint").  Finally
+    # the system name "TOS" denotes a system which is actually not
+    # MiNT.  But MiNT is downward compatible to TOS, so this should
+    # be no problem.
+    atarist[e]:*MiNT:*:* | atarist[e]:*mint:*:* | atarist[e]:*TOS:*:*)
+        echo m68k-atari-mint${UNAME_RELEASE}
+       exit ;;
+    atari*:*MiNT:*:* | atari*:*mint:*:* | atarist[e]:*TOS:*:*)
+       echo m68k-atari-mint${UNAME_RELEASE}
+        exit ;;
+    *falcon*:*MiNT:*:* | *falcon*:*mint:*:* | *falcon*:*TOS:*:*)
+        echo m68k-atari-mint${UNAME_RELEASE}
+       exit ;;
+    milan*:*MiNT:*:* | milan*:*mint:*:* | *milan*:*TOS:*:*)
+        echo m68k-milan-mint${UNAME_RELEASE}
+        exit ;;
+    hades*:*MiNT:*:* | hades*:*mint:*:* | *hades*:*TOS:*:*)
+        echo m68k-hades-mint${UNAME_RELEASE}
+        exit ;;
+    *:*MiNT:*:* | *:*mint:*:* | *:*TOS:*:*)
+        echo m68k-unknown-mint${UNAME_RELEASE}
+        exit ;;
+    m68k:machten:*:*)
+       echo m68k-apple-machten${UNAME_RELEASE}
+       exit ;;
+    powerpc:machten:*:*)
+       echo powerpc-apple-machten${UNAME_RELEASE}
+       exit ;;
+    RISC*:Mach:*:*)
+       echo mips-dec-mach_bsd4.3
+       exit ;;
+    RISC*:ULTRIX:*:*)
+       echo mips-dec-ultrix${UNAME_RELEASE}
+       exit ;;
+    VAX*:ULTRIX*:*:*)
+       echo vax-dec-ultrix${UNAME_RELEASE}
+       exit ;;
+    2020:CLIX:*:* | 2430:CLIX:*:*)
+       echo clipper-intergraph-clix${UNAME_RELEASE}
+       exit ;;
+    mips:*:*:UMIPS | mips:*:*:RISCos)
+       eval $set_cc_for_build
+       sed 's/^        //' << EOF >$dummy.c
+#ifdef __cplusplus
+#include <stdio.h>  /* for printf() prototype */
+       int main (int argc, char *argv[]) {
+#else
+       int main (argc, argv) int argc; char *argv[]; {
+#endif
+       #if defined (host_mips) && defined (MIPSEB)
+       #if defined (SYSTYPE_SYSV)
+         printf ("mips-mips-riscos%ssysv\n", argv[1]); exit (0);
+       #endif
+       #if defined (SYSTYPE_SVR4)
+         printf ("mips-mips-riscos%ssvr4\n", argv[1]); exit (0);
+       #endif
+       #if defined (SYSTYPE_BSD43) || defined(SYSTYPE_BSD)
+         printf ("mips-mips-riscos%sbsd\n", argv[1]); exit (0);
+       #endif
+       #endif
+         exit (-1);
+       }
+EOF
+       $CC_FOR_BUILD -o $dummy $dummy.c &&
+         dummyarg=`echo "${UNAME_RELEASE}" | sed -n 's/\([0-9]*\).*/\1/p'` &&
+         SYSTEM_NAME=`$dummy $dummyarg` &&
+           { echo "$SYSTEM_NAME"; exit; }
+       echo mips-mips-riscos${UNAME_RELEASE}
+       exit ;;
+    Motorola:PowerMAX_OS:*:*)
+       echo powerpc-motorola-powermax
+       exit ;;
+    Motorola:*:4.3:PL8-*)
+       echo powerpc-harris-powermax
+       exit ;;
+    Night_Hawk:*:*:PowerMAX_OS | Synergy:PowerMAX_OS:*:*)
+       echo powerpc-harris-powermax
+       exit ;;
+    Night_Hawk:Power_UNIX:*:*)
+       echo powerpc-harris-powerunix
+       exit ;;
+    m88k:CX/UX:7*:*)
+       echo m88k-harris-cxux7
+       exit ;;
+    m88k:*:4*:R4*)
+       echo m88k-motorola-sysv4
+       exit ;;
+    m88k:*:3*:R3*)
+       echo m88k-motorola-sysv3
+       exit ;;
+    AViiON:dgux:*:*)
+        # DG/UX returns AViiON for all architectures
+        UNAME_PROCESSOR=`/usr/bin/uname -p`
+       if [ $UNAME_PROCESSOR = mc88100 ] || [ $UNAME_PROCESSOR = mc88110 ]
+       then
+           if [ ${TARGET_BINARY_INTERFACE}x = m88kdguxelfx ] || \
+              [ ${TARGET_BINARY_INTERFACE}x = x ]
+           then
+               echo m88k-dg-dgux${UNAME_RELEASE}
+           else
+               echo m88k-dg-dguxbcs${UNAME_RELEASE}
+           fi
+       else
+           echo i586-dg-dgux${UNAME_RELEASE}
+       fi
+       exit ;;
+    M88*:DolphinOS:*:*)        # DolphinOS (SVR3)
+       echo m88k-dolphin-sysv3
+       exit ;;
+    M88*:*:R3*:*)
+       # Delta 88k system running SVR3
+       echo m88k-motorola-sysv3
+       exit ;;
+    XD88*:*:*:*) # Tektronix XD88 system running UTekV (SVR3)
+       echo m88k-tektronix-sysv3
+       exit ;;
+    Tek43[0-9][0-9]:UTek:*:*) # Tektronix 4300 system running UTek (BSD)
+       echo m68k-tektronix-bsd
+       exit ;;
+    *:IRIX*:*:*)
+       echo mips-sgi-irix`echo ${UNAME_RELEASE}|sed -e 's/-/_/g'`
+       exit ;;
+    ????????:AIX?:[12].1:2)   # AIX 2.2.1 or AIX 2.1.1 is RT/PC AIX.
+       echo romp-ibm-aix     # uname -m gives an 8 hex-code CPU id
+       exit ;;               # Note that: echo "'`uname -s`'" gives 'AIX '
+    i*86:AIX:*:*)
+       echo i386-ibm-aix
+       exit ;;
+    ia64:AIX:*:*)
+       if [ -x /usr/bin/oslevel ] ; then
+               IBM_REV=`/usr/bin/oslevel`
+       else
+               IBM_REV=${UNAME_VERSION}.${UNAME_RELEASE}
+       fi
+       echo ${UNAME_MACHINE}-ibm-aix${IBM_REV}
+       exit ;;
+    *:AIX:2:3)
+       if grep bos325 /usr/include/stdio.h >/dev/null 2>&1; then
+               eval $set_cc_for_build
+               sed 's/^                //' << EOF >$dummy.c
+               #include <sys/systemcfg.h>
+
+               main()
+                       {
+                       if (!__power_pc())
+                               exit(1);
+                       puts("powerpc-ibm-aix3.2.5");
+                       exit(0);
+                       }
+EOF
+               if $CC_FOR_BUILD -o $dummy $dummy.c && SYSTEM_NAME=`$dummy`
+               then
+                       echo "$SYSTEM_NAME"
+               else
+                       echo rs6000-ibm-aix3.2.5
+               fi
+       elif grep bos324 /usr/include/stdio.h >/dev/null 2>&1; then
+               echo rs6000-ibm-aix3.2.4
+       else
+               echo rs6000-ibm-aix3.2
+       fi
+       exit ;;
+    *:AIX:*:[45])
+       IBM_CPU_ID=`/usr/sbin/lsdev -C -c processor -S available | sed 1q | awk '{ print $1 }'`
+       if /usr/sbin/lsattr -El ${IBM_CPU_ID} | grep ' POWER' >/dev/null 2>&1; then
+               IBM_ARCH=rs6000
+       else
+               IBM_ARCH=powerpc
+       fi
+       if [ -x /usr/bin/oslevel ] ; then
+               IBM_REV=`/usr/bin/oslevel`
+       else
+               IBM_REV=${UNAME_VERSION}.${UNAME_RELEASE}
+       fi
+       echo ${IBM_ARCH}-ibm-aix${IBM_REV}
+       exit ;;
+    *:AIX:*:*)
+       echo rs6000-ibm-aix
+       exit ;;
+    ibmrt:4.4BSD:*|romp-ibm:BSD:*)
+       echo romp-ibm-bsd4.4
+       exit ;;
+    ibmrt:*BSD:*|romp-ibm:BSD:*)            # covers RT/PC BSD and
+       echo romp-ibm-bsd${UNAME_RELEASE}   # 4.3 with uname added to
+       exit ;;                             # report: romp-ibm BSD 4.3
+    *:BOSX:*:*)
+       echo rs6000-bull-bosx
+       exit ;;
+    DPX/2?00:B.O.S.:*:*)
+       echo m68k-bull-sysv3
+       exit ;;
+    9000/[34]??:4.3bsd:1.*:*)
+       echo m68k-hp-bsd
+       exit ;;
+    hp300:4.4BSD:*:* | 9000/[34]??:4.3bsd:2.*:*)
+       echo m68k-hp-bsd4.4
+       exit ;;
+    9000/[34678]??:HP-UX:*:*)
+       HPUX_REV=`echo ${UNAME_RELEASE}|sed -e 's/[^.]*.[0B]*//'`
+       case "${UNAME_MACHINE}" in
+           9000/31? )            HP_ARCH=m68000 ;;
+           9000/[34]?? )         HP_ARCH=m68k ;;
+           9000/[678][0-9][0-9])
+               if [ -x /usr/bin/getconf ]; then
+                   sc_cpu_version=`/usr/bin/getconf SC_CPU_VERSION 2>/dev/null`
+                    sc_kernel_bits=`/usr/bin/getconf SC_KERNEL_BITS 2>/dev/null`
+                    case "${sc_cpu_version}" in
+                      523) HP_ARCH="hppa1.0" ;; # CPU_PA_RISC1_0
+                      528) HP_ARCH="hppa1.1" ;; # CPU_PA_RISC1_1
+                      532)                      # CPU_PA_RISC2_0
+                        case "${sc_kernel_bits}" in
+                          32) HP_ARCH="hppa2.0n" ;;
+                          64) HP_ARCH="hppa2.0w" ;;
+                         '') HP_ARCH="hppa2.0" ;;   # HP-UX 10.20
+                        esac ;;
+                    esac
+               fi
+               if [ "${HP_ARCH}" = "" ]; then
+                   eval $set_cc_for_build
+                   sed 's/^              //' << EOF >$dummy.c
+
+              #define _HPUX_SOURCE
+              #include <stdlib.h>
+              #include <unistd.h>
+
+              int main ()
+              {
+              #if defined(_SC_KERNEL_BITS)
+                  long bits = sysconf(_SC_KERNEL_BITS);
+              #endif
+                  long cpu  = sysconf (_SC_CPU_VERSION);
+
+                  switch (cpu)
+               {
+               case CPU_PA_RISC1_0: puts ("hppa1.0"); break;
+               case CPU_PA_RISC1_1: puts ("hppa1.1"); break;
+               case CPU_PA_RISC2_0:
+              #if defined(_SC_KERNEL_BITS)
+                   switch (bits)
+                       {
+                       case 64: puts ("hppa2.0w"); break;
+                       case 32: puts ("hppa2.0n"); break;
+                       default: puts ("hppa2.0"); break;
+                       } break;
+              #else  /* !defined(_SC_KERNEL_BITS) */
+                   puts ("hppa2.0"); break;
+              #endif
+               default: puts ("hppa1.0"); break;
+               }
+                  exit (0);
+              }
+EOF
+                   (CCOPTS= $CC_FOR_BUILD -o $dummy $dummy.c 2>/dev/null) && HP_ARCH=`$dummy`
+                   test -z "$HP_ARCH" && HP_ARCH=hppa
+               fi ;;
+       esac
+       if [ ${HP_ARCH} = "hppa2.0w" ]
+       then
+           eval $set_cc_for_build
+
+           # hppa2.0w-hp-hpux* has a 64-bit kernel and a compiler generating
+           # 32-bit code.  hppa64-hp-hpux* has the same kernel and a compiler
+           # generating 64-bit code.  GNU and HP use different nomenclature:
+           #
+           # $ CC_FOR_BUILD=cc ./config.guess
+           # => hppa2.0w-hp-hpux11.23
+           # $ CC_FOR_BUILD="cc +DA2.0w" ./config.guess
+           # => hppa64-hp-hpux11.23
+
+           if echo __LP64__ | (CCOPTS= $CC_FOR_BUILD -E - 2>/dev/null) |
+               grep __LP64__ >/dev/null
+           then
+               HP_ARCH="hppa2.0w"
+           else
+               HP_ARCH="hppa64"
+           fi
+       fi
+       echo ${HP_ARCH}-hp-hpux${HPUX_REV}
+       exit ;;
+    ia64:HP-UX:*:*)
+       HPUX_REV=`echo ${UNAME_RELEASE}|sed -e 's/[^.]*.[0B]*//'`
+       echo ia64-hp-hpux${HPUX_REV}
+       exit ;;
+    3050*:HI-UX:*:*)
+       eval $set_cc_for_build
+       sed 's/^        //' << EOF >$dummy.c
+       #include <unistd.h>
+       int
+       main ()
+       {
+         long cpu = sysconf (_SC_CPU_VERSION);
+         /* The order matters, because CPU_IS_HP_MC68K erroneously returns
+            true for CPU_PA_RISC1_0.  CPU_IS_PA_RISC returns correct
+            results, however.  */
+         if (CPU_IS_PA_RISC (cpu))
+           {
+             switch (cpu)
+               {
+                 case CPU_PA_RISC1_0: puts ("hppa1.0-hitachi-hiuxwe2"); break;
+                 case CPU_PA_RISC1_1: puts ("hppa1.1-hitachi-hiuxwe2"); break;
+                 case CPU_PA_RISC2_0: puts ("hppa2.0-hitachi-hiuxwe2"); break;
+                 default: puts ("hppa-hitachi-hiuxwe2"); break;
+               }
+           }
+         else if (CPU_IS_HP_MC68K (cpu))
+           puts ("m68k-hitachi-hiuxwe2");
+         else puts ("unknown-hitachi-hiuxwe2");
+         exit (0);
+       }
+EOF
+       $CC_FOR_BUILD -o $dummy $dummy.c && SYSTEM_NAME=`$dummy` &&
+               { echo "$SYSTEM_NAME"; exit; }
+       echo unknown-hitachi-hiuxwe2
+       exit ;;
+    9000/7??:4.3bsd:*:* | 9000/8?[79]:4.3bsd:*:* )
+       echo hppa1.1-hp-bsd
+       exit ;;
+    9000/8??:4.3bsd:*:*)
+       echo hppa1.0-hp-bsd
+       exit ;;
+    *9??*:MPE/iX:*:* | *3000*:MPE/iX:*:*)
+       echo hppa1.0-hp-mpeix
+       exit ;;
+    hp7??:OSF1:*:* | hp8?[79]:OSF1:*:* )
+       echo hppa1.1-hp-osf
+       exit ;;
+    hp8??:OSF1:*:*)
+       echo hppa1.0-hp-osf
+       exit ;;
+    i*86:OSF1:*:*)
+       if [ -x /usr/sbin/sysversion ] ; then
+           echo ${UNAME_MACHINE}-unknown-osf1mk
+       else
+           echo ${UNAME_MACHINE}-unknown-osf1
+       fi
+       exit ;;
+    parisc*:Lites*:*:*)
+       echo hppa1.1-hp-lites
+       exit ;;
+    C1*:ConvexOS:*:* | convex:ConvexOS:C1*:*)
+       echo c1-convex-bsd
+        exit ;;
+    C2*:ConvexOS:*:* | convex:ConvexOS:C2*:*)
+       if getsysinfo -f scalar_acc
+       then echo c32-convex-bsd
+       else echo c2-convex-bsd
+       fi
+        exit ;;
+    C34*:ConvexOS:*:* | convex:ConvexOS:C34*:*)
+       echo c34-convex-bsd
+        exit ;;
+    C38*:ConvexOS:*:* | convex:ConvexOS:C38*:*)
+       echo c38-convex-bsd
+        exit ;;
+    C4*:ConvexOS:*:* | convex:ConvexOS:C4*:*)
+       echo c4-convex-bsd
+        exit ;;
+    CRAY*Y-MP:*:*:*)
+       echo ymp-cray-unicos${UNAME_RELEASE} | sed -e 's/\.[^.]*$/.X/'
+       exit ;;
+    CRAY*[A-Z]90:*:*:*)
+       echo ${UNAME_MACHINE}-cray-unicos${UNAME_RELEASE} \
+       | sed -e 's/CRAY.*\([A-Z]90\)/\1/' \
+             -e y/ABCDEFGHIJKLMNOPQRSTUVWXYZ/abcdefghijklmnopqrstuvwxyz/ \
+             -e 's/\.[^.]*$/.X/'
+       exit ;;
+    CRAY*TS:*:*:*)
+       echo t90-cray-unicos${UNAME_RELEASE} | sed -e 's/\.[^.]*$/.X/'
+       exit ;;
+    CRAY*T3E:*:*:*)
+       echo alphaev5-cray-unicosmk${UNAME_RELEASE} | sed -e 's/\.[^.]*$/.X/'
+       exit ;;
+    CRAY*SV1:*:*:*)
+       echo sv1-cray-unicos${UNAME_RELEASE} | sed -e 's/\.[^.]*$/.X/'
+       exit ;;
+    *:UNICOS/mp:*:*)
+       echo craynv-cray-unicosmp${UNAME_RELEASE} | sed -e 's/\.[^.]*$/.X/'
+       exit ;;
+    F30[01]:UNIX_System_V:*:* | F700:UNIX_System_V:*:*)
+       FUJITSU_PROC=`uname -m | tr 'ABCDEFGHIJKLMNOPQRSTUVWXYZ' 'abcdefghijklmnopqrstuvwxyz'`
+        FUJITSU_SYS=`uname -p | tr 'ABCDEFGHIJKLMNOPQRSTUVWXYZ' 'abcdefghijklmnopqrstuvwxyz' | sed -e 's/\///'`
+        FUJITSU_REL=`echo ${UNAME_RELEASE} | sed -e 's/ /_/'`
+        echo "${FUJITSU_PROC}-fujitsu-${FUJITSU_SYS}${FUJITSU_REL}"
+        exit ;;
+    5000:UNIX_System_V:4.*:*)
+        FUJITSU_SYS=`uname -p | tr 'ABCDEFGHIJKLMNOPQRSTUVWXYZ' 'abcdefghijklmnopqrstuvwxyz' | sed -e 's/\///'`
+        FUJITSU_REL=`echo ${UNAME_RELEASE} | tr 'ABCDEFGHIJKLMNOPQRSTUVWXYZ' 'abcdefghijklmnopqrstuvwxyz' | sed -e 's/ /_/'`
+        echo "sparc-fujitsu-${FUJITSU_SYS}${FUJITSU_REL}"
+       exit ;;
+    i*86:BSD/386:*:* | i*86:BSD/OS:*:* | *:Ascend\ Embedded/OS:*:*)
+       echo ${UNAME_MACHINE}-pc-bsdi${UNAME_RELEASE}
+       exit ;;
+    sparc*:BSD/OS:*:*)
+       echo sparc-unknown-bsdi${UNAME_RELEASE}
+       exit ;;
+    *:BSD/OS:*:*)
+       echo ${UNAME_MACHINE}-unknown-bsdi${UNAME_RELEASE}
+       exit ;;
+    *:FreeBSD:*:*)
+       case ${UNAME_MACHINE} in
+           pc98)
+               echo i386-unknown-freebsd`echo ${UNAME_RELEASE}|sed -e 's/[-(].*//'` ;;
+           *)
+               echo ${UNAME_MACHINE}-unknown-freebsd`echo ${UNAME_RELEASE}|sed -e 's/[-(].*//'` ;;
+       esac
+       exit ;;
+    i*:CYGWIN*:*)
+       echo ${UNAME_MACHINE}-pc-cygwin
+       exit ;;
+    i*:MINGW*:*)
+       echo ${UNAME_MACHINE}-pc-mingw32
+       exit ;;
+    i*:MSYS_NT-*:*:*)
+       echo ${UNAME_MACHINE}-pc-mingw32
+       exit ;;
+    i*:windows32*:*)
+       # uname -m includes "-pc" on this system.
+       echo ${UNAME_MACHINE}-mingw32
+       exit ;;
+    i*:PW*:*)
+       echo ${UNAME_MACHINE}-pc-pw32
+       exit ;;
+    x86:Interix*:[345]*)
+       echo i586-pc-interix${UNAME_RELEASE}
+       exit ;;
+    EM64T:Interix*:[345]*)
+       echo x86_64-unknown-interix${UNAME_RELEASE}
+       exit ;;
+    [345]86:Windows_95:* | [345]86:Windows_98:* | [345]86:Windows_NT:*)
+       echo i${UNAME_MACHINE}-pc-mks
+       exit ;;
+    i*:Windows_NT*:* | Pentium*:Windows_NT*:*)
+       # How do we know it's Interix rather than the generic POSIX subsystem?
+       # It also conflicts with pre-2.0 versions of AT&T UWIN. Should we
+       # UNAME_MACHINE based on the output of uname instead of i386?
+       echo i586-pc-interix
+       exit ;;
+    i*:UWIN*:*)
+       echo ${UNAME_MACHINE}-pc-uwin
+       exit ;;
+    amd64:CYGWIN*:*:* | x86_64:CYGWIN*:*:*)
+       echo x86_64-unknown-cygwin
+       exit ;;
+    p*:CYGWIN*:*)
+       echo powerpcle-unknown-cygwin
+       exit ;;
+    prep*:SunOS:5.*:*)
+       echo powerpcle-unknown-solaris2`echo ${UNAME_RELEASE}|sed -e 's/[^.]*//'`
+       exit ;;
+    *:GNU:*:*)
+       # the GNU system
+       echo `echo ${UNAME_MACHINE}|sed -e 's,[-/].*$,,'`-unknown-gnu`echo ${UNAME_RELEASE}|sed -e 's,/.*$,,'`
+       exit ;;
+    *:GNU/*:*:*)
+       # other systems with GNU libc and userland
+       echo ${UNAME_MACHINE}-unknown-`echo ${UNAME_SYSTEM} | sed 's,^[^/]*/,,' | tr '[A-Z]' '[a-z]'``echo ${UNAME_RELEASE}|sed -e 's/[-(].*//'`-gnu
+       exit ;;
+    i*86:Minix:*:*)
+       echo ${UNAME_MACHINE}-pc-minix
+       exit ;;
+    arm*:Linux:*:*)
+       echo ${UNAME_MACHINE}-unknown-linux-gnu
+       exit ;;
+    cris:Linux:*:*)
+       echo cris-axis-linux-gnu
+       exit ;;
+    crisv32:Linux:*:*)
+       echo crisv32-axis-linux-gnu
+       exit ;;
+    frv:Linux:*:*)
+       echo frv-unknown-linux-gnu
+       exit ;;
+    ia64:Linux:*:*)
+       echo ${UNAME_MACHINE}-unknown-linux-gnu
+       exit ;;
+    m32r*:Linux:*:*)
+       echo ${UNAME_MACHINE}-unknown-linux-gnu
+       exit ;;
+    m68*:Linux:*:*)
+       echo ${UNAME_MACHINE}-unknown-linux-gnu
+       exit ;;
+    mips:Linux:*:*)
+       eval $set_cc_for_build
+       sed 's/^        //' << EOF >$dummy.c
+       #undef CPU
+       #undef mips
+       #undef mipsel
+       #if defined(__MIPSEL__) || defined(__MIPSEL) || defined(_MIPSEL) || defined(MIPSEL)
+       CPU=mipsel
+       #else
+       #if defined(__MIPSEB__) || defined(__MIPSEB) || defined(_MIPSEB) || defined(MIPSEB)
+       CPU=mips
+       #else
+       CPU=
+       #endif
+       #endif
+EOF
+       eval "`$CC_FOR_BUILD -E $dummy.c 2>/dev/null | sed -n '
+           /^CPU/{
+               s: ::g
+               p
+           }'`"
+       test x"${CPU}" != x && { echo "${CPU}-unknown-linux-gnu"; exit; }
+       ;;
+    mips64:Linux:*:*)
+       eval $set_cc_for_build
+       sed 's/^        //' << EOF >$dummy.c
+       #undef CPU
+       #undef mips64
+       #undef mips64el
+       #if defined(__MIPSEL__) || defined(__MIPSEL) || defined(_MIPSEL) || defined(MIPSEL)
+       CPU=mips64el
+       #else
+       #if defined(__MIPSEB__) || defined(__MIPSEB) || defined(_MIPSEB) || defined(MIPSEB)
+       CPU=mips64
+       #else
+       CPU=
+       #endif
+       #endif
+EOF
+       eval "`$CC_FOR_BUILD -E $dummy.c 2>/dev/null | sed -n '
+           /^CPU/{
+               s: ::g
+               p
+           }'`"
+       test x"${CPU}" != x && { echo "${CPU}-unknown-linux-gnu"; exit; }
+       ;;
+    or32:Linux:*:*)
+       echo or32-unknown-linux-gnu
+       exit ;;
+    ppc:Linux:*:*)
+       echo powerpc-unknown-linux-gnu
+       exit ;;
+    ppc64:Linux:*:*)
+       echo powerpc64-unknown-linux-gnu
+       exit ;;
+    alpha:Linux:*:*)
+       case `sed -n '/^cpu model/s/^.*: \(.*\)/\1/p' < /proc/cpuinfo` in
+         EV5)   UNAME_MACHINE=alphaev5 ;;
+         EV56)  UNAME_MACHINE=alphaev56 ;;
+         PCA56) UNAME_MACHINE=alphapca56 ;;
+         PCA57) UNAME_MACHINE=alphapca56 ;;
+         EV6)   UNAME_MACHINE=alphaev6 ;;
+         EV67)  UNAME_MACHINE=alphaev67 ;;
+         EV68*) UNAME_MACHINE=alphaev68 ;;
+        esac
+       objdump --private-headers /bin/sh | grep ld.so.1 >/dev/null
+       if test "$?" = 0 ; then LIBC="libc1" ; else LIBC="" ; fi
+       echo ${UNAME_MACHINE}-unknown-linux-gnu${LIBC}
+       exit ;;
+    parisc:Linux:*:* | hppa:Linux:*:*)
+       # Look for CPU level
+       case `grep '^cpu[^a-z]*:' /proc/cpuinfo 2>/dev/null | cut -d' ' -f2` in
+         PA7*) echo hppa1.1-unknown-linux-gnu ;;
+         PA8*) echo hppa2.0-unknown-linux-gnu ;;
+         *)    echo hppa-unknown-linux-gnu ;;
+       esac
+       exit ;;
+    parisc64:Linux:*:* | hppa64:Linux:*:*)
+       echo hppa64-unknown-linux-gnu
+       exit ;;
+    s390:Linux:*:* | s390x:Linux:*:*)
+       echo ${UNAME_MACHINE}-ibm-linux
+       exit ;;
+    sh64*:Linux:*:*)
+       echo ${UNAME_MACHINE}-unknown-linux-gnu
+       exit ;;
+    sh*:Linux:*:*)
+       echo ${UNAME_MACHINE}-unknown-linux-gnu
+       exit ;;
+    sparc:Linux:*:* | sparc64:Linux:*:*)
+       echo ${UNAME_MACHINE}-unknown-linux-gnu
+       exit ;;
+    vax:Linux:*:*)
+       echo ${UNAME_MACHINE}-dec-linux-gnu
+       exit ;;
+    x86_64:Linux:*:*)
+       echo x86_64-unknown-linux-gnu
+       exit ;;
+    i*86:Linux:*:*)
+       # The BFD linker knows what the default object file format is, so
+       # first see if it will tell us. cd to the root directory to prevent
+       # problems with other programs or directories called `ld' in the path.
+       # Set LC_ALL=C to ensure ld outputs messages in English.
+       ld_supported_targets=`cd /; LC_ALL=C ld --help 2>&1 \
+                        | sed -ne '/supported targets:/!d
+                                   s/[         ][      ]*/ /g
+                                   s/.*supported targets: *//
+                                   s/ .*//
+                                   p'`
+        case "$ld_supported_targets" in
+         elf32-i386)
+               TENTATIVE="${UNAME_MACHINE}-pc-linux-gnu"
+               ;;
+         a.out-i386-linux)
+               echo "${UNAME_MACHINE}-pc-linux-gnuaout"
+               exit ;;
+         coff-i386)
+               echo "${UNAME_MACHINE}-pc-linux-gnucoff"
+               exit ;;
+         "")
+               # Either a pre-BFD a.out linker (linux-gnuoldld) or
+               # one that does not give us useful --help.
+               echo "${UNAME_MACHINE}-pc-linux-gnuoldld"
+               exit ;;
+       esac
+       # Determine whether the default compiler is a.out or elf
+       eval $set_cc_for_build
+       sed 's/^        //' << EOF >$dummy.c
+       #include <features.h>
+       #ifdef __ELF__
+       # ifdef __GLIBC__
+       #  if __GLIBC__ >= 2
+       LIBC=gnu
+       #  else
+       LIBC=gnulibc1
+       #  endif
+       # else
+       LIBC=gnulibc1
+       # endif
+       #else
+       #if defined(__INTEL_COMPILER) || defined(__PGI) || defined(__sun)
+       LIBC=gnu
+       #else
+       LIBC=gnuaout
+       #endif
+       #endif
+       #ifdef __dietlibc__
+       LIBC=dietlibc
+       #endif
+EOF
+       eval "`$CC_FOR_BUILD -E $dummy.c 2>/dev/null | sed -n '
+           /^LIBC/{
+               s: ::g
+               p
+           }'`"
+       test x"${LIBC}" != x && {
+               echo "${UNAME_MACHINE}-pc-linux-${LIBC}"
+               exit
+       }
+       test x"${TENTATIVE}" != x && { echo "${TENTATIVE}"; exit; }
+       ;;
+    i*86:DYNIX/ptx:4*:*)
+       # ptx 4.0 does uname -s correctly, with DYNIX/ptx in there.
+       # earlier versions are messed up and put the nodename in both
+       # sysname and nodename.
+       echo i386-sequent-sysv4
+       exit ;;
+    i*86:UNIX_SV:4.2MP:2.*)
+        # Unixware is an offshoot of SVR4, but it has its own version
+        # number series starting with 2...
+        # I am not positive that other SVR4 systems won't match this,
+       # I just have to hope.  -- rms.
+        # Use sysv4.2uw... so that sysv4* matches it.
+       echo ${UNAME_MACHINE}-pc-sysv4.2uw${UNAME_VERSION}
+       exit ;;
+    i*86:OS/2:*:*)
+       # If we were able to find `uname', then EMX Unix compatibility
+       # is probably installed.
+       echo ${UNAME_MACHINE}-pc-os2-emx
+       exit ;;
+    i*86:XTS-300:*:STOP)
+       echo ${UNAME_MACHINE}-unknown-stop
+       exit ;;
+    i*86:atheos:*:*)
+       echo ${UNAME_MACHINE}-unknown-atheos
+       exit ;;
+    i*86:syllable:*:*)
+       echo ${UNAME_MACHINE}-pc-syllable
+       exit ;;
+    i*86:LynxOS:2.*:* | i*86:LynxOS:3.[01]*:* | i*86:LynxOS:4.0*:*)
+       echo i386-unknown-lynxos${UNAME_RELEASE}
+       exit ;;
+    i*86:*DOS:*:*)
+       echo ${UNAME_MACHINE}-pc-msdosdjgpp
+       exit ;;
+    i*86:*:4.*:* | i*86:SYSTEM_V:4.*:*)
+       UNAME_REL=`echo ${UNAME_RELEASE} | sed 's/\/MP$//'`
+       if grep Novell /usr/include/link.h >/dev/null 2>/dev/null; then
+               echo ${UNAME_MACHINE}-univel-sysv${UNAME_REL}
+       else
+               echo ${UNAME_MACHINE}-pc-sysv${UNAME_REL}
+       fi
+       exit ;;
+    i*86:*:5:[678]*)
+       # UnixWare 7.x, OpenUNIX and OpenServer 6.
+       case `/bin/uname -X | grep "^Machine"` in
+           *486*)           UNAME_MACHINE=i486 ;;
+           *Pentium)        UNAME_MACHINE=i586 ;;
+           *Pent*|*Celeron) UNAME_MACHINE=i686 ;;
+       esac
+       echo ${UNAME_MACHINE}-unknown-sysv${UNAME_RELEASE}${UNAME_SYSTEM}${UNAME_VERSION}
+       exit ;;
+    i*86:*:3.2:*)
+       if test -f /usr/options/cb.name; then
+               UNAME_REL=`sed -n 's/.*Version //p' </usr/options/cb.name`
+               echo ${UNAME_MACHINE}-pc-isc$UNAME_REL
+       elif /bin/uname -X 2>/dev/null >/dev/null ; then
+               UNAME_REL=`(/bin/uname -X|grep Release|sed -e 's/.*= //')`
+               (/bin/uname -X|grep i80486 >/dev/null) && UNAME_MACHINE=i486
+               (/bin/uname -X|grep '^Machine.*Pentium' >/dev/null) \
+                       && UNAME_MACHINE=i586
+               (/bin/uname -X|grep '^Machine.*Pent *II' >/dev/null) \
+                       && UNAME_MACHINE=i686
+               (/bin/uname -X|grep '^Machine.*Pentium Pro' >/dev/null) \
+                       && UNAME_MACHINE=i686
+               echo ${UNAME_MACHINE}-pc-sco$UNAME_REL
+       else
+               echo ${UNAME_MACHINE}-pc-sysv32
+       fi
+       exit ;;
+    pc:*:*:*)
+       # Left here for compatibility:
+        # uname -m prints for DJGPP always 'pc', but it prints nothing about
+        # the processor, so we play safe by assuming i386.
+       echo i386-pc-msdosdjgpp
+        exit ;;
+    Intel:Mach:3*:*)
+       echo i386-pc-mach3
+       exit ;;
+    paragon:*:*:*)
+       echo i860-intel-osf1
+       exit ;;
+    i860:*:4.*:*) # i860-SVR4
+       if grep Stardent /usr/include/sys/uadmin.h >/dev/null 2>&1 ; then
+         echo i860-stardent-sysv${UNAME_RELEASE} # Stardent Vistra i860-SVR4
+       else # Add other i860-SVR4 vendors below as they are discovered.
+         echo i860-unknown-sysv${UNAME_RELEASE}  # Unknown i860-SVR4
+       fi
+       exit ;;
+    mini*:CTIX:SYS*5:*)
+       # "miniframe"
+       echo m68010-convergent-sysv
+       exit ;;
+    mc68k:UNIX:SYSTEM5:3.51m)
+       echo m68k-convergent-sysv
+       exit ;;
+    M680?0:D-NIX:5.3:*)
+       echo m68k-diab-dnix
+       exit ;;
+    M68*:*:R3V[5678]*:*)
+       test -r /sysV68 && { echo 'm68k-motorola-sysv'; exit; } ;;
+    3[345]??:*:4.0:3.0 | 3[34]??A:*:4.0:3.0 | 3[34]??,*:*:4.0:3.0 | 3[34]??/*:*:4.0:3.0 | 4400:*:4.0:3.0 | 4850:*:4.0:3.0 | SKA40:*:4.0:3.0 | SDS2:*:4.0:3.0 | SHG2:*:4.0:3.0 | S7501*:*:4.0:3.0)
+       OS_REL=''
+       test -r /etc/.relid \
+       && OS_REL=.`sed -n 's/[^ ]* [^ ]* \([0-9][0-9]\).*/\1/p' < /etc/.relid`
+       /bin/uname -p 2>/dev/null | grep 86 >/dev/null \
+         && { echo i486-ncr-sysv4.3${OS_REL}; exit; }
+       /bin/uname -p 2>/dev/null | /bin/grep entium >/dev/null \
+         && { echo i586-ncr-sysv4.3${OS_REL}; exit; } ;;
+    3[34]??:*:4.0:* | 3[34]??,*:*:4.0:*)
+        /bin/uname -p 2>/dev/null | grep 86 >/dev/null \
+          && { echo i486-ncr-sysv4; exit; } ;;
+    m68*:LynxOS:2.*:* | m68*:LynxOS:3.0*:*)
+       echo m68k-unknown-lynxos${UNAME_RELEASE}
+       exit ;;
+    mc68030:UNIX_System_V:4.*:*)
+       echo m68k-atari-sysv4
+       exit ;;
+    TSUNAMI:LynxOS:2.*:*)
+       echo sparc-unknown-lynxos${UNAME_RELEASE}
+       exit ;;
+    rs6000:LynxOS:2.*:*)
+       echo rs6000-unknown-lynxos${UNAME_RELEASE}
+       exit ;;
+    PowerPC:LynxOS:2.*:* | PowerPC:LynxOS:3.[01]*:* | PowerPC:LynxOS:4.0*:*)
+       echo powerpc-unknown-lynxos${UNAME_RELEASE}
+       exit ;;
+    SM[BE]S:UNIX_SV:*:*)
+       echo mips-dde-sysv${UNAME_RELEASE}
+       exit ;;
+    RM*:ReliantUNIX-*:*:*)
+       echo mips-sni-sysv4
+       exit ;;
+    RM*:SINIX-*:*:*)
+       echo mips-sni-sysv4
+       exit ;;
+    *:SINIX-*:*:*)
+       if uname -p 2>/dev/null >/dev/null ; then
+               UNAME_MACHINE=`(uname -p) 2>/dev/null`
+               echo ${UNAME_MACHINE}-sni-sysv4
+       else
+               echo ns32k-sni-sysv
+       fi
+       exit ;;
+    PENTIUM:*:4.0*:*) # Unisys `ClearPath HMP IX 4000' SVR4/MP effort
+                      # says <Richard.M.Bartel@ccMail.Census.GOV>
+        echo i586-unisys-sysv4
+        exit ;;
+    *:UNIX_System_V:4*:FTX*)
+       # From Gerald Hewes <hewes@openmarket.com>.
+       # How about differentiating between stratus architectures? -djm
+       echo hppa1.1-stratus-sysv4
+       exit ;;
+    *:*:*:FTX*)
+       # From seanf@swdc.stratus.com.
+       echo i860-stratus-sysv4
+       exit ;;
+    i*86:VOS:*:*)
+       # From Paul.Green@stratus.com.
+       echo ${UNAME_MACHINE}-stratus-vos
+       exit ;;
+    *:VOS:*:*)
+       # From Paul.Green@stratus.com.
+       echo hppa1.1-stratus-vos
+       exit ;;
+    mc68*:A/UX:*:*)
+       echo m68k-apple-aux${UNAME_RELEASE}
+       exit ;;
+    news*:NEWS-OS:6*:*)
+       echo mips-sony-newsos6
+       exit ;;
+    R[34]000:*System_V*:*:* | R4000:UNIX_SYSV:*:* | R*000:UNIX_SV:*:*)
+       if [ -d /usr/nec ]; then
+               echo mips-nec-sysv${UNAME_RELEASE}
+       else
+               echo mips-unknown-sysv${UNAME_RELEASE}
+       fi
+        exit ;;
+    BeBox:BeOS:*:*)    # BeOS running on hardware made by Be, PPC only.
+       echo powerpc-be-beos
+       exit ;;
+    BeMac:BeOS:*:*)    # BeOS running on Mac or Mac clone, PPC only.
+       echo powerpc-apple-beos
+       exit ;;
+    BePC:BeOS:*:*)     # BeOS running on Intel PC compatible.
+       echo i586-pc-beos
+       exit ;;
+    SX-4:SUPER-UX:*:*)
+       echo sx4-nec-superux${UNAME_RELEASE}
+       exit ;;
+    SX-5:SUPER-UX:*:*)
+       echo sx5-nec-superux${UNAME_RELEASE}
+       exit ;;
+    SX-6:SUPER-UX:*:*)
+       echo sx6-nec-superux${UNAME_RELEASE}
+       exit ;;
+    Power*:Rhapsody:*:*)
+       echo powerpc-apple-rhapsody${UNAME_RELEASE}
+       exit ;;
+    *:Rhapsody:*:*)
+       echo ${UNAME_MACHINE}-apple-rhapsody${UNAME_RELEASE}
+       exit ;;
+    *:Darwin:*:*)
+       UNAME_PROCESSOR=`uname -p` || UNAME_PROCESSOR=unknown
+       case $UNAME_PROCESSOR in
+           unknown) UNAME_PROCESSOR=powerpc ;;
+       esac
+       echo ${UNAME_PROCESSOR}-apple-darwin${UNAME_RELEASE}
+       exit ;;
+    *:procnto*:*:* | *:QNX:[0123456789]*:*)
+       UNAME_PROCESSOR=`uname -p`
+       if test "$UNAME_PROCESSOR" = "x86"; then
+               UNAME_PROCESSOR=i386
+               UNAME_MACHINE=pc
+       fi
+       echo ${UNAME_PROCESSOR}-${UNAME_MACHINE}-nto-qnx${UNAME_RELEASE}
+       exit ;;
+    *:QNX:*:4*)
+       echo i386-pc-qnx
+       exit ;;
+    NSE-?:NONSTOP_KERNEL:*:*)
+       echo nse-tandem-nsk${UNAME_RELEASE}
+       exit ;;
+    NSR-?:NONSTOP_KERNEL:*:*)
+       echo nsr-tandem-nsk${UNAME_RELEASE}
+       exit ;;
+    *:NonStop-UX:*:*)
+       echo mips-compaq-nonstopux
+       exit ;;
+    BS2000:POSIX*:*:*)
+       echo bs2000-siemens-sysv
+       exit ;;
+    DS/*:UNIX_System_V:*:*)
+       echo ${UNAME_MACHINE}-${UNAME_SYSTEM}-${UNAME_RELEASE}
+       exit ;;
+    *:Plan9:*:*)
+       # "uname -m" is not consistent, so use $cputype instead. 386
+       # is converted to i386 for consistency with other x86
+       # operating systems.
+       if test "$cputype" = "386"; then
+           UNAME_MACHINE=i386
+       else
+           UNAME_MACHINE="$cputype"
+       fi
+       echo ${UNAME_MACHINE}-unknown-plan9
+       exit ;;
+    *:TOPS-10:*:*)
+       echo pdp10-unknown-tops10
+       exit ;;
+    *:TENEX:*:*)
+       echo pdp10-unknown-tenex
+       exit ;;
+    KS10:TOPS-20:*:* | KL10:TOPS-20:*:* | TYPE4:TOPS-20:*:*)
+       echo pdp10-dec-tops20
+       exit ;;
+    XKL-1:TOPS-20:*:* | TYPE5:TOPS-20:*:*)
+       echo pdp10-xkl-tops20
+       exit ;;
+    *:TOPS-20:*:*)
+       echo pdp10-unknown-tops20
+       exit ;;
+    *:ITS:*:*)
+       echo pdp10-unknown-its
+       exit ;;
+    SEI:*:*:SEIUX)
+        echo mips-sei-seiux${UNAME_RELEASE}
+       exit ;;
+    *:DragonFly:*:*)
+       echo ${UNAME_MACHINE}-unknown-dragonfly`echo ${UNAME_RELEASE}|sed -e 's/[-(].*//'`
+       exit ;;
+    *:*VMS:*:*)
+       UNAME_MACHINE=`(uname -p) 2>/dev/null`
+       case "${UNAME_MACHINE}" in
+           A*) echo alpha-dec-vms ; exit ;;
+           I*) echo ia64-dec-vms ; exit ;;
+           V*) echo vax-dec-vms ; exit ;;
+       esac ;;
+    *:XENIX:*:SysV)
+       echo i386-pc-xenix
+       exit ;;
+    i*86:skyos:*:*)
+       echo ${UNAME_MACHINE}-pc-skyos`echo ${UNAME_RELEASE}` | sed -e 's/ .*$//'
+       exit ;;
+    i*86:rdos:*:*)
+       echo ${UNAME_MACHINE}-pc-rdos
+       exit ;;
+esac
+
+#echo '(No uname command or uname output not recognized.)' 1>&2
+#echo "${UNAME_MACHINE}:${UNAME_SYSTEM}:${UNAME_RELEASE}:${UNAME_VERSION}" 1>&2
+
+eval $set_cc_for_build
+cat >$dummy.c <<EOF
+#ifdef _SEQUENT_
+# include <sys/types.h>
+# include <sys/utsname.h>
+#endif
+main ()
+{
+#if defined (sony)
+#if defined (MIPSEB)
+  /* BFD wants "bsd" instead of "newsos".  Perhaps BFD should be changed,
+     I don't know....  */
+  printf ("mips-sony-bsd\n"); exit (0);
+#else
+#include <sys/param.h>
+  printf ("m68k-sony-newsos%s\n",
+#ifdef NEWSOS4
+          "4"
+#else
+         ""
+#endif
+         ); exit (0);
+#endif
+#endif
+
+#if defined (__arm) && defined (__acorn) && defined (__unix)
+  printf ("arm-acorn-riscix\n"); exit (0);
+#endif
+
+#if defined (hp300) && !defined (hpux)
+  printf ("m68k-hp-bsd\n"); exit (0);
+#endif
+
+#if defined (NeXT)
+#if !defined (__ARCHITECTURE__)
+#define __ARCHITECTURE__ "m68k"
+#endif
+  int version;
+  version=`(hostinfo | sed -n 's/.*NeXT Mach \([0-9]*\).*/\1/p') 2>/dev/null`;
+  if (version < 4)
+    printf ("%s-next-nextstep%d\n", __ARCHITECTURE__, version);
+  else
+    printf ("%s-next-openstep%d\n", __ARCHITECTURE__, version);
+  exit (0);
+#endif
+
+#if defined (MULTIMAX) || defined (n16)
+#if defined (UMAXV)
+  printf ("ns32k-encore-sysv\n"); exit (0);
+#else
+#if defined (CMU)
+  printf ("ns32k-encore-mach\n"); exit (0);
+#else
+  printf ("ns32k-encore-bsd\n"); exit (0);
+#endif
+#endif
+#endif
+
+#if defined (__386BSD__)
+  printf ("i386-pc-bsd\n"); exit (0);
+#endif
+
+#if defined (sequent)
+#if defined (i386)
+  printf ("i386-sequent-dynix\n"); exit (0);
+#endif
+#if defined (ns32000)
+  printf ("ns32k-sequent-dynix\n"); exit (0);
+#endif
+#endif
+
+#if defined (_SEQUENT_)
+    struct utsname un;
+
+    uname(&un);
+
+    if (strncmp(un.version, "V2", 2) == 0) {
+       printf ("i386-sequent-ptx2\n"); exit (0);
+    }
+    if (strncmp(un.version, "V1", 2) == 0) { /* XXX is V1 correct? */
+       printf ("i386-sequent-ptx1\n"); exit (0);
+    }
+    printf ("i386-sequent-ptx\n"); exit (0);
+
+#endif
+
+#if defined (vax)
+# if !defined (ultrix)
+#  include <sys/param.h>
+#  if defined (BSD)
+#   if BSD == 43
+      printf ("vax-dec-bsd4.3\n"); exit (0);
+#   else
+#    if BSD == 199006
+      printf ("vax-dec-bsd4.3reno\n"); exit (0);
+#    else
+      printf ("vax-dec-bsd\n"); exit (0);
+#    endif
+#   endif
+#  else
+    printf ("vax-dec-bsd\n"); exit (0);
+#  endif
+# else
+    printf ("vax-dec-ultrix\n"); exit (0);
+# endif
+#endif
+
+#if defined (alliant) && defined (i860)
+  printf ("i860-alliant-bsd\n"); exit (0);
+#endif
+
+  exit (1);
+}
+EOF
+
+$CC_FOR_BUILD -o $dummy $dummy.c 2>/dev/null && SYSTEM_NAME=`$dummy` &&
+       { echo "$SYSTEM_NAME"; exit; }
+
+# Apollos put the system type in the environment.
+
+test -d /usr/apollo && { echo ${ISP}-apollo-${SYSTYPE}; exit; }
+
+# Convex versions that predate uname can use getsysinfo(1)
+
+if [ -x /usr/convex/getsysinfo ]
+then
+    case `getsysinfo -f cpu_type` in
+    c1*)
+       echo c1-convex-bsd
+       exit ;;
+    c2*)
+       if getsysinfo -f scalar_acc
+       then echo c32-convex-bsd
+       else echo c2-convex-bsd
+       fi
+       exit ;;
+    c34*)
+       echo c34-convex-bsd
+       exit ;;
+    c38*)
+       echo c38-convex-bsd
+       exit ;;
+    c4*)
+       echo c4-convex-bsd
+       exit ;;
+    esac
+fi
+
+cat >&2 <<EOF
+$0: unable to guess system type
+
+This script, last modified $timestamp, has failed to recognize
+the operating system you are using. It is advised that you
+download the most up to date version of the config scripts from
+
+  http://savannah.gnu.org/cgi-bin/viewcvs/*checkout*/config/config/config.guess
+and
+  http://savannah.gnu.org/cgi-bin/viewcvs/*checkout*/config/config/config.sub
+
+If the version you run ($0) is already up to date, please
+send the following data and any information you think might be
+pertinent to <config-patches@gnu.org> in order to provide the needed
+information to handle your system.
+
+config.guess timestamp = $timestamp
+
+uname -m = `(uname -m) 2>/dev/null || echo unknown`
+uname -r = `(uname -r) 2>/dev/null || echo unknown`
+uname -s = `(uname -s) 2>/dev/null || echo unknown`
+uname -v = `(uname -v) 2>/dev/null || echo unknown`
+
+/usr/bin/uname -p = `(/usr/bin/uname -p) 2>/dev/null`
+/bin/uname -X     = `(/bin/uname -X) 2>/dev/null`
+
+hostinfo               = `(hostinfo) 2>/dev/null`
+/bin/universe          = `(/bin/universe) 2>/dev/null`
+/usr/bin/arch -k       = `(/usr/bin/arch -k) 2>/dev/null`
+/bin/arch              = `(/bin/arch) 2>/dev/null`
+/usr/bin/oslevel       = `(/usr/bin/oslevel) 2>/dev/null`
+/usr/convex/getsysinfo = `(/usr/convex/getsysinfo) 2>/dev/null`
+
+UNAME_MACHINE = ${UNAME_MACHINE}
+UNAME_RELEASE = ${UNAME_RELEASE}
+UNAME_SYSTEM  = ${UNAME_SYSTEM}
+UNAME_VERSION = ${UNAME_VERSION}
+EOF
+
+exit 1
+
+# Local variables:
+# eval: (add-hook 'write-file-hooks 'time-stamp)
+# time-stamp-start: "timestamp='"
+# time-stamp-format: "%:y-%02m-%02d"
+# time-stamp-end: "'"
+# End:
diff --git a/libs/libsndfile/config.sub b/libs/libsndfile/config.sub
new file mode 100755 (executable)
index 0000000..ad9f395
--- /dev/null
@@ -0,0 +1,1608 @@
+#! /bin/sh
+# Configuration validation subroutine script.
+#   Copyright (C) 1992, 1993, 1994, 1995, 1996, 1997, 1998, 1999,
+#   2000, 2001, 2002, 2003, 2004, 2005 Free Software Foundation, Inc.
+
+timestamp='2006-02-23'
+
+# This file is (in principle) common to ALL GNU software.
+# The presence of a machine in this file suggests that SOME GNU software
+# can handle that machine.  It does not imply ALL GNU software can.
+#
+# This file is free software; you can redistribute it and/or modify
+# it under the terms of the GNU General Public License as published by
+# the Free Software Foundation; either version 2 of the License, or
+# (at your option) any later version.
+#
+# This program is distributed in the hope that it will be useful,
+# but WITHOUT ANY WARRANTY; without even the implied warranty of
+# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+# GNU General Public License for more details.
+#
+# You should have received a copy of the GNU General Public License
+# along with this program; if not, write to the Free Software
+# Foundation, Inc., 51 Franklin Street - Fifth Floor, Boston, MA
+# 02110-1301, USA.
+#
+# As a special exception to the GNU General Public License, if you
+# distribute this file as part of a program that contains a
+# configuration script generated by Autoconf, you may include it under
+# the same distribution terms that you use for the rest of that program.
+
+
+# Please send patches to <config-patches@gnu.org>.  Submit a context
+# diff and a properly formatted ChangeLog entry.
+#
+# Configuration subroutine to validate and canonicalize a configuration type.
+# Supply the specified configuration type as an argument.
+# If it is invalid, we print an error message on stderr and exit with code 1.
+# Otherwise, we print the canonical config type on stdout and succeed.
+
+# This file is supposed to be the same for all GNU packages
+# and recognize all the CPU types, system types and aliases
+# that are meaningful with *any* GNU software.
+# Each package is responsible for reporting which valid configurations
+# it does not support.  The user should be able to distinguish
+# a failure to support a valid configuration from a meaningless
+# configuration.
+
+# The goal of this file is to map all the various variations of a given
+# machine specification into a single specification in the form:
+#      CPU_TYPE-MANUFACTURER-OPERATING_SYSTEM
+# or in some cases, the newer four-part form:
+#      CPU_TYPE-MANUFACTURER-KERNEL-OPERATING_SYSTEM
+# It is wrong to echo any other type of specification.
+
+me=`echo "$0" | sed -e 's,.*/,,'`
+
+usage="\
+Usage: $0 [OPTION] CPU-MFR-OPSYS
+       $0 [OPTION] ALIAS
+
+Canonicalize a configuration name.
+
+Operation modes:
+  -h, --help         print this help, then exit
+  -t, --time-stamp   print date of last modification, then exit
+  -v, --version      print version number, then exit
+
+Report bugs and patches to <config-patches@gnu.org>."
+
+version="\
+GNU config.sub ($timestamp)
+
+Copyright (C) 1992, 1993, 1994, 1995, 1996, 1997, 1998, 1999, 2000, 2001, 2002, 2003, 2004, 2005
+Free Software Foundation, Inc.
+
+This is free software; see the source for copying conditions.  There is NO
+warranty; not even for MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE."
+
+help="
+Try \`$me --help' for more information."
+
+# Parse command line
+while test $# -gt 0 ; do
+  case $1 in
+    --time-stamp | --time* | -t )
+       echo "$timestamp" ; exit ;;
+    --version | -v )
+       echo "$version" ; exit ;;
+    --help | --h* | -h )
+       echo "$usage"; exit ;;
+    -- )     # Stop option processing
+       shift; break ;;
+    - )        # Use stdin as input.
+       break ;;
+    -* )
+       echo "$me: invalid option $1$help"
+       exit 1 ;;
+
+    *local*)
+       # First pass through any local machine types.
+       echo $1
+       exit ;;
+
+    * )
+       break ;;
+  esac
+done
+
+case $# in
+ 0) echo "$me: missing argument$help" >&2
+    exit 1;;
+ 1) ;;
+ *) echo "$me: too many arguments$help" >&2
+    exit 1;;
+esac
+
+# Separate what the user gave into CPU-COMPANY and OS or KERNEL-OS (if any).
+# Here we must recognize all the valid KERNEL-OS combinations.
+maybe_os=`echo $1 | sed 's/^\(.*\)-\([^-]*-[^-]*\)$/\2/'`
+case $maybe_os in
+  nto-qnx* | linux-gnu* | linux-dietlibc | linux-newlib* | linux-uclibc* | \
+  uclinux-uclibc* | uclinux-gnu* | kfreebsd*-gnu* | knetbsd*-gnu* | netbsd*-gnu* | \
+  storm-chaos* | os2-emx* | rtmk-nova*)
+    os=-$maybe_os
+    basic_machine=`echo $1 | sed 's/^\(.*\)-\([^-]*-[^-]*\)$/\1/'`
+    ;;
+  *)
+    basic_machine=`echo $1 | sed 's/-[^-]*$//'`
+    if [ $basic_machine != $1 ]
+    then os=`echo $1 | sed 's/.*-/-/'`
+    else os=; fi
+    ;;
+esac
+
+### Let's recognize common machines as not being operating systems so
+### that things like config.sub decstation-3100 work.  We also
+### recognize some manufacturers as not being operating systems, so we
+### can provide default operating systems below.
+case $os in
+       -sun*os*)
+               # Prevent following clause from handling this invalid input.
+               ;;
+       -dec* | -mips* | -sequent* | -encore* | -pc532* | -sgi* | -sony* | \
+       -att* | -7300* | -3300* | -delta* | -motorola* | -sun[234]* | \
+       -unicom* | -ibm* | -next | -hp | -isi* | -apollo | -altos* | \
+       -convergent* | -ncr* | -news | -32* | -3600* | -3100* | -hitachi* |\
+       -c[123]* | -convex* | -sun | -crds | -omron* | -dg | -ultra | -tti* | \
+       -harris | -dolphin | -highlevel | -gould | -cbm | -ns | -masscomp | \
+       -apple | -axis | -knuth | -cray)
+               os=
+               basic_machine=$1
+               ;;
+       -sim | -cisco | -oki | -wec | -winbond)
+               os=
+               basic_machine=$1
+               ;;
+       -scout)
+               ;;
+       -wrs)
+               os=-vxworks
+               basic_machine=$1
+               ;;
+       -chorusos*)
+               os=-chorusos
+               basic_machine=$1
+               ;;
+       -chorusrdb)
+               os=-chorusrdb
+               basic_machine=$1
+               ;;
+       -hiux*)
+               os=-hiuxwe2
+               ;;
+       -sco6)
+               os=-sco5v6
+               basic_machine=`echo $1 | sed -e 's/86-.*/86-pc/'`
+               ;;
+       -sco5)
+               os=-sco3.2v5
+               basic_machine=`echo $1 | sed -e 's/86-.*/86-pc/'`
+               ;;
+       -sco4)
+               os=-sco3.2v4
+               basic_machine=`echo $1 | sed -e 's/86-.*/86-pc/'`
+               ;;
+       -sco3.2.[4-9]*)
+               os=`echo $os | sed -e 's/sco3.2./sco3.2v/'`
+               basic_machine=`echo $1 | sed -e 's/86-.*/86-pc/'`
+               ;;
+       -sco3.2v[4-9]*)
+               # Don't forget version if it is 3.2v4 or newer.
+               basic_machine=`echo $1 | sed -e 's/86-.*/86-pc/'`
+               ;;
+       -sco5v6*)
+               # Don't forget version if it is 3.2v4 or newer.
+               basic_machine=`echo $1 | sed -e 's/86-.*/86-pc/'`
+               ;;
+       -sco*)
+               os=-sco3.2v2
+               basic_machine=`echo $1 | sed -e 's/86-.*/86-pc/'`
+               ;;
+       -udk*)
+               basic_machine=`echo $1 | sed -e 's/86-.*/86-pc/'`
+               ;;
+       -isc)
+               os=-isc2.2
+               basic_machine=`echo $1 | sed -e 's/86-.*/86-pc/'`
+               ;;
+       -clix*)
+               basic_machine=clipper-intergraph
+               ;;
+       -isc*)
+               basic_machine=`echo $1 | sed -e 's/86-.*/86-pc/'`
+               ;;
+       -lynx*)
+               os=-lynxos
+               ;;
+       -ptx*)
+               basic_machine=`echo $1 | sed -e 's/86-.*/86-sequent/'`
+               ;;
+       -windowsnt*)
+               os=`echo $os | sed -e 's/windowsnt/winnt/'`
+               ;;
+       -psos*)
+               os=-psos
+               ;;
+       -mint | -mint[0-9]*)
+               basic_machine=m68k-atari
+               os=-mint
+               ;;
+esac
+
+# Decode aliases for certain CPU-COMPANY combinations.
+case $basic_machine in
+       # Recognize the basic CPU types without company name.
+       # Some are omitted here because they have special meanings below.
+       1750a | 580 \
+       | a29k \
+       | alpha | alphaev[4-8] | alphaev56 | alphaev6[78] | alphapca5[67] \
+       | alpha64 | alpha64ev[4-8] | alpha64ev56 | alpha64ev6[78] | alpha64pca5[67] \
+       | am33_2.0 \
+       | arc | arm | arm[bl]e | arme[lb] | armv[2345] | armv[345][lb] | avr \
+       | bfin \
+       | c4x | clipper \
+       | d10v | d30v | dlx | dsp16xx \
+       | fr30 | frv \
+       | h8300 | h8500 | hppa | hppa1.[01] | hppa2.0 | hppa2.0[nw] | hppa64 \
+       | i370 | i860 | i960 | ia64 \
+       | ip2k | iq2000 \
+       | m32r | m32rle | m68000 | m68k | m88k | maxq | mb | microblaze | mcore \
+       | mips | mipsbe | mipseb | mipsel | mipsle \
+       | mips16 \
+       | mips64 | mips64el \
+       | mips64vr | mips64vrel \
+       | mips64orion | mips64orionel \
+       | mips64vr4100 | mips64vr4100el \
+       | mips64vr4300 | mips64vr4300el \
+       | mips64vr5000 | mips64vr5000el \
+       | mips64vr5900 | mips64vr5900el \
+       | mipsisa32 | mipsisa32el \
+       | mipsisa32r2 | mipsisa32r2el \
+       | mipsisa64 | mipsisa64el \
+       | mipsisa64r2 | mipsisa64r2el \
+       | mipsisa64sb1 | mipsisa64sb1el \
+       | mipsisa64sr71k | mipsisa64sr71kel \
+       | mipstx39 | mipstx39el \
+       | mn10200 | mn10300 \
+       | mt \
+       | msp430 \
+       | nios | nios2 \
+       | ns16k | ns32k \
+       | or32 \
+       | pdp10 | pdp11 | pj | pjl \
+       | powerpc | powerpc64 | powerpc64le | powerpcle | ppcbe \
+       | pyramid \
+       | sh | sh[1234] | sh[24]a | sh[23]e | sh[34]eb | shbe | shle | sh[1234]le | sh3ele \
+       | sh64 | sh64le \
+       | sparc | sparc64 | sparc64b | sparc86x | sparclet | sparclite \
+       | sparcv8 | sparcv9 | sparcv9b \
+       | strongarm \
+       | tahoe | thumb | tic4x | tic80 | tron \
+       | v850 | v850e \
+       | we32k \
+       | x86 | xscale | xscalee[bl] | xstormy16 | xtensa \
+       | z8k)
+               basic_machine=$basic_machine-unknown
+               ;;
+       m32c)
+               basic_machine=$basic_machine-unknown
+               ;;
+       m6811 | m68hc11 | m6812 | m68hc12)
+               # Motorola 68HC11/12.
+               basic_machine=$basic_machine-unknown
+               os=-none
+               ;;
+       m88110 | m680[12346]0 | m683?2 | m68360 | m5200 | v70 | w65 | z8k)
+               ;;
+       ms1)
+               basic_machine=mt-unknown
+               ;;
+
+       # We use `pc' rather than `unknown'
+       # because (1) that's what they normally are, and
+       # (2) the word "unknown" tends to confuse beginning users.
+       i*86 | x86_64)
+         basic_machine=$basic_machine-pc
+         ;;
+       # Object if more than one company name word.
+       *-*-*)
+               echo Invalid configuration \`$1\': machine \`$basic_machine\' not recognized 1>&2
+               exit 1
+               ;;
+       # Recognize the basic CPU types with company name.
+       580-* \
+       | a29k-* \
+       | alpha-* | alphaev[4-8]-* | alphaev56-* | alphaev6[78]-* \
+       | alpha64-* | alpha64ev[4-8]-* | alpha64ev56-* | alpha64ev6[78]-* \
+       | alphapca5[67]-* | alpha64pca5[67]-* | arc-* \
+       | arm-*  | armbe-* | armle-* | armeb-* | armv*-* \
+       | avr-* \
+       | bfin-* | bs2000-* \
+       | c[123]* | c30-* | [cjt]90-* | c4x-* | c54x-* | c55x-* | c6x-* \
+       | clipper-* | craynv-* | cydra-* \
+       | d10v-* | d30v-* | dlx-* \
+       | elxsi-* \
+       | f30[01]-* | f700-* | fr30-* | frv-* | fx80-* \
+       | h8300-* | h8500-* \
+       | hppa-* | hppa1.[01]-* | hppa2.0-* | hppa2.0[nw]-* | hppa64-* \
+       | i*86-* | i860-* | i960-* | ia64-* \
+       | ip2k-* | iq2000-* \
+       | m32r-* | m32rle-* \
+       | m68000-* | m680[012346]0-* | m68360-* | m683?2-* | m68k-* \
+       | m88110-* | m88k-* | maxq-* | mcore-* \
+       | mips-* | mipsbe-* | mipseb-* | mipsel-* | mipsle-* \
+       | mips16-* \
+       | mips64-* | mips64el-* \
+       | mips64vr-* | mips64vrel-* \
+       | mips64orion-* | mips64orionel-* \
+       | mips64vr4100-* | mips64vr4100el-* \
+       | mips64vr4300-* | mips64vr4300el-* \
+       | mips64vr5000-* | mips64vr5000el-* \
+       | mips64vr5900-* | mips64vr5900el-* \
+       | mipsisa32-* | mipsisa32el-* \
+       | mipsisa32r2-* | mipsisa32r2el-* \
+       | mipsisa64-* | mipsisa64el-* \
+       | mipsisa64r2-* | mipsisa64r2el-* \
+       | mipsisa64sb1-* | mipsisa64sb1el-* \
+       | mipsisa64sr71k-* | mipsisa64sr71kel-* \
+       | mipstx39-* | mipstx39el-* \
+       | mmix-* \
+       | mt-* \
+       | msp430-* \
+       | nios-* | nios2-* \
+       | none-* | np1-* | ns16k-* | ns32k-* \
+       | orion-* \
+       | pdp10-* | pdp11-* | pj-* | pjl-* | pn-* | power-* \
+       | powerpc-* | powerpc64-* | powerpc64le-* | powerpcle-* | ppcbe-* \
+       | pyramid-* \
+       | romp-* | rs6000-* \
+       | sh-* | sh[1234]-* | sh[24]a-* | sh[23]e-* | sh[34]eb-* | shbe-* \
+       | shle-* | sh[1234]le-* | sh3ele-* | sh64-* | sh64le-* \
+       | sparc-* | sparc64-* | sparc64b-* | sparc86x-* | sparclet-* \
+       | sparclite-* \
+       | sparcv8-* | sparcv9-* | sparcv9b-* | strongarm-* | sv1-* | sx?-* \
+       | tahoe-* | thumb-* \
+       | tic30-* | tic4x-* | tic54x-* | tic55x-* | tic6x-* | tic80-* \
+       | tron-* \
+       | v850-* | v850e-* | vax-* \
+       | we32k-* \
+       | x86-* | x86_64-* | xps100-* | xscale-* | xscalee[bl]-* \
+       | xstormy16-* | xtensa-* \
+       | ymp-* \
+       | z8k-*)
+               ;;
+       m32c-*)
+               ;;
+       # Recognize the various machine names and aliases which stand
+       # for a CPU type and a company and sometimes even an OS.
+       386bsd)
+               basic_machine=i386-unknown
+               os=-bsd
+               ;;
+       3b1 | 7300 | 7300-att | att-7300 | pc7300 | safari | unixpc)
+               basic_machine=m68000-att
+               ;;
+       3b*)
+               basic_machine=we32k-att
+               ;;
+       a29khif)
+               basic_machine=a29k-amd
+               os=-udi
+               ;;
+       abacus)
+               basic_machine=abacus-unknown
+               ;;
+       adobe68k)
+               basic_machine=m68010-adobe
+               os=-scout
+               ;;
+       alliant | fx80)
+               basic_machine=fx80-alliant
+               ;;
+       altos | altos3068)
+               basic_machine=m68k-altos
+               ;;
+       am29k)
+               basic_machine=a29k-none
+               os=-bsd
+               ;;
+       amd64)
+               basic_machine=x86_64-pc
+               ;;
+       amd64-*)
+               basic_machine=x86_64-`echo $basic_machine | sed 's/^[^-]*-//'`
+               ;;
+       amdahl)
+               basic_machine=580-amdahl
+               os=-sysv
+               ;;
+       amiga | amiga-*)
+               basic_machine=m68k-unknown
+               ;;
+       amigaos | amigados)
+               basic_machine=m68k-unknown
+               os=-amigaos
+               ;;
+       amigaunix | amix)
+               basic_machine=m68k-unknown
+               os=-sysv4
+               ;;
+       apollo68)
+               basic_machine=m68k-apollo
+               os=-sysv
+               ;;
+       apollo68bsd)
+               basic_machine=m68k-apollo
+               os=-bsd
+               ;;
+       aux)
+               basic_machine=m68k-apple
+               os=-aux
+               ;;
+       balance)
+               basic_machine=ns32k-sequent
+               os=-dynix
+               ;;
+       c90)
+               basic_machine=c90-cray
+               os=-unicos
+               ;;
+       convex-c1)
+               basic_machine=c1-convex
+               os=-bsd
+               ;;
+       convex-c2)
+               basic_machine=c2-convex
+               os=-bsd
+               ;;
+       convex-c32)
+               basic_machine=c32-convex
+               os=-bsd
+               ;;
+       convex-c34)
+               basic_machine=c34-convex
+               os=-bsd
+               ;;
+       convex-c38)
+               basic_machine=c38-convex
+               os=-bsd
+               ;;
+       cray | j90)
+               basic_machine=j90-cray
+               os=-unicos
+               ;;
+       craynv)
+               basic_machine=craynv-cray
+               os=-unicosmp
+               ;;
+       cr16c)
+               basic_machine=cr16c-unknown
+               os=-elf
+               ;;
+       crds | unos)
+               basic_machine=m68k-crds
+               ;;
+       crisv32 | crisv32-* | etraxfs*)
+               basic_machine=crisv32-axis
+               ;;
+       cris | cris-* | etrax*)
+               basic_machine=cris-axis
+               ;;
+       crx)
+               basic_machine=crx-unknown
+               os=-elf
+               ;;
+       da30 | da30-*)
+               basic_machine=m68k-da30
+               ;;
+       decstation | decstation-3100 | pmax | pmax-* | pmin | dec3100 | decstatn)
+               basic_machine=mips-dec
+               ;;
+       decsystem10* | dec10*)
+               basic_machine=pdp10-dec
+               os=-tops10
+               ;;
+       decsystem20* | dec20*)
+               basic_machine=pdp10-dec
+               os=-tops20
+               ;;
+       delta | 3300 | motorola-3300 | motorola-delta \
+             | 3300-motorola | delta-motorola)
+               basic_machine=m68k-motorola
+               ;;
+       delta88)
+               basic_machine=m88k-motorola
+               os=-sysv3
+               ;;
+       djgpp)
+               basic_machine=i586-pc
+               os=-msdosdjgpp
+               ;;
+       dpx20 | dpx20-*)
+               basic_machine=rs6000-bull
+               os=-bosx
+               ;;
+       dpx2* | dpx2*-bull)
+               basic_machine=m68k-bull
+               os=-sysv3
+               ;;
+       ebmon29k)
+               basic_machine=a29k-amd
+               os=-ebmon
+               ;;
+       elxsi)
+               basic_machine=elxsi-elxsi
+               os=-bsd
+               ;;
+       encore | umax | mmax)
+               basic_machine=ns32k-encore
+               ;;
+       es1800 | OSE68k | ose68k | ose | OSE)
+               basic_machine=m68k-ericsson
+               os=-ose
+               ;;
+       fx2800)
+               basic_machine=i860-alliant
+               ;;
+       genix)
+               basic_machine=ns32k-ns
+               ;;
+       gmicro)
+               basic_machine=tron-gmicro
+               os=-sysv
+               ;;
+       go32)
+               basic_machine=i386-pc
+               os=-go32
+               ;;
+       h3050r* | hiux*)
+               basic_machine=hppa1.1-hitachi
+               os=-hiuxwe2
+               ;;
+       h8300hms)
+               basic_machine=h8300-hitachi
+               os=-hms
+               ;;
+       h8300xray)
+               basic_machine=h8300-hitachi
+               os=-xray
+               ;;
+       h8500hms)
+               basic_machine=h8500-hitachi
+               os=-hms
+               ;;
+       harris)
+               basic_machine=m88k-harris
+               os=-sysv3
+               ;;
+       hp300-*)
+               basic_machine=m68k-hp
+               ;;
+       hp300bsd)
+               basic_machine=m68k-hp
+               os=-bsd
+               ;;
+       hp300hpux)
+               basic_machine=m68k-hp
+               os=-hpux
+               ;;
+       hp3k9[0-9][0-9] | hp9[0-9][0-9])
+               basic_machine=hppa1.0-hp
+               ;;
+       hp9k2[0-9][0-9] | hp9k31[0-9])
+               basic_machine=m68000-hp
+               ;;
+       hp9k3[2-9][0-9])
+               basic_machine=m68k-hp
+               ;;
+       hp9k6[0-9][0-9] | hp6[0-9][0-9])
+               basic_machine=hppa1.0-hp
+               ;;
+       hp9k7[0-79][0-9] | hp7[0-79][0-9])
+               basic_machine=hppa1.1-hp
+               ;;
+       hp9k78[0-9] | hp78[0-9])
+               # FIXME: really hppa2.0-hp
+               basic_machine=hppa1.1-hp
+               ;;
+       hp9k8[67]1 | hp8[67]1 | hp9k80[24] | hp80[24] | hp9k8[78]9 | hp8[78]9 | hp9k893 | hp893)
+               # FIXME: really hppa2.0-hp
+               basic_machine=hppa1.1-hp
+               ;;
+       hp9k8[0-9][13679] | hp8[0-9][13679])
+               basic_machine=hppa1.1-hp
+               ;;
+       hp9k8[0-9][0-9] | hp8[0-9][0-9])
+               basic_machine=hppa1.0-hp
+               ;;
+       hppa-next)
+               os=-nextstep3
+               ;;
+       hppaosf)
+               basic_machine=hppa1.1-hp
+               os=-osf
+               ;;
+       hppro)
+               basic_machine=hppa1.1-hp
+               os=-proelf
+               ;;
+       i370-ibm* | ibm*)
+               basic_machine=i370-ibm
+               ;;
+# I'm not sure what "Sysv32" means.  Should this be sysv3.2?
+       i*86v32)
+               basic_machine=`echo $1 | sed -e 's/86.*/86-pc/'`
+               os=-sysv32
+               ;;
+       i*86v4*)
+               basic_machine=`echo $1 | sed -e 's/86.*/86-pc/'`
+               os=-sysv4
+               ;;
+       i*86v)
+               basic_machine=`echo $1 | sed -e 's/86.*/86-pc/'`
+               os=-sysv
+               ;;
+       i*86sol2)
+               basic_machine=`echo $1 | sed -e 's/86.*/86-pc/'`
+               os=-solaris2
+               ;;
+       i386mach)
+               basic_machine=i386-mach
+               os=-mach
+               ;;
+       i386-vsta | vsta)
+               basic_machine=i386-unknown
+               os=-vsta
+               ;;
+       iris | iris4d)
+               basic_machine=mips-sgi
+               case $os in
+                   -irix*)
+                       ;;
+                   *)
+                       os=-irix4
+                       ;;
+               esac
+               ;;
+       isi68 | isi)
+               basic_machine=m68k-isi
+               os=-sysv
+               ;;
+       m88k-omron*)
+               basic_machine=m88k-omron
+               ;;
+       magnum | m3230)
+               basic_machine=mips-mips
+               os=-sysv
+               ;;
+       merlin)
+               basic_machine=ns32k-utek
+               os=-sysv
+               ;;
+       mingw32)
+               basic_machine=i386-pc
+               os=-mingw32
+               ;;
+       miniframe)
+               basic_machine=m68000-convergent
+               ;;
+       *mint | -mint[0-9]* | *MiNT | *MiNT[0-9]*)
+               basic_machine=m68k-atari
+               os=-mint
+               ;;
+       mips3*-*)
+               basic_machine=`echo $basic_machine | sed -e 's/mips3/mips64/'`
+               ;;
+       mips3*)
+               basic_machine=`echo $basic_machine | sed -e 's/mips3/mips64/'`-unknown
+               ;;
+       monitor)
+               basic_machine=m68k-rom68k
+               os=-coff
+               ;;
+       morphos)
+               basic_machine=powerpc-unknown
+               os=-morphos
+               ;;
+       msdos)
+               basic_machine=i386-pc
+               os=-msdos
+               ;;
+       ms1-*)
+               basic_machine=`echo $basic_machine | sed -e 's/ms1-/mt-/'`
+               ;;
+       mvs)
+               basic_machine=i370-ibm
+               os=-mvs
+               ;;
+       ncr3000)
+               basic_machine=i486-ncr
+               os=-sysv4
+               ;;
+       netbsd386)
+               basic_machine=i386-unknown
+               os=-netbsd
+               ;;
+       netwinder)
+               basic_machine=armv4l-rebel
+               os=-linux
+               ;;
+       news | news700 | news800 | news900)
+               basic_machine=m68k-sony
+               os=-newsos
+               ;;
+       news1000)
+               basic_machine=m68030-sony
+               os=-newsos
+               ;;
+       news-3600 | risc-news)
+               basic_machine=mips-sony
+               os=-newsos
+               ;;
+       necv70)
+               basic_machine=v70-nec
+               os=-sysv
+               ;;
+       next | m*-next )
+               basic_machine=m68k-next
+               case $os in
+                   -nextstep* )
+                       ;;
+                   -ns2*)
+                     os=-nextstep2
+                       ;;
+                   *)
+                     os=-nextstep3
+                       ;;
+               esac
+               ;;
+       nh3000)
+               basic_machine=m68k-harris
+               os=-cxux
+               ;;
+       nh[45]000)
+               basic_machine=m88k-harris
+               os=-cxux
+               ;;
+       nindy960)
+               basic_machine=i960-intel
+               os=-nindy
+               ;;
+       mon960)
+               basic_machine=i960-intel
+               os=-mon960
+               ;;
+       nonstopux)
+               basic_machine=mips-compaq
+               os=-nonstopux
+               ;;
+       np1)
+               basic_machine=np1-gould
+               ;;
+       nsr-tandem)
+               basic_machine=nsr-tandem
+               ;;
+       op50n-* | op60c-*)
+               basic_machine=hppa1.1-oki
+               os=-proelf
+               ;;
+       openrisc | openrisc-*)
+               basic_machine=or32-unknown
+               ;;
+       os400)
+               basic_machine=powerpc-ibm
+               os=-os400
+               ;;
+       OSE68000 | ose68000)
+               basic_machine=m68000-ericsson
+               os=-ose
+               ;;
+       os68k)
+               basic_machine=m68k-none
+               os=-os68k
+               ;;
+       pa-hitachi)
+               basic_machine=hppa1.1-hitachi
+               os=-hiuxwe2
+               ;;
+       paragon)
+               basic_machine=i860-intel
+               os=-osf
+               ;;
+       pbd)
+               basic_machine=sparc-tti
+               ;;
+       pbb)
+               basic_machine=m68k-tti
+               ;;
+       pc532 | pc532-*)
+               basic_machine=ns32k-pc532
+               ;;
+       pc98)
+               basic_machine=i386-pc
+               ;;
+       pc98-*)
+               basic_machine=i386-`echo $basic_machine | sed 's/^[^-]*-//'`
+               ;;
+       pentium | p5 | k5 | k6 | nexgen | viac3)
+               basic_machine=i586-pc
+               ;;
+       pentiumpro | p6 | 6x86 | athlon | athlon_*)
+               basic_machine=i686-pc
+               ;;
+       pentiumii | pentium2 | pentiumiii | pentium3)
+               basic_machine=i686-pc
+               ;;
+       pentium4)
+               basic_machine=i786-pc
+               ;;
+       pentium-* | p5-* | k5-* | k6-* | nexgen-* | viac3-*)
+               basic_machine=i586-`echo $basic_machine | sed 's/^[^-]*-//'`
+               ;;
+       pentiumpro-* | p6-* | 6x86-* | athlon-*)
+               basic_machine=i686-`echo $basic_machine | sed 's/^[^-]*-//'`
+               ;;
+       pentiumii-* | pentium2-* | pentiumiii-* | pentium3-*)
+               basic_machine=i686-`echo $basic_machine | sed 's/^[^-]*-//'`
+               ;;
+       pentium4-*)
+               basic_machine=i786-`echo $basic_machine | sed 's/^[^-]*-//'`
+               ;;
+       pn)
+               basic_machine=pn-gould
+               ;;
+       power)  basic_machine=power-ibm
+               ;;
+       ppc)    basic_machine=powerpc-unknown
+               ;;
+       ppc-*)  basic_machine=powerpc-`echo $basic_machine | sed 's/^[^-]*-//'`
+               ;;
+       ppcle | powerpclittle | ppc-le | powerpc-little)
+               basic_machine=powerpcle-unknown
+               ;;
+       ppcle-* | powerpclittle-*)
+               basic_machine=powerpcle-`echo $basic_machine | sed 's/^[^-]*-//'`
+               ;;
+       ppc64)  basic_machine=powerpc64-unknown
+               ;;
+       ppc64-*) basic_machine=powerpc64-`echo $basic_machine | sed 's/^[^-]*-//'`
+               ;;
+       ppc64le | powerpc64little | ppc64-le | powerpc64-little)
+               basic_machine=powerpc64le-unknown
+               ;;
+       ppc64le-* | powerpc64little-*)
+               basic_machine=powerpc64le-`echo $basic_machine | sed 's/^[^-]*-//'`
+               ;;
+       ps2)
+               basic_machine=i386-ibm
+               ;;
+       pw32)
+               basic_machine=i586-unknown
+               os=-pw32
+               ;;
+       rdos)
+               basic_machine=i386-pc
+               os=-rdos
+               ;;
+       rom68k)
+               basic_machine=m68k-rom68k
+               os=-coff
+               ;;
+       rm[46]00)
+               basic_machine=mips-siemens
+               ;;
+       rtpc | rtpc-*)
+               basic_machine=romp-ibm
+               ;;
+       s390 | s390-*)
+               basic_machine=s390-ibm
+               ;;
+       s390x | s390x-*)
+               basic_machine=s390x-ibm
+               ;;
+       sa29200)
+               basic_machine=a29k-amd
+               os=-udi
+               ;;
+       sb1)
+               basic_machine=mipsisa64sb1-unknown
+               ;;
+       sb1el)
+               basic_machine=mipsisa64sb1el-unknown
+               ;;
+       sei)
+               basic_machine=mips-sei
+               os=-seiux
+               ;;
+       sequent)
+               basic_machine=i386-sequent
+               ;;
+       sh)
+               basic_machine=sh-hitachi
+               os=-hms
+               ;;
+       sh64)
+               basic_machine=sh64-unknown
+               ;;
+       sparclite-wrs | simso-wrs)
+               basic_machine=sparclite-wrs
+               os=-vxworks
+               ;;
+       sps7)
+               basic_machine=m68k-bull
+               os=-sysv2
+               ;;
+       spur)
+               basic_machine=spur-unknown
+               ;;
+       st2000)
+               basic_machine=m68k-tandem
+               ;;
+       stratus)
+               basic_machine=i860-stratus
+               os=-sysv4
+               ;;
+       sun2)
+               basic_machine=m68000-sun
+               ;;
+       sun2os3)
+               basic_machine=m68000-sun
+               os=-sunos3
+               ;;
+       sun2os4)
+               basic_machine=m68000-sun
+               os=-sunos4
+               ;;
+       sun3os3)
+               basic_machine=m68k-sun
+               os=-sunos3
+               ;;
+       sun3os4)
+               basic_machine=m68k-sun
+               os=-sunos4
+               ;;
+       sun4os3)
+               basic_machine=sparc-sun
+               os=-sunos3
+               ;;
+       sun4os4)
+               basic_machine=sparc-sun
+               os=-sunos4
+               ;;
+       sun4sol2)
+               basic_machine=sparc-sun
+               os=-solaris2
+               ;;
+       sun3 | sun3-*)
+               basic_machine=m68k-sun
+               ;;
+       sun4)
+               basic_machine=sparc-sun
+               ;;
+       sun386 | sun386i | roadrunner)
+               basic_machine=i386-sun
+               ;;
+       sv1)
+               basic_machine=sv1-cray
+               os=-unicos
+               ;;
+       symmetry)
+               basic_machine=i386-sequent
+               os=-dynix
+               ;;
+       t3e)
+               basic_machine=alphaev5-cray
+               os=-unicos
+               ;;
+       t90)
+               basic_machine=t90-cray
+               os=-unicos
+               ;;
+       tic54x | c54x*)
+               basic_machine=tic54x-unknown
+               os=-coff
+               ;;
+       tic55x | c55x*)
+               basic_machine=tic55x-unknown
+               os=-coff
+               ;;
+       tic6x | c6x*)
+               basic_machine=tic6x-unknown
+               os=-coff
+               ;;
+       tx39)
+               basic_machine=mipstx39-unknown
+               ;;
+       tx39el)
+               basic_machine=mipstx39el-unknown
+               ;;
+       toad1)
+               basic_machine=pdp10-xkl
+               os=-tops20
+               ;;
+       tower | tower-32)
+               basic_machine=m68k-ncr
+               ;;
+       tpf)
+               basic_machine=s390x-ibm
+               os=-tpf
+               ;;
+       udi29k)
+               basic_machine=a29k-amd
+               os=-udi
+               ;;
+       ultra3)
+               basic_machine=a29k-nyu
+               os=-sym1
+               ;;
+       v810 | necv810)
+               basic_machine=v810-nec
+               os=-none
+               ;;
+       vaxv)
+               basic_machine=vax-dec
+               os=-sysv
+               ;;
+       vms)
+               basic_machine=vax-dec
+               os=-vms
+               ;;
+       vpp*|vx|vx-*)
+               basic_machine=f301-fujitsu
+               ;;
+       vxworks960)
+               basic_machine=i960-wrs
+               os=-vxworks
+               ;;
+       vxworks68)
+               basic_machine=m68k-wrs
+               os=-vxworks
+               ;;
+       vxworks29k)
+               basic_machine=a29k-wrs
+               os=-vxworks
+               ;;
+       w65*)
+               basic_machine=w65-wdc
+               os=-none
+               ;;
+       w89k-*)
+               basic_machine=hppa1.1-winbond
+               os=-proelf
+               ;;
+       xbox)
+               basic_machine=i686-pc
+               os=-mingw32
+               ;;
+       xps | xps100)
+               basic_machine=xps100-honeywell
+               ;;
+       ymp)
+               basic_machine=ymp-cray
+               os=-unicos
+               ;;
+       z8k-*-coff)
+               basic_machine=z8k-unknown
+               os=-sim
+               ;;
+       none)
+               basic_machine=none-none
+               os=-none
+               ;;
+
+# Here we handle the default manufacturer of certain CPU types.  It is in
+# some cases the only manufacturer, in others, it is the most popular.
+       w89k)
+               basic_machine=hppa1.1-winbond
+               ;;
+       op50n)
+               basic_machine=hppa1.1-oki
+               ;;
+       op60c)
+               basic_machine=hppa1.1-oki
+               ;;
+       romp)
+               basic_machine=romp-ibm
+               ;;
+       mmix)
+               basic_machine=mmix-knuth
+               ;;
+       rs6000)
+               basic_machine=rs6000-ibm
+               ;;
+       vax)
+               basic_machine=vax-dec
+               ;;
+       pdp10)
+               # there are many clones, so DEC is not a safe bet
+               basic_machine=pdp10-unknown
+               ;;
+       pdp11)
+               basic_machine=pdp11-dec
+               ;;
+       we32k)
+               basic_machine=we32k-att
+               ;;
+       sh[1234] | sh[24]a | sh[34]eb | sh[1234]le | sh[23]ele)
+               basic_machine=sh-unknown
+               ;;
+       sparc | sparcv8 | sparcv9 | sparcv9b)
+               basic_machine=sparc-sun
+               ;;
+       cydra)
+               basic_machine=cydra-cydrome
+               ;;
+       orion)
+               basic_machine=orion-highlevel
+               ;;
+       orion105)
+               basic_machine=clipper-highlevel
+               ;;
+       mac | mpw | mac-mpw)
+               basic_machine=m68k-apple
+               ;;
+       pmac | pmac-mpw)
+               basic_machine=powerpc-apple
+               ;;
+       *-unknown)
+               # Make sure to match an already-canonicalized machine name.
+               ;;
+       *)
+               echo Invalid configuration \`$1\': machine \`$basic_machine\' not recognized 1>&2
+               exit 1
+               ;;
+esac
+
+# Here we canonicalize certain aliases for manufacturers.
+case $basic_machine in
+       *-digital*)
+               basic_machine=`echo $basic_machine | sed 's/digital.*/dec/'`
+               ;;
+       *-commodore*)
+               basic_machine=`echo $basic_machine | sed 's/commodore.*/cbm/'`
+               ;;
+       *)
+               ;;
+esac
+
+# Decode manufacturer-specific aliases for certain operating systems.
+
+if [ x"$os" != x"" ]
+then
+case $os in
+        # First match some system type aliases
+        # that might get confused with valid system types.
+       # -solaris* is a basic system type, with this one exception.
+       -solaris1 | -solaris1.*)
+               os=`echo $os | sed -e 's|solaris1|sunos4|'`
+               ;;
+       -solaris)
+               os=-solaris2
+               ;;
+       -svr4*)
+               os=-sysv4
+               ;;
+       -unixware*)
+               os=-sysv4.2uw
+               ;;
+       -gnu/linux*)
+               os=`echo $os | sed -e 's|gnu/linux|linux-gnu|'`
+               ;;
+       # First accept the basic system types.
+       # The portable systems comes first.
+       # Each alternative MUST END IN A *, to match a version number.
+       # -sysv* is not here because it comes later, after sysvr4.
+       -gnu* | -bsd* | -mach* | -minix* | -genix* | -ultrix* | -irix* \
+             | -*vms* | -sco* | -esix* | -isc* | -aix* | -sunos | -sunos[34]*\
+             | -hpux* | -unos* | -osf* | -luna* | -dgux* | -solaris* | -sym* \
+             | -amigaos* | -amigados* | -msdos* | -newsos* | -unicos* | -aof* \
+             | -aos* \
+             | -nindy* | -vxsim* | -vxworks* | -ebmon* | -hms* | -mvs* \
+             | -clix* | -riscos* | -uniplus* | -iris* | -rtu* | -xenix* \
+             | -hiux* | -386bsd* | -knetbsd* | -mirbsd* | -netbsd* \
+             | -openbsd* | -solidbsd* \
+             | -ekkobsd* | -kfreebsd* | -freebsd* | -riscix* | -lynxos* \
+             | -bosx* | -nextstep* | -cxux* | -aout* | -elf* | -oabi* \
+             | -ptx* | -coff* | -ecoff* | -winnt* | -domain* | -vsta* \
+             | -udi* | -eabi* | -lites* | -ieee* | -go32* | -aux* \
+             | -chorusos* | -chorusrdb* \
+             | -cygwin* | -pe* | -psos* | -moss* | -proelf* | -rtems* \
+             | -mingw32* | -linux-gnu* | -linux-newlib* | -linux-uclibc* \
+             | -uxpv* | -beos* | -mpeix* | -udk* \
+             | -interix* | -uwin* | -mks* | -rhapsody* | -darwin* | -opened* \
+             | -openstep* | -oskit* | -conix* | -pw32* | -nonstopux* \
+             | -storm-chaos* | -tops10* | -tenex* | -tops20* | -its* \
+             | -os2* | -vos* | -palmos* | -uclinux* | -nucleus* \
+             | -morphos* | -superux* | -rtmk* | -rtmk-nova* | -windiss* \
+             | -powermax* | -dnix* | -nx6 | -nx7 | -sei* | -dragonfly* \
+             | -skyos* | -haiku* | -rdos*)
+       # Remember, each alternative MUST END IN *, to match a version number.
+               ;;
+       -qnx*)
+               case $basic_machine in
+                   x86-* | i*86-*)
+                       ;;
+                   *)
+                       os=-nto$os
+                       ;;
+               esac
+               ;;
+       -nto-qnx*)
+               ;;
+       -nto*)
+               os=`echo $os | sed -e 's|nto|nto-qnx|'`
+               ;;
+       -sim | -es1800* | -hms* | -xray | -os68k* | -none* | -v88r* \
+             | -windows* | -osx | -abug | -netware* | -os9* | -beos* | -haiku* \
+             | -macos* | -mpw* | -magic* | -mmixware* | -mon960* | -lnews*)
+               ;;
+       -mac*)
+               os=`echo $os | sed -e 's|mac|macos|'`
+               ;;
+       -linux-dietlibc)
+               os=-linux-dietlibc
+               ;;
+       -linux*)
+               os=`echo $os | sed -e 's|linux|linux-gnu|'`
+               ;;
+       -sunos5*)
+               os=`echo $os | sed -e 's|sunos5|solaris2|'`
+               ;;
+       -sunos6*)
+               os=`echo $os | sed -e 's|sunos6|solaris3|'`
+               ;;
+       -opened*)
+               os=-openedition
+               ;;
+        -os400*)
+               os=-os400
+               ;;
+       -wince*)
+               os=-wince
+               ;;
+       -osfrose*)
+               os=-osfrose
+               ;;
+       -osf*)
+               os=-osf
+               ;;
+       -utek*)
+               os=-bsd
+               ;;
+       -dynix*)
+               os=-bsd
+               ;;
+       -acis*)
+               os=-aos
+               ;;
+       -atheos*)
+               os=-atheos
+               ;;
+       -syllable*)
+               os=-syllable
+               ;;
+       -386bsd)
+               os=-bsd
+               ;;
+       -ctix* | -uts*)
+               os=-sysv
+               ;;
+       -nova*)
+               os=-rtmk-nova
+               ;;
+       -ns2 )
+               os=-nextstep2
+               ;;
+       -nsk*)
+               os=-nsk
+               ;;
+       # Preserve the version number of sinix5.
+       -sinix5.*)
+               os=`echo $os | sed -e 's|sinix|sysv|'`
+               ;;
+       -sinix*)
+               os=-sysv4
+               ;;
+        -tpf*)
+               os=-tpf
+               ;;
+       -triton*)
+               os=-sysv3
+               ;;
+       -oss*)
+               os=-sysv3
+               ;;
+       -svr4)
+               os=-sysv4
+               ;;
+       -svr3)
+               os=-sysv3
+               ;;
+       -sysvr4)
+               os=-sysv4
+               ;;
+       # This must come after -sysvr4.
+       -sysv*)
+               ;;
+       -ose*)
+               os=-ose
+               ;;
+       -es1800*)
+               os=-ose
+               ;;
+       -xenix)
+               os=-xenix
+               ;;
+       -*mint | -mint[0-9]* | -*MiNT | -MiNT[0-9]*)
+               os=-mint
+               ;;
+       -aros*)
+               os=-aros
+               ;;
+       -kaos*)
+               os=-kaos
+               ;;
+       -zvmoe)
+               os=-zvmoe
+               ;;
+       -none)
+               ;;
+       *)
+               # Get rid of the `-' at the beginning of $os.
+               os=`echo $os | sed 's/[^-]*-//'`
+               echo Invalid configuration \`$1\': system \`$os\' not recognized 1>&2
+               exit 1
+               ;;
+esac
+else
+
+# Here we handle the default operating systems that come with various machines.
+# The value should be what the vendor currently ships out the door with their
+# machine or put another way, the most popular os provided with the machine.
+
+# Note that if you're going to try to match "-MANUFACTURER" here (say,
+# "-sun"), then you have to tell the case statement up towards the top
+# that MANUFACTURER isn't an operating system.  Otherwise, code above
+# will signal an error saying that MANUFACTURER isn't an operating
+# system, and we'll never get to this point.
+
+case $basic_machine in
+       *-acorn)
+               os=-riscix1.2
+               ;;
+       arm*-rebel)
+               os=-linux
+               ;;
+       arm*-semi)
+               os=-aout
+               ;;
+    c4x-* | tic4x-*)
+        os=-coff
+        ;;
+       # This must come before the *-dec entry.
+       pdp10-*)
+               os=-tops20
+               ;;
+       pdp11-*)
+               os=-none
+               ;;
+       *-dec | vax-*)
+               os=-ultrix4.2
+               ;;
+       m68*-apollo)
+               os=-domain
+               ;;
+       i386-sun)
+               os=-sunos4.0.2
+               ;;
+       m68000-sun)
+               os=-sunos3
+               # This also exists in the configure program, but was not the
+               # default.
+               # os=-sunos4
+               ;;
+       m68*-cisco)
+               os=-aout
+               ;;
+       mips*-cisco)
+               os=-elf
+               ;;
+       mips*-*)
+               os=-elf
+               ;;
+       or32-*)
+               os=-coff
+               ;;
+       *-tti)  # must be before sparc entry or we get the wrong os.
+               os=-sysv3
+               ;;
+       sparc-* | *-sun)
+               os=-sunos4.1.1
+               ;;
+       *-be)
+               os=-beos
+               ;;
+       *-haiku)
+               os=-haiku
+               ;;
+       *-ibm)
+               os=-aix
+               ;;
+       *-knuth)
+               os=-mmixware
+               ;;
+       *-wec)
+               os=-proelf
+               ;;
+       *-winbond)
+               os=-proelf
+               ;;
+       *-oki)
+               os=-proelf
+               ;;
+       *-hp)
+               os=-hpux
+               ;;
+       *-hitachi)
+               os=-hiux
+               ;;
+       i860-* | *-att | *-ncr | *-altos | *-motorola | *-convergent)
+               os=-sysv
+               ;;
+       *-cbm)
+               os=-amigaos
+               ;;
+       *-dg)
+               os=-dgux
+               ;;
+       *-dolphin)
+               os=-sysv3
+               ;;
+       m68k-ccur)
+               os=-rtu
+               ;;
+       m88k-omron*)
+               os=-luna
+               ;;
+       *-next )
+               os=-nextstep
+               ;;
+       *-sequent)
+               os=-ptx
+               ;;
+       *-crds)
+               os=-unos
+               ;;
+       *-ns)
+               os=-genix
+               ;;
+       i370-*)
+               os=-mvs
+               ;;
+       *-next)
+               os=-nextstep3
+               ;;
+       *-gould)
+               os=-sysv
+               ;;
+       *-highlevel)
+               os=-bsd
+               ;;
+       *-encore)
+               os=-bsd
+               ;;
+       *-sgi)
+               os=-irix
+               ;;
+       *-siemens)
+               os=-sysv4
+               ;;
+       *-masscomp)
+               os=-rtu
+               ;;
+       f30[01]-fujitsu | f700-fujitsu)
+               os=-uxpv
+               ;;
+       *-rom68k)
+               os=-coff
+               ;;
+       *-*bug)
+               os=-coff
+               ;;
+       *-apple)
+               os=-macos
+               ;;
+       *-atari*)
+               os=-mint
+               ;;
+       *)
+               os=-none
+               ;;
+esac
+fi
+
+# Here we handle the case where we know the os, and the CPU type, but not the
+# manufacturer.  We pick the logical manufacturer.
+vendor=unknown
+case $basic_machine in
+       *-unknown)
+               case $os in
+                       -riscix*)
+                               vendor=acorn
+                               ;;
+                       -sunos*)
+                               vendor=sun
+                               ;;
+                       -aix*)
+                               vendor=ibm
+                               ;;
+                       -beos*)
+                               vendor=be
+                               ;;
+                       -hpux*)
+                               vendor=hp
+                               ;;
+                       -mpeix*)
+                               vendor=hp
+                               ;;
+                       -hiux*)
+                               vendor=hitachi
+                               ;;
+                       -unos*)
+                               vendor=crds
+                               ;;
+                       -dgux*)
+                               vendor=dg
+                               ;;
+                       -luna*)
+                               vendor=omron
+                               ;;
+                       -genix*)
+                               vendor=ns
+                               ;;
+                       -mvs* | -opened*)
+                               vendor=ibm
+                               ;;
+                       -os400*)
+                               vendor=ibm
+                               ;;
+                       -ptx*)
+                               vendor=sequent
+                               ;;
+                       -tpf*)
+                               vendor=ibm
+                               ;;
+                       -vxsim* | -vxworks* | -windiss*)
+                               vendor=wrs
+                               ;;
+                       -aux*)
+                               vendor=apple
+                               ;;
+                       -hms*)
+                               vendor=hitachi
+                               ;;
+                       -mpw* | -macos*)
+                               vendor=apple
+                               ;;
+                       -*mint | -mint[0-9]* | -*MiNT | -MiNT[0-9]*)
+                               vendor=atari
+                               ;;
+                       -vos*)
+                               vendor=stratus
+                               ;;
+               esac
+               basic_machine=`echo $basic_machine | sed "s/unknown/$vendor/"`
+               ;;
+esac
+
+echo $basic_machine$os
+exit
+
+# Local variables:
+# eval: (add-hook 'write-file-hooks 'time-stamp)
+# time-stamp-start: "timestamp='"
+# time-stamp-format: "%:y-%02m-%02d"
+# time-stamp-end: "'"
+# End:
diff --git a/libs/libsndfile/configure b/libs/libsndfile/configure
new file mode 100755 (executable)
index 0000000..8aaca4e
--- /dev/null
@@ -0,0 +1,13925 @@
+#! /bin/sh
+# Guess values for system-dependent variables and create Makefiles.
+# Generated by GNU Autoconf 2.59 for libsndfile ardour-special.
+#
+# Report bugs to <ardour@ardour.org>.
+#
+# Copyright (C) 2003 Free Software Foundation, Inc.
+# This configure script is free software; the Free Software Foundation
+# gives unlimited permission to copy, distribute and modify it.
+## --------------------- ##
+## M4sh Initialization.  ##
+## --------------------- ##
+
+# Be Bourne compatible
+if test -n "${ZSH_VERSION+set}" && (emulate sh) >/dev/null 2>&1; then
+  emulate sh
+  NULLCMD=:
+  # Zsh 3.x and 4.x performs word splitting on ${1+"$@"}, which
+  # is contrary to our usage.  Disable this feature.
+  alias -g '${1+"$@"}'='"$@"'
+elif test -n "${BASH_VERSION+set}" && (set -o posix) >/dev/null 2>&1; then
+  set -o posix
+fi
+DUALCASE=1; export DUALCASE # for MKS sh
+
+# Support unset when possible.
+if ( (MAIL=60; unset MAIL) || exit) >/dev/null 2>&1; then
+  as_unset=unset
+else
+  as_unset=false
+fi
+
+
+# Work around bugs in pre-3.0 UWIN ksh.
+$as_unset ENV MAIL MAILPATH
+PS1='$ '
+PS2='> '
+PS4='+ '
+
+# NLS nuisances.
+for as_var in \
+  LANG LANGUAGE LC_ADDRESS LC_ALL LC_COLLATE LC_CTYPE LC_IDENTIFICATION \
+  LC_MEASUREMENT LC_MESSAGES LC_MONETARY LC_NAME LC_NUMERIC LC_PAPER \
+  LC_TELEPHONE LC_TIME
+do
+  if (set +x; test -z "`(eval $as_var=C; export $as_var) 2>&1`"); then
+    eval $as_var=C; export $as_var
+  else
+    $as_unset $as_var
+  fi
+done
+
+# Required to use basename.
+if expr a : '\(a\)' >/dev/null 2>&1; then
+  as_expr=expr
+else
+  as_expr=false
+fi
+
+if (basename /) >/dev/null 2>&1 && test "X`basename / 2>&1`" = "X/"; then
+  as_basename=basename
+else
+  as_basename=false
+fi
+
+
+# Name of the executable.
+as_me=`$as_basename "$0" ||
+$as_expr X/"$0" : '.*/\([^/][^/]*\)/*$' \| \
+        X"$0" : 'X\(//\)$' \| \
+        X"$0" : 'X\(/\)$' \| \
+        .     : '\(.\)' 2>/dev/null ||
+echo X/"$0" |
+    sed '/^.*\/\([^/][^/]*\)\/*$/{ s//\1/; q; }
+         /^X\/\(\/\/\)$/{ s//\1/; q; }
+         /^X\/\(\/\).*/{ s//\1/; q; }
+         s/.*/./; q'`
+
+
+# PATH needs CR, and LINENO needs CR and PATH.
+# Avoid depending upon Character Ranges.
+as_cr_letters='abcdefghijklmnopqrstuvwxyz'
+as_cr_LETTERS='ABCDEFGHIJKLMNOPQRSTUVWXYZ'
+as_cr_Letters=$as_cr_letters$as_cr_LETTERS
+as_cr_digits='0123456789'
+as_cr_alnum=$as_cr_Letters$as_cr_digits
+
+# The user is always right.
+if test "${PATH_SEPARATOR+set}" != set; then
+  echo "#! /bin/sh" >conf$$.sh
+  echo  "exit 0"   >>conf$$.sh
+  chmod +x conf$$.sh
+  if (PATH="/nonexistent;."; conf$$.sh) >/dev/null 2>&1; then
+    PATH_SEPARATOR=';'
+  else
+    PATH_SEPARATOR=:
+  fi
+  rm -f conf$$.sh
+fi
+
+
+  as_lineno_1=$LINENO
+  as_lineno_2=$LINENO
+  as_lineno_3=`(expr $as_lineno_1 + 1) 2>/dev/null`
+  test "x$as_lineno_1" != "x$as_lineno_2" &&
+  test "x$as_lineno_3"  = "x$as_lineno_2"  || {
+  # Find who we are.  Look in the path if we contain no path at all
+  # relative or not.
+  case $0 in
+    *[\\/]* ) as_myself=$0 ;;
+    *) as_save_IFS=$IFS; IFS=$PATH_SEPARATOR
+for as_dir in $PATH
+do
+  IFS=$as_save_IFS
+  test -z "$as_dir" && as_dir=.
+  test -r "$as_dir/$0" && as_myself=$as_dir/$0 && break
+done
+
+       ;;
+  esac
+  # We did not find ourselves, most probably we were run as `sh COMMAND'
+  # in which case we are not to be found in the path.
+  if test "x$as_myself" = x; then
+    as_myself=$0
+  fi
+  if test ! -f "$as_myself"; then
+    { echo "$as_me: error: cannot find myself; rerun with an absolute path" >&2
+   { (exit 1); exit 1; }; }
+  fi
+  case $CONFIG_SHELL in
+  '')
+    as_save_IFS=$IFS; IFS=$PATH_SEPARATOR
+for as_dir in /bin$PATH_SEPARATOR/usr/bin$PATH_SEPARATOR$PATH
+do
+  IFS=$as_save_IFS
+  test -z "$as_dir" && as_dir=.
+  for as_base in sh bash ksh sh5; do
+        case $as_dir in
+        /*)
+          if ("$as_dir/$as_base" -c '
+  as_lineno_1=$LINENO
+  as_lineno_2=$LINENO
+  as_lineno_3=`(expr $as_lineno_1 + 1) 2>/dev/null`
+  test "x$as_lineno_1" != "x$as_lineno_2" &&
+  test "x$as_lineno_3"  = "x$as_lineno_2" ') 2>/dev/null; then
+            $as_unset BASH_ENV || test "${BASH_ENV+set}" != set || { BASH_ENV=; export BASH_ENV; }
+            $as_unset ENV || test "${ENV+set}" != set || { ENV=; export ENV; }
+            CONFIG_SHELL=$as_dir/$as_base
+            export CONFIG_SHELL
+            exec "$CONFIG_SHELL" "$0" ${1+"$@"}
+          fi;;
+        esac
+       done
+done
+;;
+  esac
+
+  # Create $as_me.lineno as a copy of $as_myself, but with $LINENO
+  # uniformly replaced by the line number.  The first 'sed' inserts a
+  # line-number line before each line; the second 'sed' does the real
+  # work.  The second script uses 'N' to pair each line-number line
+  # with the numbered line, and appends trailing '-' during
+  # substitution so that $LINENO is not a special case at line end.
+  # (Raja R Harinath suggested sed '=', and Paul Eggert wrote the
+  # second 'sed' script.  Blame Lee E. McMahon for sed's syntax.  :-)
+  sed '=' <$as_myself |
+    sed '
+      N
+      s,$,-,
+      : loop
+      s,^\(['$as_cr_digits']*\)\(.*\)[$]LINENO\([^'$as_cr_alnum'_]\),\1\2\1\3,
+      t loop
+      s,-$,,
+      s,^['$as_cr_digits']*\n,,
+    ' >$as_me.lineno &&
+  chmod +x $as_me.lineno ||
+    { echo "$as_me: error: cannot create $as_me.lineno; rerun with a POSIX shell" >&2
+   { (exit 1); exit 1; }; }
+
+  # Don't try to exec as it changes $[0], causing all sort of problems
+  # (the dirname of $[0] is not the place where we might find the
+  # original and so on.  Autoconf is especially sensible to this).
+  . ./$as_me.lineno
+  # Exit status is that of the last command.
+  exit
+}
+
+
+case `echo "testing\c"; echo 1,2,3`,`echo -n testing; echo 1,2,3` in
+  *c*,-n*) ECHO_N= ECHO_C='
+' ECHO_T='     ' ;;
+  *c*,*  ) ECHO_N=-n ECHO_C= ECHO_T= ;;
+  *)       ECHO_N= ECHO_C='\c' ECHO_T= ;;
+esac
+
+if expr a : '\(a\)' >/dev/null 2>&1; then
+  as_expr=expr
+else
+  as_expr=false
+fi
+
+rm -f conf$$ conf$$.exe conf$$.file
+echo >conf$$.file
+if ln -s conf$$.file conf$$ 2>/dev/null; then
+  # We could just check for DJGPP; but this test a) works b) is more generic
+  # and c) will remain valid once DJGPP supports symlinks (DJGPP 2.04).
+  if test -f conf$$.exe; then
+    # Don't use ln at all; we don't have any links
+    as_ln_s='cp -p'
+  else
+    as_ln_s='ln -s'
+  fi
+elif ln conf$$.file conf$$ 2>/dev/null; then
+  as_ln_s=ln
+else
+  as_ln_s='cp -p'
+fi
+rm -f conf$$ conf$$.exe conf$$.file
+
+if mkdir -p . 2>/dev/null; then
+  as_mkdir_p=:
+else
+  test -d ./-p && rmdir ./-p
+  as_mkdir_p=false
+fi
+
+as_executable_p="test -f"
+
+# Sed expression to map a string onto a valid CPP name.
+as_tr_cpp="eval sed 'y%*$as_cr_letters%P$as_cr_LETTERS%;s%[^_$as_cr_alnum]%_%g'"
+
+# Sed expression to map a string onto a valid variable name.
+as_tr_sh="eval sed 'y%*+%pp%;s%[^_$as_cr_alnum]%_%g'"
+
+
+# IFS
+# We need space, tab and new line, in precisely that order.
+as_nl='
+'
+IFS="  $as_nl"
+
+# CDPATH.
+$as_unset CDPATH
+
+
+# Name of the host.
+# hostname on some systems (SVR3.2, Linux) returns a bogus exit status,
+# so uname gets run too.
+ac_hostname=`(hostname || uname -n) 2>/dev/null | sed 1q`
+
+exec 6>&1
+
+#
+# Initializations.
+#
+ac_default_prefix=/usr/local
+ac_config_libobj_dir=.
+cross_compiling=no
+subdirs=
+MFLAGS=
+MAKEFLAGS=
+SHELL=${CONFIG_SHELL-/bin/sh}
+
+# Maximum number of lines to put in a shell here document.
+# This variable seems obsolete.  It should probably be removed, and
+# only ac_max_sed_lines should be used.
+: ${ac_max_here_lines=38}
+
+# Identity of this package.
+PACKAGE_NAME='libsndfile'
+PACKAGE_TARNAME='libsndfile'
+PACKAGE_VERSION='ardour-special'
+PACKAGE_STRING='libsndfile ardour-special'
+PACKAGE_BUGREPORT='ardour@ardour.org'
+
+ac_unique_file="src/sndfile.c"
+# Factoring default headers for most tests.
+ac_includes_default="\
+#include <stdio.h>
+#if HAVE_SYS_TYPES_H
+# include <sys/types.h>
+#endif
+#if HAVE_SYS_STAT_H
+# include <sys/stat.h>
+#endif
+#if STDC_HEADERS
+# include <stdlib.h>
+# include <stddef.h>
+#else
+# if HAVE_STDLIB_H
+#  include <stdlib.h>
+# endif
+#endif
+#if HAVE_STRING_H
+# if !STDC_HEADERS && HAVE_MEMORY_H
+#  include <memory.h>
+# endif
+# include <string.h>
+#endif
+#if HAVE_STRINGS_H
+# include <strings.h>
+#endif
+#if HAVE_INTTYPES_H
+# include <inttypes.h>
+#else
+# if HAVE_STDINT_H
+#  include <stdint.h>
+# endif
+#endif
+#if HAVE_UNISTD_H
+# include <unistd.h>
+#endif"
+
+ac_subst_vars='SHELL PATH_SEPARATOR PACKAGE_NAME PACKAGE_TARNAME PACKAGE_VERSION PACKAGE_STRING PACKAGE_BUGREPORT exec_prefix prefix program_transform_name bindir sbindir libexecdir datadir sysconfdir sharedstatedir localstatedir libdir includedir oldincludedir infodir mandir build_alias host_alias target_alias DEFS ECHO_C ECHO_N ECHO_T LIBS build build_cpu build_vendor build_os host host_cpu host_vendor host_os target target_cpu target_vendor target_os CC CFLAGS LDFLAGS CPPFLAGS ac_ct_CC EXEEXT OBJEXT autogen INSTALL_PROGRAM INSTALL_SCRIPT INSTALL_DATA LN_S CPP EGREP GETCONF ac_ct_GETCONF TYPEOF_SF_COUNT_T SIZEOF_SF_COUNT_T SF_COUNT_MAX PKG_CONFIG SQLITE3_CFLAGS SQLITE3_LIBS htmldocdir HTML_BGCOLOUR HTML_FGCOLOUR SHLIB_VERSION_ARG SHARED_VERSION_INFO OS_SPECIFIC_CFLAGS OS_SPECIFIC_LINKS ALSA_LIBS FLAC_LIBS ENABLE_EXPERIMENTAL_CODE COMPILER_IS_GCC GCC_MAJOR_VERSION LIBTOOL_DEPS LIBOBJS LTLIBOBJS'
+ac_subst_files=''
+
+# Initialize some variables set by options.
+ac_init_help=
+ac_init_version=false
+# The variables have the same names as the options, with
+# dashes changed to underlines.
+cache_file=/dev/null
+exec_prefix=NONE
+no_create=
+no_recursion=
+prefix=NONE
+program_prefix=NONE
+program_suffix=NONE
+program_transform_name=s,x,x,
+silent=
+site=
+srcdir=
+verbose=
+x_includes=NONE
+x_libraries=NONE
+
+# Installation directory options.
+# These are left unexpanded so users can "make install exec_prefix=/foo"
+# and all the variables that are supposed to be based on exec_prefix
+# by default will actually change.
+# Use braces instead of parens because sh, perl, etc. also accept them.
+bindir='${exec_prefix}/bin'
+sbindir='${exec_prefix}/sbin'
+libexecdir='${exec_prefix}/libexec'
+datadir='${prefix}/share'
+sysconfdir='${prefix}/etc'
+sharedstatedir='${prefix}/com'
+localstatedir='${prefix}/var'
+libdir='${exec_prefix}/lib'
+includedir='${prefix}/include'
+oldincludedir='/usr/include'
+infodir='${prefix}/info'
+mandir='${prefix}/man'
+
+ac_prev=
+for ac_option
+do
+  # If the previous option needs an argument, assign it.
+  if test -n "$ac_prev"; then
+    eval "$ac_prev=\$ac_option"
+    ac_prev=
+    continue
+  fi
+
+  ac_optarg=`expr "x$ac_option" : 'x[^=]*=\(.*\)'`
+
+  # Accept the important Cygnus configure options, so we can diagnose typos.
+
+  case $ac_option in
+
+  -bindir | --bindir | --bindi | --bind | --bin | --bi)
+    ac_prev=bindir ;;
+  -bindir=* | --bindir=* | --bindi=* | --bind=* | --bin=* | --bi=*)
+    bindir=$ac_optarg ;;
+
+  -build | --build | --buil | --bui | --bu)
+    ac_prev=build_alias ;;
+  -build=* | --build=* | --buil=* | --bui=* | --bu=*)
+    build_alias=$ac_optarg ;;
+
+  -cache-file | --cache-file | --cache-fil | --cache-fi \
+  | --cache-f | --cache- | --cache | --cach | --cac | --ca | --c)
+    ac_prev=cache_file ;;
+  -cache-file=* | --cache-file=* | --cache-fil=* | --cache-fi=* \
+  | --cache-f=* | --cache-=* | --cache=* | --cach=* | --cac=* | --ca=* | --c=*)
+    cache_file=$ac_optarg ;;
+
+  --config-cache | -C)
+    cache_file=config.cache ;;
+
+  -datadir | --datadir | --datadi | --datad | --data | --dat | --da)
+    ac_prev=datadir ;;
+  -datadir=* | --datadir=* | --datadi=* | --datad=* | --data=* | --dat=* \
+  | --da=*)
+    datadir=$ac_optarg ;;
+
+  -disable-* | --disable-*)
+    ac_feature=`expr "x$ac_option" : 'x-*disable-\(.*\)'`
+    # Reject names that are not valid shell variable names.
+    expr "x$ac_feature" : ".*[^-_$as_cr_alnum]" >/dev/null &&
+      { echo "$as_me: error: invalid feature name: $ac_feature" >&2
+   { (exit 1); exit 1; }; }
+    ac_feature=`echo $ac_feature | sed 's/-/_/g'`
+    eval "enable_$ac_feature=no" ;;
+
+  -enable-* | --enable-*)
+    ac_feature=`expr "x$ac_option" : 'x-*enable-\([^=]*\)'`
+    # Reject names that are not valid shell variable names.
+    expr "x$ac_feature" : ".*[^-_$as_cr_alnum]" >/dev/null &&
+      { echo "$as_me: error: invalid feature name: $ac_feature" >&2
+   { (exit 1); exit 1; }; }
+    ac_feature=`echo $ac_feature | sed 's/-/_/g'`
+    case $ac_option in
+      *=*) ac_optarg=`echo "$ac_optarg" | sed "s/'/'\\\\\\\\''/g"`;;
+      *) ac_optarg=yes ;;
+    esac
+    eval "enable_$ac_feature='$ac_optarg'" ;;
+
+  -exec-prefix | --exec_prefix | --exec-prefix | --exec-prefi \
+  | --exec-pref | --exec-pre | --exec-pr | --exec-p | --exec- \
+  | --exec | --exe | --ex)
+    ac_prev=exec_prefix ;;
+  -exec-prefix=* | --exec_prefix=* | --exec-prefix=* | --exec-prefi=* \
+  | --exec-pref=* | --exec-pre=* | --exec-pr=* | --exec-p=* | --exec-=* \
+  | --exec=* | --exe=* | --ex=*)
+    exec_prefix=$ac_optarg ;;
+
+  -gas | --gas | --ga | --g)
+    # Obsolete; use --with-gas.
+    with_gas=yes ;;
+
+  -help | --help | --hel | --he | -h)
+    ac_init_help=long ;;
+  -help=r* | --help=r* | --hel=r* | --he=r* | -hr*)
+    ac_init_help=recursive ;;
+  -help=s* | --help=s* | --hel=s* | --he=s* | -hs*)
+    ac_init_help=short ;;
+
+  -host | --host | --hos | --ho)
+    ac_prev=host_alias ;;
+  -host=* | --host=* | --hos=* | --ho=*)
+    host_alias=$ac_optarg ;;
+
+  -includedir | --includedir | --includedi | --included | --include \
+  | --includ | --inclu | --incl | --inc)
+    ac_prev=includedir ;;
+  -includedir=* | --includedir=* | --includedi=* | --included=* | --include=* \
+  | --includ=* | --inclu=* | --incl=* | --inc=*)
+    includedir=$ac_optarg ;;
+
+  -infodir | --infodir | --infodi | --infod | --info | --inf)
+    ac_prev=infodir ;;
+  -infodir=* | --infodir=* | --infodi=* | --infod=* | --info=* | --inf=*)
+    infodir=$ac_optarg ;;
+
+  -libdir | --libdir | --libdi | --libd)
+    ac_prev=libdir ;;
+  -libdir=* | --libdir=* | --libdi=* | --libd=*)
+    libdir=$ac_optarg ;;
+
+  -libexecdir | --libexecdir | --libexecdi | --libexecd | --libexec \
+  | --libexe | --libex | --libe)
+    ac_prev=libexecdir ;;
+  -libexecdir=* | --libexecdir=* | --libexecdi=* | --libexecd=* | --libexec=* \
+  | --libexe=* | --libex=* | --libe=*)
+    libexecdir=$ac_optarg ;;
+
+  -localstatedir | --localstatedir | --localstatedi | --localstated \
+  | --localstate | --localstat | --localsta | --localst \
+  | --locals | --local | --loca | --loc | --lo)
+    ac_prev=localstatedir ;;
+  -localstatedir=* | --localstatedir=* | --localstatedi=* | --localstated=* \
+  | --localstate=* | --localstat=* | --localsta=* | --localst=* \
+  | --locals=* | --local=* | --loca=* | --loc=* | --lo=*)
+    localstatedir=$ac_optarg ;;
+
+  -mandir | --mandir | --mandi | --mand | --man | --ma | --m)
+    ac_prev=mandir ;;
+  -mandir=* | --mandir=* | --mandi=* | --mand=* | --man=* | --ma=* | --m=*)
+    mandir=$ac_optarg ;;
+
+  -nfp | --nfp | --nf)
+    # Obsolete; use --without-fp.
+    with_fp=no ;;
+
+  -no-create | --no-create | --no-creat | --no-crea | --no-cre \
+  | --no-cr | --no-c | -n)
+    no_create=yes ;;
+
+  -no-recursion | --no-recursion | --no-recursio | --no-recursi \
+  | --no-recurs | --no-recur | --no-recu | --no-rec | --no-re | --no-r)
+    no_recursion=yes ;;
+
+  -oldincludedir | --oldincludedir | --oldincludedi | --oldincluded \
+  | --oldinclude | --oldinclud | --oldinclu | --oldincl | --oldinc \
+  | --oldin | --oldi | --old | --ol | --o)
+    ac_prev=oldincludedir ;;
+  -oldincludedir=* | --oldincludedir=* | --oldincludedi=* | --oldincluded=* \
+  | --oldinclude=* | --oldinclud=* | --oldinclu=* | --oldincl=* | --oldinc=* \
+  | --oldin=* | --oldi=* | --old=* | --ol=* | --o=*)
+    oldincludedir=$ac_optarg ;;
+
+  -prefix | --prefix | --prefi | --pref | --pre | --pr | --p)
+    ac_prev=prefix ;;
+  -prefix=* | --prefix=* | --prefi=* | --pref=* | --pre=* | --pr=* | --p=*)
+    prefix=$ac_optarg ;;
+
+  -program-prefix | --program-prefix | --program-prefi | --program-pref \
+  | --program-pre | --program-pr | --program-p)
+    ac_prev=program_prefix ;;
+  -program-prefix=* | --program-prefix=* | --program-prefi=* \
+  | --program-pref=* | --program-pre=* | --program-pr=* | --program-p=*)
+    program_prefix=$ac_optarg ;;
+
+  -program-suffix | --program-suffix | --program-suffi | --program-suff \
+  | --program-suf | --program-su | --program-s)
+    ac_prev=program_suffix ;;
+  -program-suffix=* | --program-suffix=* | --program-suffi=* \
+  | --program-suff=* | --program-suf=* | --program-su=* | --program-s=*)
+    program_suffix=$ac_optarg ;;
+
+  -program-transform-name | --program-transform-name \
+  | --program-transform-nam | --program-transform-na \
+  | --program-transform-n | --program-transform- \
+  | --program-transform | --program-transfor \
+  | --program-transfo | --program-transf \
+  | --program-trans | --program-tran \
+  | --progr-tra | --program-tr | --program-t)
+    ac_prev=program_transform_name ;;
+  -program-transform-name=* | --program-transform-name=* \
+  | --program-transform-nam=* | --program-transform-na=* \
+  | --program-transform-n=* | --program-transform-=* \
+  | --program-transform=* | --program-transfor=* \
+  | --program-transfo=* | --program-transf=* \
+  | --program-trans=* | --program-tran=* \
+  | --progr-tra=* | --program-tr=* | --program-t=*)
+    program_transform_name=$ac_optarg ;;
+
+  -q | -quiet | --quiet | --quie | --qui | --qu | --q \
+  | -silent | --silent | --silen | --sile | --sil)
+    silent=yes ;;
+
+  -sbindir | --sbindir | --sbindi | --sbind | --sbin | --sbi | --sb)
+    ac_prev=sbindir ;;
+  -sbindir=* | --sbindir=* | --sbindi=* | --sbind=* | --sbin=* \
+  | --sbi=* | --sb=*)
+    sbindir=$ac_optarg ;;
+
+  -sharedstatedir | --sharedstatedir | --sharedstatedi \
+  | --sharedstated | --sharedstate | --sharedstat | --sharedsta \
+  | --sharedst | --shareds | --shared | --share | --shar \
+  | --sha | --sh)
+    ac_prev=sharedstatedir ;;
+  -sharedstatedir=* | --sharedstatedir=* | --sharedstatedi=* \
+  | --sharedstated=* | --sharedstate=* | --sharedstat=* | --sharedsta=* \
+  | --sharedst=* | --shareds=* | --shared=* | --share=* | --shar=* \
+  | --sha=* | --sh=*)
+    sharedstatedir=$ac_optarg ;;
+
+  -site | --site | --sit)
+    ac_prev=site ;;
+  -site=* | --site=* | --sit=*)
+    site=$ac_optarg ;;
+
+  -srcdir | --srcdir | --srcdi | --srcd | --src | --sr)
+    ac_prev=srcdir ;;
+  -srcdir=* | --srcdir=* | --srcdi=* | --srcd=* | --src=* | --sr=*)
+    srcdir=$ac_optarg ;;
+
+  -sysconfdir | --sysconfdir | --sysconfdi | --sysconfd | --sysconf \
+  | --syscon | --sysco | --sysc | --sys | --sy)
+    ac_prev=sysconfdir ;;
+  -sysconfdir=* | --sysconfdir=* | --sysconfdi=* | --sysconfd=* | --sysconf=* \
+  | --syscon=* | --sysco=* | --sysc=* | --sys=* | --sy=*)
+    sysconfdir=$ac_optarg ;;
+
+  -target | --target | --targe | --targ | --tar | --ta | --t)
+    ac_prev=target_alias ;;
+  -target=* | --target=* | --targe=* | --targ=* | --tar=* | --ta=* | --t=*)
+    target_alias=$ac_optarg ;;
+
+  -v | -verbose | --verbose | --verbos | --verbo | --verb)
+    verbose=yes ;;
+
+  -version | --version | --versio | --versi | --vers | -V)
+    ac_init_version=: ;;
+
+  -with-* | --with-*)
+    ac_package=`expr "x$ac_option" : 'x-*with-\([^=]*\)'`
+    # Reject names that are not valid shell variable names.
+    expr "x$ac_package" : ".*[^-_$as_cr_alnum]" >/dev/null &&
+      { echo "$as_me: error: invalid package name: $ac_package" >&2
+   { (exit 1); exit 1; }; }
+    ac_package=`echo $ac_package| sed 's/-/_/g'`
+    case $ac_option in
+      *=*) ac_optarg=`echo "$ac_optarg" | sed "s/'/'\\\\\\\\''/g"`;;
+      *) ac_optarg=yes ;;
+    esac
+    eval "with_$ac_package='$ac_optarg'" ;;
+
+  -without-* | --without-*)
+    ac_package=`expr "x$ac_option" : 'x-*without-\(.*\)'`
+    # Reject names that are not valid shell variable names.
+    expr "x$ac_package" : ".*[^-_$as_cr_alnum]" >/dev/null &&
+      { echo "$as_me: error: invalid package name: $ac_package" >&2
+   { (exit 1); exit 1; }; }
+    ac_package=`echo $ac_package | sed 's/-/_/g'`
+    eval "with_$ac_package=no" ;;
+
+  --x)
+    # Obsolete; use --with-x.
+    with_x=yes ;;
+
+  -x-includes | --x-includes | --x-include | --x-includ | --x-inclu \
+  | --x-incl | --x-inc | --x-in | --x-i)
+    ac_prev=x_includes ;;
+  -x-includes=* | --x-includes=* | --x-include=* | --x-includ=* | --x-inclu=* \
+  | --x-incl=* | --x-inc=* | --x-in=* | --x-i=*)
+    x_includes=$ac_optarg ;;
+
+  -x-libraries | --x-libraries | --x-librarie | --x-librari \
+  | --x-librar | --x-libra | --x-libr | --x-lib | --x-li | --x-l)
+    ac_prev=x_libraries ;;
+  -x-libraries=* | --x-libraries=* | --x-librarie=* | --x-librari=* \
+  | --x-librar=* | --x-libra=* | --x-libr=* | --x-lib=* | --x-li=* | --x-l=*)
+    x_libraries=$ac_optarg ;;
+
+  -*) { echo "$as_me: error: unrecognized option: $ac_option
+Try \`$0 --help' for more information." >&2
+   { (exit 1); exit 1; }; }
+    ;;
+
+  *=*)
+    ac_envvar=`expr "x$ac_option" : 'x\([^=]*\)='`
+    # Reject names that are not valid shell variable names.
+    expr "x$ac_envvar" : ".*[^_$as_cr_alnum]" >/dev/null &&
+      { echo "$as_me: error: invalid variable name: $ac_envvar" >&2
+   { (exit 1); exit 1; }; }
+    ac_optarg=`echo "$ac_optarg" | sed "s/'/'\\\\\\\\''/g"`
+    eval "$ac_envvar='$ac_optarg'"
+    export $ac_envvar ;;
+
+  *)
+    # FIXME: should be removed in autoconf 3.0.
+    echo "$as_me: WARNING: you should use --build, --host, --target" >&2
+    expr "x$ac_option" : ".*[^-._$as_cr_alnum]" >/dev/null &&
+      echo "$as_me: WARNING: invalid host type: $ac_option" >&2
+    : ${build_alias=$ac_option} ${host_alias=$ac_option} ${target_alias=$ac_option}
+    ;;
+
+  esac
+done
+
+if test -n "$ac_prev"; then
+  ac_option=--`echo $ac_prev | sed 's/_/-/g'`
+  { echo "$as_me: error: missing argument to $ac_option" >&2
+   { (exit 1); exit 1; }; }
+fi
+
+# Be sure to have absolute paths.
+for ac_var in exec_prefix prefix
+do
+  eval ac_val=$`echo $ac_var`
+  case $ac_val in
+    [\\/$]* | ?:[\\/]* | NONE | '' ) ;;
+    *)  { echo "$as_me: error: expected an absolute directory name for --$ac_var: $ac_val" >&2
+   { (exit 1); exit 1; }; };;
+  esac
+done
+
+# Be sure to have absolute paths.
+for ac_var in bindir sbindir libexecdir datadir sysconfdir sharedstatedir \
+             localstatedir libdir includedir oldincludedir infodir mandir
+do
+  eval ac_val=$`echo $ac_var`
+  case $ac_val in
+    [\\/$]* | ?:[\\/]* ) ;;
+    *)  { echo "$as_me: error: expected an absolute directory name for --$ac_var: $ac_val" >&2
+   { (exit 1); exit 1; }; };;
+  esac
+done
+
+# There might be people who depend on the old broken behavior: `$host'
+# used to hold the argument of --host etc.
+# FIXME: To remove some day.
+build=$build_alias
+host=$host_alias
+target=$target_alias
+
+# FIXME: To remove some day.
+if test "x$host_alias" != x; then
+  if test "x$build_alias" = x; then
+    cross_compiling=maybe
+    echo "$as_me: WARNING: If you wanted to set the --build type, don't use --host.
+    If a cross compiler is detected then cross compile mode will be used." >&2
+  elif test "x$build_alias" != "x$host_alias"; then
+    cross_compiling=yes
+  fi
+fi
+
+ac_tool_prefix=
+test -n "$host_alias" && ac_tool_prefix=$host_alias-
+
+test "$silent" = yes && exec 6>/dev/null
+
+
+# Find the source files, if location was not specified.
+if test -z "$srcdir"; then
+  ac_srcdir_defaulted=yes
+  # Try the directory containing this script, then its parent.
+  ac_confdir=`(dirname "$0") 2>/dev/null ||
+$as_expr X"$0" : 'X\(.*[^/]\)//*[^/][^/]*/*$' \| \
+        X"$0" : 'X\(//\)[^/]' \| \
+        X"$0" : 'X\(//\)$' \| \
+        X"$0" : 'X\(/\)' \| \
+        .     : '\(.\)' 2>/dev/null ||
+echo X"$0" |
+    sed '/^X\(.*[^/]\)\/\/*[^/][^/]*\/*$/{ s//\1/; q; }
+         /^X\(\/\/\)[^/].*/{ s//\1/; q; }
+         /^X\(\/\/\)$/{ s//\1/; q; }
+         /^X\(\/\).*/{ s//\1/; q; }
+         s/.*/./; q'`
+  srcdir=$ac_confdir
+  if test ! -r $srcdir/$ac_unique_file; then
+    srcdir=..
+  fi
+else
+  ac_srcdir_defaulted=no
+fi
+if test ! -r $srcdir/$ac_unique_file; then
+  if test "$ac_srcdir_defaulted" = yes; then
+    { echo "$as_me: error: cannot find sources ($ac_unique_file) in $ac_confdir or .." >&2
+   { (exit 1); exit 1; }; }
+  else
+    { echo "$as_me: error: cannot find sources ($ac_unique_file) in $srcdir" >&2
+   { (exit 1); exit 1; }; }
+  fi
+fi
+(cd $srcdir && test -r ./$ac_unique_file) 2>/dev/null ||
+  { echo "$as_me: error: sources are in $srcdir, but \`cd $srcdir' does not work" >&2
+   { (exit 1); exit 1; }; }
+srcdir=`echo "$srcdir" | sed 's%\([^\\/]\)[\\/]*$%\1%'`
+ac_env_build_alias_set=${build_alias+set}
+ac_env_build_alias_value=$build_alias
+ac_cv_env_build_alias_set=${build_alias+set}
+ac_cv_env_build_alias_value=$build_alias
+ac_env_host_alias_set=${host_alias+set}
+ac_env_host_alias_value=$host_alias
+ac_cv_env_host_alias_set=${host_alias+set}
+ac_cv_env_host_alias_value=$host_alias
+ac_env_target_alias_set=${target_alias+set}
+ac_env_target_alias_value=$target_alias
+ac_cv_env_target_alias_set=${target_alias+set}
+ac_cv_env_target_alias_value=$target_alias
+ac_env_CC_set=${CC+set}
+ac_env_CC_value=$CC
+ac_cv_env_CC_set=${CC+set}
+ac_cv_env_CC_value=$CC
+ac_env_CFLAGS_set=${CFLAGS+set}
+ac_env_CFLAGS_value=$CFLAGS
+ac_cv_env_CFLAGS_set=${CFLAGS+set}
+ac_cv_env_CFLAGS_value=$CFLAGS
+ac_env_LDFLAGS_set=${LDFLAGS+set}
+ac_env_LDFLAGS_value=$LDFLAGS
+ac_cv_env_LDFLAGS_set=${LDFLAGS+set}
+ac_cv_env_LDFLAGS_value=$LDFLAGS
+ac_env_CPPFLAGS_set=${CPPFLAGS+set}
+ac_env_CPPFLAGS_value=$CPPFLAGS
+ac_cv_env_CPPFLAGS_set=${CPPFLAGS+set}
+ac_cv_env_CPPFLAGS_value=$CPPFLAGS
+ac_env_CPP_set=${CPP+set}
+ac_env_CPP_value=$CPP
+ac_cv_env_CPP_set=${CPP+set}
+ac_cv_env_CPP_value=$CPP
+
+#
+# Report the --help message.
+#
+if test "$ac_init_help" = "long"; then
+  # Omit some internal or obsolete options to make the list less imposing.
+  # This message is too long to be a string in the A/UX 3.1 sh.
+  cat <<_ACEOF
+\`configure' configures libsndfile ardour-special to adapt to many kinds of systems.
+
+Usage: $0 [OPTION]... [VAR=VALUE]...
+
+To assign environment variables (e.g., CC, CFLAGS...), specify them as
+VAR=VALUE.  See below for descriptions of some of the useful variables.
+
+Defaults for the options are specified in brackets.
+
+Configuration:
+  -h, --help              display this help and exit
+      --help=short        display options specific to this package
+      --help=recursive    display the short help of all the included packages
+  -V, --version           display version information and exit
+  -q, --quiet, --silent   do not print \`checking...' messages
+      --cache-file=FILE   cache test results in FILE [disabled]
+  -C, --config-cache      alias for \`--cache-file=config.cache'
+  -n, --no-create         do not create output files
+      --srcdir=DIR        find the sources in DIR [configure dir or \`..']
+
+_ACEOF
+
+  cat <<_ACEOF
+Installation directories:
+  --prefix=PREFIX         install architecture-independent files in PREFIX
+                         [$ac_default_prefix]
+  --exec-prefix=EPREFIX   install architecture-dependent files in EPREFIX
+                         [PREFIX]
+
+By default, \`make install' will install all the files in
+\`$ac_default_prefix/bin', \`$ac_default_prefix/lib' etc.  You can specify
+an installation prefix other than \`$ac_default_prefix' using \`--prefix',
+for instance \`--prefix=\$HOME'.
+
+For better control, use the options below.
+
+Fine tuning of the installation directories:
+  --bindir=DIR           user executables [EPREFIX/bin]
+  --sbindir=DIR          system admin executables [EPREFIX/sbin]
+  --libexecdir=DIR       program executables [EPREFIX/libexec]
+  --datadir=DIR          read-only architecture-independent data [PREFIX/share]
+  --sysconfdir=DIR       read-only single-machine data [PREFIX/etc]
+  --sharedstatedir=DIR   modifiable architecture-independent data [PREFIX/com]
+  --localstatedir=DIR    modifiable single-machine data [PREFIX/var]
+  --libdir=DIR           object code libraries [EPREFIX/lib]
+  --includedir=DIR       C header files [PREFIX/include]
+  --oldincludedir=DIR    C header files for non-gcc [/usr/include]
+  --infodir=DIR          info documentation [PREFIX/info]
+  --mandir=DIR           man documentation [PREFIX/man]
+_ACEOF
+
+  cat <<\_ACEOF
+
+System types:
+  --build=BUILD     configure for building on BUILD [guessed]
+  --host=HOST       cross-compile to build programs to run on HOST [BUILD]
+  --target=TARGET   configure for building compilers for TARGET [HOST]
+_ACEOF
+fi
+
+if test -n "$ac_init_help"; then
+  case $ac_init_help in
+     short | recursive ) echo "Configuration of libsndfile ardour-special:";;
+   esac
+  cat <<\_ACEOF
+
+Optional Features:
+  --disable-FEATURE       do not include FEATURE (same as --enable-FEATURE=no)
+  --enable-FEATURE[=ARG]  include FEATURE [ARG=yes]
+  --enable-experimental   enable experimental code
+  --enable-gcc-werror     enable -Werror in all Makefiles
+  --disable-gcc-pipe      disable gcc -pipe option
+  --disable-gcc-opt       disable gcc optimisations
+  --disable-cpu-clip      disable tricky cpu specific clipper
+  --enable-bow-docs       enable black-on-white html docs
+  --disable-sqlite        disable use of sqlite
+  --disable-flac          disable use of FLAC
+  --disable-alsa          disable use of ALSA
+  --disable-largefile     omit support for large files
+
+Some influential environment variables:
+  CC          C compiler command
+  CFLAGS      C compiler flags
+  LDFLAGS     linker flags, e.g. -L<lib dir> if you have libraries in a
+              nonstandard directory <lib dir>
+  CPPFLAGS    C/C++ preprocessor flags, e.g. -I<include dir> if you have
+              headers in a nonstandard directory <include dir>
+  CPP         C preprocessor
+
+Use these variables to override the choices made by `configure' or to help
+it to find libraries and programs with nonstandard names/locations.
+
+Report bugs to <ardour@ardour.org>.
+_ACEOF
+fi
+
+if test "$ac_init_help" = "recursive"; then
+  # If there are subdirs, report their specific --help.
+  ac_popdir=`pwd`
+  for ac_dir in : $ac_subdirs_all; do test "x$ac_dir" = x: && continue
+    test -d $ac_dir || continue
+    ac_builddir=.
+
+if test "$ac_dir" != .; then
+  ac_dir_suffix=/`echo "$ac_dir" | sed 's,^\.[\\/],,'`
+  # A "../" for each directory in $ac_dir_suffix.
+  ac_top_builddir=`echo "$ac_dir_suffix" | sed 's,/[^\\/]*,../,g'`
+else
+  ac_dir_suffix= ac_top_builddir=
+fi
+
+case $srcdir in
+  .)  # No --srcdir option.  We are building in place.
+    ac_srcdir=.
+    if test -z "$ac_top_builddir"; then
+       ac_top_srcdir=.
+    else
+       ac_top_srcdir=`echo $ac_top_builddir | sed 's,/$,,'`
+    fi ;;
+  [\\/]* | ?:[\\/]* )  # Absolute path.
+    ac_srcdir=$srcdir$ac_dir_suffix;
+    ac_top_srcdir=$srcdir ;;
+  *) # Relative path.
+    ac_srcdir=$ac_top_builddir$srcdir$ac_dir_suffix
+    ac_top_srcdir=$ac_top_builddir$srcdir ;;
+esac
+
+# Do not use `cd foo && pwd` to compute absolute paths, because
+# the directories may not exist.
+case `pwd` in
+.) ac_abs_builddir="$ac_dir";;
+*)
+  case "$ac_dir" in
+  .) ac_abs_builddir=`pwd`;;
+  [\\/]* | ?:[\\/]* ) ac_abs_builddir="$ac_dir";;
+  *) ac_abs_builddir=`pwd`/"$ac_dir";;
+  esac;;
+esac
+case $ac_abs_builddir in
+.) ac_abs_top_builddir=${ac_top_builddir}.;;
+*)
+  case ${ac_top_builddir}. in
+  .) ac_abs_top_builddir=$ac_abs_builddir;;
+  [\\/]* | ?:[\\/]* ) ac_abs_top_builddir=${ac_top_builddir}.;;
+  *) ac_abs_top_builddir=$ac_abs_builddir/${ac_top_builddir}.;;
+  esac;;
+esac
+case $ac_abs_builddir in
+.) ac_abs_srcdir=$ac_srcdir;;
+*)
+  case $ac_srcdir in
+  .) ac_abs_srcdir=$ac_abs_builddir;;
+  [\\/]* | ?:[\\/]* ) ac_abs_srcdir=$ac_srcdir;;
+  *) ac_abs_srcdir=$ac_abs_builddir/$ac_srcdir;;
+  esac;;
+esac
+case $ac_abs_builddir in
+.) ac_abs_top_srcdir=$ac_top_srcdir;;
+*)
+  case $ac_top_srcdir in
+  .) ac_abs_top_srcdir=$ac_abs_builddir;;
+  [\\/]* | ?:[\\/]* ) ac_abs_top_srcdir=$ac_top_srcdir;;
+  *) ac_abs_top_srcdir=$ac_abs_builddir/$ac_top_srcdir;;
+  esac;;
+esac
+
+    cd $ac_dir
+    # Check for guested configure; otherwise get Cygnus style configure.
+    if test -f $ac_srcdir/configure.gnu; then
+      echo
+      $SHELL $ac_srcdir/configure.gnu  --help=recursive
+    elif test -f $ac_srcdir/configure; then
+      echo
+      $SHELL $ac_srcdir/configure  --help=recursive
+    elif test -f $ac_srcdir/configure.ac ||
+          test -f $ac_srcdir/configure.in; then
+      echo
+      $ac_configure --help
+    else
+      echo "$as_me: WARNING: no configuration information is in $ac_dir" >&2
+    fi
+    cd $ac_popdir
+  done
+fi
+
+test -n "$ac_init_help" && exit 0
+if $ac_init_version; then
+  cat <<\_ACEOF
+libsndfile configure ardour-special
+generated by GNU Autoconf 2.59
+
+Copyright (C) 2003 Free Software Foundation, Inc.
+This configure script is free software; the Free Software Foundation
+gives unlimited permission to copy, distribute and modify it.
+_ACEOF
+  exit 0
+fi
+exec 5>config.log
+cat >&5 <<_ACEOF
+This file contains any messages produced by compilers while
+running configure, to aid debugging if configure makes a mistake.
+
+It was created by libsndfile $as_me ardour-special, which was
+generated by GNU Autoconf 2.59.  Invocation command line was
+
+  $ $0 $@
+
+_ACEOF
+{
+cat <<_ASUNAME
+## --------- ##
+## Platform. ##
+## --------- ##
+
+hostname = `(hostname || uname -n) 2>/dev/null | sed 1q`
+uname -m = `(uname -m) 2>/dev/null || echo unknown`
+uname -r = `(uname -r) 2>/dev/null || echo unknown`
+uname -s = `(uname -s) 2>/dev/null || echo unknown`
+uname -v = `(uname -v) 2>/dev/null || echo unknown`
+
+/usr/bin/uname -p = `(/usr/bin/uname -p) 2>/dev/null || echo unknown`
+/bin/uname -X     = `(/bin/uname -X) 2>/dev/null     || echo unknown`
+
+/bin/arch              = `(/bin/arch) 2>/dev/null              || echo unknown`
+/usr/bin/arch -k       = `(/usr/bin/arch -k) 2>/dev/null       || echo unknown`
+/usr/convex/getsysinfo = `(/usr/convex/getsysinfo) 2>/dev/null || echo unknown`
+hostinfo               = `(hostinfo) 2>/dev/null               || echo unknown`
+/bin/machine           = `(/bin/machine) 2>/dev/null           || echo unknown`
+/usr/bin/oslevel       = `(/usr/bin/oslevel) 2>/dev/null       || echo unknown`
+/bin/universe          = `(/bin/universe) 2>/dev/null          || echo unknown`
+
+_ASUNAME
+
+as_save_IFS=$IFS; IFS=$PATH_SEPARATOR
+for as_dir in $PATH
+do
+  IFS=$as_save_IFS
+  test -z "$as_dir" && as_dir=.
+  echo "PATH: $as_dir"
+done
+
+} >&5
+
+cat >&5 <<_ACEOF
+
+
+## ----------- ##
+## Core tests. ##
+## ----------- ##
+
+_ACEOF
+
+
+# Keep a trace of the command line.
+# Strip out --no-create and --no-recursion so they do not pile up.
+# Strip out --silent because we don't want to record it for future runs.
+# Also quote any args containing shell meta-characters.
+# Make two passes to allow for proper duplicate-argument suppression.
+ac_configure_args=
+ac_configure_args0=
+ac_configure_args1=
+ac_sep=
+ac_must_keep_next=false
+for ac_pass in 1 2
+do
+  for ac_arg
+  do
+    case $ac_arg in
+    -no-create | --no-c* | -n | -no-recursion | --no-r*) continue ;;
+    -q | -quiet | --quiet | --quie | --qui | --qu | --q \
+    | -silent | --silent | --silen | --sile | --sil)
+      continue ;;
+    *" "*|*"   "*|*[\[\]\~\#\$\^\&\*\(\)\{\}\\\|\;\<\>\?\"\']*)
+      ac_arg=`echo "$ac_arg" | sed "s/'/'\\\\\\\\''/g"` ;;
+    esac
+    case $ac_pass in
+    1) ac_configure_args0="$ac_configure_args0 '$ac_arg'" ;;
+    2)
+      ac_configure_args1="$ac_configure_args1 '$ac_arg'"
+      if test $ac_must_keep_next = true; then
+       ac_must_keep_next=false # Got value, back to normal.
+      else
+       case $ac_arg in
+         *=* | --config-cache | -C | -disable-* | --disable-* \
+         | -enable-* | --enable-* | -gas | --g* | -nfp | --nf* \
+         | -q | -quiet | --q* | -silent | --sil* | -v | -verb* \
+         | -with-* | --with-* | -without-* | --without-* | --x)
+           case "$ac_configure_args0 " in
+             "$ac_configure_args1"*" '$ac_arg' "* ) continue ;;
+           esac
+           ;;
+         -* ) ac_must_keep_next=true ;;
+       esac
+      fi
+      ac_configure_args="$ac_configure_args$ac_sep'$ac_arg'"
+      # Get rid of the leading space.
+      ac_sep=" "
+      ;;
+    esac
+  done
+done
+$as_unset ac_configure_args0 || test "${ac_configure_args0+set}" != set || { ac_configure_args0=; export ac_configure_args0; }
+$as_unset ac_configure_args1 || test "${ac_configure_args1+set}" != set || { ac_configure_args1=; export ac_configure_args1; }
+
+# When interrupted or exit'd, cleanup temporary files, and complete
+# config.log.  We remove comments because anyway the quotes in there
+# would cause problems or look ugly.
+# WARNING: Be sure not to use single quotes in there, as some shells,
+# such as our DU 5.0 friend, will then `close' the trap.
+trap 'exit_status=$?
+  # Save into config.log some information that might help in debugging.
+  {
+    echo
+
+    cat <<\_ASBOX
+## ---------------- ##
+## Cache variables. ##
+## ---------------- ##
+_ASBOX
+    echo
+    # The following way of writing the cache mishandles newlines in values,
+{
+  (set) 2>&1 |
+    case `(ac_space='"'"' '"'"'; set | grep ac_space) 2>&1` in
+    *ac_space=\ *)
+      sed -n \
+       "s/'"'"'/'"'"'\\\\'"'"''"'"'/g;
+         s/^\\([_$as_cr_alnum]*_cv_[_$as_cr_alnum]*\\)=\\(.*\\)/\\1='"'"'\\2'"'"'/p"
+      ;;
+    *)
+      sed -n \
+       "s/^\\([_$as_cr_alnum]*_cv_[_$as_cr_alnum]*\\)=\\(.*\\)/\\1=\\2/p"
+      ;;
+    esac;
+}
+    echo
+
+    cat <<\_ASBOX
+## ----------------- ##
+## Output variables. ##
+## ----------------- ##
+_ASBOX
+    echo
+    for ac_var in $ac_subst_vars
+    do
+      eval ac_val=$`echo $ac_var`
+      echo "$ac_var='"'"'$ac_val'"'"'"
+    done | sort
+    echo
+
+    if test -n "$ac_subst_files"; then
+      cat <<\_ASBOX
+## ------------- ##
+## Output files. ##
+## ------------- ##
+_ASBOX
+      echo
+      for ac_var in $ac_subst_files
+      do
+       eval ac_val=$`echo $ac_var`
+       echo "$ac_var='"'"'$ac_val'"'"'"
+      done | sort
+      echo
+    fi
+
+    if test -s confdefs.h; then
+      cat <<\_ASBOX
+## ----------- ##
+## confdefs.h. ##
+## ----------- ##
+_ASBOX
+      echo
+      sed "/^$/d" confdefs.h | sort
+      echo
+    fi
+    test "$ac_signal" != 0 &&
+      echo "$as_me: caught signal $ac_signal"
+    echo "$as_me: exit $exit_status"
+  } >&5
+  rm -f core *.core &&
+  rm -rf conftest* confdefs* conf$$* $ac_clean_files &&
+    exit $exit_status
+     ' 0
+for ac_signal in 1 2 13 15; do
+  trap 'ac_signal='$ac_signal'; { (exit 1); exit 1; }' $ac_signal
+done
+ac_signal=0
+
+# confdefs.h avoids OS command line length limits that DEFS can exceed.
+rm -rf conftest* confdefs.h
+# AIX cpp loses on an empty file, so make sure it contains at least a newline.
+echo >confdefs.h
+
+# Predefined preprocessor variables.
+
+cat >>confdefs.h <<_ACEOF
+#define PACKAGE_NAME "$PACKAGE_NAME"
+_ACEOF
+
+
+cat >>confdefs.h <<_ACEOF
+#define PACKAGE_TARNAME "$PACKAGE_TARNAME"
+_ACEOF
+
+
+cat >>confdefs.h <<_ACEOF
+#define PACKAGE_VERSION "$PACKAGE_VERSION"
+_ACEOF
+
+
+cat >>confdefs.h <<_ACEOF
+#define PACKAGE_STRING "$PACKAGE_STRING"
+_ACEOF
+
+
+cat >>confdefs.h <<_ACEOF
+#define PACKAGE_BUGREPORT "$PACKAGE_BUGREPORT"
+_ACEOF
+
+
+# Let the site file select an alternate cache file if it wants to.
+# Prefer explicitly selected file to automatically selected ones.
+if test -z "$CONFIG_SITE"; then
+  if test "x$prefix" != xNONE; then
+    CONFIG_SITE="$prefix/share/config.site $prefix/etc/config.site"
+  else
+    CONFIG_SITE="$ac_default_prefix/share/config.site $ac_default_prefix/etc/config.site"
+  fi
+fi
+for ac_site_file in $CONFIG_SITE; do
+  if test -r "$ac_site_file"; then
+    { echo "$as_me:$LINENO: loading site script $ac_site_file" >&5
+echo "$as_me: loading site script $ac_site_file" >&6;}
+    sed 's/^/| /' "$ac_site_file" >&5
+    . "$ac_site_file"
+  fi
+done
+
+if test -r "$cache_file"; then
+  # Some versions of bash will fail to source /dev/null (special
+  # files actually), so we avoid doing that.
+  if test -f "$cache_file"; then
+    { echo "$as_me:$LINENO: loading cache $cache_file" >&5
+echo "$as_me: loading cache $cache_file" >&6;}
+    case $cache_file in
+      [\\/]* | ?:[\\/]* ) . $cache_file;;
+      *)                      . ./$cache_file;;
+    esac
+  fi
+else
+  { echo "$as_me:$LINENO: creating cache $cache_file" >&5
+echo "$as_me: creating cache $cache_file" >&6;}
+  >$cache_file
+fi
+
+# Check that the precious variables saved in the cache have kept the same
+# value.
+ac_cache_corrupted=false
+for ac_var in `(set) 2>&1 |
+              sed -n 's/^ac_env_\([a-zA-Z_0-9]*\)_set=.*/\1/p'`; do
+  eval ac_old_set=\$ac_cv_env_${ac_var}_set
+  eval ac_new_set=\$ac_env_${ac_var}_set
+  eval ac_old_val="\$ac_cv_env_${ac_var}_value"
+  eval ac_new_val="\$ac_env_${ac_var}_value"
+  case $ac_old_set,$ac_new_set in
+    set,)
+      { echo "$as_me:$LINENO: error: \`$ac_var' was set to \`$ac_old_val' in the previous run" >&5
+echo "$as_me: error: \`$ac_var' was set to \`$ac_old_val' in the previous run" >&2;}
+      ac_cache_corrupted=: ;;
+    ,set)
+      { echo "$as_me:$LINENO: error: \`$ac_var' was not set in the previous run" >&5
+echo "$as_me: error: \`$ac_var' was not set in the previous run" >&2;}
+      ac_cache_corrupted=: ;;
+    ,);;
+    *)
+      if test "x$ac_old_val" != "x$ac_new_val"; then
+       { echo "$as_me:$LINENO: error: \`$ac_var' has changed since the previous run:" >&5
+echo "$as_me: error: \`$ac_var' has changed since the previous run:" >&2;}
+       { echo "$as_me:$LINENO:   former value:  $ac_old_val" >&5
+echo "$as_me:   former value:  $ac_old_val" >&2;}
+       { echo "$as_me:$LINENO:   current value: $ac_new_val" >&5
+echo "$as_me:   current value: $ac_new_val" >&2;}
+       ac_cache_corrupted=:
+      fi;;
+  esac
+  # Pass precious variables to config.status.
+  if test "$ac_new_set" = set; then
+    case $ac_new_val in
+    *" "*|*"   "*|*[\[\]\~\#\$\^\&\*\(\)\{\}\\\|\;\<\>\?\"\']*)
+      ac_arg=$ac_var=`echo "$ac_new_val" | sed "s/'/'\\\\\\\\''/g"` ;;
+    *) ac_arg=$ac_var=$ac_new_val ;;
+    esac
+    case " $ac_configure_args " in
+      *" '$ac_arg' "*) ;; # Avoid dups.  Use of quotes ensures accuracy.
+      *) ac_configure_args="$ac_configure_args '$ac_arg'" ;;
+    esac
+  fi
+done
+if $ac_cache_corrupted; then
+  { echo "$as_me:$LINENO: error: changes in the environment can compromise the build" >&5
+echo "$as_me: error: changes in the environment can compromise the build" >&2;}
+  { { echo "$as_me:$LINENO: error: run \`make distclean' and/or \`rm $cache_file' and start over" >&5
+echo "$as_me: error: run \`make distclean' and/or \`rm $cache_file' and start over" >&2;}
+   { (exit 1); exit 1; }; }
+fi
+
+ac_ext=c
+ac_cpp='$CPP $CPPFLAGS'
+ac_compile='$CC -c $CFLAGS $CPPFLAGS conftest.$ac_ext >&5'
+ac_link='$CC -o conftest$ac_exeext $CFLAGS $CPPFLAGS $LDFLAGS conftest.$ac_ext $LIBS >&5'
+ac_compiler_gnu=$ac_cv_c_compiler_gnu
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+ac_aux_dir=
+for ac_dir in $srcdir $srcdir/.. $srcdir/../..; do
+  if test -f $ac_dir/install-sh; then
+    ac_aux_dir=$ac_dir
+    ac_install_sh="$ac_aux_dir/install-sh -c"
+    break
+  elif test -f $ac_dir/install.sh; then
+    ac_aux_dir=$ac_dir
+    ac_install_sh="$ac_aux_dir/install.sh -c"
+    break
+  elif test -f $ac_dir/shtool; then
+    ac_aux_dir=$ac_dir
+    ac_install_sh="$ac_aux_dir/shtool install -c"
+    break
+  fi
+done
+if test -z "$ac_aux_dir"; then
+  { { echo "$as_me:$LINENO: error: cannot find install-sh or install.sh in $srcdir $srcdir/.. $srcdir/../.." >&5
+echo "$as_me: error: cannot find install-sh or install.sh in $srcdir $srcdir/.. $srcdir/../.." >&2;}
+   { (exit 1); exit 1; }; }
+fi
+ac_config_guess="$SHELL $ac_aux_dir/config.guess"
+ac_config_sub="$SHELL $ac_aux_dir/config.sub"
+ac_configure="$SHELL $ac_aux_dir/configure" # This should be Cygnus configure.
+
+# Make sure we can run config.sub.
+$ac_config_sub sun4 >/dev/null 2>&1 ||
+  { { echo "$as_me:$LINENO: error: cannot run $ac_config_sub" >&5
+echo "$as_me: error: cannot run $ac_config_sub" >&2;}
+   { (exit 1); exit 1; }; }
+
+echo "$as_me:$LINENO: checking build system type" >&5
+echo $ECHO_N "checking build system type... $ECHO_C" >&6
+if test "${ac_cv_build+set}" = set; then
+  echo $ECHO_N "(cached) $ECHO_C" >&6
+else
+  ac_cv_build_alias=$build_alias
+test -z "$ac_cv_build_alias" &&
+  ac_cv_build_alias=`$ac_config_guess`
+test -z "$ac_cv_build_alias" &&
+  { { echo "$as_me:$LINENO: error: cannot guess build type; you must specify one" >&5
+echo "$as_me: error: cannot guess build type; you must specify one" >&2;}
+   { (exit 1); exit 1; }; }
+ac_cv_build=`$ac_config_sub $ac_cv_build_alias` ||
+  { { echo "$as_me:$LINENO: error: $ac_config_sub $ac_cv_build_alias failed" >&5
+echo "$as_me: error: $ac_config_sub $ac_cv_build_alias failed" >&2;}
+   { (exit 1); exit 1; }; }
+
+fi
+echo "$as_me:$LINENO: result: $ac_cv_build" >&5
+echo "${ECHO_T}$ac_cv_build" >&6
+build=$ac_cv_build
+build_cpu=`echo $ac_cv_build | sed 's/^\([^-]*\)-\([^-]*\)-\(.*\)$/\1/'`
+build_vendor=`echo $ac_cv_build | sed 's/^\([^-]*\)-\([^-]*\)-\(.*\)$/\2/'`
+build_os=`echo $ac_cv_build | sed 's/^\([^-]*\)-\([^-]*\)-\(.*\)$/\3/'`
+
+
+echo "$as_me:$LINENO: checking host system type" >&5
+echo $ECHO_N "checking host system type... $ECHO_C" >&6
+if test "${ac_cv_host+set}" = set; then
+  echo $ECHO_N "(cached) $ECHO_C" >&6
+else
+  ac_cv_host_alias=$host_alias
+test -z "$ac_cv_host_alias" &&
+  ac_cv_host_alias=$ac_cv_build_alias
+ac_cv_host=`$ac_config_sub $ac_cv_host_alias` ||
+  { { echo "$as_me:$LINENO: error: $ac_config_sub $ac_cv_host_alias failed" >&5
+echo "$as_me: error: $ac_config_sub $ac_cv_host_alias failed" >&2;}
+   { (exit 1); exit 1; }; }
+
+fi
+echo "$as_me:$LINENO: result: $ac_cv_host" >&5
+echo "${ECHO_T}$ac_cv_host" >&6
+host=$ac_cv_host
+host_cpu=`echo $ac_cv_host | sed 's/^\([^-]*\)-\([^-]*\)-\(.*\)$/\1/'`
+host_vendor=`echo $ac_cv_host | sed 's/^\([^-]*\)-\([^-]*\)-\(.*\)$/\2/'`
+host_os=`echo $ac_cv_host | sed 's/^\([^-]*\)-\([^-]*\)-\(.*\)$/\3/'`
+
+
+echo "$as_me:$LINENO: checking target system type" >&5
+echo $ECHO_N "checking target system type... $ECHO_C" >&6
+if test "${ac_cv_target+set}" = set; then
+  echo $ECHO_N "(cached) $ECHO_C" >&6
+else
+  ac_cv_target_alias=$target_alias
+test "x$ac_cv_target_alias" = "x" &&
+  ac_cv_target_alias=$ac_cv_host_alias
+ac_cv_target=`$ac_config_sub $ac_cv_target_alias` ||
+  { { echo "$as_me:$LINENO: error: $ac_config_sub $ac_cv_target_alias failed" >&5
+echo "$as_me: error: $ac_config_sub $ac_cv_target_alias failed" >&2;}
+   { (exit 1); exit 1; }; }
+
+fi
+echo "$as_me:$LINENO: result: $ac_cv_target" >&5
+echo "${ECHO_T}$ac_cv_target" >&6
+target=$ac_cv_target
+target_cpu=`echo $ac_cv_target | sed 's/^\([^-]*\)-\([^-]*\)-\(.*\)$/\1/'`
+target_vendor=`echo $ac_cv_target | sed 's/^\([^-]*\)-\([^-]*\)-\(.*\)$/\2/'`
+target_os=`echo $ac_cv_target | sed 's/^\([^-]*\)-\([^-]*\)-\(.*\)$/\3/'`
+
+
+# The aliases save the names the user supplied, while $host etc.
+# will get canonicalized.
+test -n "$target_alias" &&
+  test "$program_prefix$program_suffix$program_transform_name" = \
+    NONENONEs,x,x, &&
+  program_prefix=${target_alias}-
+
+          ac_config_headers="$ac_config_headers src/config.h"
+
+
+ac_ext=c
+ac_cpp='$CPP $CPPFLAGS'
+ac_compile='$CC -c $CFLAGS $CPPFLAGS conftest.$ac_ext >&5'
+ac_link='$CC -o conftest$ac_exeext $CFLAGS $CPPFLAGS $LDFLAGS conftest.$ac_ext $LIBS >&5'
+ac_compiler_gnu=$ac_cv_c_compiler_gnu
+
+
+#------------------------------------------------------------------------------------
+# Rules for library version information:
+#
+#  1. Start with version information of `0:0:0' for each libtool library.
+#  2. Update the version information only immediately before a public release of
+#     your software. More frequent updates are unnecessary, and only guarantee
+#     that the current interface number gets larger faster.
+#  3. If the library source code has changed at all since the last update, then
+#     increment revision (`c:r:a' becomes `c:r+1:a').
+#  4. If any interfaces have been added, removed, or changed since the last update,
+#     increment current, and set revision to 0.
+#  5. If any interfaces have been added since the last public release, then increment
+#     age.
+#  6. If any interfaces have been removed since the last public release, then set age
+#     to 0.
+
+SHARED_VERSION_INFO="1:16:0"
+
+ac_ext=c
+ac_cpp='$CPP $CPPFLAGS'
+ac_compile='$CC -c $CFLAGS $CPPFLAGS conftest.$ac_ext >&5'
+ac_link='$CC -o conftest$ac_exeext $CFLAGS $CPPFLAGS $LDFLAGS conftest.$ac_ext $LIBS >&5'
+ac_compiler_gnu=$ac_cv_c_compiler_gnu
+if test -n "$ac_tool_prefix"; then
+  # Extract the first word of "${ac_tool_prefix}gcc", so it can be a program name with args.
+set dummy ${ac_tool_prefix}gcc; ac_word=$2
+echo "$as_me:$LINENO: checking for $ac_word" >&5
+echo $ECHO_N "checking for $ac_word... $ECHO_C" >&6
+if test "${ac_cv_prog_CC+set}" = set; then
+  echo $ECHO_N "(cached) $ECHO_C" >&6
+else
+  if test -n "$CC"; then
+  ac_cv_prog_CC="$CC" # Let the user override the test.
+else
+as_save_IFS=$IFS; IFS=$PATH_SEPARATOR
+for as_dir in $PATH
+do
+  IFS=$as_save_IFS
+  test -z "$as_dir" && as_dir=.
+  for ac_exec_ext in '' $ac_executable_extensions; do
+  if $as_executable_p "$as_dir/$ac_word$ac_exec_ext"; then
+    ac_cv_prog_CC="${ac_tool_prefix}gcc"
+    echo "$as_me:$LINENO: found $as_dir/$ac_word$ac_exec_ext" >&5
+    break 2
+  fi
+done
+done
+
+fi
+fi
+CC=$ac_cv_prog_CC
+if test -n "$CC"; then
+  echo "$as_me:$LINENO: result: $CC" >&5
+echo "${ECHO_T}$CC" >&6
+else
+  echo "$as_me:$LINENO: result: no" >&5
+echo "${ECHO_T}no" >&6
+fi
+
+fi
+if test -z "$ac_cv_prog_CC"; then
+  ac_ct_CC=$CC
+  # Extract the first word of "gcc", so it can be a program name with args.
+set dummy gcc; ac_word=$2
+echo "$as_me:$LINENO: checking for $ac_word" >&5
+echo $ECHO_N "checking for $ac_word... $ECHO_C" >&6
+if test "${ac_cv_prog_ac_ct_CC+set}" = set; then
+  echo $ECHO_N "(cached) $ECHO_C" >&6
+else
+  if test -n "$ac_ct_CC"; then
+  ac_cv_prog_ac_ct_CC="$ac_ct_CC" # Let the user override the test.
+else
+as_save_IFS=$IFS; IFS=$PATH_SEPARATOR
+for as_dir in $PATH
+do
+  IFS=$as_save_IFS
+  test -z "$as_dir" && as_dir=.
+  for ac_exec_ext in '' $ac_executable_extensions; do
+  if $as_executable_p "$as_dir/$ac_word$ac_exec_ext"; then
+    ac_cv_prog_ac_ct_CC="gcc"
+    echo "$as_me:$LINENO: found $as_dir/$ac_word$ac_exec_ext" >&5
+    break 2
+  fi
+done
+done
+
+fi
+fi
+ac_ct_CC=$ac_cv_prog_ac_ct_CC
+if test -n "$ac_ct_CC"; then
+  echo "$as_me:$LINENO: result: $ac_ct_CC" >&5
+echo "${ECHO_T}$ac_ct_CC" >&6
+else
+  echo "$as_me:$LINENO: result: no" >&5
+echo "${ECHO_T}no" >&6
+fi
+
+  CC=$ac_ct_CC
+else
+  CC="$ac_cv_prog_CC"
+fi
+
+if test -z "$CC"; then
+  if test -n "$ac_tool_prefix"; then
+  # Extract the first word of "${ac_tool_prefix}cc", so it can be a program name with args.
+set dummy ${ac_tool_prefix}cc; ac_word=$2
+echo "$as_me:$LINENO: checking for $ac_word" >&5
+echo $ECHO_N "checking for $ac_word... $ECHO_C" >&6
+if test "${ac_cv_prog_CC+set}" = set; then
+  echo $ECHO_N "(cached) $ECHO_C" >&6
+else
+  if test -n "$CC"; then
+  ac_cv_prog_CC="$CC" # Let the user override the test.
+else
+as_save_IFS=$IFS; IFS=$PATH_SEPARATOR
+for as_dir in $PATH
+do
+  IFS=$as_save_IFS
+  test -z "$as_dir" && as_dir=.
+  for ac_exec_ext in '' $ac_executable_extensions; do
+  if $as_executable_p "$as_dir/$ac_word$ac_exec_ext"; then
+    ac_cv_prog_CC="${ac_tool_prefix}cc"
+    echo "$as_me:$LINENO: found $as_dir/$ac_word$ac_exec_ext" >&5
+    break 2
+  fi
+done
+done
+
+fi
+fi
+CC=$ac_cv_prog_CC
+if test -n "$CC"; then
+  echo "$as_me:$LINENO: result: $CC" >&5
+echo "${ECHO_T}$CC" >&6
+else
+  echo "$as_me:$LINENO: result: no" >&5
+echo "${ECHO_T}no" >&6
+fi
+
+fi
+if test -z "$ac_cv_prog_CC"; then
+  ac_ct_CC=$CC
+  # Extract the first word of "cc", so it can be a program name with args.
+set dummy cc; ac_word=$2
+echo "$as_me:$LINENO: checking for $ac_word" >&5
+echo $ECHO_N "checking for $ac_word... $ECHO_C" >&6
+if test "${ac_cv_prog_ac_ct_CC+set}" = set; then
+  echo $ECHO_N "(cached) $ECHO_C" >&6
+else
+  if test -n "$ac_ct_CC"; then
+  ac_cv_prog_ac_ct_CC="$ac_ct_CC" # Let the user override the test.
+else
+as_save_IFS=$IFS; IFS=$PATH_SEPARATOR
+for as_dir in $PATH
+do
+  IFS=$as_save_IFS
+  test -z "$as_dir" && as_dir=.
+  for ac_exec_ext in '' $ac_executable_extensions; do
+  if $as_executable_p "$as_dir/$ac_word$ac_exec_ext"; then
+    ac_cv_prog_ac_ct_CC="cc"
+    echo "$as_me:$LINENO: found $as_dir/$ac_word$ac_exec_ext" >&5
+    break 2
+  fi
+done
+done
+
+fi
+fi
+ac_ct_CC=$ac_cv_prog_ac_ct_CC
+if test -n "$ac_ct_CC"; then
+  echo "$as_me:$LINENO: result: $ac_ct_CC" >&5
+echo "${ECHO_T}$ac_ct_CC" >&6
+else
+  echo "$as_me:$LINENO: result: no" >&5
+echo "${ECHO_T}no" >&6
+fi
+
+  CC=$ac_ct_CC
+else
+  CC="$ac_cv_prog_CC"
+fi
+
+fi
+if test -z "$CC"; then
+  # Extract the first word of "cc", so it can be a program name with args.
+set dummy cc; ac_word=$2
+echo "$as_me:$LINENO: checking for $ac_word" >&5
+echo $ECHO_N "checking for $ac_word... $ECHO_C" >&6
+if test "${ac_cv_prog_CC+set}" = set; then
+  echo $ECHO_N "(cached) $ECHO_C" >&6
+else
+  if test -n "$CC"; then
+  ac_cv_prog_CC="$CC" # Let the user override the test.
+else
+  ac_prog_rejected=no
+as_save_IFS=$IFS; IFS=$PATH_SEPARATOR
+for as_dir in $PATH
+do
+  IFS=$as_save_IFS
+  test -z "$as_dir" && as_dir=.
+  for ac_exec_ext in '' $ac_executable_extensions; do
+  if $as_executable_p "$as_dir/$ac_word$ac_exec_ext"; then
+    if test "$as_dir/$ac_word$ac_exec_ext" = "/usr/ucb/cc"; then
+       ac_prog_rejected=yes
+       continue
+     fi
+    ac_cv_prog_CC="cc"
+    echo "$as_me:$LINENO: found $as_dir/$ac_word$ac_exec_ext" >&5
+    break 2
+  fi
+done
+done
+
+if test $ac_prog_rejected = yes; then
+  # We found a bogon in the path, so make sure we never use it.
+  set dummy $ac_cv_prog_CC
+  shift
+  if test $# != 0; then
+    # We chose a different compiler from the bogus one.
+    # However, it has the same basename, so the bogon will be chosen
+    # first if we set CC to just the basename; use the full file name.
+    shift
+    ac_cv_prog_CC="$as_dir/$ac_word${1+' '}$@"
+  fi
+fi
+fi
+fi
+CC=$ac_cv_prog_CC
+if test -n "$CC"; then
+  echo "$as_me:$LINENO: result: $CC" >&5
+echo "${ECHO_T}$CC" >&6
+else
+  echo "$as_me:$LINENO: result: no" >&5
+echo "${ECHO_T}no" >&6
+fi
+
+fi
+if test -z "$CC"; then
+  if test -n "$ac_tool_prefix"; then
+  for ac_prog in cl
+  do
+    # Extract the first word of "$ac_tool_prefix$ac_prog", so it can be a program name with args.
+set dummy $ac_tool_prefix$ac_prog; ac_word=$2
+echo "$as_me:$LINENO: checking for $ac_word" >&5
+echo $ECHO_N "checking for $ac_word... $ECHO_C" >&6
+if test "${ac_cv_prog_CC+set}" = set; then
+  echo $ECHO_N "(cached) $ECHO_C" >&6
+else
+  if test -n "$CC"; then
+  ac_cv_prog_CC="$CC" # Let the user override the test.
+else
+as_save_IFS=$IFS; IFS=$PATH_SEPARATOR
+for as_dir in $PATH
+do
+  IFS=$as_save_IFS
+  test -z "$as_dir" && as_dir=.
+  for ac_exec_ext in '' $ac_executable_extensions; do
+  if $as_executable_p "$as_dir/$ac_word$ac_exec_ext"; then
+    ac_cv_prog_CC="$ac_tool_prefix$ac_prog"
+    echo "$as_me:$LINENO: found $as_dir/$ac_word$ac_exec_ext" >&5
+    break 2
+  fi
+done
+done
+
+fi
+fi
+CC=$ac_cv_prog_CC
+if test -n "$CC"; then
+  echo "$as_me:$LINENO: result: $CC" >&5
+echo "${ECHO_T}$CC" >&6
+else
+  echo "$as_me:$LINENO: result: no" >&5
+echo "${ECHO_T}no" >&6
+fi
+
+    test -n "$CC" && break
+  done
+fi
+if test -z "$CC"; then
+  ac_ct_CC=$CC
+  for ac_prog in cl
+do
+  # Extract the first word of "$ac_prog", so it can be a program name with args.
+set dummy $ac_prog; ac_word=$2
+echo "$as_me:$LINENO: checking for $ac_word" >&5
+echo $ECHO_N "checking for $ac_word... $ECHO_C" >&6
+if test "${ac_cv_prog_ac_ct_CC+set}" = set; then
+  echo $ECHO_N "(cached) $ECHO_C" >&6
+else
+  if test -n "$ac_ct_CC"; then
+  ac_cv_prog_ac_ct_CC="$ac_ct_CC" # Let the user override the test.
+else
+as_save_IFS=$IFS; IFS=$PATH_SEPARATOR
+for as_dir in $PATH
+do
+  IFS=$as_save_IFS
+  test -z "$as_dir" && as_dir=.
+  for ac_exec_ext in '' $ac_executable_extensions; do
+  if $as_executable_p "$as_dir/$ac_word$ac_exec_ext"; then
+    ac_cv_prog_ac_ct_CC="$ac_prog"
+    echo "$as_me:$LINENO: found $as_dir/$ac_word$ac_exec_ext" >&5
+    break 2
+  fi
+done
+done
+
+fi
+fi
+ac_ct_CC=$ac_cv_prog_ac_ct_CC
+if test -n "$ac_ct_CC"; then
+  echo "$as_me:$LINENO: result: $ac_ct_CC" >&5
+echo "${ECHO_T}$ac_ct_CC" >&6
+else
+  echo "$as_me:$LINENO: result: no" >&5
+echo "${ECHO_T}no" >&6
+fi
+
+  test -n "$ac_ct_CC" && break
+done
+
+  CC=$ac_ct_CC
+fi
+
+fi
+
+
+test -z "$CC" && { { echo "$as_me:$LINENO: error: no acceptable C compiler found in \$PATH
+See \`config.log' for more details." >&5
+echo "$as_me: error: no acceptable C compiler found in \$PATH
+See \`config.log' for more details." >&2;}
+   { (exit 1); exit 1; }; }
+
+# Provide some information about the compiler.
+echo "$as_me:$LINENO:" \
+     "checking for C compiler version" >&5
+ac_compiler=`set X $ac_compile; echo $2`
+{ (eval echo "$as_me:$LINENO: \"$ac_compiler --version </dev/null >&5\"") >&5
+  (eval $ac_compiler --version </dev/null >&5) 2>&5
+  ac_status=$?
+  echo "$as_me:$LINENO: \$? = $ac_status" >&5
+  (exit $ac_status); }
+{ (eval echo "$as_me:$LINENO: \"$ac_compiler -v </dev/null >&5\"") >&5
+  (eval $ac_compiler -v </dev/null >&5) 2>&5
+  ac_status=$?
+  echo "$as_me:$LINENO: \$? = $ac_status" >&5
+  (exit $ac_status); }
+{ (eval echo "$as_me:$LINENO: \"$ac_compiler -V </dev/null >&5\"") >&5
+  (eval $ac_compiler -V </dev/null >&5) 2>&5
+  ac_status=$?
+  echo "$as_me:$LINENO: \$? = $ac_status" >&5
+  (exit $ac_status); }
+
+cat >conftest.$ac_ext <<_ACEOF
+/* confdefs.h.  */
+_ACEOF
+cat confdefs.h >>conftest.$ac_ext
+cat >>conftest.$ac_ext <<_ACEOF
+/* end confdefs.h.  */
+
+int
+main ()
+{
+
+  ;
+  return 0;
+}
+_ACEOF
+ac_clean_files_save=$ac_clean_files
+ac_clean_files="$ac_clean_files a.out a.exe b.out"
+# Try to create an executable without -o first, disregard a.out.
+# It will help us diagnose broken compilers, and finding out an intuition
+# of exeext.
+echo "$as_me:$LINENO: checking for C compiler default output file name" >&5
+echo $ECHO_N "checking for C compiler default output file name... $ECHO_C" >&6
+ac_link_default=`echo "$ac_link" | sed 's/ -o *conftest[^ ]*//'`
+if { (eval echo "$as_me:$LINENO: \"$ac_link_default\"") >&5
+  (eval $ac_link_default) 2>&5
+  ac_status=$?
+  echo "$as_me:$LINENO: \$? = $ac_status" >&5
+  (exit $ac_status); }; then
+  # Find the output, starting from the most likely.  This scheme is
+# not robust to junk in `.', hence go to wildcards (a.*) only as a last
+# resort.
+
+# Be careful to initialize this variable, since it used to be cached.
+# Otherwise an old cache value of `no' led to `EXEEXT = no' in a Makefile.
+ac_cv_exeext=
+# b.out is created by i960 compilers.
+for ac_file in a_out.exe a.exe conftest.exe a.out conftest a.* conftest.* b.out
+do
+  test -f "$ac_file" || continue
+  case $ac_file in
+    *.$ac_ext | *.xcoff | *.tds | *.d | *.pdb | *.xSYM | *.bb | *.bbg | *.o | *.obj )
+       ;;
+    conftest.$ac_ext )
+       # This is the source file.
+       ;;
+    [ab].out )
+       # We found the default executable, but exeext='' is most
+       # certainly right.
+       break;;
+    *.* )
+       ac_cv_exeext=`expr "$ac_file" : '[^.]*\(\..*\)'`
+       # FIXME: I believe we export ac_cv_exeext for Libtool,
+       # but it would be cool to find out if it's true.  Does anybody
+       # maintain Libtool? --akim.
+       export ac_cv_exeext
+       break;;
+    * )
+       break;;
+  esac
+done
+else
+  echo "$as_me: failed program was:" >&5
+sed 's/^/| /' conftest.$ac_ext >&5
+
+{ { echo "$as_me:$LINENO: error: C compiler cannot create executables
+See \`config.log' for more details." >&5
+echo "$as_me: error: C compiler cannot create executables
+See \`config.log' for more details." >&2;}
+   { (exit 77); exit 77; }; }
+fi
+
+ac_exeext=$ac_cv_exeext
+echo "$as_me:$LINENO: result: $ac_file" >&5
+echo "${ECHO_T}$ac_file" >&6
+
+# Check the compiler produces executables we can run.  If not, either
+# the compiler is broken, or we cross compile.
+echo "$as_me:$LINENO: checking whether the C compiler works" >&5
+echo $ECHO_N "checking whether the C compiler works... $ECHO_C" >&6
+# FIXME: These cross compiler hacks should be removed for Autoconf 3.0
+# If not cross compiling, check that we can run a simple program.
+if test "$cross_compiling" != yes; then
+  if { ac_try='./$ac_file'
+  { (eval echo "$as_me:$LINENO: \"$ac_try\"") >&5
+  (eval $ac_try) 2>&5
+  ac_status=$?
+  echo "$as_me:$LINENO: \$? = $ac_status" >&5
+  (exit $ac_status); }; }; then
+    cross_compiling=no
+  else
+    if test "$cross_compiling" = maybe; then
+       cross_compiling=yes
+    else
+       { { echo "$as_me:$LINENO: error: cannot run C compiled programs.
+If you meant to cross compile, use \`--host'.
+See \`config.log' for more details." >&5
+echo "$as_me: error: cannot run C compiled programs.
+If you meant to cross compile, use \`--host'.
+See \`config.log' for more details." >&2;}
+   { (exit 1); exit 1; }; }
+    fi
+  fi
+fi
+echo "$as_me:$LINENO: result: yes" >&5
+echo "${ECHO_T}yes" >&6
+
+rm -f a.out a.exe conftest$ac_cv_exeext b.out
+ac_clean_files=$ac_clean_files_save
+# Check the compiler produces executables we can run.  If not, either
+# the compiler is broken, or we cross compile.
+echo "$as_me:$LINENO: checking whether we are cross compiling" >&5
+echo $ECHO_N "checking whether we are cross compiling... $ECHO_C" >&6
+echo "$as_me:$LINENO: result: $cross_compiling" >&5
+echo "${ECHO_T}$cross_compiling" >&6
+
+echo "$as_me:$LINENO: checking for suffix of executables" >&5
+echo $ECHO_N "checking for suffix of executables... $ECHO_C" >&6
+if { (eval echo "$as_me:$LINENO: \"$ac_link\"") >&5
+  (eval $ac_link) 2>&5
+  ac_status=$?
+  echo "$as_me:$LINENO: \$? = $ac_status" >&5
+  (exit $ac_status); }; then
+  # If both `conftest.exe' and `conftest' are `present' (well, observable)
+# catch `conftest.exe'.  For instance with Cygwin, `ls conftest' will
+# work properly (i.e., refer to `conftest.exe'), while it won't with
+# `rm'.
+for ac_file in conftest.exe conftest conftest.*; do
+  test -f "$ac_file" || continue
+  case $ac_file in
+    *.$ac_ext | *.xcoff | *.tds | *.d | *.pdb | *.xSYM | *.bb | *.bbg | *.o | *.obj ) ;;
+    *.* ) ac_cv_exeext=`expr "$ac_file" : '[^.]*\(\..*\)'`
+         export ac_cv_exeext
+         break;;
+    * ) break;;
+  esac
+done
+else
+  { { echo "$as_me:$LINENO: error: cannot compute suffix of executables: cannot compile and link
+See \`config.log' for more details." >&5
+echo "$as_me: error: cannot compute suffix of executables: cannot compile and link
+See \`config.log' for more details." >&2;}
+   { (exit 1); exit 1; }; }
+fi
+
+rm -f conftest$ac_cv_exeext
+echo "$as_me:$LINENO: result: $ac_cv_exeext" >&5
+echo "${ECHO_T}$ac_cv_exeext" >&6
+
+rm -f conftest.$ac_ext
+EXEEXT=$ac_cv_exeext
+ac_exeext=$EXEEXT
+echo "$as_me:$LINENO: checking for suffix of object files" >&5
+echo $ECHO_N "checking for suffix of object files... $ECHO_C" >&6
+if test "${ac_cv_objext+set}" = set; then
+  echo $ECHO_N "(cached) $ECHO_C" >&6
+else
+  cat >conftest.$ac_ext <<_ACEOF
+/* confdefs.h.  */
+_ACEOF
+cat confdefs.h >>conftest.$ac_ext
+cat >>conftest.$ac_ext <<_ACEOF
+/* end confdefs.h.  */
+
+int
+main ()
+{
+
+  ;
+  return 0;
+}
+_ACEOF
+rm -f conftest.o conftest.obj
+if { (eval echo "$as_me:$LINENO: \"$ac_compile\"") >&5
+  (eval $ac_compile) 2>&5
+  ac_status=$?
+  echo "$as_me:$LINENO: \$? = $ac_status" >&5
+  (exit $ac_status); }; then
+  for ac_file in `(ls conftest.o conftest.obj; ls conftest.*) 2>/dev/null`; do
+  case $ac_file in
+    *.$ac_ext | *.xcoff | *.tds | *.d | *.pdb | *.xSYM | *.bb | *.bbg ) ;;
+    *) ac_cv_objext=`expr "$ac_file" : '.*\.\(.*\)'`
+       break;;
+  esac
+done
+else
+  echo "$as_me: failed program was:" >&5
+sed 's/^/| /' conftest.$ac_ext >&5
+
+{ { echo "$as_me:$LINENO: error: cannot compute suffix of object files: cannot compile
+See \`config.log' for more details." >&5
+echo "$as_me: error: cannot compute suffix of object files: cannot compile
+See \`config.log' for more details." >&2;}
+   { (exit 1); exit 1; }; }
+fi
+
+rm -f conftest.$ac_cv_objext conftest.$ac_ext
+fi
+echo "$as_me:$LINENO: result: $ac_cv_objext" >&5
+echo "${ECHO_T}$ac_cv_objext" >&6
+OBJEXT=$ac_cv_objext
+ac_objext=$OBJEXT
+echo "$as_me:$LINENO: checking whether we are using the GNU C compiler" >&5
+echo $ECHO_N "checking whether we are using the GNU C compiler... $ECHO_C" >&6
+if test "${ac_cv_c_compiler_gnu+set}" = set; then
+  echo $ECHO_N "(cached) $ECHO_C" >&6
+else
+  cat >conftest.$ac_ext <<_ACEOF
+/* confdefs.h.  */
+_ACEOF
+cat confdefs.h >>conftest.$ac_ext
+cat >>conftest.$ac_ext <<_ACEOF
+/* end confdefs.h.  */
+
+int
+main ()
+{
+#ifndef __GNUC__
+       choke me
+#endif
+
+  ;
+  return 0;
+}
+_ACEOF
+rm -f conftest.$ac_objext
+if { (eval echo "$as_me:$LINENO: \"$ac_compile\"") >&5
+  (eval $ac_compile) 2>conftest.er1
+  ac_status=$?
+  grep -v '^ *+' conftest.er1 >conftest.err
+  rm -f conftest.er1
+  cat conftest.err >&5
+  echo "$as_me:$LINENO: \$? = $ac_status" >&5
+  (exit $ac_status); } &&
+        { ac_try='test -z "$ac_c_werror_flag"
+                        || test ! -s conftest.err'
+  { (eval echo "$as_me:$LINENO: \"$ac_try\"") >&5
+  (eval $ac_try) 2>&5
+  ac_status=$?
+  echo "$as_me:$LINENO: \$? = $ac_status" >&5
+  (exit $ac_status); }; } &&
+        { ac_try='test -s conftest.$ac_objext'
+  { (eval echo "$as_me:$LINENO: \"$ac_try\"") >&5
+  (eval $ac_try) 2>&5
+  ac_status=$?
+  echo "$as_me:$LINENO: \$? = $ac_status" >&5
+  (exit $ac_status); }; }; then
+  ac_compiler_gnu=yes
+else
+  echo "$as_me: failed program was:" >&5
+sed 's/^/| /' conftest.$ac_ext >&5
+
+ac_compiler_gnu=no
+fi
+rm -f conftest.err conftest.$ac_objext conftest.$ac_ext
+ac_cv_c_compiler_gnu=$ac_compiler_gnu
+
+fi
+echo "$as_me:$LINENO: result: $ac_cv_c_compiler_gnu" >&5
+echo "${ECHO_T}$ac_cv_c_compiler_gnu" >&6
+GCC=`test $ac_compiler_gnu = yes && echo yes`
+ac_test_CFLAGS=${CFLAGS+set}
+ac_save_CFLAGS=$CFLAGS
+CFLAGS="-g"
+echo "$as_me:$LINENO: checking whether $CC accepts -g" >&5
+echo $ECHO_N "checking whether $CC accepts -g... $ECHO_C" >&6
+if test "${ac_cv_prog_cc_g+set}" = set; then
+  echo $ECHO_N "(cached) $ECHO_C" >&6
+else
+  cat >conftest.$ac_ext <<_ACEOF
+/* confdefs.h.  */
+_ACEOF
+cat confdefs.h >>conftest.$ac_ext
+cat >>conftest.$ac_ext <<_ACEOF
+/* end confdefs.h.  */
+
+int
+main ()
+{
+
+  ;
+  return 0;
+}
+_ACEOF
+rm -f conftest.$ac_objext
+if { (eval echo "$as_me:$LINENO: \"$ac_compile\"") >&5
+  (eval $ac_compile) 2>conftest.er1
+  ac_status=$?
+  grep -v '^ *+' conftest.er1 >conftest.err
+  rm -f conftest.er1
+  cat conftest.err >&5
+  echo "$as_me:$LINENO: \$? = $ac_status" >&5
+  (exit $ac_status); } &&
+        { ac_try='test -z "$ac_c_werror_flag"
+                        || test ! -s conftest.err'
+  { (eval echo "$as_me:$LINENO: \"$ac_try\"") >&5
+  (eval $ac_try) 2>&5
+  ac_status=$?
+  echo "$as_me:$LINENO: \$? = $ac_status" >&5
+  (exit $ac_status); }; } &&
+        { ac_try='test -s conftest.$ac_objext'
+  { (eval echo "$as_me:$LINENO: \"$ac_try\"") >&5
+  (eval $ac_try) 2>&5
+  ac_status=$?
+  echo "$as_me:$LINENO: \$? = $ac_status" >&5
+  (exit $ac_status); }; }; then
+  ac_cv_prog_cc_g=yes
+else
+  echo "$as_me: failed program was:" >&5
+sed 's/^/| /' conftest.$ac_ext >&5
+
+ac_cv_prog_cc_g=no
+fi
+rm -f conftest.err conftest.$ac_objext conftest.$ac_ext
+fi
+echo "$as_me:$LINENO: result: $ac_cv_prog_cc_g" >&5
+echo "${ECHO_T}$ac_cv_prog_cc_g" >&6
+if test "$ac_test_CFLAGS" = set; then
+  CFLAGS=$ac_save_CFLAGS
+elif test $ac_cv_prog_cc_g = yes; then
+  if test "$GCC" = yes; then
+    CFLAGS="-g -O2"
+  else
+    CFLAGS="-g"
+  fi
+else
+  if test "$GCC" = yes; then
+    CFLAGS="-O2"
+  else
+    CFLAGS=
+  fi
+fi
+echo "$as_me:$LINENO: checking for $CC option to accept ANSI C" >&5
+echo $ECHO_N "checking for $CC option to accept ANSI C... $ECHO_C" >&6
+if test "${ac_cv_prog_cc_stdc+set}" = set; then
+  echo $ECHO_N "(cached) $ECHO_C" >&6
+else
+  ac_cv_prog_cc_stdc=no
+ac_save_CC=$CC
+cat >conftest.$ac_ext <<_ACEOF
+/* confdefs.h.  */
+_ACEOF
+cat confdefs.h >>conftest.$ac_ext
+cat >>conftest.$ac_ext <<_ACEOF
+/* end confdefs.h.  */
+#include <stdarg.h>
+#include <stdio.h>
+#include <sys/types.h>
+#include <sys/stat.h>
+/* Most of the following tests are stolen from RCS 5.7's src/conf.sh.  */
+struct buf { int x; };
+FILE * (*rcsopen) (struct buf *, struct stat *, int);
+static char *e (p, i)
+     char **p;
+     int i;
+{
+  return p[i];
+}
+static char *f (char * (*g) (char **, int), char **p, ...)
+{
+  char *s;
+  va_list v;
+  va_start (v,p);
+  s = g (p, va_arg (v,int));
+  va_end (v);
+  return s;
+}
+
+/* OSF 4.0 Compaq cc is some sort of almost-ANSI by default.  It has
+   function prototypes and stuff, but not '\xHH' hex character constants.
+   These don't provoke an error unfortunately, instead are silently treated
+   as 'x'.  The following induces an error, until -std1 is added to get
+   proper ANSI mode.  Curiously '\x00'!='x' always comes out true, for an
+   array size at least.  It's necessary to write '\x00'==0 to get something
+   that's true only with -std1.  */
+int osf4_cc_array ['\x00' == 0 ? 1 : -1];
+
+int test (int i, double x);
+struct s1 {int (*f) (int a);};
+struct s2 {int (*f) (double a);};
+int pairnames (int, char **, FILE *(*)(struct buf *, struct stat *, int), int, int);
+int argc;
+char **argv;
+int
+main ()
+{
+return f (e, argv, 0) != argv[0]  ||  f (e, argv, 1) != argv[1];
+  ;
+  return 0;
+}
+_ACEOF
+# Don't try gcc -ansi; that turns off useful extensions and
+# breaks some systems' header files.
+# AIX                  -qlanglvl=ansi
+# Ultrix and OSF/1     -std1
+# HP-UX 10.20 and later        -Ae
+# HP-UX older versions -Aa -D_HPUX_SOURCE
+# SVR4                 -Xc -D__EXTENSIONS__
+for ac_arg in "" -qlanglvl=ansi -std1 -Ae "-Aa -D_HPUX_SOURCE" "-Xc -D__EXTENSIONS__"
+do
+  CC="$ac_save_CC $ac_arg"
+  rm -f conftest.$ac_objext
+if { (eval echo "$as_me:$LINENO: \"$ac_compile\"") >&5
+  (eval $ac_compile) 2>conftest.er1
+  ac_status=$?
+  grep -v '^ *+' conftest.er1 >conftest.err
+  rm -f conftest.er1
+  cat conftest.err >&5
+  echo "$as_me:$LINENO: \$? = $ac_status" >&5
+  (exit $ac_status); } &&
+        { ac_try='test -z "$ac_c_werror_flag"
+                        || test ! -s conftest.err'
+  { (eval echo "$as_me:$LINENO: \"$ac_try\"") >&5
+  (eval $ac_try) 2>&5
+  ac_status=$?
+  echo "$as_me:$LINENO: \$? = $ac_status" >&5
+  (exit $ac_status); }; } &&
+        { ac_try='test -s conftest.$ac_objext'
+  { (eval echo "$as_me:$LINENO: \"$ac_try\"") >&5
+  (eval $ac_try) 2>&5
+  ac_status=$?
+  echo "$as_me:$LINENO: \$? = $ac_status" >&5
+  (exit $ac_status); }; }; then
+  ac_cv_prog_cc_stdc=$ac_arg
+break
+else
+  echo "$as_me: failed program was:" >&5
+sed 's/^/| /' conftest.$ac_ext >&5
+
+fi
+rm -f conftest.err conftest.$ac_objext
+done
+rm -f conftest.$ac_ext conftest.$ac_objext
+CC=$ac_save_CC
+
+fi
+
+case "x$ac_cv_prog_cc_stdc" in
+  x|xno)
+    echo "$as_me:$LINENO: result: none needed" >&5
+echo "${ECHO_T}none needed" >&6 ;;
+  *)
+    echo "$as_me:$LINENO: result: $ac_cv_prog_cc_stdc" >&5
+echo "${ECHO_T}$ac_cv_prog_cc_stdc" >&6
+    CC="$CC $ac_cv_prog_cc_stdc" ;;
+esac
+
+# Some people use a C++ compiler to compile C.  Since we use `exit',
+# in C++ we need to declare it.  In case someone uses the same compiler
+# for both compiling C and C++ we need to have the C++ compiler decide
+# the declaration of exit, since it's the most demanding environment.
+cat >conftest.$ac_ext <<_ACEOF
+#ifndef __cplusplus
+  choke me
+#endif
+_ACEOF
+rm -f conftest.$ac_objext
+if { (eval echo "$as_me:$LINENO: \"$ac_compile\"") >&5
+  (eval $ac_compile) 2>conftest.er1
+  ac_status=$?
+  grep -v '^ *+' conftest.er1 >conftest.err
+  rm -f conftest.er1
+  cat conftest.err >&5
+  echo "$as_me:$LINENO: \$? = $ac_status" >&5
+  (exit $ac_status); } &&
+        { ac_try='test -z "$ac_c_werror_flag"
+                        || test ! -s conftest.err'
+  { (eval echo "$as_me:$LINENO: \"$ac_try\"") >&5
+  (eval $ac_try) 2>&5
+  ac_status=$?
+  echo "$as_me:$LINENO: \$? = $ac_status" >&5
+  (exit $ac_status); }; } &&
+        { ac_try='test -s conftest.$ac_objext'
+  { (eval echo "$as_me:$LINENO: \"$ac_try\"") >&5
+  (eval $ac_try) 2>&5
+  ac_status=$?
+  echo "$as_me:$LINENO: \$? = $ac_status" >&5
+  (exit $ac_status); }; }; then
+  for ac_declaration in \
+   '' \
+   'extern "C" void std::exit (int) throw (); using std::exit;' \
+   'extern "C" void std::exit (int); using std::exit;' \
+   'extern "C" void exit (int) throw ();' \
+   'extern "C" void exit (int);' \
+   'void exit (int);'
+do
+  cat >conftest.$ac_ext <<_ACEOF
+/* confdefs.h.  */
+_ACEOF
+cat confdefs.h >>conftest.$ac_ext
+cat >>conftest.$ac_ext <<_ACEOF
+/* end confdefs.h.  */
+$ac_declaration
+#include <stdlib.h>
+int
+main ()
+{
+exit (42);
+  ;
+  return 0;
+}
+_ACEOF
+rm -f conftest.$ac_objext
+if { (eval echo "$as_me:$LINENO: \"$ac_compile\"") >&5
+  (eval $ac_compile) 2>conftest.er1
+  ac_status=$?
+  grep -v '^ *+' conftest.er1 >conftest.err
+  rm -f conftest.er1
+  cat conftest.err >&5
+  echo "$as_me:$LINENO: \$? = $ac_status" >&5
+  (exit $ac_status); } &&
+        { ac_try='test -z "$ac_c_werror_flag"
+                        || test ! -s conftest.err'
+  { (eval echo "$as_me:$LINENO: \"$ac_try\"") >&5
+  (eval $ac_try) 2>&5
+  ac_status=$?
+  echo "$as_me:$LINENO: \$? = $ac_status" >&5
+  (exit $ac_status); }; } &&
+        { ac_try='test -s conftest.$ac_objext'
+  { (eval echo "$as_me:$LINENO: \"$ac_try\"") >&5
+  (eval $ac_try) 2>&5
+  ac_status=$?
+  echo "$as_me:$LINENO: \$? = $ac_status" >&5
+  (exit $ac_status); }; }; then
+  :
+else
+  echo "$as_me: failed program was:" >&5
+sed 's/^/| /' conftest.$ac_ext >&5
+
+continue
+fi
+rm -f conftest.err conftest.$ac_objext conftest.$ac_ext
+  cat >conftest.$ac_ext <<_ACEOF
+/* confdefs.h.  */
+_ACEOF
+cat confdefs.h >>conftest.$ac_ext
+cat >>conftest.$ac_ext <<_ACEOF
+/* end confdefs.h.  */
+$ac_declaration
+int
+main ()
+{
+exit (42);
+  ;
+  return 0;
+}
+_ACEOF
+rm -f conftest.$ac_objext
+if { (eval echo "$as_me:$LINENO: \"$ac_compile\"") >&5
+  (eval $ac_compile) 2>conftest.er1
+  ac_status=$?
+  grep -v '^ *+' conftest.er1 >conftest.err
+  rm -f conftest.er1
+  cat conftest.err >&5
+  echo "$as_me:$LINENO: \$? = $ac_status" >&5
+  (exit $ac_status); } &&
+        { ac_try='test -z "$ac_c_werror_flag"
+                        || test ! -s conftest.err'
+  { (eval echo "$as_me:$LINENO: \"$ac_try\"") >&5
+  (eval $ac_try) 2>&5
+  ac_status=$?
+  echo "$as_me:$LINENO: \$? = $ac_status" >&5
+  (exit $ac_status); }; } &&
+        { ac_try='test -s conftest.$ac_objext'
+  { (eval echo "$as_me:$LINENO: \"$ac_try\"") >&5
+  (eval $ac_try) 2>&5
+  ac_status=$?
+  echo "$as_me:$LINENO: \$? = $ac_status" >&5
+  (exit $ac_status); }; }; then
+  break
+else
+  echo "$as_me: failed program was:" >&5
+sed 's/^/| /' conftest.$ac_ext >&5
+
+fi
+rm -f conftest.err conftest.$ac_objext conftest.$ac_ext
+done
+rm -f conftest*
+if test -n "$ac_declaration"; then
+  echo '#ifdef __cplusplus' >>confdefs.h
+  echo $ac_declaration      >>confdefs.h
+  echo '#endif'             >>confdefs.h
+fi
+
+else
+  echo "$as_me: failed program was:" >&5
+sed 's/^/| /' conftest.$ac_ext >&5
+
+fi
+rm -f conftest.err conftest.$ac_objext conftest.$ac_ext
+ac_ext=c
+ac_cpp='$CPP $CPPFLAGS'
+ac_compile='$CC -c $CFLAGS $CPPFLAGS conftest.$ac_ext >&5'
+ac_link='$CC -o conftest$ac_exeext $CFLAGS $CPPFLAGS $LDFLAGS conftest.$ac_ext $LIBS >&5'
+ac_compiler_gnu=$ac_cv_c_compiler_gnu
+
+#AM_PROG_LIBTOOL
+
+# Extract the first word of "autogen", so it can be a program name with args.
+set dummy autogen; ac_word=$2
+echo "$as_me:$LINENO: checking for $ac_word" >&5
+echo $ECHO_N "checking for $ac_word... $ECHO_C" >&6
+if test "${ac_cv_prog_autogen+set}" = set; then
+  echo $ECHO_N "(cached) $ECHO_C" >&6
+else
+  if test -n "$autogen"; then
+  ac_cv_prog_autogen="$autogen" # Let the user override the test.
+else
+as_save_IFS=$IFS; IFS=$PATH_SEPARATOR
+for as_dir in $PATH
+do
+  IFS=$as_save_IFS
+  test -z "$as_dir" && as_dir=.
+  for ac_exec_ext in '' $ac_executable_extensions; do
+  if $as_executable_p "$as_dir/$ac_word$ac_exec_ext"; then
+    ac_cv_prog_autogen="yes"
+    echo "$as_me:$LINENO: found $as_dir/$ac_word$ac_exec_ext" >&5
+    break 2
+  fi
+done
+done
+
+  test -z "$ac_cv_prog_autogen" && ac_cv_prog_autogen="no"
+fi
+fi
+autogen=$ac_cv_prog_autogen
+if test -n "$autogen"; then
+  echo "$as_me:$LINENO: result: $autogen" >&5
+echo "${ECHO_T}$autogen" >&6
+else
+  echo "$as_me:$LINENO: result: no" >&5
+echo "${ECHO_T}no" >&6
+fi
+
+
+# Find a good install program.  We prefer a C program (faster),
+# so one script is as good as another.  But avoid the broken or
+# incompatible versions:
+# SysV /etc/install, /usr/sbin/install
+# SunOS /usr/etc/install
+# IRIX /sbin/install
+# AIX /bin/install
+# AmigaOS /C/install, which installs bootblocks on floppy discs
+# AIX 4 /usr/bin/installbsd, which doesn't work without a -g flag
+# AFS /usr/afsws/bin/install, which mishandles nonexistent args
+# SVR4 /usr/ucb/install, which tries to use the nonexistent group "staff"
+# OS/2's system install, which has a completely different semantic
+# ./install, which can be erroneously created by make from ./install.sh.
+echo "$as_me:$LINENO: checking for a BSD-compatible install" >&5
+echo $ECHO_N "checking for a BSD-compatible install... $ECHO_C" >&6
+if test -z "$INSTALL"; then
+if test "${ac_cv_path_install+set}" = set; then
+  echo $ECHO_N "(cached) $ECHO_C" >&6
+else
+  as_save_IFS=$IFS; IFS=$PATH_SEPARATOR
+for as_dir in $PATH
+do
+  IFS=$as_save_IFS
+  test -z "$as_dir" && as_dir=.
+  # Account for people who put trailing slashes in PATH elements.
+case $as_dir/ in
+  ./ | .// | /cC/* | \
+  /etc/* | /usr/sbin/* | /usr/etc/* | /sbin/* | /usr/afsws/bin/* | \
+  ?:\\/os2\\/install\\/* | ?:\\/OS2\\/INSTALL\\/* | \
+  /usr/ucb/* ) ;;
+  *)
+    # OSF1 and SCO ODT 3.0 have their own names for install.
+    # Don't use installbsd from OSF since it installs stuff as root
+    # by default.
+    for ac_prog in ginstall scoinst install; do
+      for ac_exec_ext in '' $ac_executable_extensions; do
+       if $as_executable_p "$as_dir/$ac_prog$ac_exec_ext"; then
+         if test $ac_prog = install &&
+           grep dspmsg "$as_dir/$ac_prog$ac_exec_ext" >/dev/null 2>&1; then
+           # AIX install.  It has an incompatible calling convention.
+           :
+         elif test $ac_prog = install &&
+           grep pwplus "$as_dir/$ac_prog$ac_exec_ext" >/dev/null 2>&1; then
+           # program-specific install script used by HP pwplus--don't use.
+           :
+         else
+           ac_cv_path_install="$as_dir/$ac_prog$ac_exec_ext -c"
+           break 3
+         fi
+       fi
+      done
+    done
+    ;;
+esac
+done
+
+
+fi
+  if test "${ac_cv_path_install+set}" = set; then
+    INSTALL=$ac_cv_path_install
+  else
+    # As a last resort, use the slow shell script.  We don't cache a
+    # path for INSTALL within a source directory, because that will
+    # break other packages using the cache if that directory is
+    # removed, or if the path is relative.
+    INSTALL=$ac_install_sh
+  fi
+fi
+echo "$as_me:$LINENO: result: $INSTALL" >&5
+echo "${ECHO_T}$INSTALL" >&6
+
+# Use test -z because SunOS4 sh mishandles braces in ${var-val}.
+# It thinks the first close brace ends the variable substitution.
+test -z "$INSTALL_PROGRAM" && INSTALL_PROGRAM='${INSTALL}'
+
+test -z "$INSTALL_SCRIPT" && INSTALL_SCRIPT='${INSTALL}'
+
+test -z "$INSTALL_DATA" && INSTALL_DATA='${INSTALL} -m 644'
+
+echo "$as_me:$LINENO: checking whether ln -s works" >&5
+echo $ECHO_N "checking whether ln -s works... $ECHO_C" >&6
+LN_S=$as_ln_s
+if test "$LN_S" = "ln -s"; then
+  echo "$as_me:$LINENO: result: yes" >&5
+echo "${ECHO_T}yes" >&6
+else
+  echo "$as_me:$LINENO: result: no, using $LN_S" >&5
+echo "${ECHO_T}no, using $LN_S" >&6
+fi
+
+
+
+ac_ext=c
+ac_cpp='$CPP $CPPFLAGS'
+ac_compile='$CC -c $CFLAGS $CPPFLAGS conftest.$ac_ext >&5'
+ac_link='$CC -o conftest$ac_exeext $CFLAGS $CPPFLAGS $LDFLAGS conftest.$ac_ext $LIBS >&5'
+ac_compiler_gnu=$ac_cv_c_compiler_gnu
+echo "$as_me:$LINENO: checking how to run the C preprocessor" >&5
+echo $ECHO_N "checking how to run the C preprocessor... $ECHO_C" >&6
+# On Suns, sometimes $CPP names a directory.
+if test -n "$CPP" && test -d "$CPP"; then
+  CPP=
+fi
+if test -z "$CPP"; then
+  if test "${ac_cv_prog_CPP+set}" = set; then
+  echo $ECHO_N "(cached) $ECHO_C" >&6
+else
+      # Double quotes because CPP needs to be expanded
+    for CPP in "$CC -E" "$CC -E -traditional-cpp" "/lib/cpp"
+    do
+      ac_preproc_ok=false
+for ac_c_preproc_warn_flag in '' yes
+do
+  # Use a header file that comes with gcc, so configuring glibc
+  # with a fresh cross-compiler works.
+  # Prefer <limits.h> to <assert.h> if __STDC__ is defined, since
+  # <limits.h> exists even on freestanding compilers.
+  # On the NeXT, cc -E runs the code through the compiler's parser,
+  # not just through cpp. "Syntax error" is here to catch this case.
+  cat >conftest.$ac_ext <<_ACEOF
+/* confdefs.h.  */
+_ACEOF
+cat confdefs.h >>conftest.$ac_ext
+cat >>conftest.$ac_ext <<_ACEOF
+/* end confdefs.h.  */
+#ifdef __STDC__
+# include <limits.h>
+#else
+# include <assert.h>
+#endif
+                    Syntax error
+_ACEOF
+if { (eval echo "$as_me:$LINENO: \"$ac_cpp conftest.$ac_ext\"") >&5
+  (eval $ac_cpp conftest.$ac_ext) 2>conftest.er1
+  ac_status=$?
+  grep -v '^ *+' conftest.er1 >conftest.err
+  rm -f conftest.er1
+  cat conftest.err >&5
+  echo "$as_me:$LINENO: \$? = $ac_status" >&5
+  (exit $ac_status); } >/dev/null; then
+  if test -s conftest.err; then
+    ac_cpp_err=$ac_c_preproc_warn_flag
+    ac_cpp_err=$ac_cpp_err$ac_c_werror_flag
+  else
+    ac_cpp_err=
+  fi
+else
+  ac_cpp_err=yes
+fi
+if test -z "$ac_cpp_err"; then
+  :
+else
+  echo "$as_me: failed program was:" >&5
+sed 's/^/| /' conftest.$ac_ext >&5
+
+  # Broken: fails on valid input.
+continue
+fi
+rm -f conftest.err conftest.$ac_ext
+
+  # OK, works on sane cases.  Now check whether non-existent headers
+  # can be detected and how.
+  cat >conftest.$ac_ext <<_ACEOF
+/* confdefs.h.  */
+_ACEOF
+cat confdefs.h >>conftest.$ac_ext
+cat >>conftest.$ac_ext <<_ACEOF
+/* end confdefs.h.  */
+#include <ac_nonexistent.h>
+_ACEOF
+if { (eval echo "$as_me:$LINENO: \"$ac_cpp conftest.$ac_ext\"") >&5
+  (eval $ac_cpp conftest.$ac_ext) 2>conftest.er1
+  ac_status=$?
+  grep -v '^ *+' conftest.er1 >conftest.err
+  rm -f conftest.er1
+  cat conftest.err >&5
+  echo "$as_me:$LINENO: \$? = $ac_status" >&5
+  (exit $ac_status); } >/dev/null; then
+  if test -s conftest.err; then
+    ac_cpp_err=$ac_c_preproc_warn_flag
+    ac_cpp_err=$ac_cpp_err$ac_c_werror_flag
+  else
+    ac_cpp_err=
+  fi
+else
+  ac_cpp_err=yes
+fi
+if test -z "$ac_cpp_err"; then
+  # Broken: success on invalid input.
+continue
+else
+  echo "$as_me: failed program was:" >&5
+sed 's/^/| /' conftest.$ac_ext >&5
+
+  # Passes both tests.
+ac_preproc_ok=:
+break
+fi
+rm -f conftest.err conftest.$ac_ext
+
+done
+# Because of `break', _AC_PREPROC_IFELSE's cleaning code was skipped.
+rm -f conftest.err conftest.$ac_ext
+if $ac_preproc_ok; then
+  break
+fi
+
+    done
+    ac_cv_prog_CPP=$CPP
+
+fi
+  CPP=$ac_cv_prog_CPP
+else
+  ac_cv_prog_CPP=$CPP
+fi
+echo "$as_me:$LINENO: result: $CPP" >&5
+echo "${ECHO_T}$CPP" >&6
+ac_preproc_ok=false
+for ac_c_preproc_warn_flag in '' yes
+do
+  # Use a header file that comes with gcc, so configuring glibc
+  # with a fresh cross-compiler works.
+  # Prefer <limits.h> to <assert.h> if __STDC__ is defined, since
+  # <limits.h> exists even on freestanding compilers.
+  # On the NeXT, cc -E runs the code through the compiler's parser,
+  # not just through cpp. "Syntax error" is here to catch this case.
+  cat >conftest.$ac_ext <<_ACEOF
+/* confdefs.h.  */
+_ACEOF
+cat confdefs.h >>conftest.$ac_ext
+cat >>conftest.$ac_ext <<_ACEOF
+/* end confdefs.h.  */
+#ifdef __STDC__
+# include <limits.h>
+#else
+# include <assert.h>
+#endif
+                    Syntax error
+_ACEOF
+if { (eval echo "$as_me:$LINENO: \"$ac_cpp conftest.$ac_ext\"") >&5
+  (eval $ac_cpp conftest.$ac_ext) 2>conftest.er1
+  ac_status=$?
+  grep -v '^ *+' conftest.er1 >conftest.err
+  rm -f conftest.er1
+  cat conftest.err >&5
+  echo "$as_me:$LINENO: \$? = $ac_status" >&5
+  (exit $ac_status); } >/dev/null; then
+  if test -s conftest.err; then
+    ac_cpp_err=$ac_c_preproc_warn_flag
+    ac_cpp_err=$ac_cpp_err$ac_c_werror_flag
+  else
+    ac_cpp_err=
+  fi
+else
+  ac_cpp_err=yes
+fi
+if test -z "$ac_cpp_err"; then
+  :
+else
+  echo "$as_me: failed program was:" >&5
+sed 's/^/| /' conftest.$ac_ext >&5
+
+  # Broken: fails on valid input.
+continue
+fi
+rm -f conftest.err conftest.$ac_ext
+
+  # OK, works on sane cases.  Now check whether non-existent headers
+  # can be detected and how.
+  cat >conftest.$ac_ext <<_ACEOF
+/* confdefs.h.  */
+_ACEOF
+cat confdefs.h >>conftest.$ac_ext
+cat >>conftest.$ac_ext <<_ACEOF
+/* end confdefs.h.  */
+#include <ac_nonexistent.h>
+_ACEOF
+if { (eval echo "$as_me:$LINENO: \"$ac_cpp conftest.$ac_ext\"") >&5
+  (eval $ac_cpp conftest.$ac_ext) 2>conftest.er1
+  ac_status=$?
+  grep -v '^ *+' conftest.er1 >conftest.err
+  rm -f conftest.er1
+  cat conftest.err >&5
+  echo "$as_me:$LINENO: \$? = $ac_status" >&5
+  (exit $ac_status); } >/dev/null; then
+  if test -s conftest.err; then
+    ac_cpp_err=$ac_c_preproc_warn_flag
+    ac_cpp_err=$ac_cpp_err$ac_c_werror_flag
+  else
+    ac_cpp_err=
+  fi
+else
+  ac_cpp_err=yes
+fi
+if test -z "$ac_cpp_err"; then
+  # Broken: success on invalid input.
+continue
+else
+  echo "$as_me: failed program was:" >&5
+sed 's/^/| /' conftest.$ac_ext >&5
+
+  # Passes both tests.
+ac_preproc_ok=:
+break
+fi
+rm -f conftest.err conftest.$ac_ext
+
+done
+# Because of `break', _AC_PREPROC_IFELSE's cleaning code was skipped.
+rm -f conftest.err conftest.$ac_ext
+if $ac_preproc_ok; then
+  :
+else
+  { { echo "$as_me:$LINENO: error: C preprocessor \"$CPP\" fails sanity check
+See \`config.log' for more details." >&5
+echo "$as_me: error: C preprocessor \"$CPP\" fails sanity check
+See \`config.log' for more details." >&2;}
+   { (exit 1); exit 1; }; }
+fi
+
+ac_ext=c
+ac_cpp='$CPP $CPPFLAGS'
+ac_compile='$CC -c $CFLAGS $CPPFLAGS conftest.$ac_ext >&5'
+ac_link='$CC -o conftest$ac_exeext $CFLAGS $CPPFLAGS $LDFLAGS conftest.$ac_ext $LIBS >&5'
+ac_compiler_gnu=$ac_cv_c_compiler_gnu
+
+
+echo "$as_me:$LINENO: checking for egrep" >&5
+echo $ECHO_N "checking for egrep... $ECHO_C" >&6
+if test "${ac_cv_prog_egrep+set}" = set; then
+  echo $ECHO_N "(cached) $ECHO_C" >&6
+else
+  if echo a | (grep -E '(a|b)') >/dev/null 2>&1
+    then ac_cv_prog_egrep='grep -E'
+    else ac_cv_prog_egrep='egrep'
+    fi
+fi
+echo "$as_me:$LINENO: result: $ac_cv_prog_egrep" >&5
+echo "${ECHO_T}$ac_cv_prog_egrep" >&6
+ EGREP=$ac_cv_prog_egrep
+
+
+echo "$as_me:$LINENO: checking for ANSI C header files" >&5
+echo $ECHO_N "checking for ANSI C header files... $ECHO_C" >&6
+if test "${ac_cv_header_stdc+set}" = set; then
+  echo $ECHO_N "(cached) $ECHO_C" >&6
+else
+  cat >conftest.$ac_ext <<_ACEOF
+/* confdefs.h.  */
+_ACEOF
+cat confdefs.h >>conftest.$ac_ext
+cat >>conftest.$ac_ext <<_ACEOF
+/* end confdefs.h.  */
+#include <stdlib.h>
+#include <stdarg.h>
+#include <string.h>
+#include <float.h>
+
+int
+main ()
+{
+
+  ;
+  return 0;
+}
+_ACEOF
+rm -f conftest.$ac_objext
+if { (eval echo "$as_me:$LINENO: \"$ac_compile\"") >&5
+  (eval $ac_compile) 2>conftest.er1
+  ac_status=$?
+  grep -v '^ *+' conftest.er1 >conftest.err
+  rm -f conftest.er1
+  cat conftest.err >&5
+  echo "$as_me:$LINENO: \$? = $ac_status" >&5
+  (exit $ac_status); } &&
+        { ac_try='test -z "$ac_c_werror_flag"
+                        || test ! -s conftest.err'
+  { (eval echo "$as_me:$LINENO: \"$ac_try\"") >&5
+  (eval $ac_try) 2>&5
+  ac_status=$?
+  echo "$as_me:$LINENO: \$? = $ac_status" >&5
+  (exit $ac_status); }; } &&
+        { ac_try='test -s conftest.$ac_objext'
+  { (eval echo "$as_me:$LINENO: \"$ac_try\"") >&5
+  (eval $ac_try) 2>&5
+  ac_status=$?
+  echo "$as_me:$LINENO: \$? = $ac_status" >&5
+  (exit $ac_status); }; }; then
+  ac_cv_header_stdc=yes
+else
+  echo "$as_me: failed program was:" >&5
+sed 's/^/| /' conftest.$ac_ext >&5
+
+ac_cv_header_stdc=no
+fi
+rm -f conftest.err conftest.$ac_objext conftest.$ac_ext
+
+if test $ac_cv_header_stdc = yes; then
+  # SunOS 4.x string.h does not declare mem*, contrary to ANSI.
+  cat >conftest.$ac_ext <<_ACEOF
+/* confdefs.h.  */
+_ACEOF
+cat confdefs.h >>conftest.$ac_ext
+cat >>conftest.$ac_ext <<_ACEOF
+/* end confdefs.h.  */
+#include <string.h>
+
+_ACEOF
+if (eval "$ac_cpp conftest.$ac_ext") 2>&5 |
+  $EGREP "memchr" >/dev/null 2>&1; then
+  :
+else
+  ac_cv_header_stdc=no
+fi
+rm -f conftest*
+
+fi
+
+if test $ac_cv_header_stdc = yes; then
+  # ISC 2.0.2 stdlib.h does not declare free, contrary to ANSI.
+  cat >conftest.$ac_ext <<_ACEOF
+/* confdefs.h.  */
+_ACEOF
+cat confdefs.h >>conftest.$ac_ext
+cat >>conftest.$ac_ext <<_ACEOF
+/* end confdefs.h.  */
+#include <stdlib.h>
+
+_ACEOF
+if (eval "$ac_cpp conftest.$ac_ext") 2>&5 |
+  $EGREP "free" >/dev/null 2>&1; then
+  :
+else
+  ac_cv_header_stdc=no
+fi
+rm -f conftest*
+
+fi
+
+if test $ac_cv_header_stdc = yes; then
+  # /bin/cc in Irix-4.0.5 gets non-ANSI ctype macros unless using -ansi.
+  if test "$cross_compiling" = yes; then
+  :
+else
+  cat >conftest.$ac_ext <<_ACEOF
+/* confdefs.h.  */
+_ACEOF
+cat confdefs.h >>conftest.$ac_ext
+cat >>conftest.$ac_ext <<_ACEOF
+/* end confdefs.h.  */
+#include <ctype.h>
+#if ((' ' & 0x0FF) == 0x020)
+# define ISLOWER(c) ('a' <= (c) && (c) <= 'z')
+# define TOUPPER(c) (ISLOWER(c) ? 'A' + ((c) - 'a') : (c))
+#else
+# define ISLOWER(c) \
+                  (('a' <= (c) && (c) <= 'i') \
+                    || ('j' <= (c) && (c) <= 'r') \
+                    || ('s' <= (c) && (c) <= 'z'))
+# define TOUPPER(c) (ISLOWER(c) ? ((c) | 0x40) : (c))
+#endif
+
+#define XOR(e, f) (((e) && !(f)) || (!(e) && (f)))
+int
+main ()
+{
+  int i;
+  for (i = 0; i < 256; i++)
+    if (XOR (islower (i), ISLOWER (i))
+       || toupper (i) != TOUPPER (i))
+      exit(2);
+  exit (0);
+}
+_ACEOF
+rm -f conftest$ac_exeext
+if { (eval echo "$as_me:$LINENO: \"$ac_link\"") >&5
+  (eval $ac_link) 2>&5
+  ac_status=$?
+  echo "$as_me:$LINENO: \$? = $ac_status" >&5
+  (exit $ac_status); } && { ac_try='./conftest$ac_exeext'
+  { (eval echo "$as_me:$LINENO: \"$ac_try\"") >&5
+  (eval $ac_try) 2>&5
+  ac_status=$?
+  echo "$as_me:$LINENO: \$? = $ac_status" >&5
+  (exit $ac_status); }; }; then
+  :
+else
+  echo "$as_me: program exited with status $ac_status" >&5
+echo "$as_me: failed program was:" >&5
+sed 's/^/| /' conftest.$ac_ext >&5
+
+( exit $ac_status )
+ac_cv_header_stdc=no
+fi
+rm -f core *.core gmon.out bb.out conftest$ac_exeext conftest.$ac_objext conftest.$ac_ext
+fi
+fi
+fi
+echo "$as_me:$LINENO: result: $ac_cv_header_stdc" >&5
+echo "${ECHO_T}$ac_cv_header_stdc" >&6
+if test $ac_cv_header_stdc = yes; then
+
+cat >>confdefs.h <<\_ACEOF
+#define STDC_HEADERS 1
+_ACEOF
+
+fi
+
+
+# On IRIX 5.3, sys/types and inttypes.h are conflicting.
+
+
+
+
+
+
+
+
+
+for ac_header in sys/types.h sys/stat.h stdlib.h string.h memory.h strings.h \
+                 inttypes.h stdint.h unistd.h
+do
+as_ac_Header=`echo "ac_cv_header_$ac_header" | $as_tr_sh`
+echo "$as_me:$LINENO: checking for $ac_header" >&5
+echo $ECHO_N "checking for $ac_header... $ECHO_C" >&6
+if eval "test \"\${$as_ac_Header+set}\" = set"; then
+  echo $ECHO_N "(cached) $ECHO_C" >&6
+else
+  cat >conftest.$ac_ext <<_ACEOF
+/* confdefs.h.  */
+_ACEOF
+cat confdefs.h >>conftest.$ac_ext
+cat >>conftest.$ac_ext <<_ACEOF
+/* end confdefs.h.  */
+$ac_includes_default
+
+#include <$ac_header>
+_ACEOF
+rm -f conftest.$ac_objext
+if { (eval echo "$as_me:$LINENO: \"$ac_compile\"") >&5
+  (eval $ac_compile) 2>conftest.er1
+  ac_status=$?
+  grep -v '^ *+' conftest.er1 >conftest.err
+  rm -f conftest.er1
+  cat conftest.err >&5
+  echo "$as_me:$LINENO: \$? = $ac_status" >&5
+  (exit $ac_status); } &&
+        { ac_try='test -z "$ac_c_werror_flag"
+                        || test ! -s conftest.err'
+  { (eval echo "$as_me:$LINENO: \"$ac_try\"") >&5
+  (eval $ac_try) 2>&5
+  ac_status=$?
+  echo "$as_me:$LINENO: \$? = $ac_status" >&5
+  (exit $ac_status); }; } &&
+        { ac_try='test -s conftest.$ac_objext'
+  { (eval echo "$as_me:$LINENO: \"$ac_try\"") >&5
+  (eval $ac_try) 2>&5
+  ac_status=$?
+  echo "$as_me:$LINENO: \$? = $ac_status" >&5
+  (exit $ac_status); }; }; then
+  eval "$as_ac_Header=yes"
+else
+  echo "$as_me: failed program was:" >&5
+sed 's/^/| /' conftest.$ac_ext >&5
+
+eval "$as_ac_Header=no"
+fi
+rm -f conftest.err conftest.$ac_objext conftest.$ac_ext
+fi
+echo "$as_me:$LINENO: result: `eval echo '${'$as_ac_Header'}'`" >&5
+echo "${ECHO_T}`eval echo '${'$as_ac_Header'}'`" >&6
+if test `eval echo '${'$as_ac_Header'}'` = yes; then
+  cat >>confdefs.h <<_ACEOF
+#define `echo "HAVE_$ac_header" | $as_tr_cpp` 1
+_ACEOF
+
+fi
+
+done
+
+
+
+for ac_header in endian.h
+do
+as_ac_Header=`echo "ac_cv_header_$ac_header" | $as_tr_sh`
+if eval "test \"\${$as_ac_Header+set}\" = set"; then
+  echo "$as_me:$LINENO: checking for $ac_header" >&5
+echo $ECHO_N "checking for $ac_header... $ECHO_C" >&6
+if eval "test \"\${$as_ac_Header+set}\" = set"; then
+  echo $ECHO_N "(cached) $ECHO_C" >&6
+fi
+echo "$as_me:$LINENO: result: `eval echo '${'$as_ac_Header'}'`" >&5
+echo "${ECHO_T}`eval echo '${'$as_ac_Header'}'`" >&6
+else
+  # Is the header compilable?
+echo "$as_me:$LINENO: checking $ac_header usability" >&5
+echo $ECHO_N "checking $ac_header usability... $ECHO_C" >&6
+cat >conftest.$ac_ext <<_ACEOF
+/* confdefs.h.  */
+_ACEOF
+cat confdefs.h >>conftest.$ac_ext
+cat >>conftest.$ac_ext <<_ACEOF
+/* end confdefs.h.  */
+$ac_includes_default
+#include <$ac_header>
+_ACEOF
+rm -f conftest.$ac_objext
+if { (eval echo "$as_me:$LINENO: \"$ac_compile\"") >&5
+  (eval $ac_compile) 2>conftest.er1
+  ac_status=$?
+  grep -v '^ *+' conftest.er1 >conftest.err
+  rm -f conftest.er1
+  cat conftest.err >&5
+  echo "$as_me:$LINENO: \$? = $ac_status" >&5
+  (exit $ac_status); } &&
+        { ac_try='test -z "$ac_c_werror_flag"
+                        || test ! -s conftest.err'
+  { (eval echo "$as_me:$LINENO: \"$ac_try\"") >&5
+  (eval $ac_try) 2>&5
+  ac_status=$?
+  echo "$as_me:$LINENO: \$? = $ac_status" >&5
+  (exit $ac_status); }; } &&
+        { ac_try='test -s conftest.$ac_objext'
+  { (eval echo "$as_me:$LINENO: \"$ac_try\"") >&5
+  (eval $ac_try) 2>&5
+  ac_status=$?
+  echo "$as_me:$LINENO: \$? = $ac_status" >&5
+  (exit $ac_status); }; }; then
+  ac_header_compiler=yes
+else
+  echo "$as_me: failed program was:" >&5
+sed 's/^/| /' conftest.$ac_ext >&5
+
+ac_header_compiler=no
+fi
+rm -f conftest.err conftest.$ac_objext conftest.$ac_ext
+echo "$as_me:$LINENO: result: $ac_header_compiler" >&5
+echo "${ECHO_T}$ac_header_compiler" >&6
+
+# Is the header present?
+echo "$as_me:$LINENO: checking $ac_header presence" >&5
+echo $ECHO_N "checking $ac_header presence... $ECHO_C" >&6
+cat >conftest.$ac_ext <<_ACEOF
+/* confdefs.h.  */
+_ACEOF
+cat confdefs.h >>conftest.$ac_ext
+cat >>conftest.$ac_ext <<_ACEOF
+/* end confdefs.h.  */
+#include <$ac_header>
+_ACEOF
+if { (eval echo "$as_me:$LINENO: \"$ac_cpp conftest.$ac_ext\"") >&5
+  (eval $ac_cpp conftest.$ac_ext) 2>conftest.er1
+  ac_status=$?
+  grep -v '^ *+' conftest.er1 >conftest.err
+  rm -f conftest.er1
+  cat conftest.err >&5
+  echo "$as_me:$LINENO: \$? = $ac_status" >&5
+  (exit $ac_status); } >/dev/null; then
+  if test -s conftest.err; then
+    ac_cpp_err=$ac_c_preproc_warn_flag
+    ac_cpp_err=$ac_cpp_err$ac_c_werror_flag
+  else
+    ac_cpp_err=
+  fi
+else
+  ac_cpp_err=yes
+fi
+if test -z "$ac_cpp_err"; then
+  ac_header_preproc=yes
+else
+  echo "$as_me: failed program was:" >&5
+sed 's/^/| /' conftest.$ac_ext >&5
+
+  ac_header_preproc=no
+fi
+rm -f conftest.err conftest.$ac_ext
+echo "$as_me:$LINENO: result: $ac_header_preproc" >&5
+echo "${ECHO_T}$ac_header_preproc" >&6
+
+# So?  What about this header?
+case $ac_header_compiler:$ac_header_preproc:$ac_c_preproc_warn_flag in
+  yes:no: )
+    { echo "$as_me:$LINENO: WARNING: $ac_header: accepted by the compiler, rejected by the preprocessor!" >&5
+echo "$as_me: WARNING: $ac_header: accepted by the compiler, rejected by the preprocessor!" >&2;}
+    { echo "$as_me:$LINENO: WARNING: $ac_header: proceeding with the compiler's result" >&5
+echo "$as_me: WARNING: $ac_header: proceeding with the compiler's result" >&2;}
+    ac_header_preproc=yes
+    ;;
+  no:yes:* )
+    { echo "$as_me:$LINENO: WARNING: $ac_header: present but cannot be compiled" >&5
+echo "$as_me: WARNING: $ac_header: present but cannot be compiled" >&2;}
+    { echo "$as_me:$LINENO: WARNING: $ac_header:     check for missing prerequisite headers?" >&5
+echo "$as_me: WARNING: $ac_header:     check for missing prerequisite headers?" >&2;}
+    { echo "$as_me:$LINENO: WARNING: $ac_header: see the Autoconf documentation" >&5
+echo "$as_me: WARNING: $ac_header: see the Autoconf documentation" >&2;}
+    { echo "$as_me:$LINENO: WARNING: $ac_header:     section \"Present But Cannot Be Compiled\"" >&5
+echo "$as_me: WARNING: $ac_header:     section \"Present But Cannot Be Compiled\"" >&2;}
+    { echo "$as_me:$LINENO: WARNING: $ac_header: proceeding with the preprocessor's result" >&5
+echo "$as_me: WARNING: $ac_header: proceeding with the preprocessor's result" >&2;}
+    { echo "$as_me:$LINENO: WARNING: $ac_header: in the future, the compiler will take precedence" >&5
+echo "$as_me: WARNING: $ac_header: in the future, the compiler will take precedence" >&2;}
+    (
+      cat <<\_ASBOX
+## -------------------------------- ##
+## Report this to ardour@ardour.org ##
+## -------------------------------- ##
+_ASBOX
+    ) |
+      sed "s/^/$as_me: WARNING:     /" >&2
+    ;;
+esac
+echo "$as_me:$LINENO: checking for $ac_header" >&5
+echo $ECHO_N "checking for $ac_header... $ECHO_C" >&6
+if eval "test \"\${$as_ac_Header+set}\" = set"; then
+  echo $ECHO_N "(cached) $ECHO_C" >&6
+else
+  eval "$as_ac_Header=\$ac_header_preproc"
+fi
+echo "$as_me:$LINENO: result: `eval echo '${'$as_ac_Header'}'`" >&5
+echo "${ECHO_T}`eval echo '${'$as_ac_Header'}'`" >&6
+
+fi
+if test `eval echo '${'$as_ac_Header'}'` = yes; then
+  cat >>confdefs.h <<_ACEOF
+#define `echo "HAVE_$ac_header" | $as_tr_cpp` 1
+_ACEOF
+
+fi
+
+done
+
+
+for ac_header in byteswap.h
+do
+as_ac_Header=`echo "ac_cv_header_$ac_header" | $as_tr_sh`
+if eval "test \"\${$as_ac_Header+set}\" = set"; then
+  echo "$as_me:$LINENO: checking for $ac_header" >&5
+echo $ECHO_N "checking for $ac_header... $ECHO_C" >&6
+if eval "test \"\${$as_ac_Header+set}\" = set"; then
+  echo $ECHO_N "(cached) $ECHO_C" >&6
+fi
+echo "$as_me:$LINENO: result: `eval echo '${'$as_ac_Header'}'`" >&5
+echo "${ECHO_T}`eval echo '${'$as_ac_Header'}'`" >&6
+else
+  # Is the header compilable?
+echo "$as_me:$LINENO: checking $ac_header usability" >&5
+echo $ECHO_N "checking $ac_header usability... $ECHO_C" >&6
+cat >conftest.$ac_ext <<_ACEOF
+/* confdefs.h.  */
+_ACEOF
+cat confdefs.h >>conftest.$ac_ext
+cat >>conftest.$ac_ext <<_ACEOF
+/* end confdefs.h.  */
+$ac_includes_default
+#include <$ac_header>
+_ACEOF
+rm -f conftest.$ac_objext
+if { (eval echo "$as_me:$LINENO: \"$ac_compile\"") >&5
+  (eval $ac_compile) 2>conftest.er1
+  ac_status=$?
+  grep -v '^ *+' conftest.er1 >conftest.err
+  rm -f conftest.er1
+  cat conftest.err >&5
+  echo "$as_me:$LINENO: \$? = $ac_status" >&5
+  (exit $ac_status); } &&
+        { ac_try='test -z "$ac_c_werror_flag"
+                        || test ! -s conftest.err'
+  { (eval echo "$as_me:$LINENO: \"$ac_try\"") >&5
+  (eval $ac_try) 2>&5
+  ac_status=$?
+  echo "$as_me:$LINENO: \$? = $ac_status" >&5
+  (exit $ac_status); }; } &&
+        { ac_try='test -s conftest.$ac_objext'
+  { (eval echo "$as_me:$LINENO: \"$ac_try\"") >&5
+  (eval $ac_try) 2>&5
+  ac_status=$?
+  echo "$as_me:$LINENO: \$? = $ac_status" >&5
+  (exit $ac_status); }; }; then
+  ac_header_compiler=yes
+else
+  echo "$as_me: failed program was:" >&5
+sed 's/^/| /' conftest.$ac_ext >&5
+
+ac_header_compiler=no
+fi
+rm -f conftest.err conftest.$ac_objext conftest.$ac_ext
+echo "$as_me:$LINENO: result: $ac_header_compiler" >&5
+echo "${ECHO_T}$ac_header_compiler" >&6
+
+# Is the header present?
+echo "$as_me:$LINENO: checking $ac_header presence" >&5
+echo $ECHO_N "checking $ac_header presence... $ECHO_C" >&6
+cat >conftest.$ac_ext <<_ACEOF
+/* confdefs.h.  */
+_ACEOF
+cat confdefs.h >>conftest.$ac_ext
+cat >>conftest.$ac_ext <<_ACEOF
+/* end confdefs.h.  */
+#include <$ac_header>
+_ACEOF
+if { (eval echo "$as_me:$LINENO: \"$ac_cpp conftest.$ac_ext\"") >&5
+  (eval $ac_cpp conftest.$ac_ext) 2>conftest.er1
+  ac_status=$?
+  grep -v '^ *+' conftest.er1 >conftest.err
+  rm -f conftest.er1
+  cat conftest.err >&5
+  echo "$as_me:$LINENO: \$? = $ac_status" >&5
+  (exit $ac_status); } >/dev/null; then
+  if test -s conftest.err; then
+    ac_cpp_err=$ac_c_preproc_warn_flag
+    ac_cpp_err=$ac_cpp_err$ac_c_werror_flag
+  else
+    ac_cpp_err=
+  fi
+else
+  ac_cpp_err=yes
+fi
+if test -z "$ac_cpp_err"; then
+  ac_header_preproc=yes
+else
+  echo "$as_me: failed program was:" >&5
+sed 's/^/| /' conftest.$ac_ext >&5
+
+  ac_header_preproc=no
+fi
+rm -f conftest.err conftest.$ac_ext
+echo "$as_me:$LINENO: result: $ac_header_preproc" >&5
+echo "${ECHO_T}$ac_header_preproc" >&6
+
+# So?  What about this header?
+case $ac_header_compiler:$ac_header_preproc:$ac_c_preproc_warn_flag in
+  yes:no: )
+    { echo "$as_me:$LINENO: WARNING: $ac_header: accepted by the compiler, rejected by the preprocessor!" >&5
+echo "$as_me: WARNING: $ac_header: accepted by the compiler, rejected by the preprocessor!" >&2;}
+    { echo "$as_me:$LINENO: WARNING: $ac_header: proceeding with the compiler's result" >&5
+echo "$as_me: WARNING: $ac_header: proceeding with the compiler's result" >&2;}
+    ac_header_preproc=yes
+    ;;
+  no:yes:* )
+    { echo "$as_me:$LINENO: WARNING: $ac_header: present but cannot be compiled" >&5
+echo "$as_me: WARNING: $ac_header: present but cannot be compiled" >&2;}
+    { echo "$as_me:$LINENO: WARNING: $ac_header:     check for missing prerequisite headers?" >&5
+echo "$as_me: WARNING: $ac_header:     check for missing prerequisite headers?" >&2;}
+    { echo "$as_me:$LINENO: WARNING: $ac_header: see the Autoconf documentation" >&5
+echo "$as_me: WARNING: $ac_header: see the Autoconf documentation" >&2;}
+    { echo "$as_me:$LINENO: WARNING: $ac_header:     section \"Present But Cannot Be Compiled\"" >&5
+echo "$as_me: WARNING: $ac_header:     section \"Present But Cannot Be Compiled\"" >&2;}
+    { echo "$as_me:$LINENO: WARNING: $ac_header: proceeding with the preprocessor's result" >&5
+echo "$as_me: WARNING: $ac_header: proceeding with the preprocessor's result" >&2;}
+    { echo "$as_me:$LINENO: WARNING: $ac_header: in the future, the compiler will take precedence" >&5
+echo "$as_me: WARNING: $ac_header: in the future, the compiler will take precedence" >&2;}
+    (
+      cat <<\_ASBOX
+## -------------------------------- ##
+## Report this to ardour@ardour.org ##
+## -------------------------------- ##
+_ASBOX
+    ) |
+      sed "s/^/$as_me: WARNING:     /" >&2
+    ;;
+esac
+echo "$as_me:$LINENO: checking for $ac_header" >&5
+echo $ECHO_N "checking for $ac_header... $ECHO_C" >&6
+if eval "test \"\${$as_ac_Header+set}\" = set"; then
+  echo $ECHO_N "(cached) $ECHO_C" >&6
+else
+  eval "$as_ac_Header=\$ac_header_preproc"
+fi
+echo "$as_me:$LINENO: result: `eval echo '${'$as_ac_Header'}'`" >&5
+echo "${ECHO_T}`eval echo '${'$as_ac_Header'}'`" >&6
+
+fi
+if test `eval echo '${'$as_ac_Header'}'` = yes; then
+  cat >>confdefs.h <<_ACEOF
+#define `echo "HAVE_$ac_header" | $as_tr_cpp` 1
+_ACEOF
+
+fi
+
+done
+
+
+for ac_header in locale.h
+do
+as_ac_Header=`echo "ac_cv_header_$ac_header" | $as_tr_sh`
+if eval "test \"\${$as_ac_Header+set}\" = set"; then
+  echo "$as_me:$LINENO: checking for $ac_header" >&5
+echo $ECHO_N "checking for $ac_header... $ECHO_C" >&6
+if eval "test \"\${$as_ac_Header+set}\" = set"; then
+  echo $ECHO_N "(cached) $ECHO_C" >&6
+fi
+echo "$as_me:$LINENO: result: `eval echo '${'$as_ac_Header'}'`" >&5
+echo "${ECHO_T}`eval echo '${'$as_ac_Header'}'`" >&6
+else
+  # Is the header compilable?
+echo "$as_me:$LINENO: checking $ac_header usability" >&5
+echo $ECHO_N "checking $ac_header usability... $ECHO_C" >&6
+cat >conftest.$ac_ext <<_ACEOF
+/* confdefs.h.  */
+_ACEOF
+cat confdefs.h >>conftest.$ac_ext
+cat >>conftest.$ac_ext <<_ACEOF
+/* end confdefs.h.  */
+$ac_includes_default
+#include <$ac_header>
+_ACEOF
+rm -f conftest.$ac_objext
+if { (eval echo "$as_me:$LINENO: \"$ac_compile\"") >&5
+  (eval $ac_compile) 2>conftest.er1
+  ac_status=$?
+  grep -v '^ *+' conftest.er1 >conftest.err
+  rm -f conftest.er1
+  cat conftest.err >&5
+  echo "$as_me:$LINENO: \$? = $ac_status" >&5
+  (exit $ac_status); } &&
+        { ac_try='test -z "$ac_c_werror_flag"
+                        || test ! -s conftest.err'
+  { (eval echo "$as_me:$LINENO: \"$ac_try\"") >&5
+  (eval $ac_try) 2>&5
+  ac_status=$?
+  echo "$as_me:$LINENO: \$? = $ac_status" >&5
+  (exit $ac_status); }; } &&
+        { ac_try='test -s conftest.$ac_objext'
+  { (eval echo "$as_me:$LINENO: \"$ac_try\"") >&5
+  (eval $ac_try) 2>&5
+  ac_status=$?
+  echo "$as_me:$LINENO: \$? = $ac_status" >&5
+  (exit $ac_status); }; }; then
+  ac_header_compiler=yes
+else
+  echo "$as_me: failed program was:" >&5
+sed 's/^/| /' conftest.$ac_ext >&5
+
+ac_header_compiler=no
+fi
+rm -f conftest.err conftest.$ac_objext conftest.$ac_ext
+echo "$as_me:$LINENO: result: $ac_header_compiler" >&5
+echo "${ECHO_T}$ac_header_compiler" >&6
+
+# Is the header present?
+echo "$as_me:$LINENO: checking $ac_header presence" >&5
+echo $ECHO_N "checking $ac_header presence... $ECHO_C" >&6
+cat >conftest.$ac_ext <<_ACEOF
+/* confdefs.h.  */
+_ACEOF
+cat confdefs.h >>conftest.$ac_ext
+cat >>conftest.$ac_ext <<_ACEOF
+/* end confdefs.h.  */
+#include <$ac_header>
+_ACEOF
+if { (eval echo "$as_me:$LINENO: \"$ac_cpp conftest.$ac_ext\"") >&5
+  (eval $ac_cpp conftest.$ac_ext) 2>conftest.er1
+  ac_status=$?
+  grep -v '^ *+' conftest.er1 >conftest.err
+  rm -f conftest.er1
+  cat conftest.err >&5
+  echo "$as_me:$LINENO: \$? = $ac_status" >&5
+  (exit $ac_status); } >/dev/null; then
+  if test -s conftest.err; then
+    ac_cpp_err=$ac_c_preproc_warn_flag
+    ac_cpp_err=$ac_cpp_err$ac_c_werror_flag
+  else
+    ac_cpp_err=
+  fi
+else
+  ac_cpp_err=yes
+fi
+if test -z "$ac_cpp_err"; then
+  ac_header_preproc=yes
+else
+  echo "$as_me: failed program was:" >&5
+sed 's/^/| /' conftest.$ac_ext >&5
+
+  ac_header_preproc=no
+fi
+rm -f conftest.err conftest.$ac_ext
+echo "$as_me:$LINENO: result: $ac_header_preproc" >&5
+echo "${ECHO_T}$ac_header_preproc" >&6
+
+# So?  What about this header?
+case $ac_header_compiler:$ac_header_preproc:$ac_c_preproc_warn_flag in
+  yes:no: )
+    { echo "$as_me:$LINENO: WARNING: $ac_header: accepted by the compiler, rejected by the preprocessor!" >&5
+echo "$as_me: WARNING: $ac_header: accepted by the compiler, rejected by the preprocessor!" >&2;}
+    { echo "$as_me:$LINENO: WARNING: $ac_header: proceeding with the compiler's result" >&5
+echo "$as_me: WARNING: $ac_header: proceeding with the compiler's result" >&2;}
+    ac_header_preproc=yes
+    ;;
+  no:yes:* )
+    { echo "$as_me:$LINENO: WARNING: $ac_header: present but cannot be compiled" >&5
+echo "$as_me: WARNING: $ac_header: present but cannot be compiled" >&2;}
+    { echo "$as_me:$LINENO: WARNING: $ac_header:     check for missing prerequisite headers?" >&5
+echo "$as_me: WARNING: $ac_header:     check for missing prerequisite headers?" >&2;}
+    { echo "$as_me:$LINENO: WARNING: $ac_header: see the Autoconf documentation" >&5
+echo "$as_me: WARNING: $ac_header: see the Autoconf documentation" >&2;}
+    { echo "$as_me:$LINENO: WARNING: $ac_header:     section \"Present But Cannot Be Compiled\"" >&5
+echo "$as_me: WARNING: $ac_header:     section \"Present But Cannot Be Compiled\"" >&2;}
+    { echo "$as_me:$LINENO: WARNING: $ac_header: proceeding with the preprocessor's result" >&5
+echo "$as_me: WARNING: $ac_header: proceeding with the preprocessor's result" >&2;}
+    { echo "$as_me:$LINENO: WARNING: $ac_header: in the future, the compiler will take precedence" >&5
+echo "$as_me: WARNING: $ac_header: in the future, the compiler will take precedence" >&2;}
+    (
+      cat <<\_ASBOX
+## -------------------------------- ##
+## Report this to ardour@ardour.org ##
+## -------------------------------- ##
+_ASBOX
+    ) |
+      sed "s/^/$as_me: WARNING:     /" >&2
+    ;;
+esac
+echo "$as_me:$LINENO: checking for $ac_header" >&5
+echo $ECHO_N "checking for $ac_header... $ECHO_C" >&6
+if eval "test \"\${$as_ac_Header+set}\" = set"; then
+  echo $ECHO_N "(cached) $ECHO_C" >&6
+else
+  eval "$as_ac_Header=\$ac_header_preproc"
+fi
+echo "$as_me:$LINENO: result: `eval echo '${'$as_ac_Header'}'`" >&5
+echo "${ECHO_T}`eval echo '${'$as_ac_Header'}'`" >&6
+
+fi
+if test `eval echo '${'$as_ac_Header'}'` = yes; then
+  cat >>confdefs.h <<_ACEOF
+#define `echo "HAVE_$ac_header" | $as_tr_cpp` 1
+_ACEOF
+
+fi
+
+done
+
+
+for ac_header in inttypes.h
+do
+as_ac_Header=`echo "ac_cv_header_$ac_header" | $as_tr_sh`
+if eval "test \"\${$as_ac_Header+set}\" = set"; then
+  echo "$as_me:$LINENO: checking for $ac_header" >&5
+echo $ECHO_N "checking for $ac_header... $ECHO_C" >&6
+if eval "test \"\${$as_ac_Header+set}\" = set"; then
+  echo $ECHO_N "(cached) $ECHO_C" >&6
+fi
+echo "$as_me:$LINENO: result: `eval echo '${'$as_ac_Header'}'`" >&5
+echo "${ECHO_T}`eval echo '${'$as_ac_Header'}'`" >&6
+else
+  # Is the header compilable?
+echo "$as_me:$LINENO: checking $ac_header usability" >&5
+echo $ECHO_N "checking $ac_header usability... $ECHO_C" >&6
+cat >conftest.$ac_ext <<_ACEOF
+/* confdefs.h.  */
+_ACEOF
+cat confdefs.h >>conftest.$ac_ext
+cat >>conftest.$ac_ext <<_ACEOF
+/* end confdefs.h.  */
+$ac_includes_default
+#include <$ac_header>
+_ACEOF
+rm -f conftest.$ac_objext
+if { (eval echo "$as_me:$LINENO: \"$ac_compile\"") >&5
+  (eval $ac_compile) 2>conftest.er1
+  ac_status=$?
+  grep -v '^ *+' conftest.er1 >conftest.err
+  rm -f conftest.er1
+  cat conftest.err >&5
+  echo "$as_me:$LINENO: \$? = $ac_status" >&5
+  (exit $ac_status); } &&
+        { ac_try='test -z "$ac_c_werror_flag"
+                        || test ! -s conftest.err'
+  { (eval echo "$as_me:$LINENO: \"$ac_try\"") >&5
+  (eval $ac_try) 2>&5
+  ac_status=$?
+  echo "$as_me:$LINENO: \$? = $ac_status" >&5
+  (exit $ac_status); }; } &&
+        { ac_try='test -s conftest.$ac_objext'
+  { (eval echo "$as_me:$LINENO: \"$ac_try\"") >&5
+  (eval $ac_try) 2>&5
+  ac_status=$?
+  echo "$as_me:$LINENO: \$? = $ac_status" >&5
+  (exit $ac_status); }; }; then
+  ac_header_compiler=yes
+else
+  echo "$as_me: failed program was:" >&5
+sed 's/^/| /' conftest.$ac_ext >&5
+
+ac_header_compiler=no
+fi
+rm -f conftest.err conftest.$ac_objext conftest.$ac_ext
+echo "$as_me:$LINENO: result: $ac_header_compiler" >&5
+echo "${ECHO_T}$ac_header_compiler" >&6
+
+# Is the header present?
+echo "$as_me:$LINENO: checking $ac_header presence" >&5
+echo $ECHO_N "checking $ac_header presence... $ECHO_C" >&6
+cat >conftest.$ac_ext <<_ACEOF
+/* confdefs.h.  */
+_ACEOF
+cat confdefs.h >>conftest.$ac_ext
+cat >>conftest.$ac_ext <<_ACEOF
+/* end confdefs.h.  */
+#include <$ac_header>
+_ACEOF
+if { (eval echo "$as_me:$LINENO: \"$ac_cpp conftest.$ac_ext\"") >&5
+  (eval $ac_cpp conftest.$ac_ext) 2>conftest.er1
+  ac_status=$?
+  grep -v '^ *+' conftest.er1 >conftest.err
+  rm -f conftest.er1
+  cat conftest.err >&5
+  echo "$as_me:$LINENO: \$? = $ac_status" >&5
+  (exit $ac_status); } >/dev/null; then
+  if test -s conftest.err; then
+    ac_cpp_err=$ac_c_preproc_warn_flag
+    ac_cpp_err=$ac_cpp_err$ac_c_werror_flag
+  else
+    ac_cpp_err=
+  fi
+else
+  ac_cpp_err=yes
+fi
+if test -z "$ac_cpp_err"; then
+  ac_header_preproc=yes
+else
+  echo "$as_me: failed program was:" >&5
+sed 's/^/| /' conftest.$ac_ext >&5
+
+  ac_header_preproc=no
+fi
+rm -f conftest.err conftest.$ac_ext
+echo "$as_me:$LINENO: result: $ac_header_preproc" >&5
+echo "${ECHO_T}$ac_header_preproc" >&6
+
+# So?  What about this header?
+case $ac_header_compiler:$ac_header_preproc:$ac_c_preproc_warn_flag in
+  yes:no: )
+    { echo "$as_me:$LINENO: WARNING: $ac_header: accepted by the compiler, rejected by the preprocessor!" >&5
+echo "$as_me: WARNING: $ac_header: accepted by the compiler, rejected by the preprocessor!" >&2;}
+    { echo "$as_me:$LINENO: WARNING: $ac_header: proceeding with the compiler's result" >&5
+echo "$as_me: WARNING: $ac_header: proceeding with the compiler's result" >&2;}
+    ac_header_preproc=yes
+    ;;
+  no:yes:* )
+    { echo "$as_me:$LINENO: WARNING: $ac_header: present but cannot be compiled" >&5
+echo "$as_me: WARNING: $ac_header: present but cannot be compiled" >&2;}
+    { echo "$as_me:$LINENO: WARNING: $ac_header:     check for missing prerequisite headers?" >&5
+echo "$as_me: WARNING: $ac_header:     check for missing prerequisite headers?" >&2;}
+    { echo "$as_me:$LINENO: WARNING: $ac_header: see the Autoconf documentation" >&5
+echo "$as_me: WARNING: $ac_header: see the Autoconf documentation" >&2;}
+    { echo "$as_me:$LINENO: WARNING: $ac_header:     section \"Present But Cannot Be Compiled\"" >&5
+echo "$as_me: WARNING: $ac_header:     section \"Present But Cannot Be Compiled\"" >&2;}
+    { echo "$as_me:$LINENO: WARNING: $ac_header: proceeding with the preprocessor's result" >&5
+echo "$as_me: WARNING: $ac_header: proceeding with the preprocessor's result" >&2;}
+    { echo "$as_me:$LINENO: WARNING: $ac_header: in the future, the compiler will take precedence" >&5
+echo "$as_me: WARNING: $ac_header: in the future, the compiler will take precedence" >&2;}
+    (
+      cat <<\_ASBOX
+## -------------------------------- ##
+## Report this to ardour@ardour.org ##
+## -------------------------------- ##
+_ASBOX
+    ) |
+      sed "s/^/$as_me: WARNING:     /" >&2
+    ;;
+esac
+echo "$as_me:$LINENO: checking for $ac_header" >&5
+echo $ECHO_N "checking for $ac_header... $ECHO_C" >&6
+if eval "test \"\${$as_ac_Header+set}\" = set"; then
+  echo $ECHO_N "(cached) $ECHO_C" >&6
+else
+  eval "$as_ac_Header=\$ac_header_preproc"
+fi
+echo "$as_me:$LINENO: result: `eval echo '${'$as_ac_Header'}'`" >&5
+echo "${ECHO_T}`eval echo '${'$as_ac_Header'}'`" >&6
+
+fi
+if test `eval echo '${'$as_ac_Header'}'` = yes; then
+  cat >>confdefs.h <<_ACEOF
+#define `echo "HAVE_$ac_header" | $as_tr_cpp` 1
+_ACEOF
+
+fi
+
+done
+
+
+echo "$as_me:$LINENO: checking for sys/wait.h that is POSIX.1 compatible" >&5
+echo $ECHO_N "checking for sys/wait.h that is POSIX.1 compatible... $ECHO_C" >&6
+if test "${ac_cv_header_sys_wait_h+set}" = set; then
+  echo $ECHO_N "(cached) $ECHO_C" >&6
+else
+  cat >conftest.$ac_ext <<_ACEOF
+/* confdefs.h.  */
+_ACEOF
+cat confdefs.h >>conftest.$ac_ext
+cat >>conftest.$ac_ext <<_ACEOF
+/* end confdefs.h.  */
+#include <sys/types.h>
+#include <sys/wait.h>
+#ifndef WEXITSTATUS
+# define WEXITSTATUS(stat_val) ((unsigned)(stat_val) >> 8)
+#endif
+#ifndef WIFEXITED
+# define WIFEXITED(stat_val) (((stat_val) & 255) == 0)
+#endif
+
+int
+main ()
+{
+  int s;
+  wait (&s);
+  s = WIFEXITED (s) ? WEXITSTATUS (s) : 1;
+  ;
+  return 0;
+}
+_ACEOF
+rm -f conftest.$ac_objext
+if { (eval echo "$as_me:$LINENO: \"$ac_compile\"") >&5
+  (eval $ac_compile) 2>conftest.er1
+  ac_status=$?
+  grep -v '^ *+' conftest.er1 >conftest.err
+  rm -f conftest.er1
+  cat conftest.err >&5
+  echo "$as_me:$LINENO: \$? = $ac_status" >&5
+  (exit $ac_status); } &&
+        { ac_try='test -z "$ac_c_werror_flag"
+                        || test ! -s conftest.err'
+  { (eval echo "$as_me:$LINENO: \"$ac_try\"") >&5
+  (eval $ac_try) 2>&5
+  ac_status=$?
+  echo "$as_me:$LINENO: \$? = $ac_status" >&5
+  (exit $ac_status); }; } &&
+        { ac_try='test -s conftest.$ac_objext'
+  { (eval echo "$as_me:$LINENO: \"$ac_try\"") >&5
+  (eval $ac_try) 2>&5
+  ac_status=$?
+  echo "$as_me:$LINENO: \$? = $ac_status" >&5
+  (exit $ac_status); }; }; then
+  ac_cv_header_sys_wait_h=yes
+else
+  echo "$as_me: failed program was:" >&5
+sed 's/^/| /' conftest.$ac_ext >&5
+
+ac_cv_header_sys_wait_h=no
+fi
+rm -f conftest.err conftest.$ac_objext conftest.$ac_ext
+fi
+echo "$as_me:$LINENO: result: $ac_cv_header_sys_wait_h" >&5
+echo "${ECHO_T}$ac_cv_header_sys_wait_h" >&6
+if test $ac_cv_header_sys_wait_h = yes; then
+
+cat >>confdefs.h <<\_ACEOF
+#define HAVE_SYS_WAIT_H 1
+_ACEOF
+
+fi
+
+
+echo "$as_me:$LINENO: checking whether S_IRGRP is declared" >&5
+echo $ECHO_N "checking whether S_IRGRP is declared... $ECHO_C" >&6
+if test "${ac_cv_have_decl_S_IRGRP+set}" = set; then
+  echo $ECHO_N "(cached) $ECHO_C" >&6
+else
+  cat >conftest.$ac_ext <<_ACEOF
+/* confdefs.h.  */
+_ACEOF
+cat confdefs.h >>conftest.$ac_ext
+cat >>conftest.$ac_ext <<_ACEOF
+/* end confdefs.h.  */
+$ac_includes_default
+int
+main ()
+{
+#ifndef S_IRGRP
+  char *p = (char *) S_IRGRP;
+#endif
+
+  ;
+  return 0;
+}
+_ACEOF
+rm -f conftest.$ac_objext
+if { (eval echo "$as_me:$LINENO: \"$ac_compile\"") >&5
+  (eval $ac_compile) 2>conftest.er1
+  ac_status=$?
+  grep -v '^ *+' conftest.er1 >conftest.err
+  rm -f conftest.er1
+  cat conftest.err >&5
+  echo "$as_me:$LINENO: \$? = $ac_status" >&5
+  (exit $ac_status); } &&
+        { ac_try='test -z "$ac_c_werror_flag"
+                        || test ! -s conftest.err'
+  { (eval echo "$as_me:$LINENO: \"$ac_try\"") >&5
+  (eval $ac_try) 2>&5
+  ac_status=$?
+  echo "$as_me:$LINENO: \$? = $ac_status" >&5
+  (exit $ac_status); }; } &&
+        { ac_try='test -s conftest.$ac_objext'
+  { (eval echo "$as_me:$LINENO: \"$ac_try\"") >&5
+  (eval $ac_try) 2>&5
+  ac_status=$?
+  echo "$as_me:$LINENO: \$? = $ac_status" >&5
+  (exit $ac_status); }; }; then
+  ac_cv_have_decl_S_IRGRP=yes
+else
+  echo "$as_me: failed program was:" >&5
+sed 's/^/| /' conftest.$ac_ext >&5
+
+ac_cv_have_decl_S_IRGRP=no
+fi
+rm -f conftest.err conftest.$ac_objext conftest.$ac_ext
+fi
+echo "$as_me:$LINENO: result: $ac_cv_have_decl_S_IRGRP" >&5
+echo "${ECHO_T}$ac_cv_have_decl_S_IRGRP" >&6
+if test $ac_cv_have_decl_S_IRGRP = yes; then
+
+cat >>confdefs.h <<_ACEOF
+#define HAVE_DECL_S_IRGRP 1
+_ACEOF
+
+
+else
+  cat >>confdefs.h <<_ACEOF
+#define HAVE_DECL_S_IRGRP 0
+_ACEOF
+
+
+fi
+
+
+
+cat >>confdefs.h <<_ACEOF
+#define HAVE_DECL_S_IRGRP ${HAVE_DECL_S_IRGRP}
+_ACEOF
+
+
+#====================================================================================
+# Check for support of the struct hack.
+
+echo "$as_me:$LINENO: checking C99 struct flexible array support" >&5
+echo $ECHO_N "checking C99 struct flexible array support... $ECHO_C" >&6
+if test "${ac_cv_c99_flexible_array+set}" = set; then
+  echo $ECHO_N "(cached) $ECHO_C" >&6
+else
+  # Initialize to unknown
+ac_cv_c99_flexible_array=no
+
+cat >conftest.$ac_ext <<_ACEOF
+/* confdefs.h.  */
+_ACEOF
+cat confdefs.h >>conftest.$ac_ext
+cat >>conftest.$ac_ext <<_ACEOF
+/* end confdefs.h.  */
+
+       #include <stdlib.h>
+       typedef struct {
+       int k;
+       char buffer [] ;
+       } MY_STRUCT ;
+
+int
+main ()
+{
+  MY_STRUCT *p = calloc (1, sizeof (MY_STRUCT) + 42);
+  ;
+  return 0;
+}
+_ACEOF
+rm -f conftest.$ac_objext conftest$ac_exeext
+if { (eval echo "$as_me:$LINENO: \"$ac_link\"") >&5
+  (eval $ac_link) 2>conftest.er1
+  ac_status=$?
+  grep -v '^ *+' conftest.er1 >conftest.err
+  rm -f conftest.er1
+  cat conftest.err >&5
+  echo "$as_me:$LINENO: \$? = $ac_status" >&5
+  (exit $ac_status); } &&
+        { ac_try='test -z "$ac_c_werror_flag"
+                        || test ! -s conftest.err'
+  { (eval echo "$as_me:$LINENO: \"$ac_try\"") >&5
+  (eval $ac_try) 2>&5
+  ac_status=$?
+  echo "$as_me:$LINENO: \$? = $ac_status" >&5
+  (exit $ac_status); }; } &&
+        { ac_try='test -s conftest$ac_exeext'
+  { (eval echo "$as_me:$LINENO: \"$ac_try\"") >&5
+  (eval $ac_try) 2>&5
+  ac_status=$?
+  echo "$as_me:$LINENO: \$? = $ac_status" >&5
+  (exit $ac_status); }; }; then
+  ac_cv_c99_flexible_array=yes
+else
+  echo "$as_me: failed program was:" >&5
+sed 's/^/| /' conftest.$ac_ext >&5
+
+ac_cv_c99_flexible_array=no
+
+fi
+rm -f conftest.err conftest.$ac_objext \
+      conftest$ac_exeext conftest.$ac_ext
+fi
+echo "$as_me:$LINENO: result: $ac_cv_c99_flexible_array" >&5
+echo "${ECHO_T}$ac_cv_c99_flexible_array" >&6
+
+
+if test x$ac_cv_c99_flexible_array = xyes ; then
+
+cat >>confdefs.h <<\_ACEOF
+#define HAVE_FLEXIBLE_ARRAY 1
+_ACEOF
+
+else
+       { echo "$as_me:$LINENO: WARNING: *** This compiler does not support the 1999 ISO C Standard ***" >&5
+echo "$as_me: WARNING: *** This compiler does not support the 1999 ISO C Standard ***" >&2;}
+       { echo "$as_me:$LINENO: WARNING: *** feature known as the flexible array struct member.     ***" >&5
+echo "$as_me: WARNING: *** feature known as the flexible array struct member.     ***" >&2;}
+       cat >>confdefs.h <<\_ACEOF
+#define HAVE_FLEXIBLE_ARRAY 0
+_ACEOF
+
+       fi
+
+#====================================================================================
+# Couple of initializations here. Fill in real values later.
+
+SHLIB_VERSION_ARG=""
+
+#====================================================================================
+# Finished checking, handle options.
+
+# Check whether --enable-experimental or --disable-experimental was given.
+if test "${enable_experimental+set}" = set; then
+  enableval="$enable_experimental"
+
+fi;
+
+EXPERIMENTAL_CODE=0
+if test x$enable_experimental = xyes ; then
+       EXPERIMENTAL_CODE=1
+       fi
+
+cat >>confdefs.h <<_ACEOF
+#define ENABLE_EXPERIMENTAL_CODE ${EXPERIMENTAL_CODE}
+_ACEOF
+
+
+# Check whether --enable-gcc-werror or --disable-gcc-werror was given.
+if test "${enable_gcc_werror+set}" = set; then
+  enableval="$enable_gcc_werror"
+
+fi;
+
+# Check whether --enable-gcc-pipe or --disable-gcc-pipe was given.
+if test "${enable_gcc_pipe+set}" = set; then
+  enableval="$enable_gcc_pipe"
+
+fi;
+
+# Check whether --enable-gcc-opt or --disable-gcc-opt was given.
+if test "${enable_gcc_opt+set}" = set; then
+  enableval="$enable_gcc_opt"
+
+fi;
+
+# Check whether --enable-cpu-clip or --disable-cpu-clip was given.
+if test "${enable_cpu_clip+set}" = set; then
+  enableval="$enable_cpu_clip"
+
+fi;
+
+# Check whether --enable-bow-docs or --disable-bow-docs was given.
+if test "${enable_bow_docs+set}" = set; then
+  enableval="$enable_bow_docs"
+
+fi;
+
+# Check whether --enable-sqlite or --disable-sqlite was given.
+if test "${enable_sqlite+set}" = set; then
+  enableval="$enable_sqlite"
+
+fi;
+
+# Check whether --enable-flac or --disable-flac was given.
+if test "${enable_flac+set}" = set; then
+  enableval="$enable_flac"
+
+fi;
+
+# Check whether --enable-alsa or --disable-alsa was given.
+if test "${enable_alsa+set}" = set; then
+  enableval="$enable_alsa"
+
+fi;
+
+#====================================================================================
+# Check types and their sizes.
+
+echo "$as_me:$LINENO: checking for short" >&5
+echo $ECHO_N "checking for short... $ECHO_C" >&6
+if test "${ac_cv_type_short+set}" = set; then
+  echo $ECHO_N "(cached) $ECHO_C" >&6
+else
+  cat >conftest.$ac_ext <<_ACEOF
+/* confdefs.h.  */
+_ACEOF
+cat confdefs.h >>conftest.$ac_ext
+cat >>conftest.$ac_ext <<_ACEOF
+/* end confdefs.h.  */
+$ac_includes_default
+int
+main ()
+{
+if ((short *) 0)
+  return 0;
+if (sizeof (short))
+  return 0;
+  ;
+  return 0;
+}
+_ACEOF
+rm -f conftest.$ac_objext
+if { (eval echo "$as_me:$LINENO: \"$ac_compile\"") >&5
+  (eval $ac_compile) 2>conftest.er1
+  ac_status=$?
+  grep -v '^ *+' conftest.er1 >conftest.err
+  rm -f conftest.er1
+  cat conftest.err >&5
+  echo "$as_me:$LINENO: \$? = $ac_status" >&5
+  (exit $ac_status); } &&
+        { ac_try='test -z "$ac_c_werror_flag"
+                        || test ! -s conftest.err'
+  { (eval echo "$as_me:$LINENO: \"$ac_try\"") >&5
+  (eval $ac_try) 2>&5
+  ac_status=$?
+  echo "$as_me:$LINENO: \$? = $ac_status" >&5
+  (exit $ac_status); }; } &&
+        { ac_try='test -s conftest.$ac_objext'
+  { (eval echo "$as_me:$LINENO: \"$ac_try\"") >&5
+  (eval $ac_try) 2>&5
+  ac_status=$?
+  echo "$as_me:$LINENO: \$? = $ac_status" >&5
+  (exit $ac_status); }; }; then
+  ac_cv_type_short=yes
+else
+  echo "$as_me: failed program was:" >&5
+sed 's/^/| /' conftest.$ac_ext >&5
+
+ac_cv_type_short=no
+fi
+rm -f conftest.err conftest.$ac_objext conftest.$ac_ext
+fi
+echo "$as_me:$LINENO: result: $ac_cv_type_short" >&5
+echo "${ECHO_T}$ac_cv_type_short" >&6
+
+echo "$as_me:$LINENO: checking size of short" >&5
+echo $ECHO_N "checking size of short... $ECHO_C" >&6
+if test "${ac_cv_sizeof_short+set}" = set; then
+  echo $ECHO_N "(cached) $ECHO_C" >&6
+else
+  if test "$ac_cv_type_short" = yes; then
+  # The cast to unsigned long works around a bug in the HP C Compiler
+  # version HP92453-01 B.11.11.23709.GP, which incorrectly rejects
+  # declarations like `int a3[[(sizeof (unsigned char)) >= 0]];'.
+  # This bug is HP SR number 8606223364.
+  if test "$cross_compiling" = yes; then
+  # Depending upon the size, compute the lo and hi bounds.
+cat >conftest.$ac_ext <<_ACEOF
+/* confdefs.h.  */
+_ACEOF
+cat confdefs.h >>conftest.$ac_ext
+cat >>conftest.$ac_ext <<_ACEOF
+/* end confdefs.h.  */
+$ac_includes_default
+int
+main ()
+{
+static int test_array [1 - 2 * !(((long) (sizeof (short))) >= 0)];
+test_array [0] = 0
+
+  ;
+  return 0;
+}
+_ACEOF
+rm -f conftest.$ac_objext
+if { (eval echo "$as_me:$LINENO: \"$ac_compile\"") >&5
+  (eval $ac_compile) 2>conftest.er1
+  ac_status=$?
+  grep -v '^ *+' conftest.er1 >conftest.err
+  rm -f conftest.er1
+  cat conftest.err >&5
+  echo "$as_me:$LINENO: \$? = $ac_status" >&5
+  (exit $ac_status); } &&
+        { ac_try='test -z "$ac_c_werror_flag"
+                        || test ! -s conftest.err'
+  { (eval echo "$as_me:$LINENO: \"$ac_try\"") >&5
+  (eval $ac_try) 2>&5
+  ac_status=$?
+  echo "$as_me:$LINENO: \$? = $ac_status" >&5
+  (exit $ac_status); }; } &&
+        { ac_try='test -s conftest.$ac_objext'
+  { (eval echo "$as_me:$LINENO: \"$ac_try\"") >&5
+  (eval $ac_try) 2>&5
+  ac_status=$?
+  echo "$as_me:$LINENO: \$? = $ac_status" >&5
+  (exit $ac_status); }; }; then
+  ac_lo=0 ac_mid=0
+  while :; do
+    cat >conftest.$ac_ext <<_ACEOF
+/* confdefs.h.  */
+_ACEOF
+cat confdefs.h >>conftest.$ac_ext
+cat >>conftest.$ac_ext <<_ACEOF
+/* end confdefs.h.  */
+$ac_includes_default
+int
+main ()
+{
+static int test_array [1 - 2 * !(((long) (sizeof (short))) <= $ac_mid)];
+test_array [0] = 0
+
+  ;
+  return 0;
+}
+_ACEOF
+rm -f conftest.$ac_objext
+if { (eval echo "$as_me:$LINENO: \"$ac_compile\"") >&5
+  (eval $ac_compile) 2>conftest.er1
+  ac_status=$?
+  grep -v '^ *+' conftest.er1 >conftest.err
+  rm -f conftest.er1
+  cat conftest.err >&5
+  echo "$as_me:$LINENO: \$? = $ac_status" >&5
+  (exit $ac_status); } &&
+        { ac_try='test -z "$ac_c_werror_flag"
+                        || test ! -s conftest.err'
+  { (eval echo "$as_me:$LINENO: \"$ac_try\"") >&5
+  (eval $ac_try) 2>&5
+  ac_status=$?
+  echo "$as_me:$LINENO: \$? = $ac_status" >&5
+  (exit $ac_status); }; } &&
+        { ac_try='test -s conftest.$ac_objext'
+  { (eval echo "$as_me:$LINENO: \"$ac_try\"") >&5
+  (eval $ac_try) 2>&5
+  ac_status=$?
+  echo "$as_me:$LINENO: \$? = $ac_status" >&5
+  (exit $ac_status); }; }; then
+  ac_hi=$ac_mid; break
+else
+  echo "$as_me: failed program was:" >&5
+sed 's/^/| /' conftest.$ac_ext >&5
+
+ac_lo=`expr $ac_mid + 1`
+                   if test $ac_lo -le $ac_mid; then
+                     ac_lo= ac_hi=
+                     break
+                   fi
+                   ac_mid=`expr 2 '*' $ac_mid + 1`
+fi
+rm -f conftest.err conftest.$ac_objext conftest.$ac_ext
+  done
+else
+  echo "$as_me: failed program was:" >&5
+sed 's/^/| /' conftest.$ac_ext >&5
+
+cat >conftest.$ac_ext <<_ACEOF
+/* confdefs.h.  */
+_ACEOF
+cat confdefs.h >>conftest.$ac_ext
+cat >>conftest.$ac_ext <<_ACEOF
+/* end confdefs.h.  */
+$ac_includes_default
+int
+main ()
+{
+static int test_array [1 - 2 * !(((long) (sizeof (short))) < 0)];
+test_array [0] = 0
+
+  ;
+  return 0;
+}
+_ACEOF
+rm -f conftest.$ac_objext
+if { (eval echo "$as_me:$LINENO: \"$ac_compile\"") >&5
+  (eval $ac_compile) 2>conftest.er1
+  ac_status=$?
+  grep -v '^ *+' conftest.er1 >conftest.err
+  rm -f conftest.er1
+  cat conftest.err >&5
+  echo "$as_me:$LINENO: \$? = $ac_status" >&5
+  (exit $ac_status); } &&
+        { ac_try='test -z "$ac_c_werror_flag"
+                        || test ! -s conftest.err'
+  { (eval echo "$as_me:$LINENO: \"$ac_try\"") >&5
+  (eval $ac_try) 2>&5
+  ac_status=$?
+  echo "$as_me:$LINENO: \$? = $ac_status" >&5
+  (exit $ac_status); }; } &&
+        { ac_try='test -s conftest.$ac_objext'
+  { (eval echo "$as_me:$LINENO: \"$ac_try\"") >&5
+  (eval $ac_try) 2>&5
+  ac_status=$?
+  echo "$as_me:$LINENO: \$? = $ac_status" >&5
+  (exit $ac_status); }; }; then
+  ac_hi=-1 ac_mid=-1
+  while :; do
+    cat >conftest.$ac_ext <<_ACEOF
+/* confdefs.h.  */
+_ACEOF
+cat confdefs.h >>conftest.$ac_ext
+cat >>conftest.$ac_ext <<_ACEOF
+/* end confdefs.h.  */
+$ac_includes_default
+int
+main ()
+{
+static int test_array [1 - 2 * !(((long) (sizeof (short))) >= $ac_mid)];
+test_array [0] = 0
+
+  ;
+  return 0;
+}
+_ACEOF
+rm -f conftest.$ac_objext
+if { (eval echo "$as_me:$LINENO: \"$ac_compile\"") >&5
+  (eval $ac_compile) 2>conftest.er1
+  ac_status=$?
+  grep -v '^ *+' conftest.er1 >conftest.err
+  rm -f conftest.er1
+  cat conftest.err >&5
+  echo "$as_me:$LINENO: \$? = $ac_status" >&5
+  (exit $ac_status); } &&
+        { ac_try='test -z "$ac_c_werror_flag"
+                        || test ! -s conftest.err'
+  { (eval echo "$as_me:$LINENO: \"$ac_try\"") >&5
+  (eval $ac_try) 2>&5
+  ac_status=$?
+  echo "$as_me:$LINENO: \$? = $ac_status" >&5
+  (exit $ac_status); }; } &&
+        { ac_try='test -s conftest.$ac_objext'
+  { (eval echo "$as_me:$LINENO: \"$ac_try\"") >&5
+  (eval $ac_try) 2>&5
+  ac_status=$?
+  echo "$as_me:$LINENO: \$? = $ac_status" >&5
+  (exit $ac_status); }; }; then
+  ac_lo=$ac_mid; break
+else
+  echo "$as_me: failed program was:" >&5
+sed 's/^/| /' conftest.$ac_ext >&5
+
+ac_hi=`expr '(' $ac_mid ')' - 1`
+                      if test $ac_mid -le $ac_hi; then
+                        ac_lo= ac_hi=
+                        break
+                      fi
+                      ac_mid=`expr 2 '*' $ac_mid`
+fi
+rm -f conftest.err conftest.$ac_objext conftest.$ac_ext
+  done
+else
+  echo "$as_me: failed program was:" >&5
+sed 's/^/| /' conftest.$ac_ext >&5
+
+ac_lo= ac_hi=
+fi
+rm -f conftest.err conftest.$ac_objext conftest.$ac_ext
+fi
+rm -f conftest.err conftest.$ac_objext conftest.$ac_ext
+# Binary search between lo and hi bounds.
+while test "x$ac_lo" != "x$ac_hi"; do
+  ac_mid=`expr '(' $ac_hi - $ac_lo ')' / 2 + $ac_lo`
+  cat >conftest.$ac_ext <<_ACEOF
+/* confdefs.h.  */
+_ACEOF
+cat confdefs.h >>conftest.$ac_ext
+cat >>conftest.$ac_ext <<_ACEOF
+/* end confdefs.h.  */
+$ac_includes_default
+int
+main ()
+{
+static int test_array [1 - 2 * !(((long) (sizeof (short))) <= $ac_mid)];
+test_array [0] = 0
+
+  ;
+  return 0;
+}
+_ACEOF
+rm -f conftest.$ac_objext
+if { (eval echo "$as_me:$LINENO: \"$ac_compile\"") >&5
+  (eval $ac_compile) 2>conftest.er1
+  ac_status=$?
+  grep -v '^ *+' conftest.er1 >conftest.err
+  rm -f conftest.er1
+  cat conftest.err >&5
+  echo "$as_me:$LINENO: \$? = $ac_status" >&5
+  (exit $ac_status); } &&
+        { ac_try='test -z "$ac_c_werror_flag"
+                        || test ! -s conftest.err'
+  { (eval echo "$as_me:$LINENO: \"$ac_try\"") >&5
+  (eval $ac_try) 2>&5
+  ac_status=$?
+  echo "$as_me:$LINENO: \$? = $ac_status" >&5
+  (exit $ac_status); }; } &&
+        { ac_try='test -s conftest.$ac_objext'
+  { (eval echo "$as_me:$LINENO: \"$ac_try\"") >&5
+  (eval $ac_try) 2>&5
+  ac_status=$?
+  echo "$as_me:$LINENO: \$? = $ac_status" >&5
+  (exit $ac_status); }; }; then
+  ac_hi=$ac_mid
+else
+  echo "$as_me: failed program was:" >&5
+sed 's/^/| /' conftest.$ac_ext >&5
+
+ac_lo=`expr '(' $ac_mid ')' + 1`
+fi
+rm -f conftest.err conftest.$ac_objext conftest.$ac_ext
+done
+case $ac_lo in
+?*) ac_cv_sizeof_short=$ac_lo;;
+'') { { echo "$as_me:$LINENO: error: cannot compute sizeof (short), 77
+See \`config.log' for more details." >&5
+echo "$as_me: error: cannot compute sizeof (short), 77
+See \`config.log' for more details." >&2;}
+   { (exit 1); exit 1; }; } ;;
+esac
+else
+  if test "$cross_compiling" = yes; then
+  { { echo "$as_me:$LINENO: error: cannot run test program while cross compiling
+See \`config.log' for more details." >&5
+echo "$as_me: error: cannot run test program while cross compiling
+See \`config.log' for more details." >&2;}
+   { (exit 1); exit 1; }; }
+else
+  cat >conftest.$ac_ext <<_ACEOF
+/* confdefs.h.  */
+_ACEOF
+cat confdefs.h >>conftest.$ac_ext
+cat >>conftest.$ac_ext <<_ACEOF
+/* end confdefs.h.  */
+$ac_includes_default
+long longval () { return (long) (sizeof (short)); }
+unsigned long ulongval () { return (long) (sizeof (short)); }
+#include <stdio.h>
+#include <stdlib.h>
+int
+main ()
+{
+
+  FILE *f = fopen ("conftest.val", "w");
+  if (! f)
+    exit (1);
+  if (((long) (sizeof (short))) < 0)
+    {
+      long i = longval ();
+      if (i != ((long) (sizeof (short))))
+       exit (1);
+      fprintf (f, "%ld\n", i);
+    }
+  else
+    {
+      unsigned long i = ulongval ();
+      if (i != ((long) (sizeof (short))))
+       exit (1);
+      fprintf (f, "%lu\n", i);
+    }
+  exit (ferror (f) || fclose (f) != 0);
+
+  ;
+  return 0;
+}
+_ACEOF
+rm -f conftest$ac_exeext
+if { (eval echo "$as_me:$LINENO: \"$ac_link\"") >&5
+  (eval $ac_link) 2>&5
+  ac_status=$?
+  echo "$as_me:$LINENO: \$? = $ac_status" >&5
+  (exit $ac_status); } && { ac_try='./conftest$ac_exeext'
+  { (eval echo "$as_me:$LINENO: \"$ac_try\"") >&5
+  (eval $ac_try) 2>&5
+  ac_status=$?
+  echo "$as_me:$LINENO: \$? = $ac_status" >&5
+  (exit $ac_status); }; }; then
+  ac_cv_sizeof_short=`cat conftest.val`
+else
+  echo "$as_me: program exited with status $ac_status" >&5
+echo "$as_me: failed program was:" >&5
+sed 's/^/| /' conftest.$ac_ext >&5
+
+( exit $ac_status )
+{ { echo "$as_me:$LINENO: error: cannot compute sizeof (short), 77
+See \`config.log' for more details." >&5
+echo "$as_me: error: cannot compute sizeof (short), 77
+See \`config.log' for more details." >&2;}
+   { (exit 1); exit 1; }; }
+fi
+rm -f core *.core gmon.out bb.out conftest$ac_exeext conftest.$ac_objext conftest.$ac_ext
+fi
+fi
+rm -f conftest.val
+else
+  ac_cv_sizeof_short=0
+fi
+fi
+echo "$as_me:$LINENO: result: $ac_cv_sizeof_short" >&5
+echo "${ECHO_T}$ac_cv_sizeof_short" >&6
+cat >>confdefs.h <<_ACEOF
+#define SIZEOF_SHORT $ac_cv_sizeof_short
+_ACEOF
+
+
+echo "$as_me:$LINENO: checking for int" >&5
+echo $ECHO_N "checking for int... $ECHO_C" >&6
+if test "${ac_cv_type_int+set}" = set; then
+  echo $ECHO_N "(cached) $ECHO_C" >&6
+else
+  cat >conftest.$ac_ext <<_ACEOF
+/* confdefs.h.  */
+_ACEOF
+cat confdefs.h >>conftest.$ac_ext
+cat >>conftest.$ac_ext <<_ACEOF
+/* end confdefs.h.  */
+$ac_includes_default
+int
+main ()
+{
+if ((int *) 0)
+  return 0;
+if (sizeof (int))
+  return 0;
+  ;
+  return 0;
+}
+_ACEOF
+rm -f conftest.$ac_objext
+if { (eval echo "$as_me:$LINENO: \"$ac_compile\"") >&5
+  (eval $ac_compile) 2>conftest.er1
+  ac_status=$?
+  grep -v '^ *+' conftest.er1 >conftest.err
+  rm -f conftest.er1
+  cat conftest.err >&5
+  echo "$as_me:$LINENO: \$? = $ac_status" >&5
+  (exit $ac_status); } &&
+        { ac_try='test -z "$ac_c_werror_flag"
+                        || test ! -s conftest.err'
+  { (eval echo "$as_me:$LINENO: \"$ac_try\"") >&5
+  (eval $ac_try) 2>&5
+  ac_status=$?
+  echo "$as_me:$LINENO: \$? = $ac_status" >&5
+  (exit $ac_status); }; } &&
+        { ac_try='test -s conftest.$ac_objext'
+  { (eval echo "$as_me:$LINENO: \"$ac_try\"") >&5
+  (eval $ac_try) 2>&5
+  ac_status=$?
+  echo "$as_me:$LINENO: \$? = $ac_status" >&5
+  (exit $ac_status); }; }; then
+  ac_cv_type_int=yes
+else
+  echo "$as_me: failed program was:" >&5
+sed 's/^/| /' conftest.$ac_ext >&5
+
+ac_cv_type_int=no
+fi
+rm -f conftest.err conftest.$ac_objext conftest.$ac_ext
+fi
+echo "$as_me:$LINENO: result: $ac_cv_type_int" >&5
+echo "${ECHO_T}$ac_cv_type_int" >&6
+
+echo "$as_me:$LINENO: checking size of int" >&5
+echo $ECHO_N "checking size of int... $ECHO_C" >&6
+if test "${ac_cv_sizeof_int+set}" = set; then
+  echo $ECHO_N "(cached) $ECHO_C" >&6
+else
+  if test "$ac_cv_type_int" = yes; then
+  # The cast to unsigned long works around a bug in the HP C Compiler
+  # version HP92453-01 B.11.11.23709.GP, which incorrectly rejects
+  # declarations like `int a3[[(sizeof (unsigned char)) >= 0]];'.
+  # This bug is HP SR number 8606223364.
+  if test "$cross_compiling" = yes; then
+  # Depending upon the size, compute the lo and hi bounds.
+cat >conftest.$ac_ext <<_ACEOF
+/* confdefs.h.  */
+_ACEOF
+cat confdefs.h >>conftest.$ac_ext
+cat >>conftest.$ac_ext <<_ACEOF
+/* end confdefs.h.  */
+$ac_includes_default
+int
+main ()
+{
+static int test_array [1 - 2 * !(((long) (sizeof (int))) >= 0)];
+test_array [0] = 0
+
+  ;
+  return 0;
+}
+_ACEOF
+rm -f conftest.$ac_objext
+if { (eval echo "$as_me:$LINENO: \"$ac_compile\"") >&5
+  (eval $ac_compile) 2>conftest.er1
+  ac_status=$?
+  grep -v '^ *+' conftest.er1 >conftest.err
+  rm -f conftest.er1
+  cat conftest.err >&5
+  echo "$as_me:$LINENO: \$? = $ac_status" >&5
+  (exit $ac_status); } &&
+        { ac_try='test -z "$ac_c_werror_flag"
+                        || test ! -s conftest.err'
+  { (eval echo "$as_me:$LINENO: \"$ac_try\"") >&5
+  (eval $ac_try) 2>&5
+  ac_status=$?
+  echo "$as_me:$LINENO: \$? = $ac_status" >&5
+  (exit $ac_status); }; } &&
+        { ac_try='test -s conftest.$ac_objext'
+  { (eval echo "$as_me:$LINENO: \"$ac_try\"") >&5
+  (eval $ac_try) 2>&5
+  ac_status=$?
+  echo "$as_me:$LINENO: \$? = $ac_status" >&5
+  (exit $ac_status); }; }; then
+  ac_lo=0 ac_mid=0
+  while :; do
+    cat >conftest.$ac_ext <<_ACEOF
+/* confdefs.h.  */
+_ACEOF
+cat confdefs.h >>conftest.$ac_ext
+cat >>conftest.$ac_ext <<_ACEOF
+/* end confdefs.h.  */
+$ac_includes_default
+int
+main ()
+{
+static int test_array [1 - 2 * !(((long) (sizeof (int))) <= $ac_mid)];
+test_array [0] = 0
+
+  ;
+  return 0;
+}
+_ACEOF
+rm -f conftest.$ac_objext
+if { (eval echo "$as_me:$LINENO: \"$ac_compile\"") >&5
+  (eval $ac_compile) 2>conftest.er1
+  ac_status=$?
+  grep -v '^ *+' conftest.er1 >conftest.err
+  rm -f conftest.er1
+  cat conftest.err >&5
+  echo "$as_me:$LINENO: \$? = $ac_status" >&5
+  (exit $ac_status); } &&
+        { ac_try='test -z "$ac_c_werror_flag"
+                        || test ! -s conftest.err'
+  { (eval echo "$as_me:$LINENO: \"$ac_try\"") >&5
+  (eval $ac_try) 2>&5
+  ac_status=$?
+  echo "$as_me:$LINENO: \$? = $ac_status" >&5
+  (exit $ac_status); }; } &&
+        { ac_try='test -s conftest.$ac_objext'
+  { (eval echo "$as_me:$LINENO: \"$ac_try\"") >&5
+  (eval $ac_try) 2>&5
+  ac_status=$?
+  echo "$as_me:$LINENO: \$? = $ac_status" >&5
+  (exit $ac_status); }; }; then
+  ac_hi=$ac_mid; break
+else
+  echo "$as_me: failed program was:" >&5
+sed 's/^/| /' conftest.$ac_ext >&5
+
+ac_lo=`expr $ac_mid + 1`
+                   if test $ac_lo -le $ac_mid; then
+                     ac_lo= ac_hi=
+                     break
+                   fi
+                   ac_mid=`expr 2 '*' $ac_mid + 1`
+fi
+rm -f conftest.err conftest.$ac_objext conftest.$ac_ext
+  done
+else
+  echo "$as_me: failed program was:" >&5
+sed 's/^/| /' conftest.$ac_ext >&5
+
+cat >conftest.$ac_ext <<_ACEOF
+/* confdefs.h.  */
+_ACEOF
+cat confdefs.h >>conftest.$ac_ext
+cat >>conftest.$ac_ext <<_ACEOF
+/* end confdefs.h.  */
+$ac_includes_default
+int
+main ()
+{
+static int test_array [1 - 2 * !(((long) (sizeof (int))) < 0)];
+test_array [0] = 0
+
+  ;
+  return 0;
+}
+_ACEOF
+rm -f conftest.$ac_objext
+if { (eval echo "$as_me:$LINENO: \"$ac_compile\"") >&5
+  (eval $ac_compile) 2>conftest.er1
+  ac_status=$?
+  grep -v '^ *+' conftest.er1 >conftest.err
+  rm -f conftest.er1
+  cat conftest.err >&5
+  echo "$as_me:$LINENO: \$? = $ac_status" >&5
+  (exit $ac_status); } &&
+        { ac_try='test -z "$ac_c_werror_flag"
+                        || test ! -s conftest.err'
+  { (eval echo "$as_me:$LINENO: \"$ac_try\"") >&5
+  (eval $ac_try) 2>&5
+  ac_status=$?
+  echo "$as_me:$LINENO: \$? = $ac_status" >&5
+  (exit $ac_status); }; } &&
+        { ac_try='test -s conftest.$ac_objext'
+  { (eval echo "$as_me:$LINENO: \"$ac_try\"") >&5
+  (eval $ac_try) 2>&5
+  ac_status=$?
+  echo "$as_me:$LINENO: \$? = $ac_status" >&5
+  (exit $ac_status); }; }; then
+  ac_hi=-1 ac_mid=-1
+  while :; do
+    cat >conftest.$ac_ext <<_ACEOF
+/* confdefs.h.  */
+_ACEOF
+cat confdefs.h >>conftest.$ac_ext
+cat >>conftest.$ac_ext <<_ACEOF
+/* end confdefs.h.  */
+$ac_includes_default
+int
+main ()
+{
+static int test_array [1 - 2 * !(((long) (sizeof (int))) >= $ac_mid)];
+test_array [0] = 0
+
+  ;
+  return 0;
+}
+_ACEOF
+rm -f conftest.$ac_objext
+if { (eval echo "$as_me:$LINENO: \"$ac_compile\"") >&5
+  (eval $ac_compile) 2>conftest.er1
+  ac_status=$?
+  grep -v '^ *+' conftest.er1 >conftest.err
+  rm -f conftest.er1
+  cat conftest.err >&5
+  echo "$as_me:$LINENO: \$? = $ac_status" >&5
+  (exit $ac_status); } &&
+        { ac_try='test -z "$ac_c_werror_flag"
+                        || test ! -s conftest.err'
+  { (eval echo "$as_me:$LINENO: \"$ac_try\"") >&5
+  (eval $ac_try) 2>&5
+  ac_status=$?
+  echo "$as_me:$LINENO: \$? = $ac_status" >&5
+  (exit $ac_status); }; } &&
+        { ac_try='test -s conftest.$ac_objext'
+  { (eval echo "$as_me:$LINENO: \"$ac_try\"") >&5
+  (eval $ac_try) 2>&5
+  ac_status=$?
+  echo "$as_me:$LINENO: \$? = $ac_status" >&5
+  (exit $ac_status); }; }; then
+  ac_lo=$ac_mid; break
+else
+  echo "$as_me: failed program was:" >&5
+sed 's/^/| /' conftest.$ac_ext >&5
+
+ac_hi=`expr '(' $ac_mid ')' - 1`
+                      if test $ac_mid -le $ac_hi; then
+                        ac_lo= ac_hi=
+                        break
+                      fi
+                      ac_mid=`expr 2 '*' $ac_mid`
+fi
+rm -f conftest.err conftest.$ac_objext conftest.$ac_ext
+  done
+else
+  echo "$as_me: failed program was:" >&5
+sed 's/^/| /' conftest.$ac_ext >&5
+
+ac_lo= ac_hi=
+fi
+rm -f conftest.err conftest.$ac_objext conftest.$ac_ext
+fi
+rm -f conftest.err conftest.$ac_objext conftest.$ac_ext
+# Binary search between lo and hi bounds.
+while test "x$ac_lo" != "x$ac_hi"; do
+  ac_mid=`expr '(' $ac_hi - $ac_lo ')' / 2 + $ac_lo`
+  cat >conftest.$ac_ext <<_ACEOF
+/* confdefs.h.  */
+_ACEOF
+cat confdefs.h >>conftest.$ac_ext
+cat >>conftest.$ac_ext <<_ACEOF
+/* end confdefs.h.  */
+$ac_includes_default
+int
+main ()
+{
+static int test_array [1 - 2 * !(((long) (sizeof (int))) <= $ac_mid)];
+test_array [0] = 0
+
+  ;
+  return 0;
+}
+_ACEOF
+rm -f conftest.$ac_objext
+if { (eval echo "$as_me:$LINENO: \"$ac_compile\"") >&5
+  (eval $ac_compile) 2>conftest.er1
+  ac_status=$?
+  grep -v '^ *+' conftest.er1 >conftest.err
+  rm -f conftest.er1
+  cat conftest.err >&5
+  echo "$as_me:$LINENO: \$? = $ac_status" >&5
+  (exit $ac_status); } &&
+        { ac_try='test -z "$ac_c_werror_flag"
+                        || test ! -s conftest.err'
+  { (eval echo "$as_me:$LINENO: \"$ac_try\"") >&5
+  (eval $ac_try) 2>&5
+  ac_status=$?
+  echo "$as_me:$LINENO: \$? = $ac_status" >&5
+  (exit $ac_status); }; } &&
+        { ac_try='test -s conftest.$ac_objext'
+  { (eval echo "$as_me:$LINENO: \"$ac_try\"") >&5
+  (eval $ac_try) 2>&5
+  ac_status=$?
+  echo "$as_me:$LINENO: \$? = $ac_status" >&5
+  (exit $ac_status); }; }; then
+  ac_hi=$ac_mid
+else
+  echo "$as_me: failed program was:" >&5
+sed 's/^/| /' conftest.$ac_ext >&5
+
+ac_lo=`expr '(' $ac_mid ')' + 1`
+fi
+rm -f conftest.err conftest.$ac_objext conftest.$ac_ext
+done
+case $ac_lo in
+?*) ac_cv_sizeof_int=$ac_lo;;
+'') { { echo "$as_me:$LINENO: error: cannot compute sizeof (int), 77
+See \`config.log' for more details." >&5
+echo "$as_me: error: cannot compute sizeof (int), 77
+See \`config.log' for more details." >&2;}
+   { (exit 1); exit 1; }; } ;;
+esac
+else
+  if test "$cross_compiling" = yes; then
+  { { echo "$as_me:$LINENO: error: cannot run test program while cross compiling
+See \`config.log' for more details." >&5
+echo "$as_me: error: cannot run test program while cross compiling
+See \`config.log' for more details." >&2;}
+   { (exit 1); exit 1; }; }
+else
+  cat >conftest.$ac_ext <<_ACEOF
+/* confdefs.h.  */
+_ACEOF
+cat confdefs.h >>conftest.$ac_ext
+cat >>conftest.$ac_ext <<_ACEOF
+/* end confdefs.h.  */
+$ac_includes_default
+long longval () { return (long) (sizeof (int)); }
+unsigned long ulongval () { return (long) (sizeof (int)); }
+#include <stdio.h>
+#include <stdlib.h>
+int
+main ()
+{
+
+  FILE *f = fopen ("conftest.val", "w");
+  if (! f)
+    exit (1);
+  if (((long) (sizeof (int))) < 0)
+    {
+      long i = longval ();
+      if (i != ((long) (sizeof (int))))
+       exit (1);
+      fprintf (f, "%ld\n", i);
+    }
+  else
+    {
+      unsigned long i = ulongval ();
+      if (i != ((long) (sizeof (int))))
+       exit (1);
+      fprintf (f, "%lu\n", i);
+    }
+  exit (ferror (f) || fclose (f) != 0);
+
+  ;
+  return 0;
+}
+_ACEOF
+rm -f conftest$ac_exeext
+if { (eval echo "$as_me:$LINENO: \"$ac_link\"") >&5
+  (eval $ac_link) 2>&5
+  ac_status=$?
+  echo "$as_me:$LINENO: \$? = $ac_status" >&5
+  (exit $ac_status); } && { ac_try='./conftest$ac_exeext'
+  { (eval echo "$as_me:$LINENO: \"$ac_try\"") >&5
+  (eval $ac_try) 2>&5
+  ac_status=$?
+  echo "$as_me:$LINENO: \$? = $ac_status" >&5
+  (exit $ac_status); }; }; then
+  ac_cv_sizeof_int=`cat conftest.val`
+else
+  echo "$as_me: program exited with status $ac_status" >&5
+echo "$as_me: failed program was:" >&5
+sed 's/^/| /' conftest.$ac_ext >&5
+
+( exit $ac_status )
+{ { echo "$as_me:$LINENO: error: cannot compute sizeof (int), 77
+See \`config.log' for more details." >&5
+echo "$as_me: error: cannot compute sizeof (int), 77
+See \`config.log' for more details." >&2;}
+   { (exit 1); exit 1; }; }
+fi
+rm -f core *.core gmon.out bb.out conftest$ac_exeext conftest.$ac_objext conftest.$ac_ext
+fi
+fi
+rm -f conftest.val
+else
+  ac_cv_sizeof_int=0
+fi
+fi
+echo "$as_me:$LINENO: result: $ac_cv_sizeof_int" >&5
+echo "${ECHO_T}$ac_cv_sizeof_int" >&6
+cat >>confdefs.h <<_ACEOF
+#define SIZEOF_INT $ac_cv_sizeof_int
+_ACEOF
+
+
+echo "$as_me:$LINENO: checking for long" >&5
+echo $ECHO_N "checking for long... $ECHO_C" >&6
+if test "${ac_cv_type_long+set}" = set; then
+  echo $ECHO_N "(cached) $ECHO_C" >&6
+else
+  cat >conftest.$ac_ext <<_ACEOF
+/* confdefs.h.  */
+_ACEOF
+cat confdefs.h >>conftest.$ac_ext
+cat >>conftest.$ac_ext <<_ACEOF
+/* end confdefs.h.  */
+$ac_includes_default
+int
+main ()
+{
+if ((long *) 0)
+  return 0;
+if (sizeof (long))
+  return 0;
+  ;
+  return 0;
+}
+_ACEOF
+rm -f conftest.$ac_objext
+if { (eval echo "$as_me:$LINENO: \"$ac_compile\"") >&5
+  (eval $ac_compile) 2>conftest.er1
+  ac_status=$?
+  grep -v '^ *+' conftest.er1 >conftest.err
+  rm -f conftest.er1
+  cat conftest.err >&5
+  echo "$as_me:$LINENO: \$? = $ac_status" >&5
+  (exit $ac_status); } &&
+        { ac_try='test -z "$ac_c_werror_flag"
+                        || test ! -s conftest.err'
+  { (eval echo "$as_me:$LINENO: \"$ac_try\"") >&5
+  (eval $ac_try) 2>&5
+  ac_status=$?
+  echo "$as_me:$LINENO: \$? = $ac_status" >&5
+  (exit $ac_status); }; } &&
+        { ac_try='test -s conftest.$ac_objext'
+  { (eval echo "$as_me:$LINENO: \"$ac_try\"") >&5
+  (eval $ac_try) 2>&5
+  ac_status=$?
+  echo "$as_me:$LINENO: \$? = $ac_status" >&5
+  (exit $ac_status); }; }; then
+  ac_cv_type_long=yes
+else
+  echo "$as_me: failed program was:" >&5
+sed 's/^/| /' conftest.$ac_ext >&5
+
+ac_cv_type_long=no
+fi
+rm -f conftest.err conftest.$ac_objext conftest.$ac_ext
+fi
+echo "$as_me:$LINENO: result: $ac_cv_type_long" >&5
+echo "${ECHO_T}$ac_cv_type_long" >&6
+
+echo "$as_me:$LINENO: checking size of long" >&5
+echo $ECHO_N "checking size of long... $ECHO_C" >&6
+if test "${ac_cv_sizeof_long+set}" = set; then
+  echo $ECHO_N "(cached) $ECHO_C" >&6
+else
+  if test "$ac_cv_type_long" = yes; then
+  # The cast to unsigned long works around a bug in the HP C Compiler
+  # version HP92453-01 B.11.11.23709.GP, which incorrectly rejects
+  # declarations like `int a3[[(sizeof (unsigned char)) >= 0]];'.
+  # This bug is HP SR number 8606223364.
+  if test "$cross_compiling" = yes; then
+  # Depending upon the size, compute the lo and hi bounds.
+cat >conftest.$ac_ext <<_ACEOF
+/* confdefs.h.  */
+_ACEOF
+cat confdefs.h >>conftest.$ac_ext
+cat >>conftest.$ac_ext <<_ACEOF
+/* end confdefs.h.  */
+$ac_includes_default
+int
+main ()
+{
+static int test_array [1 - 2 * !(((long) (sizeof (long))) >= 0)];
+test_array [0] = 0
+
+  ;
+  return 0;
+}
+_ACEOF
+rm -f conftest.$ac_objext
+if { (eval echo "$as_me:$LINENO: \"$ac_compile\"") >&5
+  (eval $ac_compile) 2>conftest.er1
+  ac_status=$?
+  grep -v '^ *+' conftest.er1 >conftest.err
+  rm -f conftest.er1
+  cat conftest.err >&5
+  echo "$as_me:$LINENO: \$? = $ac_status" >&5
+  (exit $ac_status); } &&
+        { ac_try='test -z "$ac_c_werror_flag"
+                        || test ! -s conftest.err'
+  { (eval echo "$as_me:$LINENO: \"$ac_try\"") >&5
+  (eval $ac_try) 2>&5
+  ac_status=$?
+  echo "$as_me:$LINENO: \$? = $ac_status" >&5
+  (exit $ac_status); }; } &&
+        { ac_try='test -s conftest.$ac_objext'
+  { (eval echo "$as_me:$LINENO: \"$ac_try\"") >&5
+  (eval $ac_try) 2>&5
+  ac_status=$?
+  echo "$as_me:$LINENO: \$? = $ac_status" >&5
+  (exit $ac_status); }; }; then
+  ac_lo=0 ac_mid=0
+  while :; do
+    cat >conftest.$ac_ext <<_ACEOF
+/* confdefs.h.  */
+_ACEOF
+cat confdefs.h >>conftest.$ac_ext
+cat >>conftest.$ac_ext <<_ACEOF
+/* end confdefs.h.  */
+$ac_includes_default
+int
+main ()
+{
+static int test_array [1 - 2 * !(((long) (sizeof (long))) <= $ac_mid)];
+test_array [0] = 0
+
+  ;
+  return 0;
+}
+_ACEOF
+rm -f conftest.$ac_objext
+if { (eval echo "$as_me:$LINENO: \"$ac_compile\"") >&5
+  (eval $ac_compile) 2>conftest.er1
+  ac_status=$?
+  grep -v '^ *+' conftest.er1 >conftest.err
+  rm -f conftest.er1
+  cat conftest.err >&5
+  echo "$as_me:$LINENO: \$? = $ac_status" >&5
+  (exit $ac_status); } &&
+        { ac_try='test -z "$ac_c_werror_flag"
+                        || test ! -s conftest.err'
+  { (eval echo "$as_me:$LINENO: \"$ac_try\"") >&5
+  (eval $ac_try) 2>&5
+  ac_status=$?
+  echo "$as_me:$LINENO: \$? = $ac_status" >&5
+  (exit $ac_status); }; } &&
+        { ac_try='test -s conftest.$ac_objext'
+  { (eval echo "$as_me:$LINENO: \"$ac_try\"") >&5
+  (eval $ac_try) 2>&5
+  ac_status=$?
+  echo "$as_me:$LINENO: \$? = $ac_status" >&5
+  (exit $ac_status); }; }; then
+  ac_hi=$ac_mid; break
+else
+  echo "$as_me: failed program was:" >&5
+sed 's/^/| /' conftest.$ac_ext >&5
+
+ac_lo=`expr $ac_mid + 1`
+                   if test $ac_lo -le $ac_mid; then
+                     ac_lo= ac_hi=
+                     break
+                   fi
+                   ac_mid=`expr 2 '*' $ac_mid + 1`
+fi
+rm -f conftest.err conftest.$ac_objext conftest.$ac_ext
+  done
+else
+  echo "$as_me: failed program was:" >&5
+sed 's/^/| /' conftest.$ac_ext >&5
+
+cat >conftest.$ac_ext <<_ACEOF
+/* confdefs.h.  */
+_ACEOF
+cat confdefs.h >>conftest.$ac_ext
+cat >>conftest.$ac_ext <<_ACEOF
+/* end confdefs.h.  */
+$ac_includes_default
+int
+main ()
+{
+static int test_array [1 - 2 * !(((long) (sizeof (long))) < 0)];
+test_array [0] = 0
+
+  ;
+  return 0;
+}
+_ACEOF
+rm -f conftest.$ac_objext
+if { (eval echo "$as_me:$LINENO: \"$ac_compile\"") >&5
+  (eval $ac_compile) 2>conftest.er1
+  ac_status=$?
+  grep -v '^ *+' conftest.er1 >conftest.err
+  rm -f conftest.er1
+  cat conftest.err >&5
+  echo "$as_me:$LINENO: \$? = $ac_status" >&5
+  (exit $ac_status); } &&
+        { ac_try='test -z "$ac_c_werror_flag"
+                        || test ! -s conftest.err'
+  { (eval echo "$as_me:$LINENO: \"$ac_try\"") >&5
+  (eval $ac_try) 2>&5
+  ac_status=$?
+  echo "$as_me:$LINENO: \$? = $ac_status" >&5
+  (exit $ac_status); }; } &&
+        { ac_try='test -s conftest.$ac_objext'
+  { (eval echo "$as_me:$LINENO: \"$ac_try\"") >&5
+  (eval $ac_try) 2>&5
+  ac_status=$?
+  echo "$as_me:$LINENO: \$? = $ac_status" >&5
+  (exit $ac_status); }; }; then
+  ac_hi=-1 ac_mid=-1
+  while :; do
+    cat >conftest.$ac_ext <<_ACEOF
+/* confdefs.h.  */
+_ACEOF
+cat confdefs.h >>conftest.$ac_ext
+cat >>conftest.$ac_ext <<_ACEOF
+/* end confdefs.h.  */
+$ac_includes_default
+int
+main ()
+{
+static int test_array [1 - 2 * !(((long) (sizeof (long))) >= $ac_mid)];
+test_array [0] = 0
+
+  ;
+  return 0;
+}
+_ACEOF
+rm -f conftest.$ac_objext
+if { (eval echo "$as_me:$LINENO: \"$ac_compile\"") >&5
+  (eval $ac_compile) 2>conftest.er1
+  ac_status=$?
+  grep -v '^ *+' conftest.er1 >conftest.err
+  rm -f conftest.er1
+  cat conftest.err >&5
+  echo "$as_me:$LINENO: \$? = $ac_status" >&5
+  (exit $ac_status); } &&
+        { ac_try='test -z "$ac_c_werror_flag"
+                        || test ! -s conftest.err'
+  { (eval echo "$as_me:$LINENO: \"$ac_try\"") >&5
+  (eval $ac_try) 2>&5
+  ac_status=$?
+  echo "$as_me:$LINENO: \$? = $ac_status" >&5
+  (exit $ac_status); }; } &&
+        { ac_try='test -s conftest.$ac_objext'
+  { (eval echo "$as_me:$LINENO: \"$ac_try\"") >&5
+  (eval $ac_try) 2>&5
+  ac_status=$?
+  echo "$as_me:$LINENO: \$? = $ac_status" >&5
+  (exit $ac_status); }; }; then
+  ac_lo=$ac_mid; break
+else
+  echo "$as_me: failed program was:" >&5
+sed 's/^/| /' conftest.$ac_ext >&5
+
+ac_hi=`expr '(' $ac_mid ')' - 1`
+                      if test $ac_mid -le $ac_hi; then
+                        ac_lo= ac_hi=
+                        break
+                      fi
+                      ac_mid=`expr 2 '*' $ac_mid`
+fi
+rm -f conftest.err conftest.$ac_objext conftest.$ac_ext
+  done
+else
+  echo "$as_me: failed program was:" >&5
+sed 's/^/| /' conftest.$ac_ext >&5
+
+ac_lo= ac_hi=
+fi
+rm -f conftest.err conftest.$ac_objext conftest.$ac_ext
+fi
+rm -f conftest.err conftest.$ac_objext conftest.$ac_ext
+# Binary search between lo and hi bounds.
+while test "x$ac_lo" != "x$ac_hi"; do
+  ac_mid=`expr '(' $ac_hi - $ac_lo ')' / 2 + $ac_lo`
+  cat >conftest.$ac_ext <<_ACEOF
+/* confdefs.h.  */
+_ACEOF
+cat confdefs.h >>conftest.$ac_ext
+cat >>conftest.$ac_ext <<_ACEOF
+/* end confdefs.h.  */
+$ac_includes_default
+int
+main ()
+{
+static int test_array [1 - 2 * !(((long) (sizeof (long))) <= $ac_mid)];
+test_array [0] = 0
+
+  ;
+  return 0;
+}
+_ACEOF
+rm -f conftest.$ac_objext
+if { (eval echo "$as_me:$LINENO: \"$ac_compile\"") >&5
+  (eval $ac_compile) 2>conftest.er1
+  ac_status=$?
+  grep -v '^ *+' conftest.er1 >conftest.err
+  rm -f conftest.er1
+  cat conftest.err >&5
+  echo "$as_me:$LINENO: \$? = $ac_status" >&5
+  (exit $ac_status); } &&
+        { ac_try='test -z "$ac_c_werror_flag"
+                        || test ! -s conftest.err'
+  { (eval echo "$as_me:$LINENO: \"$ac_try\"") >&5
+  (eval $ac_try) 2>&5
+  ac_status=$?
+  echo "$as_me:$LINENO: \$? = $ac_status" >&5
+  (exit $ac_status); }; } &&
+        { ac_try='test -s conftest.$ac_objext'
+  { (eval echo "$as_me:$LINENO: \"$ac_try\"") >&5
+  (eval $ac_try) 2>&5
+  ac_status=$?
+  echo "$as_me:$LINENO: \$? = $ac_status" >&5
+  (exit $ac_status); }; }; then
+  ac_hi=$ac_mid
+else
+  echo "$as_me: failed program was:" >&5
+sed 's/^/| /' conftest.$ac_ext >&5
+
+ac_lo=`expr '(' $ac_mid ')' + 1`
+fi
+rm -f conftest.err conftest.$ac_objext conftest.$ac_ext
+done
+case $ac_lo in
+?*) ac_cv_sizeof_long=$ac_lo;;
+'') { { echo "$as_me:$LINENO: error: cannot compute sizeof (long), 77
+See \`config.log' for more details." >&5
+echo "$as_me: error: cannot compute sizeof (long), 77
+See \`config.log' for more details." >&2;}
+   { (exit 1); exit 1; }; } ;;
+esac
+else
+  if test "$cross_compiling" = yes; then
+  { { echo "$as_me:$LINENO: error: cannot run test program while cross compiling
+See \`config.log' for more details." >&5
+echo "$as_me: error: cannot run test program while cross compiling
+See \`config.log' for more details." >&2;}
+   { (exit 1); exit 1; }; }
+else
+  cat >conftest.$ac_ext <<_ACEOF
+/* confdefs.h.  */
+_ACEOF
+cat confdefs.h >>conftest.$ac_ext
+cat >>conftest.$ac_ext <<_ACEOF
+/* end confdefs.h.  */
+$ac_includes_default
+long longval () { return (long) (sizeof (long)); }
+unsigned long ulongval () { return (long) (sizeof (long)); }
+#include <stdio.h>
+#include <stdlib.h>
+int
+main ()
+{
+
+  FILE *f = fopen ("conftest.val", "w");
+  if (! f)
+    exit (1);
+  if (((long) (sizeof (long))) < 0)
+    {
+      long i = longval ();
+      if (i != ((long) (sizeof (long))))
+       exit (1);
+      fprintf (f, "%ld\n", i);
+    }
+  else
+    {
+      unsigned long i = ulongval ();
+      if (i != ((long) (sizeof (long))))
+       exit (1);
+      fprintf (f, "%lu\n", i);
+    }
+  exit (ferror (f) || fclose (f) != 0);
+
+  ;
+  return 0;
+}
+_ACEOF
+rm -f conftest$ac_exeext
+if { (eval echo "$as_me:$LINENO: \"$ac_link\"") >&5
+  (eval $ac_link) 2>&5
+  ac_status=$?
+  echo "$as_me:$LINENO: \$? = $ac_status" >&5
+  (exit $ac_status); } && { ac_try='./conftest$ac_exeext'
+  { (eval echo "$as_me:$LINENO: \"$ac_try\"") >&5
+  (eval $ac_try) 2>&5
+  ac_status=$?
+  echo "$as_me:$LINENO: \$? = $ac_status" >&5
+  (exit $ac_status); }; }; then
+  ac_cv_sizeof_long=`cat conftest.val`
+else
+  echo "$as_me: program exited with status $ac_status" >&5
+echo "$as_me: failed program was:" >&5
+sed 's/^/| /' conftest.$ac_ext >&5
+
+( exit $ac_status )
+{ { echo "$as_me:$LINENO: error: cannot compute sizeof (long), 77
+See \`config.log' for more details." >&5
+echo "$as_me: error: cannot compute sizeof (long), 77
+See \`config.log' for more details." >&2;}
+   { (exit 1); exit 1; }; }
+fi
+rm -f core *.core gmon.out bb.out conftest$ac_exeext conftest.$ac_objext conftest.$ac_ext
+fi
+fi
+rm -f conftest.val
+else
+  ac_cv_sizeof_long=0
+fi
+fi
+echo "$as_me:$LINENO: result: $ac_cv_sizeof_long" >&5
+echo "${ECHO_T}$ac_cv_sizeof_long" >&6
+cat >>confdefs.h <<_ACEOF
+#define SIZEOF_LONG $ac_cv_sizeof_long
+_ACEOF
+
+
+echo "$as_me:$LINENO: checking for float" >&5
+echo $ECHO_N "checking for float... $ECHO_C" >&6
+if test "${ac_cv_type_float+set}" = set; then
+  echo $ECHO_N "(cached) $ECHO_C" >&6
+else
+  cat >conftest.$ac_ext <<_ACEOF
+/* confdefs.h.  */
+_ACEOF
+cat confdefs.h >>conftest.$ac_ext
+cat >>conftest.$ac_ext <<_ACEOF
+/* end confdefs.h.  */
+$ac_includes_default
+int
+main ()
+{
+if ((float *) 0)
+  return 0;
+if (sizeof (float))
+  return 0;
+  ;
+  return 0;
+}
+_ACEOF
+rm -f conftest.$ac_objext
+if { (eval echo "$as_me:$LINENO: \"$ac_compile\"") >&5
+  (eval $ac_compile) 2>conftest.er1
+  ac_status=$?
+  grep -v '^ *+' conftest.er1 >conftest.err
+  rm -f conftest.er1
+  cat conftest.err >&5
+  echo "$as_me:$LINENO: \$? = $ac_status" >&5
+  (exit $ac_status); } &&
+        { ac_try='test -z "$ac_c_werror_flag"
+                        || test ! -s conftest.err'
+  { (eval echo "$as_me:$LINENO: \"$ac_try\"") >&5
+  (eval $ac_try) 2>&5
+  ac_status=$?
+  echo "$as_me:$LINENO: \$? = $ac_status" >&5
+  (exit $ac_status); }; } &&
+        { ac_try='test -s conftest.$ac_objext'
+  { (eval echo "$as_me:$LINENO: \"$ac_try\"") >&5
+  (eval $ac_try) 2>&5
+  ac_status=$?
+  echo "$as_me:$LINENO: \$? = $ac_status" >&5
+  (exit $ac_status); }; }; then
+  ac_cv_type_float=yes
+else
+  echo "$as_me: failed program was:" >&5
+sed 's/^/| /' conftest.$ac_ext >&5
+
+ac_cv_type_float=no
+fi
+rm -f conftest.err conftest.$ac_objext conftest.$ac_ext
+fi
+echo "$as_me:$LINENO: result: $ac_cv_type_float" >&5
+echo "${ECHO_T}$ac_cv_type_float" >&6
+
+echo "$as_me:$LINENO: checking size of float" >&5
+echo $ECHO_N "checking size of float... $ECHO_C" >&6
+if test "${ac_cv_sizeof_float+set}" = set; then
+  echo $ECHO_N "(cached) $ECHO_C" >&6
+else
+  if test "$ac_cv_type_float" = yes; then
+  # The cast to unsigned long works around a bug in the HP C Compiler
+  # version HP92453-01 B.11.11.23709.GP, which incorrectly rejects
+  # declarations like `int a3[[(sizeof (unsigned char)) >= 0]];'.
+  # This bug is HP SR number 8606223364.
+  if test "$cross_compiling" = yes; then
+  # Depending upon the size, compute the lo and hi bounds.
+cat >conftest.$ac_ext <<_ACEOF
+/* confdefs.h.  */
+_ACEOF
+cat confdefs.h >>conftest.$ac_ext
+cat >>conftest.$ac_ext <<_ACEOF
+/* end confdefs.h.  */
+$ac_includes_default
+int
+main ()
+{
+static int test_array [1 - 2 * !(((long) (sizeof (float))) >= 0)];
+test_array [0] = 0
+
+  ;
+  return 0;
+}
+_ACEOF
+rm -f conftest.$ac_objext
+if { (eval echo "$as_me:$LINENO: \"$ac_compile\"") >&5
+  (eval $ac_compile) 2>conftest.er1
+  ac_status=$?
+  grep -v '^ *+' conftest.er1 >conftest.err
+  rm -f conftest.er1
+  cat conftest.err >&5
+  echo "$as_me:$LINENO: \$? = $ac_status" >&5
+  (exit $ac_status); } &&
+        { ac_try='test -z "$ac_c_werror_flag"
+                        || test ! -s conftest.err'
+  { (eval echo "$as_me:$LINENO: \"$ac_try\"") >&5
+  (eval $ac_try) 2>&5
+  ac_status=$?
+  echo "$as_me:$LINENO: \$? = $ac_status" >&5
+  (exit $ac_status); }; } &&
+        { ac_try='test -s conftest.$ac_objext'
+  { (eval echo "$as_me:$LINENO: \"$ac_try\"") >&5
+  (eval $ac_try) 2>&5
+  ac_status=$?
+  echo "$as_me:$LINENO: \$? = $ac_status" >&5
+  (exit $ac_status); }; }; then
+  ac_lo=0 ac_mid=0
+  while :; do
+    cat >conftest.$ac_ext <<_ACEOF
+/* confdefs.h.  */
+_ACEOF
+cat confdefs.h >>conftest.$ac_ext
+cat >>conftest.$ac_ext <<_ACEOF
+/* end confdefs.h.  */
+$ac_includes_default
+int
+main ()
+{
+static int test_array [1 - 2 * !(((long) (sizeof (float))) <= $ac_mid)];
+test_array [0] = 0
+
+  ;
+  return 0;
+}
+_ACEOF
+rm -f conftest.$ac_objext
+if { (eval echo "$as_me:$LINENO: \"$ac_compile\"") >&5
+  (eval $ac_compile) 2>conftest.er1
+  ac_status=$?
+  grep -v '^ *+' conftest.er1 >conftest.err
+  rm -f conftest.er1
+  cat conftest.err >&5
+  echo "$as_me:$LINENO: \$? = $ac_status" >&5
+  (exit $ac_status); } &&
+        { ac_try='test -z "$ac_c_werror_flag"
+                        || test ! -s conftest.err'
+  { (eval echo "$as_me:$LINENO: \"$ac_try\"") >&5
+  (eval $ac_try) 2>&5
+  ac_status=$?
+  echo "$as_me:$LINENO: \$? = $ac_status" >&5
+  (exit $ac_status); }; } &&
+        { ac_try='test -s conftest.$ac_objext'
+  { (eval echo "$as_me:$LINENO: \"$ac_try\"") >&5
+  (eval $ac_try) 2>&5
+  ac_status=$?
+  echo "$as_me:$LINENO: \$? = $ac_status" >&5
+  (exit $ac_status); }; }; then
+  ac_hi=$ac_mid; break
+else
+  echo "$as_me: failed program was:" >&5
+sed 's/^/| /' conftest.$ac_ext >&5
+
+ac_lo=`expr $ac_mid + 1`
+                   if test $ac_lo -le $ac_mid; then
+                     ac_lo= ac_hi=
+                     break
+                   fi
+                   ac_mid=`expr 2 '*' $ac_mid + 1`
+fi
+rm -f conftest.err conftest.$ac_objext conftest.$ac_ext
+  done
+else
+  echo "$as_me: failed program was:" >&5
+sed 's/^/| /' conftest.$ac_ext >&5
+
+cat >conftest.$ac_ext <<_ACEOF
+/* confdefs.h.  */
+_ACEOF
+cat confdefs.h >>conftest.$ac_ext
+cat >>conftest.$ac_ext <<_ACEOF
+/* end confdefs.h.  */
+$ac_includes_default
+int
+main ()
+{
+static int test_array [1 - 2 * !(((long) (sizeof (float))) < 0)];
+test_array [0] = 0
+
+  ;
+  return 0;
+}
+_ACEOF
+rm -f conftest.$ac_objext
+if { (eval echo "$as_me:$LINENO: \"$ac_compile\"") >&5
+  (eval $ac_compile) 2>conftest.er1
+  ac_status=$?
+  grep -v '^ *+' conftest.er1 >conftest.err
+  rm -f conftest.er1
+  cat conftest.err >&5
+  echo "$as_me:$LINENO: \$? = $ac_status" >&5
+  (exit $ac_status); } &&
+        { ac_try='test -z "$ac_c_werror_flag"
+                        || test ! -s conftest.err'
+  { (eval echo "$as_me:$LINENO: \"$ac_try\"") >&5
+  (eval $ac_try) 2>&5
+  ac_status=$?
+  echo "$as_me:$LINENO: \$? = $ac_status" >&5
+  (exit $ac_status); }; } &&
+        { ac_try='test -s conftest.$ac_objext'
+  { (eval echo "$as_me:$LINENO: \"$ac_try\"") >&5
+  (eval $ac_try) 2>&5
+  ac_status=$?
+  echo "$as_me:$LINENO: \$? = $ac_status" >&5
+  (exit $ac_status); }; }; then
+  ac_hi=-1 ac_mid=-1
+  while :; do
+    cat >conftest.$ac_ext <<_ACEOF
+/* confdefs.h.  */
+_ACEOF
+cat confdefs.h >>conftest.$ac_ext
+cat >>conftest.$ac_ext <<_ACEOF
+/* end confdefs.h.  */
+$ac_includes_default
+int
+main ()
+{
+static int test_array [1 - 2 * !(((long) (sizeof (float))) >= $ac_mid)];
+test_array [0] = 0
+
+  ;
+  return 0;
+}
+_ACEOF
+rm -f conftest.$ac_objext
+if { (eval echo "$as_me:$LINENO: \"$ac_compile\"") >&5
+  (eval $ac_compile) 2>conftest.er1
+  ac_status=$?
+  grep -v '^ *+' conftest.er1 >conftest.err
+  rm -f conftest.er1
+  cat conftest.err >&5
+  echo "$as_me:$LINENO: \$? = $ac_status" >&5
+  (exit $ac_status); } &&
+        { ac_try='test -z "$ac_c_werror_flag"
+                        || test ! -s conftest.err'
+  { (eval echo "$as_me:$LINENO: \"$ac_try\"") >&5
+  (eval $ac_try) 2>&5
+  ac_status=$?
+  echo "$as_me:$LINENO: \$? = $ac_status" >&5
+  (exit $ac_status); }; } &&
+        { ac_try='test -s conftest.$ac_objext'
+  { (eval echo "$as_me:$LINENO: \"$ac_try\"") >&5
+  (eval $ac_try) 2>&5
+  ac_status=$?
+  echo "$as_me:$LINENO: \$? = $ac_status" >&5
+  (exit $ac_status); }; }; then
+  ac_lo=$ac_mid; break
+else
+  echo "$as_me: failed program was:" >&5
+sed 's/^/| /' conftest.$ac_ext >&5
+
+ac_hi=`expr '(' $ac_mid ')' - 1`
+                      if test $ac_mid -le $ac_hi; then
+                        ac_lo= ac_hi=
+                        break
+                      fi
+                      ac_mid=`expr 2 '*' $ac_mid`
+fi
+rm -f conftest.err conftest.$ac_objext conftest.$ac_ext
+  done
+else
+  echo "$as_me: failed program was:" >&5
+sed 's/^/| /' conftest.$ac_ext >&5
+
+ac_lo= ac_hi=
+fi
+rm -f conftest.err conftest.$ac_objext conftest.$ac_ext
+fi
+rm -f conftest.err conftest.$ac_objext conftest.$ac_ext
+# Binary search between lo and hi bounds.
+while test "x$ac_lo" != "x$ac_hi"; do
+  ac_mid=`expr '(' $ac_hi - $ac_lo ')' / 2 + $ac_lo`
+  cat >conftest.$ac_ext <<_ACEOF
+/* confdefs.h.  */
+_ACEOF
+cat confdefs.h >>conftest.$ac_ext
+cat >>conftest.$ac_ext <<_ACEOF
+/* end confdefs.h.  */
+$ac_includes_default
+int
+main ()
+{
+static int test_array [1 - 2 * !(((long) (sizeof (float))) <= $ac_mid)];
+test_array [0] = 0
+
+  ;
+  return 0;
+}
+_ACEOF
+rm -f conftest.$ac_objext
+if { (eval echo "$as_me:$LINENO: \"$ac_compile\"") >&5
+  (eval $ac_compile) 2>conftest.er1
+  ac_status=$?
+  grep -v '^ *+' conftest.er1 >conftest.err
+  rm -f conftest.er1
+  cat conftest.err >&5
+  echo "$as_me:$LINENO: \$? = $ac_status" >&5
+  (exit $ac_status); } &&
+        { ac_try='test -z "$ac_c_werror_flag"
+                        || test ! -s conftest.err'
+  { (eval echo "$as_me:$LINENO: \"$ac_try\"") >&5
+  (eval $ac_try) 2>&5
+  ac_status=$?
+  echo "$as_me:$LINENO: \$? = $ac_status" >&5
+  (exit $ac_status); }; } &&
+        { ac_try='test -s conftest.$ac_objext'
+  { (eval echo "$as_me:$LINENO: \"$ac_try\"") >&5
+  (eval $ac_try) 2>&5
+  ac_status=$?
+  echo "$as_me:$LINENO: \$? = $ac_status" >&5
+  (exit $ac_status); }; }; then
+  ac_hi=$ac_mid
+else
+  echo "$as_me: failed program was:" >&5
+sed 's/^/| /' conftest.$ac_ext >&5
+
+ac_lo=`expr '(' $ac_mid ')' + 1`
+fi
+rm -f conftest.err conftest.$ac_objext conftest.$ac_ext
+done
+case $ac_lo in
+?*) ac_cv_sizeof_float=$ac_lo;;
+'') { { echo "$as_me:$LINENO: error: cannot compute sizeof (float), 77
+See \`config.log' for more details." >&5
+echo "$as_me: error: cannot compute sizeof (float), 77
+See \`config.log' for more details." >&2;}
+   { (exit 1); exit 1; }; } ;;
+esac
+else
+  if test "$cross_compiling" = yes; then
+  { { echo "$as_me:$LINENO: error: cannot run test program while cross compiling
+See \`config.log' for more details." >&5
+echo "$as_me: error: cannot run test program while cross compiling
+See \`config.log' for more details." >&2;}
+   { (exit 1); exit 1; }; }
+else
+  cat >conftest.$ac_ext <<_ACEOF
+/* confdefs.h.  */
+_ACEOF
+cat confdefs.h >>conftest.$ac_ext
+cat >>conftest.$ac_ext <<_ACEOF
+/* end confdefs.h.  */
+$ac_includes_default
+long longval () { return (long) (sizeof (float)); }
+unsigned long ulongval () { return (long) (sizeof (float)); }
+#include <stdio.h>
+#include <stdlib.h>
+int
+main ()
+{
+
+  FILE *f = fopen ("conftest.val", "w");
+  if (! f)
+    exit (1);
+  if (((long) (sizeof (float))) < 0)
+    {
+      long i = longval ();
+      if (i != ((long) (sizeof (float))))
+       exit (1);
+      fprintf (f, "%ld\n", i);
+    }
+  else
+    {
+      unsigned long i = ulongval ();
+      if (i != ((long) (sizeof (float))))
+       exit (1);
+      fprintf (f, "%lu\n", i);
+    }
+  exit (ferror (f) || fclose (f) != 0);
+
+  ;
+  return 0;
+}
+_ACEOF
+rm -f conftest$ac_exeext
+if { (eval echo "$as_me:$LINENO: \"$ac_link\"") >&5
+  (eval $ac_link) 2>&5
+  ac_status=$?
+  echo "$as_me:$LINENO: \$? = $ac_status" >&5
+  (exit $ac_status); } && { ac_try='./conftest$ac_exeext'
+  { (eval echo "$as_me:$LINENO: \"$ac_try\"") >&5
+  (eval $ac_try) 2>&5
+  ac_status=$?
+  echo "$as_me:$LINENO: \$? = $ac_status" >&5
+  (exit $ac_status); }; }; then
+  ac_cv_sizeof_float=`cat conftest.val`
+else
+  echo "$as_me: program exited with status $ac_status" >&5
+echo "$as_me: failed program was:" >&5
+sed 's/^/| /' conftest.$ac_ext >&5
+
+( exit $ac_status )
+{ { echo "$as_me:$LINENO: error: cannot compute sizeof (float), 77
+See \`config.log' for more details." >&5
+echo "$as_me: error: cannot compute sizeof (float), 77
+See \`config.log' for more details." >&2;}
+   { (exit 1); exit 1; }; }
+fi
+rm -f core *.core gmon.out bb.out conftest$ac_exeext conftest.$ac_objext conftest.$ac_ext
+fi
+fi
+rm -f conftest.val
+else
+  ac_cv_sizeof_float=0
+fi
+fi
+echo "$as_me:$LINENO: result: $ac_cv_sizeof_float" >&5
+echo "${ECHO_T}$ac_cv_sizeof_float" >&6
+cat >>confdefs.h <<_ACEOF
+#define SIZEOF_FLOAT $ac_cv_sizeof_float
+_ACEOF
+
+
+echo "$as_me:$LINENO: checking for double" >&5
+echo $ECHO_N "checking for double... $ECHO_C" >&6
+if test "${ac_cv_type_double+set}" = set; then
+  echo $ECHO_N "(cached) $ECHO_C" >&6
+else
+  cat >conftest.$ac_ext <<_ACEOF
+/* confdefs.h.  */
+_ACEOF
+cat confdefs.h >>conftest.$ac_ext
+cat >>conftest.$ac_ext <<_ACEOF
+/* end confdefs.h.  */
+$ac_includes_default
+int
+main ()
+{
+if ((double *) 0)
+  return 0;
+if (sizeof (double))
+  return 0;
+  ;
+  return 0;
+}
+_ACEOF
+rm -f conftest.$ac_objext
+if { (eval echo "$as_me:$LINENO: \"$ac_compile\"") >&5
+  (eval $ac_compile) 2>conftest.er1
+  ac_status=$?
+  grep -v '^ *+' conftest.er1 >conftest.err
+  rm -f conftest.er1
+  cat conftest.err >&5
+  echo "$as_me:$LINENO: \$? = $ac_status" >&5
+  (exit $ac_status); } &&
+        { ac_try='test -z "$ac_c_werror_flag"
+                        || test ! -s conftest.err'
+  { (eval echo "$as_me:$LINENO: \"$ac_try\"") >&5
+  (eval $ac_try) 2>&5
+  ac_status=$?
+  echo "$as_me:$LINENO: \$? = $ac_status" >&5
+  (exit $ac_status); }; } &&
+        { ac_try='test -s conftest.$ac_objext'
+  { (eval echo "$as_me:$LINENO: \"$ac_try\"") >&5
+  (eval $ac_try) 2>&5
+  ac_status=$?
+  echo "$as_me:$LINENO: \$? = $ac_status" >&5
+  (exit $ac_status); }; }; then
+  ac_cv_type_double=yes
+else
+  echo "$as_me: failed program was:" >&5
+sed 's/^/| /' conftest.$ac_ext >&5
+
+ac_cv_type_double=no
+fi
+rm -f conftest.err conftest.$ac_objext conftest.$ac_ext
+fi
+echo "$as_me:$LINENO: result: $ac_cv_type_double" >&5
+echo "${ECHO_T}$ac_cv_type_double" >&6
+
+echo "$as_me:$LINENO: checking size of double" >&5
+echo $ECHO_N "checking size of double... $ECHO_C" >&6
+if test "${ac_cv_sizeof_double+set}" = set; then
+  echo $ECHO_N "(cached) $ECHO_C" >&6
+else
+  if test "$ac_cv_type_double" = yes; then
+  # The cast to unsigned long works around a bug in the HP C Compiler
+  # version HP92453-01 B.11.11.23709.GP, which incorrectly rejects
+  # declarations like `int a3[[(sizeof (unsigned char)) >= 0]];'.
+  # This bug is HP SR number 8606223364.
+  if test "$cross_compiling" = yes; then
+  # Depending upon the size, compute the lo and hi bounds.
+cat >conftest.$ac_ext <<_ACEOF
+/* confdefs.h.  */
+_ACEOF
+cat confdefs.h >>conftest.$ac_ext
+cat >>conftest.$ac_ext <<_ACEOF
+/* end confdefs.h.  */
+$ac_includes_default
+int
+main ()
+{
+static int test_array [1 - 2 * !(((long) (sizeof (double))) >= 0)];
+test_array [0] = 0
+
+  ;
+  return 0;
+}
+_ACEOF
+rm -f conftest.$ac_objext
+if { (eval echo "$as_me:$LINENO: \"$ac_compile\"") >&5
+  (eval $ac_compile) 2>conftest.er1
+  ac_status=$?
+  grep -v '^ *+' conftest.er1 >conftest.err
+  rm -f conftest.er1
+  cat conftest.err >&5
+  echo "$as_me:$LINENO: \$? = $ac_status" >&5
+  (exit $ac_status); } &&
+        { ac_try='test -z "$ac_c_werror_flag"
+                        || test ! -s conftest.err'
+  { (eval echo "$as_me:$LINENO: \"$ac_try\"") >&5
+  (eval $ac_try) 2>&5
+  ac_status=$?
+  echo "$as_me:$LINENO: \$? = $ac_status" >&5
+  (exit $ac_status); }; } &&
+        { ac_try='test -s conftest.$ac_objext'
+  { (eval echo "$as_me:$LINENO: \"$ac_try\"") >&5
+  (eval $ac_try) 2>&5
+  ac_status=$?
+  echo "$as_me:$LINENO: \$? = $ac_status" >&5
+  (exit $ac_status); }; }; then
+  ac_lo=0 ac_mid=0
+  while :; do
+    cat >conftest.$ac_ext <<_ACEOF
+/* confdefs.h.  */
+_ACEOF
+cat confdefs.h >>conftest.$ac_ext
+cat >>conftest.$ac_ext <<_ACEOF
+/* end confdefs.h.  */
+$ac_includes_default
+int
+main ()
+{
+static int test_array [1 - 2 * !(((long) (sizeof (double))) <= $ac_mid)];
+test_array [0] = 0
+
+  ;
+  return 0;
+}
+_ACEOF
+rm -f conftest.$ac_objext
+if { (eval echo "$as_me:$LINENO: \"$ac_compile\"") >&5
+  (eval $ac_compile) 2>conftest.er1
+  ac_status=$?
+  grep -v '^ *+' conftest.er1 >conftest.err
+  rm -f conftest.er1
+  cat conftest.err >&5
+  echo "$as_me:$LINENO: \$? = $ac_status" >&5
+  (exit $ac_status); } &&
+        { ac_try='test -z "$ac_c_werror_flag"
+                        || test ! -s conftest.err'
+  { (eval echo "$as_me:$LINENO: \"$ac_try\"") >&5
+  (eval $ac_try) 2>&5
+  ac_status=$?
+  echo "$as_me:$LINENO: \$? = $ac_status" >&5
+  (exit $ac_status); }; } &&
+        { ac_try='test -s conftest.$ac_objext'
+  { (eval echo "$as_me:$LINENO: \"$ac_try\"") >&5
+  (eval $ac_try) 2>&5
+  ac_status=$?
+  echo "$as_me:$LINENO: \$? = $ac_status" >&5
+  (exit $ac_status); }; }; then
+  ac_hi=$ac_mid; break
+else
+  echo "$as_me: failed program was:" >&5
+sed 's/^/| /' conftest.$ac_ext >&5
+
+ac_lo=`expr $ac_mid + 1`
+                   if test $ac_lo -le $ac_mid; then
+                     ac_lo= ac_hi=
+                     break
+                   fi
+                   ac_mid=`expr 2 '*' $ac_mid + 1`
+fi
+rm -f conftest.err conftest.$ac_objext conftest.$ac_ext
+  done
+else
+  echo "$as_me: failed program was:" >&5
+sed 's/^/| /' conftest.$ac_ext >&5
+
+cat >conftest.$ac_ext <<_ACEOF
+/* confdefs.h.  */
+_ACEOF
+cat confdefs.h >>conftest.$ac_ext
+cat >>conftest.$ac_ext <<_ACEOF
+/* end confdefs.h.  */
+$ac_includes_default
+int
+main ()
+{
+static int test_array [1 - 2 * !(((long) (sizeof (double))) < 0)];
+test_array [0] = 0
+
+  ;
+  return 0;
+}
+_ACEOF
+rm -f conftest.$ac_objext
+if { (eval echo "$as_me:$LINENO: \"$ac_compile\"") >&5
+  (eval $ac_compile) 2>conftest.er1
+  ac_status=$?
+  grep -v '^ *+' conftest.er1 >conftest.err
+  rm -f conftest.er1
+  cat conftest.err >&5
+  echo "$as_me:$LINENO: \$? = $ac_status" >&5
+  (exit $ac_status); } &&
+        { ac_try='test -z "$ac_c_werror_flag"
+                        || test ! -s conftest.err'
+  { (eval echo "$as_me:$LINENO: \"$ac_try\"") >&5
+  (eval $ac_try) 2>&5
+  ac_status=$?
+  echo "$as_me:$LINENO: \$? = $ac_status" >&5
+  (exit $ac_status); }; } &&
+        { ac_try='test -s conftest.$ac_objext'
+  { (eval echo "$as_me:$LINENO: \"$ac_try\"") >&5
+  (eval $ac_try) 2>&5
+  ac_status=$?
+  echo "$as_me:$LINENO: \$? = $ac_status" >&5
+  (exit $ac_status); }; }; then
+  ac_hi=-1 ac_mid=-1
+  while :; do
+    cat >conftest.$ac_ext <<_ACEOF
+/* confdefs.h.  */
+_ACEOF
+cat confdefs.h >>conftest.$ac_ext
+cat >>conftest.$ac_ext <<_ACEOF
+/* end confdefs.h.  */
+$ac_includes_default
+int
+main ()
+{
+static int test_array [1 - 2 * !(((long) (sizeof (double))) >= $ac_mid)];
+test_array [0] = 0
+
+  ;
+  return 0;
+}
+_ACEOF
+rm -f conftest.$ac_objext
+if { (eval echo "$as_me:$LINENO: \"$ac_compile\"") >&5
+  (eval $ac_compile) 2>conftest.er1
+  ac_status=$?
+  grep -v '^ *+' conftest.er1 >conftest.err
+  rm -f conftest.er1
+  cat conftest.err >&5
+  echo "$as_me:$LINENO: \$? = $ac_status" >&5
+  (exit $ac_status); } &&
+        { ac_try='test -z "$ac_c_werror_flag"
+                        || test ! -s conftest.err'
+  { (eval echo "$as_me:$LINENO: \"$ac_try\"") >&5
+  (eval $ac_try) 2>&5
+  ac_status=$?
+  echo "$as_me:$LINENO: \$? = $ac_status" >&5
+  (exit $ac_status); }; } &&
+        { ac_try='test -s conftest.$ac_objext'
+  { (eval echo "$as_me:$LINENO: \"$ac_try\"") >&5
+  (eval $ac_try) 2>&5
+  ac_status=$?
+  echo "$as_me:$LINENO: \$? = $ac_status" >&5
+  (exit $ac_status); }; }; then
+  ac_lo=$ac_mid; break
+else
+  echo "$as_me: failed program was:" >&5
+sed 's/^/| /' conftest.$ac_ext >&5
+
+ac_hi=`expr '(' $ac_mid ')' - 1`
+                      if test $ac_mid -le $ac_hi; then
+                        ac_lo= ac_hi=
+                        break
+                      fi
+                      ac_mid=`expr 2 '*' $ac_mid`
+fi
+rm -f conftest.err conftest.$ac_objext conftest.$ac_ext
+  done
+else
+  echo "$as_me: failed program was:" >&5
+sed 's/^/| /' conftest.$ac_ext >&5
+
+ac_lo= ac_hi=
+fi
+rm -f conftest.err conftest.$ac_objext conftest.$ac_ext
+fi
+rm -f conftest.err conftest.$ac_objext conftest.$ac_ext
+# Binary search between lo and hi bounds.
+while test "x$ac_lo" != "x$ac_hi"; do
+  ac_mid=`expr '(' $ac_hi - $ac_lo ')' / 2 + $ac_lo`
+  cat >conftest.$ac_ext <<_ACEOF
+/* confdefs.h.  */
+_ACEOF
+cat confdefs.h >>conftest.$ac_ext
+cat >>conftest.$ac_ext <<_ACEOF
+/* end confdefs.h.  */
+$ac_includes_default
+int
+main ()
+{
+static int test_array [1 - 2 * !(((long) (sizeof (double))) <= $ac_mid)];
+test_array [0] = 0
+
+  ;
+  return 0;
+}
+_ACEOF
+rm -f conftest.$ac_objext
+if { (eval echo "$as_me:$LINENO: \"$ac_compile\"") >&5
+  (eval $ac_compile) 2>conftest.er1
+  ac_status=$?
+  grep -v '^ *+' conftest.er1 >conftest.err
+  rm -f conftest.er1
+  cat conftest.err >&5
+  echo "$as_me:$LINENO: \$? = $ac_status" >&5
+  (exit $ac_status); } &&
+        { ac_try='test -z "$ac_c_werror_flag"
+                        || test ! -s conftest.err'
+  { (eval echo "$as_me:$LINENO: \"$ac_try\"") >&5
+  (eval $ac_try) 2>&5
+  ac_status=$?
+  echo "$as_me:$LINENO: \$? = $ac_status" >&5
+  (exit $ac_status); }; } &&
+        { ac_try='test -s conftest.$ac_objext'
+  { (eval echo "$as_me:$LINENO: \"$ac_try\"") >&5
+  (eval $ac_try) 2>&5
+  ac_status=$?
+  echo "$as_me:$LINENO: \$? = $ac_status" >&5
+  (exit $ac_status); }; }; then
+  ac_hi=$ac_mid
+else
+  echo "$as_me: failed program was:" >&5
+sed 's/^/| /' conftest.$ac_ext >&5
+
+ac_lo=`expr '(' $ac_mid ')' + 1`
+fi
+rm -f conftest.err conftest.$ac_objext conftest.$ac_ext
+done
+case $ac_lo in
+?*) ac_cv_sizeof_double=$ac_lo;;
+'') { { echo "$as_me:$LINENO: error: cannot compute sizeof (double), 77
+See \`config.log' for more details." >&5
+echo "$as_me: error: cannot compute sizeof (double), 77
+See \`config.log' for more details." >&2;}
+   { (exit 1); exit 1; }; } ;;
+esac
+else
+  if test "$cross_compiling" = yes; then
+  { { echo "$as_me:$LINENO: error: cannot run test program while cross compiling
+See \`config.log' for more details." >&5
+echo "$as_me: error: cannot run test program while cross compiling
+See \`config.log' for more details." >&2;}
+   { (exit 1); exit 1; }; }
+else
+  cat >conftest.$ac_ext <<_ACEOF
+/* confdefs.h.  */
+_ACEOF
+cat confdefs.h >>conftest.$ac_ext
+cat >>conftest.$ac_ext <<_ACEOF
+/* end confdefs.h.  */
+$ac_includes_default
+long longval () { return (long) (sizeof (double)); }
+unsigned long ulongval () { return (long) (sizeof (double)); }
+#include <stdio.h>
+#include <stdlib.h>
+int
+main ()
+{
+
+  FILE *f = fopen ("conftest.val", "w");
+  if (! f)
+    exit (1);
+  if (((long) (sizeof (double))) < 0)
+    {
+      long i = longval ();
+      if (i != ((long) (sizeof (double))))
+       exit (1);
+      fprintf (f, "%ld\n", i);
+    }
+  else
+    {
+      unsigned long i = ulongval ();
+      if (i != ((long) (sizeof (double))))
+       exit (1);
+      fprintf (f, "%lu\n", i);
+    }
+  exit (ferror (f) || fclose (f) != 0);
+
+  ;
+  return 0;
+}
+_ACEOF
+rm -f conftest$ac_exeext
+if { (eval echo "$as_me:$LINENO: \"$ac_link\"") >&5
+  (eval $ac_link) 2>&5
+  ac_status=$?
+  echo "$as_me:$LINENO: \$? = $ac_status" >&5
+  (exit $ac_status); } && { ac_try='./conftest$ac_exeext'
+  { (eval echo "$as_me:$LINENO: \"$ac_try\"") >&5
+  (eval $ac_try) 2>&5
+  ac_status=$?
+  echo "$as_me:$LINENO: \$? = $ac_status" >&5
+  (exit $ac_status); }; }; then
+  ac_cv_sizeof_double=`cat conftest.val`
+else
+  echo "$as_me: program exited with status $ac_status" >&5
+echo "$as_me: failed program was:" >&5
+sed 's/^/| /' conftest.$ac_ext >&5
+
+( exit $ac_status )
+{ { echo "$as_me:$LINENO: error: cannot compute sizeof (double), 77
+See \`config.log' for more details." >&5
+echo "$as_me: error: cannot compute sizeof (double), 77
+See \`config.log' for more details." >&2;}
+   { (exit 1); exit 1; }; }
+fi
+rm -f core *.core gmon.out bb.out conftest$ac_exeext conftest.$ac_objext conftest.$ac_ext
+fi
+fi
+rm -f conftest.val
+else
+  ac_cv_sizeof_double=0
+fi
+fi
+echo "$as_me:$LINENO: result: $ac_cv_sizeof_double" >&5
+echo "${ECHO_T}$ac_cv_sizeof_double" >&6
+cat >>confdefs.h <<_ACEOF
+#define SIZEOF_DOUBLE $ac_cv_sizeof_double
+_ACEOF
+
+
+echo "$as_me:$LINENO: checking for void*" >&5
+echo $ECHO_N "checking for void*... $ECHO_C" >&6
+if test "${ac_cv_type_voidp+set}" = set; then
+  echo $ECHO_N "(cached) $ECHO_C" >&6
+else
+  cat >conftest.$ac_ext <<_ACEOF
+/* confdefs.h.  */
+_ACEOF
+cat confdefs.h >>conftest.$ac_ext
+cat >>conftest.$ac_ext <<_ACEOF
+/* end confdefs.h.  */
+$ac_includes_default
+int
+main ()
+{
+if ((void* *) 0)
+  return 0;
+if (sizeof (void*))
+  return 0;
+  ;
+  return 0;
+}
+_ACEOF
+rm -f conftest.$ac_objext
+if { (eval echo "$as_me:$LINENO: \"$ac_compile\"") >&5
+  (eval $ac_compile) 2>conftest.er1
+  ac_status=$?
+  grep -v '^ *+' conftest.er1 >conftest.err
+  rm -f conftest.er1
+  cat conftest.err >&5
+  echo "$as_me:$LINENO: \$? = $ac_status" >&5
+  (exit $ac_status); } &&
+        { ac_try='test -z "$ac_c_werror_flag"
+                        || test ! -s conftest.err'
+  { (eval echo "$as_me:$LINENO: \"$ac_try\"") >&5
+  (eval $ac_try) 2>&5
+  ac_status=$?
+  echo "$as_me:$LINENO: \$? = $ac_status" >&5
+  (exit $ac_status); }; } &&
+        { ac_try='test -s conftest.$ac_objext'
+  { (eval echo "$as_me:$LINENO: \"$ac_try\"") >&5
+  (eval $ac_try) 2>&5
+  ac_status=$?
+  echo "$as_me:$LINENO: \$? = $ac_status" >&5
+  (exit $ac_status); }; }; then
+  ac_cv_type_voidp=yes
+else
+  echo "$as_me: failed program was:" >&5
+sed 's/^/| /' conftest.$ac_ext >&5
+
+ac_cv_type_voidp=no
+fi
+rm -f conftest.err conftest.$ac_objext conftest.$ac_ext
+fi
+echo "$as_me:$LINENO: result: $ac_cv_type_voidp" >&5
+echo "${ECHO_T}$ac_cv_type_voidp" >&6
+
+echo "$as_me:$LINENO: checking size of void*" >&5
+echo $ECHO_N "checking size of void*... $ECHO_C" >&6
+if test "${ac_cv_sizeof_voidp+set}" = set; then
+  echo $ECHO_N "(cached) $ECHO_C" >&6
+else
+  if test "$ac_cv_type_voidp" = yes; then
+  # The cast to unsigned long works around a bug in the HP C Compiler
+  # version HP92453-01 B.11.11.23709.GP, which incorrectly rejects
+  # declarations like `int a3[[(sizeof (unsigned char)) >= 0]];'.
+  # This bug is HP SR number 8606223364.
+  if test "$cross_compiling" = yes; then
+  # Depending upon the size, compute the lo and hi bounds.
+cat >conftest.$ac_ext <<_ACEOF
+/* confdefs.h.  */
+_ACEOF
+cat confdefs.h >>conftest.$ac_ext
+cat >>conftest.$ac_ext <<_ACEOF
+/* end confdefs.h.  */
+$ac_includes_default
+int
+main ()
+{
+static int test_array [1 - 2 * !(((long) (sizeof (void*))) >= 0)];
+test_array [0] = 0
+
+  ;
+  return 0;
+}
+_ACEOF
+rm -f conftest.$ac_objext
+if { (eval echo "$as_me:$LINENO: \"$ac_compile\"") >&5
+  (eval $ac_compile) 2>conftest.er1
+  ac_status=$?
+  grep -v '^ *+' conftest.er1 >conftest.err
+  rm -f conftest.er1
+  cat conftest.err >&5
+  echo "$as_me:$LINENO: \$? = $ac_status" >&5
+  (exit $ac_status); } &&
+        { ac_try='test -z "$ac_c_werror_flag"
+                        || test ! -s conftest.err'
+  { (eval echo "$as_me:$LINENO: \"$ac_try\"") >&5
+  (eval $ac_try) 2>&5
+  ac_status=$?
+  echo "$as_me:$LINENO: \$? = $ac_status" >&5
+  (exit $ac_status); }; } &&
+        { ac_try='test -s conftest.$ac_objext'
+  { (eval echo "$as_me:$LINENO: \"$ac_try\"") >&5
+  (eval $ac_try) 2>&5
+  ac_status=$?
+  echo "$as_me:$LINENO: \$? = $ac_status" >&5
+  (exit $ac_status); }; }; then
+  ac_lo=0 ac_mid=0
+  while :; do
+    cat >conftest.$ac_ext <<_ACEOF
+/* confdefs.h.  */
+_ACEOF
+cat confdefs.h >>conftest.$ac_ext
+cat >>conftest.$ac_ext <<_ACEOF
+/* end confdefs.h.  */
+$ac_includes_default
+int
+main ()
+{
+static int test_array [1 - 2 * !(((long) (sizeof (void*))) <= $ac_mid)];
+test_array [0] = 0
+
+  ;
+  return 0;
+}
+_ACEOF
+rm -f conftest.$ac_objext
+if { (eval echo "$as_me:$LINENO: \"$ac_compile\"") >&5
+  (eval $ac_compile) 2>conftest.er1
+  ac_status=$?
+  grep -v '^ *+' conftest.er1 >conftest.err
+  rm -f conftest.er1
+  cat conftest.err >&5
+  echo "$as_me:$LINENO: \$? = $ac_status" >&5
+  (exit $ac_status); } &&
+        { ac_try='test -z "$ac_c_werror_flag"
+                        || test ! -s conftest.err'
+  { (eval echo "$as_me:$LINENO: \"$ac_try\"") >&5
+  (eval $ac_try) 2>&5
+  ac_status=$?
+  echo "$as_me:$LINENO: \$? = $ac_status" >&5
+  (exit $ac_status); }; } &&
+        { ac_try='test -s conftest.$ac_objext'
+  { (eval echo "$as_me:$LINENO: \"$ac_try\"") >&5
+  (eval $ac_try) 2>&5
+  ac_status=$?
+  echo "$as_me:$LINENO: \$? = $ac_status" >&5
+  (exit $ac_status); }; }; then
+  ac_hi=$ac_mid; break
+else
+  echo "$as_me: failed program was:" >&5
+sed 's/^/| /' conftest.$ac_ext >&5
+
+ac_lo=`expr $ac_mid + 1`
+                   if test $ac_lo -le $ac_mid; then
+                     ac_lo= ac_hi=
+                     break
+                   fi
+                   ac_mid=`expr 2 '*' $ac_mid + 1`
+fi
+rm -f conftest.err conftest.$ac_objext conftest.$ac_ext
+  done
+else
+  echo "$as_me: failed program was:" >&5
+sed 's/^/| /' conftest.$ac_ext >&5
+
+cat >conftest.$ac_ext <<_ACEOF
+/* confdefs.h.  */
+_ACEOF
+cat confdefs.h >>conftest.$ac_ext
+cat >>conftest.$ac_ext <<_ACEOF
+/* end confdefs.h.  */
+$ac_includes_default
+int
+main ()
+{
+static int test_array [1 - 2 * !(((long) (sizeof (void*))) < 0)];
+test_array [0] = 0
+
+  ;
+  return 0;
+}
+_ACEOF
+rm -f conftest.$ac_objext
+if { (eval echo "$as_me:$LINENO: \"$ac_compile\"") >&5
+  (eval $ac_compile) 2>conftest.er1
+  ac_status=$?
+  grep -v '^ *+' conftest.er1 >conftest.err
+  rm -f conftest.er1
+  cat conftest.err >&5
+  echo "$as_me:$LINENO: \$? = $ac_status" >&5
+  (exit $ac_status); } &&
+        { ac_try='test -z "$ac_c_werror_flag"
+                        || test ! -s conftest.err'
+  { (eval echo "$as_me:$LINENO: \"$ac_try\"") >&5
+  (eval $ac_try) 2>&5
+  ac_status=$?
+  echo "$as_me:$LINENO: \$? = $ac_status" >&5
+  (exit $ac_status); }; } &&
+        { ac_try='test -s conftest.$ac_objext'
+  { (eval echo "$as_me:$LINENO: \"$ac_try\"") >&5
+  (eval $ac_try) 2>&5
+  ac_status=$?
+  echo "$as_me:$LINENO: \$? = $ac_status" >&5
+  (exit $ac_status); }; }; then
+  ac_hi=-1 ac_mid=-1
+  while :; do
+    cat >conftest.$ac_ext <<_ACEOF
+/* confdefs.h.  */
+_ACEOF
+cat confdefs.h >>conftest.$ac_ext
+cat >>conftest.$ac_ext <<_ACEOF
+/* end confdefs.h.  */
+$ac_includes_default
+int
+main ()
+{
+static int test_array [1 - 2 * !(((long) (sizeof (void*))) >= $ac_mid)];
+test_array [0] = 0
+
+  ;
+  return 0;
+}
+_ACEOF
+rm -f conftest.$ac_objext
+if { (eval echo "$as_me:$LINENO: \"$ac_compile\"") >&5
+  (eval $ac_compile) 2>conftest.er1
+  ac_status=$?
+  grep -v '^ *+' conftest.er1 >conftest.err
+  rm -f conftest.er1
+  cat conftest.err >&5
+  echo "$as_me:$LINENO: \$? = $ac_status" >&5
+  (exit $ac_status); } &&
+        { ac_try='test -z "$ac_c_werror_flag"
+                        || test ! -s conftest.err'
+  { (eval echo "$as_me:$LINENO: \"$ac_try\"") >&5
+  (eval $ac_try) 2>&5
+  ac_status=$?
+  echo "$as_me:$LINENO: \$? = $ac_status" >&5
+  (exit $ac_status); }; } &&
+        { ac_try='test -s conftest.$ac_objext'
+  { (eval echo "$as_me:$LINENO: \"$ac_try\"") >&5
+  (eval $ac_try) 2>&5
+  ac_status=$?
+  echo "$as_me:$LINENO: \$? = $ac_status" >&5
+  (exit $ac_status); }; }; then
+  ac_lo=$ac_mid; break
+else
+  echo "$as_me: failed program was:" >&5
+sed 's/^/| /' conftest.$ac_ext >&5
+
+ac_hi=`expr '(' $ac_mid ')' - 1`
+                      if test $ac_mid -le $ac_hi; then
+                        ac_lo= ac_hi=
+                        break
+                      fi
+                      ac_mid=`expr 2 '*' $ac_mid`
+fi
+rm -f conftest.err conftest.$ac_objext conftest.$ac_ext
+  done
+else
+  echo "$as_me: failed program was:" >&5
+sed 's/^/| /' conftest.$ac_ext >&5
+
+ac_lo= ac_hi=
+fi
+rm -f conftest.err conftest.$ac_objext conftest.$ac_ext
+fi
+rm -f conftest.err conftest.$ac_objext conftest.$ac_ext
+# Binary search between lo and hi bounds.
+while test "x$ac_lo" != "x$ac_hi"; do
+  ac_mid=`expr '(' $ac_hi - $ac_lo ')' / 2 + $ac_lo`
+  cat >conftest.$ac_ext <<_ACEOF
+/* confdefs.h.  */
+_ACEOF
+cat confdefs.h >>conftest.$ac_ext
+cat >>conftest.$ac_ext <<_ACEOF
+/* end confdefs.h.  */
+$ac_includes_default
+int
+main ()
+{
+static int test_array [1 - 2 * !(((long) (sizeof (void*))) <= $ac_mid)];
+test_array [0] = 0
+
+  ;
+  return 0;
+}
+_ACEOF
+rm -f conftest.$ac_objext
+if { (eval echo "$as_me:$LINENO: \"$ac_compile\"") >&5
+  (eval $ac_compile) 2>conftest.er1
+  ac_status=$?
+  grep -v '^ *+' conftest.er1 >conftest.err
+  rm -f conftest.er1
+  cat conftest.err >&5
+  echo "$as_me:$LINENO: \$? = $ac_status" >&5
+  (exit $ac_status); } &&
+        { ac_try='test -z "$ac_c_werror_flag"
+                        || test ! -s conftest.err'
+  { (eval echo "$as_me:$LINENO: \"$ac_try\"") >&5
+  (eval $ac_try) 2>&5
+  ac_status=$?
+  echo "$as_me:$LINENO: \$? = $ac_status" >&5
+  (exit $ac_status); }; } &&
+        { ac_try='test -s conftest.$ac_objext'
+  { (eval echo "$as_me:$LINENO: \"$ac_try\"") >&5
+  (eval $ac_try) 2>&5
+  ac_status=$?
+  echo "$as_me:$LINENO: \$? = $ac_status" >&5
+  (exit $ac_status); }; }; then
+  ac_hi=$ac_mid
+else
+  echo "$as_me: failed program was:" >&5
+sed 's/^/| /' conftest.$ac_ext >&5
+
+ac_lo=`expr '(' $ac_mid ')' + 1`
+fi
+rm -f conftest.err conftest.$ac_objext conftest.$ac_ext
+done
+case $ac_lo in
+?*) ac_cv_sizeof_voidp=$ac_lo;;
+'') { { echo "$as_me:$LINENO: error: cannot compute sizeof (void*), 77
+See \`config.log' for more details." >&5
+echo "$as_me: error: cannot compute sizeof (void*), 77
+See \`config.log' for more details." >&2;}
+   { (exit 1); exit 1; }; } ;;
+esac
+else
+  if test "$cross_compiling" = yes; then
+  { { echo "$as_me:$LINENO: error: cannot run test program while cross compiling
+See \`config.log' for more details." >&5
+echo "$as_me: error: cannot run test program while cross compiling
+See \`config.log' for more details." >&2;}
+   { (exit 1); exit 1; }; }
+else
+  cat >conftest.$ac_ext <<_ACEOF
+/* confdefs.h.  */
+_ACEOF
+cat confdefs.h >>conftest.$ac_ext
+cat >>conftest.$ac_ext <<_ACEOF
+/* end confdefs.h.  */
+$ac_includes_default
+long longval () { return (long) (sizeof (void*)); }
+unsigned long ulongval () { return (long) (sizeof (void*)); }
+#include <stdio.h>
+#include <stdlib.h>
+int
+main ()
+{
+
+  FILE *f = fopen ("conftest.val", "w");
+  if (! f)
+    exit (1);
+  if (((long) (sizeof (void*))) < 0)
+    {
+      long i = longval ();
+      if (i != ((long) (sizeof (void*))))
+       exit (1);
+      fprintf (f, "%ld\n", i);
+    }
+  else
+    {
+      unsigned long i = ulongval ();
+      if (i != ((long) (sizeof (void*))))
+       exit (1);
+      fprintf (f, "%lu\n", i);
+    }
+  exit (ferror (f) || fclose (f) != 0);
+
+  ;
+  return 0;
+}
+_ACEOF
+rm -f conftest$ac_exeext
+if { (eval echo "$as_me:$LINENO: \"$ac_link\"") >&5
+  (eval $ac_link) 2>&5
+  ac_status=$?
+  echo "$as_me:$LINENO: \$? = $ac_status" >&5
+  (exit $ac_status); } && { ac_try='./conftest$ac_exeext'
+  { (eval echo "$as_me:$LINENO: \"$ac_try\"") >&5
+  (eval $ac_try) 2>&5
+  ac_status=$?
+  echo "$as_me:$LINENO: \$? = $ac_status" >&5
+  (exit $ac_status); }; }; then
+  ac_cv_sizeof_voidp=`cat conftest.val`
+else
+  echo "$as_me: program exited with status $ac_status" >&5
+echo "$as_me: failed program was:" >&5
+sed 's/^/| /' conftest.$ac_ext >&5
+
+( exit $ac_status )
+{ { echo "$as_me:$LINENO: error: cannot compute sizeof (void*), 77
+See \`config.log' for more details." >&5
+echo "$as_me: error: cannot compute sizeof (void*), 77
+See \`config.log' for more details." >&2;}
+   { (exit 1); exit 1; }; }
+fi
+rm -f core *.core gmon.out bb.out conftest$ac_exeext conftest.$ac_objext conftest.$ac_ext
+fi
+fi
+rm -f conftest.val
+else
+  ac_cv_sizeof_voidp=0
+fi
+fi
+echo "$as_me:$LINENO: result: $ac_cv_sizeof_voidp" >&5
+echo "${ECHO_T}$ac_cv_sizeof_voidp" >&6
+cat >>confdefs.h <<_ACEOF
+#define SIZEOF_VOIDP $ac_cv_sizeof_voidp
+_ACEOF
+
+
+echo "$as_me:$LINENO: checking for size_t" >&5
+echo $ECHO_N "checking for size_t... $ECHO_C" >&6
+if test "${ac_cv_type_size_t+set}" = set; then
+  echo $ECHO_N "(cached) $ECHO_C" >&6
+else
+  cat >conftest.$ac_ext <<_ACEOF
+/* confdefs.h.  */
+_ACEOF
+cat confdefs.h >>conftest.$ac_ext
+cat >>conftest.$ac_ext <<_ACEOF
+/* end confdefs.h.  */
+$ac_includes_default
+int
+main ()
+{
+if ((size_t *) 0)
+  return 0;
+if (sizeof (size_t))
+  return 0;
+  ;
+  return 0;
+}
+_ACEOF
+rm -f conftest.$ac_objext
+if { (eval echo "$as_me:$LINENO: \"$ac_compile\"") >&5
+  (eval $ac_compile) 2>conftest.er1
+  ac_status=$?
+  grep -v '^ *+' conftest.er1 >conftest.err
+  rm -f conftest.er1
+  cat conftest.err >&5
+  echo "$as_me:$LINENO: \$? = $ac_status" >&5
+  (exit $ac_status); } &&
+        { ac_try='test -z "$ac_c_werror_flag"
+                        || test ! -s conftest.err'
+  { (eval echo "$as_me:$LINENO: \"$ac_try\"") >&5
+  (eval $ac_try) 2>&5
+  ac_status=$?
+  echo "$as_me:$LINENO: \$? = $ac_status" >&5
+  (exit $ac_status); }; } &&
+        { ac_try='test -s conftest.$ac_objext'
+  { (eval echo "$as_me:$LINENO: \"$ac_try\"") >&5
+  (eval $ac_try) 2>&5
+  ac_status=$?
+  echo "$as_me:$LINENO: \$? = $ac_status" >&5
+  (exit $ac_status); }; }; then
+  ac_cv_type_size_t=yes
+else
+  echo "$as_me: failed program was:" >&5
+sed 's/^/| /' conftest.$ac_ext >&5
+
+ac_cv_type_size_t=no
+fi
+rm -f conftest.err conftest.$ac_objext conftest.$ac_ext
+fi
+echo "$as_me:$LINENO: result: $ac_cv_type_size_t" >&5
+echo "${ECHO_T}$ac_cv_type_size_t" >&6
+
+echo "$as_me:$LINENO: checking size of size_t" >&5
+echo $ECHO_N "checking size of size_t... $ECHO_C" >&6
+if test "${ac_cv_sizeof_size_t+set}" = set; then
+  echo $ECHO_N "(cached) $ECHO_C" >&6
+else
+  if test "$ac_cv_type_size_t" = yes; then
+  # The cast to unsigned long works around a bug in the HP C Compiler
+  # version HP92453-01 B.11.11.23709.GP, which incorrectly rejects
+  # declarations like `int a3[[(sizeof (unsigned char)) >= 0]];'.
+  # This bug is HP SR number 8606223364.
+  if test "$cross_compiling" = yes; then
+  # Depending upon the size, compute the lo and hi bounds.
+cat >conftest.$ac_ext <<_ACEOF
+/* confdefs.h.  */
+_ACEOF
+cat confdefs.h >>conftest.$ac_ext
+cat >>conftest.$ac_ext <<_ACEOF
+/* end confdefs.h.  */
+$ac_includes_default
+int
+main ()
+{
+static int test_array [1 - 2 * !(((long) (sizeof (size_t))) >= 0)];
+test_array [0] = 0
+
+  ;
+  return 0;
+}
+_ACEOF
+rm -f conftest.$ac_objext
+if { (eval echo "$as_me:$LINENO: \"$ac_compile\"") >&5
+  (eval $ac_compile) 2>conftest.er1
+  ac_status=$?
+  grep -v '^ *+' conftest.er1 >conftest.err
+  rm -f conftest.er1
+  cat conftest.err >&5
+  echo "$as_me:$LINENO: \$? = $ac_status" >&5
+  (exit $ac_status); } &&
+        { ac_try='test -z "$ac_c_werror_flag"
+                        || test ! -s conftest.err'
+  { (eval echo "$as_me:$LINENO: \"$ac_try\"") >&5
+  (eval $ac_try) 2>&5
+  ac_status=$?
+  echo "$as_me:$LINENO: \$? = $ac_status" >&5
+  (exit $ac_status); }; } &&
+        { ac_try='test -s conftest.$ac_objext'
+  { (eval echo "$as_me:$LINENO: \"$ac_try\"") >&5
+  (eval $ac_try) 2>&5
+  ac_status=$?
+  echo "$as_me:$LINENO: \$? = $ac_status" >&5
+  (exit $ac_status); }; }; then
+  ac_lo=0 ac_mid=0
+  while :; do
+    cat >conftest.$ac_ext <<_ACEOF
+/* confdefs.h.  */
+_ACEOF
+cat confdefs.h >>conftest.$ac_ext
+cat >>conftest.$ac_ext <<_ACEOF
+/* end confdefs.h.  */
+$ac_includes_default
+int
+main ()
+{
+static int test_array [1 - 2 * !(((long) (sizeof (size_t))) <= $ac_mid)];
+test_array [0] = 0
+
+  ;
+  return 0;
+}
+_ACEOF
+rm -f conftest.$ac_objext
+if { (eval echo "$as_me:$LINENO: \"$ac_compile\"") >&5
+  (eval $ac_compile) 2>conftest.er1
+  ac_status=$?
+  grep -v '^ *+' conftest.er1 >conftest.err
+  rm -f conftest.er1
+  cat conftest.err >&5
+  echo "$as_me:$LINENO: \$? = $ac_status" >&5
+  (exit $ac_status); } &&
+        { ac_try='test -z "$ac_c_werror_flag"
+                        || test ! -s conftest.err'
+  { (eval echo "$as_me:$LINENO: \"$ac_try\"") >&5
+  (eval $ac_try) 2>&5
+  ac_status=$?
+  echo "$as_me:$LINENO: \$? = $ac_status" >&5
+  (exit $ac_status); }; } &&
+        { ac_try='test -s conftest.$ac_objext'
+  { (eval echo "$as_me:$LINENO: \"$ac_try\"") >&5
+  (eval $ac_try) 2>&5
+  ac_status=$?
+  echo "$as_me:$LINENO: \$? = $ac_status" >&5
+  (exit $ac_status); }; }; then
+  ac_hi=$ac_mid; break
+else
+  echo "$as_me: failed program was:" >&5
+sed 's/^/| /' conftest.$ac_ext >&5
+
+ac_lo=`expr $ac_mid + 1`
+                   if test $ac_lo -le $ac_mid; then
+                     ac_lo= ac_hi=
+                     break
+                   fi
+                   ac_mid=`expr 2 '*' $ac_mid + 1`
+fi
+rm -f conftest.err conftest.$ac_objext conftest.$ac_ext
+  done
+else
+  echo "$as_me: failed program was:" >&5
+sed 's/^/| /' conftest.$ac_ext >&5
+
+cat >conftest.$ac_ext <<_ACEOF
+/* confdefs.h.  */
+_ACEOF
+cat confdefs.h >>conftest.$ac_ext
+cat >>conftest.$ac_ext <<_ACEOF
+/* end confdefs.h.  */
+$ac_includes_default
+int
+main ()
+{
+static int test_array [1 - 2 * !(((long) (sizeof (size_t))) < 0)];
+test_array [0] = 0
+
+  ;
+  return 0;
+}
+_ACEOF
+rm -f conftest.$ac_objext
+if { (eval echo "$as_me:$LINENO: \"$ac_compile\"") >&5
+  (eval $ac_compile) 2>conftest.er1
+  ac_status=$?
+  grep -v '^ *+' conftest.er1 >conftest.err
+  rm -f conftest.er1
+  cat conftest.err >&5
+  echo "$as_me:$LINENO: \$? = $ac_status" >&5
+  (exit $ac_status); } &&
+        { ac_try='test -z "$ac_c_werror_flag"
+                        || test ! -s conftest.err'
+  { (eval echo "$as_me:$LINENO: \"$ac_try\"") >&5
+  (eval $ac_try) 2>&5
+  ac_status=$?
+  echo "$as_me:$LINENO: \$? = $ac_status" >&5
+  (exit $ac_status); }; } &&
+        { ac_try='test -s conftest.$ac_objext'
+  { (eval echo "$as_me:$LINENO: \"$ac_try\"") >&5
+  (eval $ac_try) 2>&5
+  ac_status=$?
+  echo "$as_me:$LINENO: \$? = $ac_status" >&5
+  (exit $ac_status); }; }; then
+  ac_hi=-1 ac_mid=-1
+  while :; do
+    cat >conftest.$ac_ext <<_ACEOF
+/* confdefs.h.  */
+_ACEOF
+cat confdefs.h >>conftest.$ac_ext
+cat >>conftest.$ac_ext <<_ACEOF
+/* end confdefs.h.  */
+$ac_includes_default
+int
+main ()
+{
+static int test_array [1 - 2 * !(((long) (sizeof (size_t))) >= $ac_mid)];
+test_array [0] = 0
+
+  ;
+  return 0;
+}
+_ACEOF
+rm -f conftest.$ac_objext
+if { (eval echo "$as_me:$LINENO: \"$ac_compile\"") >&5
+  (eval $ac_compile) 2>conftest.er1
+  ac_status=$?
+  grep -v '^ *+' conftest.er1 >conftest.err
+  rm -f conftest.er1
+  cat conftest.err >&5
+  echo "$as_me:$LINENO: \$? = $ac_status" >&5
+  (exit $ac_status); } &&
+        { ac_try='test -z "$ac_c_werror_flag"
+                        || test ! -s conftest.err'
+  { (eval echo "$as_me:$LINENO: \"$ac_try\"") >&5
+  (eval $ac_try) 2>&5
+  ac_status=$?
+  echo "$as_me:$LINENO: \$? = $ac_status" >&5
+  (exit $ac_status); }; } &&
+        { ac_try='test -s conftest.$ac_objext'
+  { (eval echo "$as_me:$LINENO: \"$ac_try\"") >&5
+  (eval $ac_try) 2>&5
+  ac_status=$?
+  echo "$as_me:$LINENO: \$? = $ac_status" >&5
+  (exit $ac_status); }; }; then
+  ac_lo=$ac_mid; break
+else
+  echo "$as_me: failed program was:" >&5
+sed 's/^/| /' conftest.$ac_ext >&5
+
+ac_hi=`expr '(' $ac_mid ')' - 1`
+                      if test $ac_mid -le $ac_hi; then
+                        ac_lo= ac_hi=
+                        break
+                      fi
+                      ac_mid=`expr 2 '*' $ac_mid`
+fi
+rm -f conftest.err conftest.$ac_objext conftest.$ac_ext
+  done
+else
+  echo "$as_me: failed program was:" >&5
+sed 's/^/| /' conftest.$ac_ext >&5
+
+ac_lo= ac_hi=
+fi
+rm -f conftest.err conftest.$ac_objext conftest.$ac_ext
+fi
+rm -f conftest.err conftest.$ac_objext conftest.$ac_ext
+# Binary search between lo and hi bounds.
+while test "x$ac_lo" != "x$ac_hi"; do
+  ac_mid=`expr '(' $ac_hi - $ac_lo ')' / 2 + $ac_lo`
+  cat >conftest.$ac_ext <<_ACEOF
+/* confdefs.h.  */
+_ACEOF
+cat confdefs.h >>conftest.$ac_ext
+cat >>conftest.$ac_ext <<_ACEOF
+/* end confdefs.h.  */
+$ac_includes_default
+int
+main ()
+{
+static int test_array [1 - 2 * !(((long) (sizeof (size_t))) <= $ac_mid)];
+test_array [0] = 0
+
+  ;
+  return 0;
+}
+_ACEOF
+rm -f conftest.$ac_objext
+if { (eval echo "$as_me:$LINENO: \"$ac_compile\"") >&5
+  (eval $ac_compile) 2>conftest.er1
+  ac_status=$?
+  grep -v '^ *+' conftest.er1 >conftest.err
+  rm -f conftest.er1
+  cat conftest.err >&5
+  echo "$as_me:$LINENO: \$? = $ac_status" >&5
+  (exit $ac_status); } &&
+        { ac_try='test -z "$ac_c_werror_flag"
+                        || test ! -s conftest.err'
+  { (eval echo "$as_me:$LINENO: \"$ac_try\"") >&5
+  (eval $ac_try) 2>&5
+  ac_status=$?
+  echo "$as_me:$LINENO: \$? = $ac_status" >&5
+  (exit $ac_status); }; } &&
+        { ac_try='test -s conftest.$ac_objext'
+  { (eval echo "$as_me:$LINENO: \"$ac_try\"") >&5
+  (eval $ac_try) 2>&5
+  ac_status=$?
+  echo "$as_me:$LINENO: \$? = $ac_status" >&5
+  (exit $ac_status); }; }; then
+  ac_hi=$ac_mid
+else
+  echo "$as_me: failed program was:" >&5
+sed 's/^/| /' conftest.$ac_ext >&5
+
+ac_lo=`expr '(' $ac_mid ')' + 1`
+fi
+rm -f conftest.err conftest.$ac_objext conftest.$ac_ext
+done
+case $ac_lo in
+?*) ac_cv_sizeof_size_t=$ac_lo;;
+'') { { echo "$as_me:$LINENO: error: cannot compute sizeof (size_t), 77
+See \`config.log' for more details." >&5
+echo "$as_me: error: cannot compute sizeof (size_t), 77
+See \`config.log' for more details." >&2;}
+   { (exit 1); exit 1; }; } ;;
+esac
+else
+  if test "$cross_compiling" = yes; then
+  { { echo "$as_me:$LINENO: error: cannot run test program while cross compiling
+See \`config.log' for more details." >&5
+echo "$as_me: error: cannot run test program while cross compiling
+See \`config.log' for more details." >&2;}
+   { (exit 1); exit 1; }; }
+else
+  cat >conftest.$ac_ext <<_ACEOF
+/* confdefs.h.  */
+_ACEOF
+cat confdefs.h >>conftest.$ac_ext
+cat >>conftest.$ac_ext <<_ACEOF
+/* end confdefs.h.  */
+$ac_includes_default
+long longval () { return (long) (sizeof (size_t)); }
+unsigned long ulongval () { return (long) (sizeof (size_t)); }
+#include <stdio.h>
+#include <stdlib.h>
+int
+main ()
+{
+
+  FILE *f = fopen ("conftest.val", "w");
+  if (! f)
+    exit (1);
+  if (((long) (sizeof (size_t))) < 0)
+    {
+      long i = longval ();
+      if (i != ((long) (sizeof (size_t))))
+       exit (1);
+      fprintf (f, "%ld\n", i);
+    }
+  else
+    {
+      unsigned long i = ulongval ();
+      if (i != ((long) (sizeof (size_t))))
+       exit (1);
+      fprintf (f, "%lu\n", i);
+    }
+  exit (ferror (f) || fclose (f) != 0);
+
+  ;
+  return 0;
+}
+_ACEOF
+rm -f conftest$ac_exeext
+if { (eval echo "$as_me:$LINENO: \"$ac_link\"") >&5
+  (eval $ac_link) 2>&5
+  ac_status=$?
+  echo "$as_me:$LINENO: \$? = $ac_status" >&5
+  (exit $ac_status); } && { ac_try='./conftest$ac_exeext'
+  { (eval echo "$as_me:$LINENO: \"$ac_try\"") >&5
+  (eval $ac_try) 2>&5
+  ac_status=$?
+  echo "$as_me:$LINENO: \$? = $ac_status" >&5
+  (exit $ac_status); }; }; then
+  ac_cv_sizeof_size_t=`cat conftest.val`
+else
+  echo "$as_me: program exited with status $ac_status" >&5
+echo "$as_me: failed program was:" >&5
+sed 's/^/| /' conftest.$ac_ext >&5
+
+( exit $ac_status )
+{ { echo "$as_me:$LINENO: error: cannot compute sizeof (size_t), 77
+See \`config.log' for more details." >&5
+echo "$as_me: error: cannot compute sizeof (size_t), 77
+See \`config.log' for more details." >&2;}
+   { (exit 1); exit 1; }; }
+fi
+rm -f core *.core gmon.out bb.out conftest$ac_exeext conftest.$ac_objext conftest.$ac_ext
+fi
+fi
+rm -f conftest.val
+else
+  ac_cv_sizeof_size_t=0
+fi
+fi
+echo "$as_me:$LINENO: result: $ac_cv_sizeof_size_t" >&5
+echo "${ECHO_T}$ac_cv_sizeof_size_t" >&6
+cat >>confdefs.h <<_ACEOF
+#define SIZEOF_SIZE_T $ac_cv_sizeof_size_t
+_ACEOF
+
+
+echo "$as_me:$LINENO: checking for int64_t" >&5
+echo $ECHO_N "checking for int64_t... $ECHO_C" >&6
+if test "${ac_cv_type_int64_t+set}" = set; then
+  echo $ECHO_N "(cached) $ECHO_C" >&6
+else
+  cat >conftest.$ac_ext <<_ACEOF
+/* confdefs.h.  */
+_ACEOF
+cat confdefs.h >>conftest.$ac_ext
+cat >>conftest.$ac_ext <<_ACEOF
+/* end confdefs.h.  */
+$ac_includes_default
+int
+main ()
+{
+if ((int64_t *) 0)
+  return 0;
+if (sizeof (int64_t))
+  return 0;
+  ;
+  return 0;
+}
+_ACEOF
+rm -f conftest.$ac_objext
+if { (eval echo "$as_me:$LINENO: \"$ac_compile\"") >&5
+  (eval $ac_compile) 2>conftest.er1
+  ac_status=$?
+  grep -v '^ *+' conftest.er1 >conftest.err
+  rm -f conftest.er1
+  cat conftest.err >&5
+  echo "$as_me:$LINENO: \$? = $ac_status" >&5
+  (exit $ac_status); } &&
+        { ac_try='test -z "$ac_c_werror_flag"
+                        || test ! -s conftest.err'
+  { (eval echo "$as_me:$LINENO: \"$ac_try\"") >&5
+  (eval $ac_try) 2>&5
+  ac_status=$?
+  echo "$as_me:$LINENO: \$? = $ac_status" >&5
+  (exit $ac_status); }; } &&
+        { ac_try='test -s conftest.$ac_objext'
+  { (eval echo "$as_me:$LINENO: \"$ac_try\"") >&5
+  (eval $ac_try) 2>&5
+  ac_status=$?
+  echo "$as_me:$LINENO: \$? = $ac_status" >&5
+  (exit $ac_status); }; }; then
+  ac_cv_type_int64_t=yes
+else
+  echo "$as_me: failed program was:" >&5
+sed 's/^/| /' conftest.$ac_ext >&5
+
+ac_cv_type_int64_t=no
+fi
+rm -f conftest.err conftest.$ac_objext conftest.$ac_ext
+fi
+echo "$as_me:$LINENO: result: $ac_cv_type_int64_t" >&5
+echo "${ECHO_T}$ac_cv_type_int64_t" >&6
+
+echo "$as_me:$LINENO: checking size of int64_t" >&5
+echo $ECHO_N "checking size of int64_t... $ECHO_C" >&6
+if test "${ac_cv_sizeof_int64_t+set}" = set; then
+  echo $ECHO_N "(cached) $ECHO_C" >&6
+else
+  if test "$ac_cv_type_int64_t" = yes; then
+  # The cast to unsigned long works around a bug in the HP C Compiler
+  # version HP92453-01 B.11.11.23709.GP, which incorrectly rejects
+  # declarations like `int a3[[(sizeof (unsigned char)) >= 0]];'.
+  # This bug is HP SR number 8606223364.
+  if test "$cross_compiling" = yes; then
+  # Depending upon the size, compute the lo and hi bounds.
+cat >conftest.$ac_ext <<_ACEOF
+/* confdefs.h.  */
+_ACEOF
+cat confdefs.h >>conftest.$ac_ext
+cat >>conftest.$ac_ext <<_ACEOF
+/* end confdefs.h.  */
+$ac_includes_default
+int
+main ()
+{
+static int test_array [1 - 2 * !(((long) (sizeof (int64_t))) >= 0)];
+test_array [0] = 0
+
+  ;
+  return 0;
+}
+_ACEOF
+rm -f conftest.$ac_objext
+if { (eval echo "$as_me:$LINENO: \"$ac_compile\"") >&5
+  (eval $ac_compile) 2>conftest.er1
+  ac_status=$?
+  grep -v '^ *+' conftest.er1 >conftest.err
+  rm -f conftest.er1
+  cat conftest.err >&5
+  echo "$as_me:$LINENO: \$? = $ac_status" >&5
+  (exit $ac_status); } &&
+        { ac_try='test -z "$ac_c_werror_flag"
+                        || test ! -s conftest.err'
+  { (eval echo "$as_me:$LINENO: \"$ac_try\"") >&5
+  (eval $ac_try) 2>&5
+  ac_status=$?
+  echo "$as_me:$LINENO: \$? = $ac_status" >&5
+  (exit $ac_status); }; } &&
+        { ac_try='test -s conftest.$ac_objext'
+  { (eval echo "$as_me:$LINENO: \"$ac_try\"") >&5
+  (eval $ac_try) 2>&5
+  ac_status=$?
+  echo "$as_me:$LINENO: \$? = $ac_status" >&5
+  (exit $ac_status); }; }; then
+  ac_lo=0 ac_mid=0
+  while :; do
+    cat >conftest.$ac_ext <<_ACEOF
+/* confdefs.h.  */
+_ACEOF
+cat confdefs.h >>conftest.$ac_ext
+cat >>conftest.$ac_ext <<_ACEOF
+/* end confdefs.h.  */
+$ac_includes_default
+int
+main ()
+{
+static int test_array [1 - 2 * !(((long) (sizeof (int64_t))) <= $ac_mid)];
+test_array [0] = 0
+
+  ;
+  return 0;
+}
+_ACEOF
+rm -f conftest.$ac_objext
+if { (eval echo "$as_me:$LINENO: \"$ac_compile\"") >&5
+  (eval $ac_compile) 2>conftest.er1
+  ac_status=$?
+  grep -v '^ *+' conftest.er1 >conftest.err
+  rm -f conftest.er1
+  cat conftest.err >&5
+  echo "$as_me:$LINENO: \$? = $ac_status" >&5
+  (exit $ac_status); } &&
+        { ac_try='test -z "$ac_c_werror_flag"
+                        || test ! -s conftest.err'
+  { (eval echo "$as_me:$LINENO: \"$ac_try\"") >&5
+  (eval $ac_try) 2>&5
+  ac_status=$?
+  echo "$as_me:$LINENO: \$? = $ac_status" >&5
+  (exit $ac_status); }; } &&
+        { ac_try='test -s conftest.$ac_objext'
+  { (eval echo "$as_me:$LINENO: \"$ac_try\"") >&5
+  (eval $ac_try) 2>&5
+  ac_status=$?
+  echo "$as_me:$LINENO: \$? = $ac_status" >&5
+  (exit $ac_status); }; }; then
+  ac_hi=$ac_mid; break
+else
+  echo "$as_me: failed program was:" >&5
+sed 's/^/| /' conftest.$ac_ext >&5
+
+ac_lo=`expr $ac_mid + 1`
+                   if test $ac_lo -le $ac_mid; then
+                     ac_lo= ac_hi=
+                     break
+                   fi
+                   ac_mid=`expr 2 '*' $ac_mid + 1`
+fi
+rm -f conftest.err conftest.$ac_objext conftest.$ac_ext
+  done
+else
+  echo "$as_me: failed program was:" >&5
+sed 's/^/| /' conftest.$ac_ext >&5
+
+cat >conftest.$ac_ext <<_ACEOF
+/* confdefs.h.  */
+_ACEOF
+cat confdefs.h >>conftest.$ac_ext
+cat >>conftest.$ac_ext <<_ACEOF
+/* end confdefs.h.  */
+$ac_includes_default
+int
+main ()
+{
+static int test_array [1 - 2 * !(((long) (sizeof (int64_t))) < 0)];
+test_array [0] = 0
+
+  ;
+  return 0;
+}
+_ACEOF
+rm -f conftest.$ac_objext
+if { (eval echo "$as_me:$LINENO: \"$ac_compile\"") >&5
+  (eval $ac_compile) 2>conftest.er1
+  ac_status=$?
+  grep -v '^ *+' conftest.er1 >conftest.err
+  rm -f conftest.er1
+  cat conftest.err >&5
+  echo "$as_me:$LINENO: \$? = $ac_status" >&5
+  (exit $ac_status); } &&
+        { ac_try='test -z "$ac_c_werror_flag"
+                        || test ! -s conftest.err'
+  { (eval echo "$as_me:$LINENO: \"$ac_try\"") >&5
+  (eval $ac_try) 2>&5
+  ac_status=$?
+  echo "$as_me:$LINENO: \$? = $ac_status" >&5
+  (exit $ac_status); }; } &&
+        { ac_try='test -s conftest.$ac_objext'
+  { (eval echo "$as_me:$LINENO: \"$ac_try\"") >&5
+  (eval $ac_try) 2>&5
+  ac_status=$?
+  echo "$as_me:$LINENO: \$? = $ac_status" >&5
+  (exit $ac_status); }; }; then
+  ac_hi=-1 ac_mid=-1
+  while :; do
+    cat >conftest.$ac_ext <<_ACEOF
+/* confdefs.h.  */
+_ACEOF
+cat confdefs.h >>conftest.$ac_ext
+cat >>conftest.$ac_ext <<_ACEOF
+/* end confdefs.h.  */
+$ac_includes_default
+int
+main ()
+{
+static int test_array [1 - 2 * !(((long) (sizeof (int64_t))) >= $ac_mid)];
+test_array [0] = 0
+
+  ;
+  return 0;
+}
+_ACEOF
+rm -f conftest.$ac_objext
+if { (eval echo "$as_me:$LINENO: \"$ac_compile\"") >&5
+  (eval $ac_compile) 2>conftest.er1
+  ac_status=$?
+  grep -v '^ *+' conftest.er1 >conftest.err
+  rm -f conftest.er1
+  cat conftest.err >&5
+  echo "$as_me:$LINENO: \$? = $ac_status" >&5
+  (exit $ac_status); } &&
+        { ac_try='test -z "$ac_c_werror_flag"
+                        || test ! -s conftest.err'
+  { (eval echo "$as_me:$LINENO: \"$ac_try\"") >&5
+  (eval $ac_try) 2>&5
+  ac_status=$?
+  echo "$as_me:$LINENO: \$? = $ac_status" >&5
+  (exit $ac_status); }; } &&
+        { ac_try='test -s conftest.$ac_objext'
+  { (eval echo "$as_me:$LINENO: \"$ac_try\"") >&5
+  (eval $ac_try) 2>&5
+  ac_status=$?
+  echo "$as_me:$LINENO: \$? = $ac_status" >&5
+  (exit $ac_status); }; }; then
+  ac_lo=$ac_mid; break
+else
+  echo "$as_me: failed program was:" >&5
+sed 's/^/| /' conftest.$ac_ext >&5
+
+ac_hi=`expr '(' $ac_mid ')' - 1`
+                      if test $ac_mid -le $ac_hi; then
+                        ac_lo= ac_hi=
+                        break
+                      fi
+                      ac_mid=`expr 2 '*' $ac_mid`
+fi
+rm -f conftest.err conftest.$ac_objext conftest.$ac_ext
+  done
+else
+  echo "$as_me: failed program was:" >&5
+sed 's/^/| /' conftest.$ac_ext >&5
+
+ac_lo= ac_hi=
+fi
+rm -f conftest.err conftest.$ac_objext conftest.$ac_ext
+fi
+rm -f conftest.err conftest.$ac_objext conftest.$ac_ext
+# Binary search between lo and hi bounds.
+while test "x$ac_lo" != "x$ac_hi"; do
+  ac_mid=`expr '(' $ac_hi - $ac_lo ')' / 2 + $ac_lo`
+  cat >conftest.$ac_ext <<_ACEOF
+/* confdefs.h.  */
+_ACEOF
+cat confdefs.h >>conftest.$ac_ext
+cat >>conftest.$ac_ext <<_ACEOF
+/* end confdefs.h.  */
+$ac_includes_default
+int
+main ()
+{
+static int test_array [1 - 2 * !(((long) (sizeof (int64_t))) <= $ac_mid)];
+test_array [0] = 0
+
+  ;
+  return 0;
+}
+_ACEOF
+rm -f conftest.$ac_objext
+if { (eval echo "$as_me:$LINENO: \"$ac_compile\"") >&5
+  (eval $ac_compile) 2>conftest.er1
+  ac_status=$?
+  grep -v '^ *+' conftest.er1 >conftest.err
+  rm -f conftest.er1
+  cat conftest.err >&5
+  echo "$as_me:$LINENO: \$? = $ac_status" >&5
+  (exit $ac_status); } &&
+        { ac_try='test -z "$ac_c_werror_flag"
+                        || test ! -s conftest.err'
+  { (eval echo "$as_me:$LINENO: \"$ac_try\"") >&5
+  (eval $ac_try) 2>&5
+  ac_status=$?
+  echo "$as_me:$LINENO: \$? = $ac_status" >&5
+  (exit $ac_status); }; } &&
+        { ac_try='test -s conftest.$ac_objext'
+  { (eval echo "$as_me:$LINENO: \"$ac_try\"") >&5
+  (eval $ac_try) 2>&5
+  ac_status=$?
+  echo "$as_me:$LINENO: \$? = $ac_status" >&5
+  (exit $ac_status); }; }; then
+  ac_hi=$ac_mid
+else
+  echo "$as_me: failed program was:" >&5
+sed 's/^/| /' conftest.$ac_ext >&5
+
+ac_lo=`expr '(' $ac_mid ')' + 1`
+fi
+rm -f conftest.err conftest.$ac_objext conftest.$ac_ext
+done
+case $ac_lo in
+?*) ac_cv_sizeof_int64_t=$ac_lo;;
+'') { { echo "$as_me:$LINENO: error: cannot compute sizeof (int64_t), 77
+See \`config.log' for more details." >&5
+echo "$as_me: error: cannot compute sizeof (int64_t), 77
+See \`config.log' for more details." >&2;}
+   { (exit 1); exit 1; }; } ;;
+esac
+else
+  if test "$cross_compiling" = yes; then
+  { { echo "$as_me:$LINENO: error: cannot run test program while cross compiling
+See \`config.log' for more details." >&5
+echo "$as_me: error: cannot run test program while cross compiling
+See \`config.log' for more details." >&2;}
+   { (exit 1); exit 1; }; }
+else
+  cat >conftest.$ac_ext <<_ACEOF
+/* confdefs.h.  */
+_ACEOF
+cat confdefs.h >>conftest.$ac_ext
+cat >>conftest.$ac_ext <<_ACEOF
+/* end confdefs.h.  */
+$ac_includes_default
+long longval () { return (long) (sizeof (int64_t)); }
+unsigned long ulongval () { return (long) (sizeof (int64_t)); }
+#include <stdio.h>
+#include <stdlib.h>
+int
+main ()
+{
+
+  FILE *f = fopen ("conftest.val", "w");
+  if (! f)
+    exit (1);
+  if (((long) (sizeof (int64_t))) < 0)
+    {
+      long i = longval ();
+      if (i != ((long) (sizeof (int64_t))))
+       exit (1);
+      fprintf (f, "%ld\n", i);
+    }
+  else
+    {
+      unsigned long i = ulongval ();
+      if (i != ((long) (sizeof (int64_t))))
+       exit (1);
+      fprintf (f, "%lu\n", i);
+    }
+  exit (ferror (f) || fclose (f) != 0);
+
+  ;
+  return 0;
+}
+_ACEOF
+rm -f conftest$ac_exeext
+if { (eval echo "$as_me:$LINENO: \"$ac_link\"") >&5
+  (eval $ac_link) 2>&5
+  ac_status=$?
+  echo "$as_me:$LINENO: \$? = $ac_status" >&5
+  (exit $ac_status); } && { ac_try='./conftest$ac_exeext'
+  { (eval echo "$as_me:$LINENO: \"$ac_try\"") >&5
+  (eval $ac_try) 2>&5
+  ac_status=$?
+  echo "$as_me:$LINENO: \$? = $ac_status" >&5
+  (exit $ac_status); }; }; then
+  ac_cv_sizeof_int64_t=`cat conftest.val`
+else
+  echo "$as_me: program exited with status $ac_status" >&5
+echo "$as_me: failed program was:" >&5
+sed 's/^/| /' conftest.$ac_ext >&5
+
+( exit $ac_status )
+{ { echo "$as_me:$LINENO: error: cannot compute sizeof (int64_t), 77
+See \`config.log' for more details." >&5
+echo "$as_me: error: cannot compute sizeof (int64_t), 77
+See \`config.log' for more details." >&2;}
+   { (exit 1); exit 1; }; }
+fi
+rm -f core *.core gmon.out bb.out conftest$ac_exeext conftest.$ac_objext conftest.$ac_ext
+fi
+fi
+rm -f conftest.val
+else
+  ac_cv_sizeof_int64_t=0
+fi
+fi
+echo "$as_me:$LINENO: result: $ac_cv_sizeof_int64_t" >&5
+echo "${ECHO_T}$ac_cv_sizeof_int64_t" >&6
+cat >>confdefs.h <<_ACEOF
+#define SIZEOF_INT64_T $ac_cv_sizeof_int64_t
+_ACEOF
+
+
+echo "$as_me:$LINENO: checking for long long" >&5
+echo $ECHO_N "checking for long long... $ECHO_C" >&6
+if test "${ac_cv_type_long_long+set}" = set; then
+  echo $ECHO_N "(cached) $ECHO_C" >&6
+else
+  cat >conftest.$ac_ext <<_ACEOF
+/* confdefs.h.  */
+_ACEOF
+cat confdefs.h >>conftest.$ac_ext
+cat >>conftest.$ac_ext <<_ACEOF
+/* end confdefs.h.  */
+$ac_includes_default
+int
+main ()
+{
+if ((long long *) 0)
+  return 0;
+if (sizeof (long long))
+  return 0;
+  ;
+  return 0;
+}
+_ACEOF
+rm -f conftest.$ac_objext
+if { (eval echo "$as_me:$LINENO: \"$ac_compile\"") >&5
+  (eval $ac_compile) 2>conftest.er1
+  ac_status=$?
+  grep -v '^ *+' conftest.er1 >conftest.err
+  rm -f conftest.er1
+  cat conftest.err >&5
+  echo "$as_me:$LINENO: \$? = $ac_status" >&5
+  (exit $ac_status); } &&
+        { ac_try='test -z "$ac_c_werror_flag"
+                        || test ! -s conftest.err'
+  { (eval echo "$as_me:$LINENO: \"$ac_try\"") >&5
+  (eval $ac_try) 2>&5
+  ac_status=$?
+  echo "$as_me:$LINENO: \$? = $ac_status" >&5
+  (exit $ac_status); }; } &&
+        { ac_try='test -s conftest.$ac_objext'
+  { (eval echo "$as_me:$LINENO: \"$ac_try\"") >&5
+  (eval $ac_try) 2>&5
+  ac_status=$?
+  echo "$as_me:$LINENO: \$? = $ac_status" >&5
+  (exit $ac_status); }; }; then
+  ac_cv_type_long_long=yes
+else
+  echo "$as_me: failed program was:" >&5
+sed 's/^/| /' conftest.$ac_ext >&5
+
+ac_cv_type_long_long=no
+fi
+rm -f conftest.err conftest.$ac_objext conftest.$ac_ext
+fi
+echo "$as_me:$LINENO: result: $ac_cv_type_long_long" >&5
+echo "${ECHO_T}$ac_cv_type_long_long" >&6
+
+echo "$as_me:$LINENO: checking size of long long" >&5
+echo $ECHO_N "checking size of long long... $ECHO_C" >&6
+if test "${ac_cv_sizeof_long_long+set}" = set; then
+  echo $ECHO_N "(cached) $ECHO_C" >&6
+else
+  if test "$ac_cv_type_long_long" = yes; then
+  # The cast to unsigned long works around a bug in the HP C Compiler
+  # version HP92453-01 B.11.11.23709.GP, which incorrectly rejects
+  # declarations like `int a3[[(sizeof (unsigned char)) >= 0]];'.
+  # This bug is HP SR number 8606223364.
+  if test "$cross_compiling" = yes; then
+  # Depending upon the size, compute the lo and hi bounds.
+cat >conftest.$ac_ext <<_ACEOF
+/* confdefs.h.  */
+_ACEOF
+cat confdefs.h >>conftest.$ac_ext
+cat >>conftest.$ac_ext <<_ACEOF
+/* end confdefs.h.  */
+$ac_includes_default
+int
+main ()
+{
+static int test_array [1 - 2 * !(((long) (sizeof (long long))) >= 0)];
+test_array [0] = 0
+
+  ;
+  return 0;
+}
+_ACEOF
+rm -f conftest.$ac_objext
+if { (eval echo "$as_me:$LINENO: \"$ac_compile\"") >&5
+  (eval $ac_compile) 2>conftest.er1
+  ac_status=$?
+  grep -v '^ *+' conftest.er1 >conftest.err
+  rm -f conftest.er1
+  cat conftest.err >&5
+  echo "$as_me:$LINENO: \$? = $ac_status" >&5
+  (exit $ac_status); } &&
+        { ac_try='test -z "$ac_c_werror_flag"
+                        || test ! -s conftest.err'
+  { (eval echo "$as_me:$LINENO: \"$ac_try\"") >&5
+  (eval $ac_try) 2>&5
+  ac_status=$?
+  echo "$as_me:$LINENO: \$? = $ac_status" >&5
+  (exit $ac_status); }; } &&
+        { ac_try='test -s conftest.$ac_objext'
+  { (eval echo "$as_me:$LINENO: \"$ac_try\"") >&5
+  (eval $ac_try) 2>&5
+  ac_status=$?
+  echo "$as_me:$LINENO: \$? = $ac_status" >&5
+  (exit $ac_status); }; }; then
+  ac_lo=0 ac_mid=0
+  while :; do
+    cat >conftest.$ac_ext <<_ACEOF
+/* confdefs.h.  */
+_ACEOF
+cat confdefs.h >>conftest.$ac_ext
+cat >>conftest.$ac_ext <<_ACEOF
+/* end confdefs.h.  */
+$ac_includes_default
+int
+main ()
+{
+static int test_array [1 - 2 * !(((long) (sizeof (long long))) <= $ac_mid)];
+test_array [0] = 0
+
+  ;
+  return 0;
+}
+_ACEOF
+rm -f conftest.$ac_objext
+if { (eval echo "$as_me:$LINENO: \"$ac_compile\"") >&5
+  (eval $ac_compile) 2>conftest.er1
+  ac_status=$?
+  grep -v '^ *+' conftest.er1 >conftest.err
+  rm -f conftest.er1
+  cat conftest.err >&5
+  echo "$as_me:$LINENO: \$? = $ac_status" >&5
+  (exit $ac_status); } &&
+        { ac_try='test -z "$ac_c_werror_flag"
+                        || test ! -s conftest.err'
+  { (eval echo "$as_me:$LINENO: \"$ac_try\"") >&5
+  (eval $ac_try) 2>&5
+  ac_status=$?
+  echo "$as_me:$LINENO: \$? = $ac_status" >&5
+  (exit $ac_status); }; } &&
+        { ac_try='test -s conftest.$ac_objext'
+  { (eval echo "$as_me:$LINENO: \"$ac_try\"") >&5
+  (eval $ac_try) 2>&5
+  ac_status=$?
+  echo "$as_me:$LINENO: \$? = $ac_status" >&5
+  (exit $ac_status); }; }; then
+  ac_hi=$ac_mid; break
+else
+  echo "$as_me: failed program was:" >&5
+sed 's/^/| /' conftest.$ac_ext >&5
+
+ac_lo=`expr $ac_mid + 1`
+                   if test $ac_lo -le $ac_mid; then
+                     ac_lo= ac_hi=
+                     break
+                   fi
+                   ac_mid=`expr 2 '*' $ac_mid + 1`
+fi
+rm -f conftest.err conftest.$ac_objext conftest.$ac_ext
+  done
+else
+  echo "$as_me: failed program was:" >&5
+sed 's/^/| /' conftest.$ac_ext >&5
+
+cat >conftest.$ac_ext <<_ACEOF
+/* confdefs.h.  */
+_ACEOF
+cat confdefs.h >>conftest.$ac_ext
+cat >>conftest.$ac_ext <<_ACEOF
+/* end confdefs.h.  */
+$ac_includes_default
+int
+main ()
+{
+static int test_array [1 - 2 * !(((long) (sizeof (long long))) < 0)];
+test_array [0] = 0
+
+  ;
+  return 0;
+}
+_ACEOF
+rm -f conftest.$ac_objext
+if { (eval echo "$as_me:$LINENO: \"$ac_compile\"") >&5
+  (eval $ac_compile) 2>conftest.er1
+  ac_status=$?
+  grep -v '^ *+' conftest.er1 >conftest.err
+  rm -f conftest.er1
+  cat conftest.err >&5
+  echo "$as_me:$LINENO: \$? = $ac_status" >&5
+  (exit $ac_status); } &&
+        { ac_try='test -z "$ac_c_werror_flag"
+                        || test ! -s conftest.err'
+  { (eval echo "$as_me:$LINENO: \"$ac_try\"") >&5
+  (eval $ac_try) 2>&5
+  ac_status=$?
+  echo "$as_me:$LINENO: \$? = $ac_status" >&5
+  (exit $ac_status); }; } &&
+        { ac_try='test -s conftest.$ac_objext'
+  { (eval echo "$as_me:$LINENO: \"$ac_try\"") >&5
+  (eval $ac_try) 2>&5
+  ac_status=$?
+  echo "$as_me:$LINENO: \$? = $ac_status" >&5
+  (exit $ac_status); }; }; then
+  ac_hi=-1 ac_mid=-1
+  while :; do
+    cat >conftest.$ac_ext <<_ACEOF
+/* confdefs.h.  */
+_ACEOF
+cat confdefs.h >>conftest.$ac_ext
+cat >>conftest.$ac_ext <<_ACEOF
+/* end confdefs.h.  */
+$ac_includes_default
+int
+main ()
+{
+static int test_array [1 - 2 * !(((long) (sizeof (long long))) >= $ac_mid)];
+test_array [0] = 0
+
+  ;
+  return 0;
+}
+_ACEOF
+rm -f conftest.$ac_objext
+if { (eval echo "$as_me:$LINENO: \"$ac_compile\"") >&5
+  (eval $ac_compile) 2>conftest.er1
+  ac_status=$?
+  grep -v '^ *+' conftest.er1 >conftest.err
+  rm -f conftest.er1
+  cat conftest.err >&5
+  echo "$as_me:$LINENO: \$? = $ac_status" >&5
+  (exit $ac_status); } &&
+        { ac_try='test -z "$ac_c_werror_flag"
+                        || test ! -s conftest.err'
+  { (eval echo "$as_me:$LINENO: \"$ac_try\"") >&5
+  (eval $ac_try) 2>&5
+  ac_status=$?
+  echo "$as_me:$LINENO: \$? = $ac_status" >&5
+  (exit $ac_status); }; } &&
+        { ac_try='test -s conftest.$ac_objext'
+  { (eval echo "$as_me:$LINENO: \"$ac_try\"") >&5
+  (eval $ac_try) 2>&5
+  ac_status=$?
+  echo "$as_me:$LINENO: \$? = $ac_status" >&5
+  (exit $ac_status); }; }; then
+  ac_lo=$ac_mid; break
+else
+  echo "$as_me: failed program was:" >&5
+sed 's/^/| /' conftest.$ac_ext >&5
+
+ac_hi=`expr '(' $ac_mid ')' - 1`
+                      if test $ac_mid -le $ac_hi; then
+                        ac_lo= ac_hi=
+                        break
+                      fi
+                      ac_mid=`expr 2 '*' $ac_mid`
+fi
+rm -f conftest.err conftest.$ac_objext conftest.$ac_ext
+  done
+else
+  echo "$as_me: failed program was:" >&5
+sed 's/^/| /' conftest.$ac_ext >&5
+
+ac_lo= ac_hi=
+fi
+rm -f conftest.err conftest.$ac_objext conftest.$ac_ext
+fi
+rm -f conftest.err conftest.$ac_objext conftest.$ac_ext
+# Binary search between lo and hi bounds.
+while test "x$ac_lo" != "x$ac_hi"; do
+  ac_mid=`expr '(' $ac_hi - $ac_lo ')' / 2 + $ac_lo`
+  cat >conftest.$ac_ext <<_ACEOF
+/* confdefs.h.  */
+_ACEOF
+cat confdefs.h >>conftest.$ac_ext
+cat >>conftest.$ac_ext <<_ACEOF
+/* end confdefs.h.  */
+$ac_includes_default
+int
+main ()
+{
+static int test_array [1 - 2 * !(((long) (sizeof (long long))) <= $ac_mid)];
+test_array [0] = 0
+
+  ;
+  return 0;
+}
+_ACEOF
+rm -f conftest.$ac_objext
+if { (eval echo "$as_me:$LINENO: \"$ac_compile\"") >&5
+  (eval $ac_compile) 2>conftest.er1
+  ac_status=$?
+  grep -v '^ *+' conftest.er1 >conftest.err
+  rm -f conftest.er1
+  cat conftest.err >&5
+  echo "$as_me:$LINENO: \$? = $ac_status" >&5
+  (exit $ac_status); } &&
+        { ac_try='test -z "$ac_c_werror_flag"
+                        || test ! -s conftest.err'
+  { (eval echo "$as_me:$LINENO: \"$ac_try\"") >&5
+  (eval $ac_try) 2>&5
+  ac_status=$?
+  echo "$as_me:$LINENO: \$? = $ac_status" >&5
+  (exit $ac_status); }; } &&
+        { ac_try='test -s conftest.$ac_objext'
+  { (eval echo "$as_me:$LINENO: \"$ac_try\"") >&5
+  (eval $ac_try) 2>&5
+  ac_status=$?
+  echo "$as_me:$LINENO: \$? = $ac_status" >&5
+  (exit $ac_status); }; }; then
+  ac_hi=$ac_mid
+else
+  echo "$as_me: failed program was:" >&5
+sed 's/^/| /' conftest.$ac_ext >&5
+
+ac_lo=`expr '(' $ac_mid ')' + 1`
+fi
+rm -f conftest.err conftest.$ac_objext conftest.$ac_ext
+done
+case $ac_lo in
+?*) ac_cv_sizeof_long_long=$ac_lo;;
+'') { { echo "$as_me:$LINENO: error: cannot compute sizeof (long long), 77
+See \`config.log' for more details." >&5
+echo "$as_me: error: cannot compute sizeof (long long), 77
+See \`config.log' for more details." >&2;}
+   { (exit 1); exit 1; }; } ;;
+esac
+else
+  if test "$cross_compiling" = yes; then
+  { { echo "$as_me:$LINENO: error: cannot run test program while cross compiling
+See \`config.log' for more details." >&5
+echo "$as_me: error: cannot run test program while cross compiling
+See \`config.log' for more details." >&2;}
+   { (exit 1); exit 1; }; }
+else
+  cat >conftest.$ac_ext <<_ACEOF
+/* confdefs.h.  */
+_ACEOF
+cat confdefs.h >>conftest.$ac_ext
+cat >>conftest.$ac_ext <<_ACEOF
+/* end confdefs.h.  */
+$ac_includes_default
+long longval () { return (long) (sizeof (long long)); }
+unsigned long ulongval () { return (long) (sizeof (long long)); }
+#include <stdio.h>
+#include <stdlib.h>
+int
+main ()
+{
+
+  FILE *f = fopen ("conftest.val", "w");
+  if (! f)
+    exit (1);
+  if (((long) (sizeof (long long))) < 0)
+    {
+      long i = longval ();
+      if (i != ((long) (sizeof (long long))))
+       exit (1);
+      fprintf (f, "%ld\n", i);
+    }
+  else
+    {
+      unsigned long i = ulongval ();
+      if (i != ((long) (sizeof (long long))))
+       exit (1);
+      fprintf (f, "%lu\n", i);
+    }
+  exit (ferror (f) || fclose (f) != 0);
+
+  ;
+  return 0;
+}
+_ACEOF
+rm -f conftest$ac_exeext
+if { (eval echo "$as_me:$LINENO: \"$ac_link\"") >&5
+  (eval $ac_link) 2>&5
+  ac_status=$?
+  echo "$as_me:$LINENO: \$? = $ac_status" >&5
+  (exit $ac_status); } && { ac_try='./conftest$ac_exeext'
+  { (eval echo "$as_me:$LINENO: \"$ac_try\"") >&5
+  (eval $ac_try) 2>&5
+  ac_status=$?
+  echo "$as_me:$LINENO: \$? = $ac_status" >&5
+  (exit $ac_status); }; }; then
+  ac_cv_sizeof_long_long=`cat conftest.val`
+else
+  echo "$as_me: program exited with status $ac_status" >&5
+echo "$as_me: failed program was:" >&5
+sed 's/^/| /' conftest.$ac_ext >&5
+
+( exit $ac_status )
+{ { echo "$as_me:$LINENO: error: cannot compute sizeof (long long), 77
+See \`config.log' for more details." >&5
+echo "$as_me: error: cannot compute sizeof (long long), 77
+See \`config.log' for more details." >&2;}
+   { (exit 1); exit 1; }; }
+fi
+rm -f core *.core gmon.out bb.out conftest$ac_exeext conftest.$ac_objext conftest.$ac_ext
+fi
+fi
+rm -f conftest.val
+else
+  ac_cv_sizeof_long_long=0
+fi
+fi
+echo "$as_me:$LINENO: result: $ac_cv_sizeof_long_long" >&5
+echo "${ECHO_T}$ac_cv_sizeof_long_long" >&6
+cat >>confdefs.h <<_ACEOF
+#define SIZEOF_LONG_LONG $ac_cv_sizeof_long_long
+_ACEOF
+
+
+
+#====================================================================================
+# Find an appropriate type for sf_count_t.
+# On systems supporting files larger than 2 Gig, sf_count_t must be a 64 bit value.
+# Unfortunately there is more than one way of ensuring this so need to do some
+# pretty rigourous testing here.
+
+unset ac_cv_sizeof_off_t
+
+echo "$as_me:$LINENO: checking for off_t" >&5
+echo $ECHO_N "checking for off_t... $ECHO_C" >&6
+if test "${ac_cv_type_off_t+set}" = set; then
+  echo $ECHO_N "(cached) $ECHO_C" >&6
+else
+  cat >conftest.$ac_ext <<_ACEOF
+/* confdefs.h.  */
+_ACEOF
+cat confdefs.h >>conftest.$ac_ext
+cat >>conftest.$ac_ext <<_ACEOF
+/* end confdefs.h.  */
+$ac_includes_default
+int
+main ()
+{
+if ((off_t *) 0)
+  return 0;
+if (sizeof (off_t))
+  return 0;
+  ;
+  return 0;
+}
+_ACEOF
+rm -f conftest.$ac_objext
+if { (eval echo "$as_me:$LINENO: \"$ac_compile\"") >&5
+  (eval $ac_compile) 2>conftest.er1
+  ac_status=$?
+  grep -v '^ *+' conftest.er1 >conftest.err
+  rm -f conftest.er1
+  cat conftest.err >&5
+  echo "$as_me:$LINENO: \$? = $ac_status" >&5
+  (exit $ac_status); } &&
+        { ac_try='test -z "$ac_c_werror_flag"
+                        || test ! -s conftest.err'
+  { (eval echo "$as_me:$LINENO: \"$ac_try\"") >&5
+  (eval $ac_try) 2>&5
+  ac_status=$?
+  echo "$as_me:$LINENO: \$? = $ac_status" >&5
+  (exit $ac_status); }; } &&
+        { ac_try='test -s conftest.$ac_objext'
+  { (eval echo "$as_me:$LINENO: \"$ac_try\"") >&5
+  (eval $ac_try) 2>&5
+  ac_status=$?
+  echo "$as_me:$LINENO: \$? = $ac_status" >&5
+  (exit $ac_status); }; }; then
+  ac_cv_type_off_t=yes
+else
+  echo "$as_me: failed program was:" >&5
+sed 's/^/| /' conftest.$ac_ext >&5
+
+ac_cv_type_off_t=no
+fi
+rm -f conftest.err conftest.$ac_objext conftest.$ac_ext
+fi
+echo "$as_me:$LINENO: result: $ac_cv_type_off_t" >&5
+echo "${ECHO_T}$ac_cv_type_off_t" >&6
+
+echo "$as_me:$LINENO: checking size of off_t" >&5
+echo $ECHO_N "checking size of off_t... $ECHO_C" >&6
+if test "${ac_cv_sizeof_off_t+set}" = set; then
+  echo $ECHO_N "(cached) $ECHO_C" >&6
+else
+  if test "$ac_cv_type_off_t" = yes; then
+  # The cast to unsigned long works around a bug in the HP C Compiler
+  # version HP92453-01 B.11.11.23709.GP, which incorrectly rejects
+  # declarations like `int a3[[(sizeof (unsigned char)) >= 0]];'.
+  # This bug is HP SR number 8606223364.
+  if test "$cross_compiling" = yes; then
+  # Depending upon the size, compute the lo and hi bounds.
+cat >conftest.$ac_ext <<_ACEOF
+/* confdefs.h.  */
+_ACEOF
+cat confdefs.h >>conftest.$ac_ext
+cat >>conftest.$ac_ext <<_ACEOF
+/* end confdefs.h.  */
+$ac_includes_default
+int
+main ()
+{
+static int test_array [1 - 2 * !(((long) (sizeof (off_t))) >= 0)];
+test_array [0] = 0
+
+  ;
+  return 0;
+}
+_ACEOF
+rm -f conftest.$ac_objext
+if { (eval echo "$as_me:$LINENO: \"$ac_compile\"") >&5
+  (eval $ac_compile) 2>conftest.er1
+  ac_status=$?
+  grep -v '^ *+' conftest.er1 >conftest.err
+  rm -f conftest.er1
+  cat conftest.err >&5
+  echo "$as_me:$LINENO: \$? = $ac_status" >&5
+  (exit $ac_status); } &&
+        { ac_try='test -z "$ac_c_werror_flag"
+                        || test ! -s conftest.err'
+  { (eval echo "$as_me:$LINENO: \"$ac_try\"") >&5
+  (eval $ac_try) 2>&5
+  ac_status=$?
+  echo "$as_me:$LINENO: \$? = $ac_status" >&5
+  (exit $ac_status); }; } &&
+        { ac_try='test -s conftest.$ac_objext'
+  { (eval echo "$as_me:$LINENO: \"$ac_try\"") >&5
+  (eval $ac_try) 2>&5
+  ac_status=$?
+  echo "$as_me:$LINENO: \$? = $ac_status" >&5
+  (exit $ac_status); }; }; then
+  ac_lo=0 ac_mid=0
+  while :; do
+    cat >conftest.$ac_ext <<_ACEOF
+/* confdefs.h.  */
+_ACEOF
+cat confdefs.h >>conftest.$ac_ext
+cat >>conftest.$ac_ext <<_ACEOF
+/* end confdefs.h.  */
+$ac_includes_default
+int
+main ()
+{
+static int test_array [1 - 2 * !(((long) (sizeof (off_t))) <= $ac_mid)];
+test_array [0] = 0
+
+  ;
+  return 0;
+}
+_ACEOF
+rm -f conftest.$ac_objext
+if { (eval echo "$as_me:$LINENO: \"$ac_compile\"") >&5
+  (eval $ac_compile) 2>conftest.er1
+  ac_status=$?
+  grep -v '^ *+' conftest.er1 >conftest.err
+  rm -f conftest.er1
+  cat conftest.err >&5
+  echo "$as_me:$LINENO: \$? = $ac_status" >&5
+  (exit $ac_status); } &&
+        { ac_try='test -z "$ac_c_werror_flag"
+                        || test ! -s conftest.err'
+  { (eval echo "$as_me:$LINENO: \"$ac_try\"") >&5
+  (eval $ac_try) 2>&5
+  ac_status=$?
+  echo "$as_me:$LINENO: \$? = $ac_status" >&5
+  (exit $ac_status); }; } &&
+        { ac_try='test -s conftest.$ac_objext'
+  { (eval echo "$as_me:$LINENO: \"$ac_try\"") >&5
+  (eval $ac_try) 2>&5
+  ac_status=$?
+  echo "$as_me:$LINENO: \$? = $ac_status" >&5
+  (exit $ac_status); }; }; then
+  ac_hi=$ac_mid; break
+else
+  echo "$as_me: failed program was:" >&5
+sed 's/^/| /' conftest.$ac_ext >&5
+
+ac_lo=`expr $ac_mid + 1`
+                   if test $ac_lo -le $ac_mid; then
+                     ac_lo= ac_hi=
+                     break
+                   fi
+                   ac_mid=`expr 2 '*' $ac_mid + 1`
+fi
+rm -f conftest.err conftest.$ac_objext conftest.$ac_ext
+  done
+else
+  echo "$as_me: failed program was:" >&5
+sed 's/^/| /' conftest.$ac_ext >&5
+
+cat >conftest.$ac_ext <<_ACEOF
+/* confdefs.h.  */
+_ACEOF
+cat confdefs.h >>conftest.$ac_ext
+cat >>conftest.$ac_ext <<_ACEOF
+/* end confdefs.h.  */
+$ac_includes_default
+int
+main ()
+{
+static int test_array [1 - 2 * !(((long) (sizeof (off_t))) < 0)];
+test_array [0] = 0
+
+  ;
+  return 0;
+}
+_ACEOF
+rm -f conftest.$ac_objext
+if { (eval echo "$as_me:$LINENO: \"$ac_compile\"") >&5
+  (eval $ac_compile) 2>conftest.er1
+  ac_status=$?
+  grep -v '^ *+' conftest.er1 >conftest.err
+  rm -f conftest.er1
+  cat conftest.err >&5
+  echo "$as_me:$LINENO: \$? = $ac_status" >&5
+  (exit $ac_status); } &&
+        { ac_try='test -z "$ac_c_werror_flag"
+                        || test ! -s conftest.err'
+  { (eval echo "$as_me:$LINENO: \"$ac_try\"") >&5
+  (eval $ac_try) 2>&5
+  ac_status=$?
+  echo "$as_me:$LINENO: \$? = $ac_status" >&5
+  (exit $ac_status); }; } &&
+        { ac_try='test -s conftest.$ac_objext'
+  { (eval echo "$as_me:$LINENO: \"$ac_try\"") >&5
+  (eval $ac_try) 2>&5
+  ac_status=$?
+  echo "$as_me:$LINENO: \$? = $ac_status" >&5
+  (exit $ac_status); }; }; then
+  ac_hi=-1 ac_mid=-1
+  while :; do
+    cat >conftest.$ac_ext <<_ACEOF
+/* confdefs.h.  */
+_ACEOF
+cat confdefs.h >>conftest.$ac_ext
+cat >>conftest.$ac_ext <<_ACEOF
+/* end confdefs.h.  */
+$ac_includes_default
+int
+main ()
+{
+static int test_array [1 - 2 * !(((long) (sizeof (off_t))) >= $ac_mid)];
+test_array [0] = 0
+
+  ;
+  return 0;
+}
+_ACEOF
+rm -f conftest.$ac_objext
+if { (eval echo "$as_me:$LINENO: \"$ac_compile\"") >&5
+  (eval $ac_compile) 2>conftest.er1
+  ac_status=$?
+  grep -v '^ *+' conftest.er1 >conftest.err
+  rm -f conftest.er1
+  cat conftest.err >&5
+  echo "$as_me:$LINENO: \$? = $ac_status" >&5
+  (exit $ac_status); } &&
+        { ac_try='test -z "$ac_c_werror_flag"
+                        || test ! -s conftest.err'
+  { (eval echo "$as_me:$LINENO: \"$ac_try\"") >&5
+  (eval $ac_try) 2>&5
+  ac_status=$?
+  echo "$as_me:$LINENO: \$? = $ac_status" >&5
+  (exit $ac_status); }; } &&
+        { ac_try='test -s conftest.$ac_objext'
+  { (eval echo "$as_me:$LINENO: \"$ac_try\"") >&5
+  (eval $ac_try) 2>&5
+  ac_status=$?
+  echo "$as_me:$LINENO: \$? = $ac_status" >&5
+  (exit $ac_status); }; }; then
+  ac_lo=$ac_mid; break
+else
+  echo "$as_me: failed program was:" >&5
+sed 's/^/| /' conftest.$ac_ext >&5
+
+ac_hi=`expr '(' $ac_mid ')' - 1`
+                      if test $ac_mid -le $ac_hi; then
+                        ac_lo= ac_hi=
+                        break
+                      fi
+                      ac_mid=`expr 2 '*' $ac_mid`
+fi
+rm -f conftest.err conftest.$ac_objext conftest.$ac_ext
+  done
+else
+  echo "$as_me: failed program was:" >&5
+sed 's/^/| /' conftest.$ac_ext >&5
+
+ac_lo= ac_hi=
+fi
+rm -f conftest.err conftest.$ac_objext conftest.$ac_ext
+fi
+rm -f conftest.err conftest.$ac_objext conftest.$ac_ext
+# Binary search between lo and hi bounds.
+while test "x$ac_lo" != "x$ac_hi"; do
+  ac_mid=`expr '(' $ac_hi - $ac_lo ')' / 2 + $ac_lo`
+  cat >conftest.$ac_ext <<_ACEOF
+/* confdefs.h.  */
+_ACEOF
+cat confdefs.h >>conftest.$ac_ext
+cat >>conftest.$ac_ext <<_ACEOF
+/* end confdefs.h.  */
+$ac_includes_default
+int
+main ()
+{
+static int test_array [1 - 2 * !(((long) (sizeof (off_t))) <= $ac_mid)];
+test_array [0] = 0
+
+  ;
+  return 0;
+}
+_ACEOF
+rm -f conftest.$ac_objext
+if { (eval echo "$as_me:$LINENO: \"$ac_compile\"") >&5
+  (eval $ac_compile) 2>conftest.er1
+  ac_status=$?
+  grep -v '^ *+' conftest.er1 >conftest.err
+  rm -f conftest.er1
+  cat conftest.err >&5
+  echo "$as_me:$LINENO: \$? = $ac_status" >&5
+  (exit $ac_status); } &&
+        { ac_try='test -z "$ac_c_werror_flag"
+                        || test ! -s conftest.err'
+  { (eval echo "$as_me:$LINENO: \"$ac_try\"") >&5
+  (eval $ac_try) 2>&5
+  ac_status=$?
+  echo "$as_me:$LINENO: \$? = $ac_status" >&5
+  (exit $ac_status); }; } &&
+        { ac_try='test -s conftest.$ac_objext'
+  { (eval echo "$as_me:$LINENO: \"$ac_try\"") >&5
+  (eval $ac_try) 2>&5
+  ac_status=$?
+  echo "$as_me:$LINENO: \$? = $ac_status" >&5
+  (exit $ac_status); }; }; then
+  ac_hi=$ac_mid
+else
+  echo "$as_me: failed program was:" >&5
+sed 's/^/| /' conftest.$ac_ext >&5
+
+ac_lo=`expr '(' $ac_mid ')' + 1`
+fi
+rm -f conftest.err conftest.$ac_objext conftest.$ac_ext
+done
+case $ac_lo in
+?*) ac_cv_sizeof_off_t=$ac_lo;;
+'') { { echo "$as_me:$LINENO: error: cannot compute sizeof (off_t), 77
+See \`config.log' for more details." >&5
+echo "$as_me: error: cannot compute sizeof (off_t), 77
+See \`config.log' for more details." >&2;}
+   { (exit 1); exit 1; }; } ;;
+esac
+else
+  if test "$cross_compiling" = yes; then
+  { { echo "$as_me:$LINENO: error: cannot run test program while cross compiling
+See \`config.log' for more details." >&5
+echo "$as_me: error: cannot run test program while cross compiling
+See \`config.log' for more details." >&2;}
+   { (exit 1); exit 1; }; }
+else
+  cat >conftest.$ac_ext <<_ACEOF
+/* confdefs.h.  */
+_ACEOF
+cat confdefs.h >>conftest.$ac_ext
+cat >>conftest.$ac_ext <<_ACEOF
+/* end confdefs.h.  */
+$ac_includes_default
+long longval () { return (long) (sizeof (off_t)); }
+unsigned long ulongval () { return (long) (sizeof (off_t)); }
+#include <stdio.h>
+#include <stdlib.h>
+int
+main ()
+{
+
+  FILE *f = fopen ("conftest.val", "w");
+  if (! f)
+    exit (1);
+  if (((long) (sizeof (off_t))) < 0)
+    {
+      long i = longval ();
+      if (i != ((long) (sizeof (off_t))))
+       exit (1);
+      fprintf (f, "%ld\n", i);
+    }
+  else
+    {
+      unsigned long i = ulongval ();
+      if (i != ((long) (sizeof (off_t))))
+       exit (1);
+      fprintf (f, "%lu\n", i);
+    }
+  exit (ferror (f) || fclose (f) != 0);
+
+  ;
+  return 0;
+}
+_ACEOF
+rm -f conftest$ac_exeext
+if { (eval echo "$as_me:$LINENO: \"$ac_link\"") >&5
+  (eval $ac_link) 2>&5
+  ac_status=$?
+  echo "$as_me:$LINENO: \$? = $ac_status" >&5
+  (exit $ac_status); } && { ac_try='./conftest$ac_exeext'
+  { (eval echo "$as_me:$LINENO: \"$ac_try\"") >&5
+  (eval $ac_try) 2>&5
+  ac_status=$?
+  echo "$as_me:$LINENO: \$? = $ac_status" >&5
+  (exit $ac_status); }; }; then
+  ac_cv_sizeof_off_t=`cat conftest.val`
+else
+  echo "$as_me: program exited with status $ac_status" >&5
+echo "$as_me: failed program was:" >&5
+sed 's/^/| /' conftest.$ac_ext >&5
+
+( exit $ac_status )
+{ { echo "$as_me:$LINENO: error: cannot compute sizeof (off_t), 77
+See \`config.log' for more details." >&5
+echo "$as_me: error: cannot compute sizeof (off_t), 77
+See \`config.log' for more details." >&2;}
+   { (exit 1); exit 1; }; }
+fi
+rm -f core *.core gmon.out bb.out conftest$ac_exeext conftest.$ac_objext conftest.$ac_ext
+fi
+fi
+rm -f conftest.val
+else
+  ac_cv_sizeof_off_t=0
+fi
+fi
+echo "$as_me:$LINENO: result: $ac_cv_sizeof_off_t" >&5
+echo "${ECHO_T}$ac_cv_sizeof_off_t" >&6
+cat >>confdefs.h <<_ACEOF
+#define SIZEOF_OFF_T $ac_cv_sizeof_off_t
+_ACEOF
+
+       # Fake default value.
+
+case "$host_os" in
+       mingw*)
+               TYPEOF_SF_COUNT_T="__int64"
+               SF_COUNT_MAX="0x7FFFFFFFFFFFFFFFLL"
+               SIZEOF_SF_COUNT_T=8
+               ;;
+       *)
+               if test "x$ac_cv_sizeof_off_t" = "x8" ; then
+                       # If sizeof (off_t) is 8, no further checking is needed.
+                       TYPEOF_SF_COUNT_T="off_t"
+                       SF_COUNT_MAX="0x7FFFFFFFFFFFFFFFLL"
+                       SIZEOF_SF_COUNT_T=8
+               else
+                       # Check for common 64 bit file offset types.
+                       echo "$as_me:$LINENO: checking for loff_t" >&5
+echo $ECHO_N "checking for loff_t... $ECHO_C" >&6
+if test "${ac_cv_type_loff_t+set}" = set; then
+  echo $ECHO_N "(cached) $ECHO_C" >&6
+else
+  cat >conftest.$ac_ext <<_ACEOF
+/* confdefs.h.  */
+_ACEOF
+cat confdefs.h >>conftest.$ac_ext
+cat >>conftest.$ac_ext <<_ACEOF
+/* end confdefs.h.  */
+$ac_includes_default
+int
+main ()
+{
+if ((loff_t *) 0)
+  return 0;
+if (sizeof (loff_t))
+  return 0;
+  ;
+  return 0;
+}
+_ACEOF
+rm -f conftest.$ac_objext
+if { (eval echo "$as_me:$LINENO: \"$ac_compile\"") >&5
+  (eval $ac_compile) 2>conftest.er1
+  ac_status=$?
+  grep -v '^ *+' conftest.er1 >conftest.err
+  rm -f conftest.er1
+  cat conftest.err >&5
+  echo "$as_me:$LINENO: \$? = $ac_status" >&5
+  (exit $ac_status); } &&
+        { ac_try='test -z "$ac_c_werror_flag"
+                        || test ! -s conftest.err'
+  { (eval echo "$as_me:$LINENO: \"$ac_try\"") >&5
+  (eval $ac_try) 2>&5
+  ac_status=$?
+  echo "$as_me:$LINENO: \$? = $ac_status" >&5
+  (exit $ac_status); }; } &&
+        { ac_try='test -s conftest.$ac_objext'
+  { (eval echo "$as_me:$LINENO: \"$ac_try\"") >&5
+  (eval $ac_try) 2>&5
+  ac_status=$?
+  echo "$as_me:$LINENO: \$? = $ac_status" >&5
+  (exit $ac_status); }; }; then
+  ac_cv_type_loff_t=yes
+else
+  echo "$as_me: failed program was:" >&5
+sed 's/^/| /' conftest.$ac_ext >&5
+
+ac_cv_type_loff_t=no
+fi
+rm -f conftest.err conftest.$ac_objext conftest.$ac_ext
+fi
+echo "$as_me:$LINENO: result: $ac_cv_type_loff_t" >&5
+echo "${ECHO_T}$ac_cv_type_loff_t" >&6
+
+echo "$as_me:$LINENO: checking size of loff_t" >&5
+echo $ECHO_N "checking size of loff_t... $ECHO_C" >&6
+if test "${ac_cv_sizeof_loff_t+set}" = set; then
+  echo $ECHO_N "(cached) $ECHO_C" >&6
+else
+  if test "$ac_cv_type_loff_t" = yes; then
+  # The cast to unsigned long works around a bug in the HP C Compiler
+  # version HP92453-01 B.11.11.23709.GP, which incorrectly rejects
+  # declarations like `int a3[[(sizeof (unsigned char)) >= 0]];'.
+  # This bug is HP SR number 8606223364.
+  if test "$cross_compiling" = yes; then
+  # Depending upon the size, compute the lo and hi bounds.
+cat >conftest.$ac_ext <<_ACEOF
+/* confdefs.h.  */
+_ACEOF
+cat confdefs.h >>conftest.$ac_ext
+cat >>conftest.$ac_ext <<_ACEOF
+/* end confdefs.h.  */
+$ac_includes_default
+int
+main ()
+{
+static int test_array [1 - 2 * !(((long) (sizeof (loff_t))) >= 0)];
+test_array [0] = 0
+
+  ;
+  return 0;
+}
+_ACEOF
+rm -f conftest.$ac_objext
+if { (eval echo "$as_me:$LINENO: \"$ac_compile\"") >&5
+  (eval $ac_compile) 2>conftest.er1
+  ac_status=$?
+  grep -v '^ *+' conftest.er1 >conftest.err
+  rm -f conftest.er1
+  cat conftest.err >&5
+  echo "$as_me:$LINENO: \$? = $ac_status" >&5
+  (exit $ac_status); } &&
+        { ac_try='test -z "$ac_c_werror_flag"
+                        || test ! -s conftest.err'
+  { (eval echo "$as_me:$LINENO: \"$ac_try\"") >&5
+  (eval $ac_try) 2>&5
+  ac_status=$?
+  echo "$as_me:$LINENO: \$? = $ac_status" >&5
+  (exit $ac_status); }; } &&
+        { ac_try='test -s conftest.$ac_objext'
+  { (eval echo "$as_me:$LINENO: \"$ac_try\"") >&5
+  (eval $ac_try) 2>&5
+  ac_status=$?
+  echo "$as_me:$LINENO: \$? = $ac_status" >&5
+  (exit $ac_status); }; }; then
+  ac_lo=0 ac_mid=0
+  while :; do
+    cat >conftest.$ac_ext <<_ACEOF
+/* confdefs.h.  */
+_ACEOF
+cat confdefs.h >>conftest.$ac_ext
+cat >>conftest.$ac_ext <<_ACEOF
+/* end confdefs.h.  */
+$ac_includes_default
+int
+main ()
+{
+static int test_array [1 - 2 * !(((long) (sizeof (loff_t))) <= $ac_mid)];
+test_array [0] = 0
+
+  ;
+  return 0;
+}
+_ACEOF
+rm -f conftest.$ac_objext
+if { (eval echo "$as_me:$LINENO: \"$ac_compile\"") >&5
+  (eval $ac_compile) 2>conftest.er1
+  ac_status=$?
+  grep -v '^ *+' conftest.er1 >conftest.err
+  rm -f conftest.er1
+  cat conftest.err >&5
+  echo "$as_me:$LINENO: \$? = $ac_status" >&5
+  (exit $ac_status); } &&
+        { ac_try='test -z "$ac_c_werror_flag"
+                        || test ! -s conftest.err'
+  { (eval echo "$as_me:$LINENO: \"$ac_try\"") >&5
+  (eval $ac_try) 2>&5
+  ac_status=$?
+  echo "$as_me:$LINENO: \$? = $ac_status" >&5
+  (exit $ac_status); }; } &&
+        { ac_try='test -s conftest.$ac_objext'
+  { (eval echo "$as_me:$LINENO: \"$ac_try\"") >&5
+  (eval $ac_try) 2>&5
+  ac_status=$?
+  echo "$as_me:$LINENO: \$? = $ac_status" >&5
+  (exit $ac_status); }; }; then
+  ac_hi=$ac_mid; break
+else
+  echo "$as_me: failed program was:" >&5
+sed 's/^/| /' conftest.$ac_ext >&5
+
+ac_lo=`expr $ac_mid + 1`
+                   if test $ac_lo -le $ac_mid; then
+                     ac_lo= ac_hi=
+                     break
+                   fi
+                   ac_mid=`expr 2 '*' $ac_mid + 1`
+fi
+rm -f conftest.err conftest.$ac_objext conftest.$ac_ext
+  done
+else
+  echo "$as_me: failed program was:" >&5
+sed 's/^/| /' conftest.$ac_ext >&5
+
+cat >conftest.$ac_ext <<_ACEOF
+/* confdefs.h.  */
+_ACEOF
+cat confdefs.h >>conftest.$ac_ext
+cat >>conftest.$ac_ext <<_ACEOF
+/* end confdefs.h.  */
+$ac_includes_default
+int
+main ()
+{
+static int test_array [1 - 2 * !(((long) (sizeof (loff_t))) < 0)];
+test_array [0] = 0
+
+  ;
+  return 0;
+}
+_ACEOF
+rm -f conftest.$ac_objext
+if { (eval echo "$as_me:$LINENO: \"$ac_compile\"") >&5
+  (eval $ac_compile) 2>conftest.er1
+  ac_status=$?
+  grep -v '^ *+' conftest.er1 >conftest.err
+  rm -f conftest.er1
+  cat conftest.err >&5
+  echo "$as_me:$LINENO: \$? = $ac_status" >&5
+  (exit $ac_status); } &&
+        { ac_try='test -z "$ac_c_werror_flag"
+                        || test ! -s conftest.err'
+  { (eval echo "$as_me:$LINENO: \"$ac_try\"") >&5
+  (eval $ac_try) 2>&5
+  ac_status=$?
+  echo "$as_me:$LINENO: \$? = $ac_status" >&5
+  (exit $ac_status); }; } &&
+        { ac_try='test -s conftest.$ac_objext'
+  { (eval echo "$as_me:$LINENO: \"$ac_try\"") >&5
+  (eval $ac_try) 2>&5
+  ac_status=$?
+  echo "$as_me:$LINENO: \$? = $ac_status" >&5
+  (exit $ac_status); }; }; then
+  ac_hi=-1 ac_mid=-1
+  while :; do
+    cat >conftest.$ac_ext <<_ACEOF
+/* confdefs.h.  */
+_ACEOF
+cat confdefs.h >>conftest.$ac_ext
+cat >>conftest.$ac_ext <<_ACEOF
+/* end confdefs.h.  */
+$ac_includes_default
+int
+main ()
+{
+static int test_array [1 - 2 * !(((long) (sizeof (loff_t))) >= $ac_mid)];
+test_array [0] = 0
+
+  ;
+  return 0;
+}
+_ACEOF
+rm -f conftest.$ac_objext
+if { (eval echo "$as_me:$LINENO: \"$ac_compile\"") >&5
+  (eval $ac_compile) 2>conftest.er1
+  ac_status=$?
+  grep -v '^ *+' conftest.er1 >conftest.err
+  rm -f conftest.er1
+  cat conftest.err >&5
+  echo "$as_me:$LINENO: \$? = $ac_status" >&5
+  (exit $ac_status); } &&
+        { ac_try='test -z "$ac_c_werror_flag"
+                        || test ! -s conftest.err'
+  { (eval echo "$as_me:$LINENO: \"$ac_try\"") >&5
+  (eval $ac_try) 2>&5
+  ac_status=$?
+  echo "$as_me:$LINENO: \$? = $ac_status" >&5
+  (exit $ac_status); }; } &&
+        { ac_try='test -s conftest.$ac_objext'
+  { (eval echo "$as_me:$LINENO: \"$ac_try\"") >&5
+  (eval $ac_try) 2>&5
+  ac_status=$?
+  echo "$as_me:$LINENO: \$? = $ac_status" >&5
+  (exit $ac_status); }; }; then
+  ac_lo=$ac_mid; break
+else
+  echo "$as_me: failed program was:" >&5
+sed 's/^/| /' conftest.$ac_ext >&5
+
+ac_hi=`expr '(' $ac_mid ')' - 1`
+                      if test $ac_mid -le $ac_hi; then
+                        ac_lo= ac_hi=
+                        break
+                      fi
+                      ac_mid=`expr 2 '*' $ac_mid`
+fi
+rm -f conftest.err conftest.$ac_objext conftest.$ac_ext
+  done
+else
+  echo "$as_me: failed program was:" >&5
+sed 's/^/| /' conftest.$ac_ext >&5
+
+ac_lo= ac_hi=
+fi
+rm -f conftest.err conftest.$ac_objext conftest.$ac_ext
+fi
+rm -f conftest.err conftest.$ac_objext conftest.$ac_ext
+# Binary search between lo and hi bounds.
+while test "x$ac_lo" != "x$ac_hi"; do
+  ac_mid=`expr '(' $ac_hi - $ac_lo ')' / 2 + $ac_lo`
+  cat >conftest.$ac_ext <<_ACEOF
+/* confdefs.h.  */
+_ACEOF
+cat confdefs.h >>conftest.$ac_ext
+cat >>conftest.$ac_ext <<_ACEOF
+/* end confdefs.h.  */
+$ac_includes_default
+int
+main ()
+{
+static int test_array [1 - 2 * !(((long) (sizeof (loff_t))) <= $ac_mid)];
+test_array [0] = 0
+
+  ;
+  return 0;
+}
+_ACEOF
+rm -f conftest.$ac_objext
+if { (eval echo "$as_me:$LINENO: \"$ac_compile\"") >&5
+  (eval $ac_compile) 2>conftest.er1
+  ac_status=$?
+  grep -v '^ *+' conftest.er1 >conftest.err
+  rm -f conftest.er1
+  cat conftest.err >&5
+  echo "$as_me:$LINENO: \$? = $ac_status" >&5
+  (exit $ac_status); } &&
+        { ac_try='test -z "$ac_c_werror_flag"
+                        || test ! -s conftest.err'
+  { (eval echo "$as_me:$LINENO: \"$ac_try\"") >&5
+  (eval $ac_try) 2>&5
+  ac_status=$?
+  echo "$as_me:$LINENO: \$? = $ac_status" >&5
+  (exit $ac_status); }; } &&
+        { ac_try='test -s conftest.$ac_objext'
+  { (eval echo "$as_me:$LINENO: \"$ac_try\"") >&5
+  (eval $ac_try) 2>&5
+  ac_status=$?
+  echo "$as_me:$LINENO: \$? = $ac_status" >&5
+  (exit $ac_status); }; }; then
+  ac_hi=$ac_mid
+else
+  echo "$as_me: failed program was:" >&5
+sed 's/^/| /' conftest.$ac_ext >&5
+
+ac_lo=`expr '(' $ac_mid ')' + 1`
+fi
+rm -f conftest.err conftest.$ac_objext conftest.$ac_ext
+done
+case $ac_lo in
+?*) ac_cv_sizeof_loff_t=$ac_lo;;
+'') { { echo "$as_me:$LINENO: error: cannot compute sizeof (loff_t), 77
+See \`config.log' for more details." >&5
+echo "$as_me: error: cannot compute sizeof (loff_t), 77
+See \`config.log' for more details." >&2;}
+   { (exit 1); exit 1; }; } ;;
+esac
+else
+  if test "$cross_compiling" = yes; then
+  { { echo "$as_me:$LINENO: error: cannot run test program while cross compiling
+See \`config.log' for more details." >&5
+echo "$as_me: error: cannot run test program while cross compiling
+See \`config.log' for more details." >&2;}
+   { (exit 1); exit 1; }; }
+else
+  cat >conftest.$ac_ext <<_ACEOF
+/* confdefs.h.  */
+_ACEOF
+cat confdefs.h >>conftest.$ac_ext
+cat >>conftest.$ac_ext <<_ACEOF
+/* end confdefs.h.  */
+$ac_includes_default
+long longval () { return (long) (sizeof (loff_t)); }
+unsigned long ulongval () { return (long) (sizeof (loff_t)); }
+#include <stdio.h>
+#include <stdlib.h>
+int
+main ()
+{
+
+  FILE *f = fopen ("conftest.val", "w");
+  if (! f)
+    exit (1);
+  if (((long) (sizeof (loff_t))) < 0)
+    {
+      long i = longval ();
+      if (i != ((long) (sizeof (loff_t))))
+       exit (1);
+      fprintf (f, "%ld\n", i);
+    }
+  else
+    {
+      unsigned long i = ulongval ();
+      if (i != ((long) (sizeof (loff_t))))
+       exit (1);
+      fprintf (f, "%lu\n", i);
+    }
+  exit (ferror (f) || fclose (f) != 0);
+
+  ;
+  return 0;
+}
+_ACEOF
+rm -f conftest$ac_exeext
+if { (eval echo "$as_me:$LINENO: \"$ac_link\"") >&5
+  (eval $ac_link) 2>&5
+  ac_status=$?
+  echo "$as_me:$LINENO: \$? = $ac_status" >&5
+  (exit $ac_status); } && { ac_try='./conftest$ac_exeext'
+  { (eval echo "$as_me:$LINENO: \"$ac_try\"") >&5
+  (eval $ac_try) 2>&5
+  ac_status=$?
+  echo "$as_me:$LINENO: \$? = $ac_status" >&5
+  (exit $ac_status); }; }; then
+  ac_cv_sizeof_loff_t=`cat conftest.val`
+else
+  echo "$as_me: program exited with status $ac_status" >&5
+echo "$as_me: failed program was:" >&5
+sed 's/^/| /' conftest.$ac_ext >&5
+
+( exit $ac_status )
+{ { echo "$as_me:$LINENO: error: cannot compute sizeof (loff_t), 77
+See \`config.log' for more details." >&5
+echo "$as_me: error: cannot compute sizeof (loff_t), 77
+See \`config.log' for more details." >&2;}
+   { (exit 1); exit 1; }; }
+fi
+rm -f core *.core gmon.out bb.out conftest$ac_exeext conftest.$ac_objext conftest.$ac_ext
+fi
+fi
+rm -f conftest.val
+else
+  ac_cv_sizeof_loff_t=0
+fi
+fi
+echo "$as_me:$LINENO: result: $ac_cv_sizeof_loff_t" >&5
+echo "${ECHO_T}$ac_cv_sizeof_loff_t" >&6
+cat >>confdefs.h <<_ACEOF
+#define SIZEOF_LOFF_T $ac_cv_sizeof_loff_t
+_ACEOF
+
+       # Fake default value.
+                       echo "$as_me:$LINENO: checking for off64_t" >&5
+echo $ECHO_N "checking for off64_t... $ECHO_C" >&6
+if test "${ac_cv_type_off64_t+set}" = set; then
+  echo $ECHO_N "(cached) $ECHO_C" >&6
+else
+  cat >conftest.$ac_ext <<_ACEOF
+/* confdefs.h.  */
+_ACEOF
+cat confdefs.h >>conftest.$ac_ext
+cat >>conftest.$ac_ext <<_ACEOF
+/* end confdefs.h.  */
+$ac_includes_default
+int
+main ()
+{
+if ((off64_t *) 0)
+  return 0;
+if (sizeof (off64_t))
+  return 0;
+  ;
+  return 0;
+}
+_ACEOF
+rm -f conftest.$ac_objext
+if { (eval echo "$as_me:$LINENO: \"$ac_compile\"") >&5
+  (eval $ac_compile) 2>conftest.er1
+  ac_status=$?
+  grep -v '^ *+' conftest.er1 >conftest.err
+  rm -f conftest.er1
+  cat conftest.err >&5
+  echo "$as_me:$LINENO: \$? = $ac_status" >&5
+  (exit $ac_status); } &&
+        { ac_try='test -z "$ac_c_werror_flag"
+                        || test ! -s conftest.err'
+  { (eval echo "$as_me:$LINENO: \"$ac_try\"") >&5
+  (eval $ac_try) 2>&5
+  ac_status=$?
+  echo "$as_me:$LINENO: \$? = $ac_status" >&5
+  (exit $ac_status); }; } &&
+        { ac_try='test -s conftest.$ac_objext'
+  { (eval echo "$as_me:$LINENO: \"$ac_try\"") >&5
+  (eval $ac_try) 2>&5
+  ac_status=$?
+  echo "$as_me:$LINENO: \$? = $ac_status" >&5
+  (exit $ac_status); }; }; then
+  ac_cv_type_off64_t=yes
+else
+  echo "$as_me: failed program was:" >&5
+sed 's/^/| /' conftest.$ac_ext >&5
+
+ac_cv_type_off64_t=no
+fi
+rm -f conftest.err conftest.$ac_objext conftest.$ac_ext
+fi
+echo "$as_me:$LINENO: result: $ac_cv_type_off64_t" >&5
+echo "${ECHO_T}$ac_cv_type_off64_t" >&6
+
+echo "$as_me:$LINENO: checking size of off64_t" >&5
+echo $ECHO_N "checking size of off64_t... $ECHO_C" >&6
+if test "${ac_cv_sizeof_off64_t+set}" = set; then
+  echo $ECHO_N "(cached) $ECHO_C" >&6
+else
+  if test "$ac_cv_type_off64_t" = yes; then
+  # The cast to unsigned long works around a bug in the HP C Compiler
+  # version HP92453-01 B.11.11.23709.GP, which incorrectly rejects
+  # declarations like `int a3[[(sizeof (unsigned char)) >= 0]];'.
+  # This bug is HP SR number 8606223364.
+  if test "$cross_compiling" = yes; then
+  # Depending upon the size, compute the lo and hi bounds.
+cat >conftest.$ac_ext <<_ACEOF
+/* confdefs.h.  */
+_ACEOF
+cat confdefs.h >>conftest.$ac_ext
+cat >>conftest.$ac_ext <<_ACEOF
+/* end confdefs.h.  */
+$ac_includes_default
+int
+main ()
+{
+static int test_array [1 - 2 * !(((long) (sizeof (off64_t))) >= 0)];
+test_array [0] = 0
+
+  ;
+  return 0;
+}
+_ACEOF
+rm -f conftest.$ac_objext
+if { (eval echo "$as_me:$LINENO: \"$ac_compile\"") >&5
+  (eval $ac_compile) 2>conftest.er1
+  ac_status=$?
+  grep -v '^ *+' conftest.er1 >conftest.err
+  rm -f conftest.er1
+  cat conftest.err >&5
+  echo "$as_me:$LINENO: \$? = $ac_status" >&5
+  (exit $ac_status); } &&
+        { ac_try='test -z "$ac_c_werror_flag"
+                        || test ! -s conftest.err'
+  { (eval echo "$as_me:$LINENO: \"$ac_try\"") >&5
+  (eval $ac_try) 2>&5
+  ac_status=$?
+  echo "$as_me:$LINENO: \$? = $ac_status" >&5
+  (exit $ac_status); }; } &&
+        { ac_try='test -s conftest.$ac_objext'
+  { (eval echo "$as_me:$LINENO: \"$ac_try\"") >&5
+  (eval $ac_try) 2>&5
+  ac_status=$?
+  echo "$as_me:$LINENO: \$? = $ac_status" >&5
+  (exit $ac_status); }; }; then
+  ac_lo=0 ac_mid=0
+  while :; do
+    cat >conftest.$ac_ext <<_ACEOF
+/* confdefs.h.  */
+_ACEOF
+cat confdefs.h >>conftest.$ac_ext
+cat >>conftest.$ac_ext <<_ACEOF
+/* end confdefs.h.  */
+$ac_includes_default
+int
+main ()
+{
+static int test_array [1 - 2 * !(((long) (sizeof (off64_t))) <= $ac_mid)];
+test_array [0] = 0
+
+  ;
+  return 0;
+}
+_ACEOF
+rm -f conftest.$ac_objext
+if { (eval echo "$as_me:$LINENO: \"$ac_compile\"") >&5
+  (eval $ac_compile) 2>conftest.er1
+  ac_status=$?
+  grep -v '^ *+' conftest.er1 >conftest.err
+  rm -f conftest.er1
+  cat conftest.err >&5
+  echo "$as_me:$LINENO: \$? = $ac_status" >&5
+  (exit $ac_status); } &&
+        { ac_try='test -z "$ac_c_werror_flag"
+                        || test ! -s conftest.err'
+  { (eval echo "$as_me:$LINENO: \"$ac_try\"") >&5
+  (eval $ac_try) 2>&5
+  ac_status=$?
+  echo "$as_me:$LINENO: \$? = $ac_status" >&5
+  (exit $ac_status); }; } &&
+        { ac_try='test -s conftest.$ac_objext'
+  { (eval echo "$as_me:$LINENO: \"$ac_try\"") >&5
+  (eval $ac_try) 2>&5
+  ac_status=$?
+  echo "$as_me:$LINENO: \$? = $ac_status" >&5
+  (exit $ac_status); }; }; then
+  ac_hi=$ac_mid; break
+else
+  echo "$as_me: failed program was:" >&5
+sed 's/^/| /' conftest.$ac_ext >&5
+
+ac_lo=`expr $ac_mid + 1`
+                   if test $ac_lo -le $ac_mid; then
+                     ac_lo= ac_hi=
+                     break
+                   fi
+                   ac_mid=`expr 2 '*' $ac_mid + 1`
+fi
+rm -f conftest.err conftest.$ac_objext conftest.$ac_ext
+  done
+else
+  echo "$as_me: failed program was:" >&5
+sed 's/^/| /' conftest.$ac_ext >&5
+
+cat >conftest.$ac_ext <<_ACEOF
+/* confdefs.h.  */
+_ACEOF
+cat confdefs.h >>conftest.$ac_ext
+cat >>conftest.$ac_ext <<_ACEOF
+/* end confdefs.h.  */
+$ac_includes_default
+int
+main ()
+{
+static int test_array [1 - 2 * !(((long) (sizeof (off64_t))) < 0)];
+test_array [0] = 0
+
+  ;
+  return 0;
+}
+_ACEOF
+rm -f conftest.$ac_objext
+if { (eval echo "$as_me:$LINENO: \"$ac_compile\"") >&5
+  (eval $ac_compile) 2>conftest.er1
+  ac_status=$?
+  grep -v '^ *+' conftest.er1 >conftest.err
+  rm -f conftest.er1
+  cat conftest.err >&5
+  echo "$as_me:$LINENO: \$? = $ac_status" >&5
+  (exit $ac_status); } &&
+        { ac_try='test -z "$ac_c_werror_flag"
+                        || test ! -s conftest.err'
+  { (eval echo "$as_me:$LINENO: \"$ac_try\"") >&5
+  (eval $ac_try) 2>&5
+  ac_status=$?
+  echo "$as_me:$LINENO: \$? = $ac_status" >&5
+  (exit $ac_status); }; } &&
+        { ac_try='test -s conftest.$ac_objext'
+  { (eval echo "$as_me:$LINENO: \"$ac_try\"") >&5
+  (eval $ac_try) 2>&5
+  ac_status=$?
+  echo "$as_me:$LINENO: \$? = $ac_status" >&5
+  (exit $ac_status); }; }; then
+  ac_hi=-1 ac_mid=-1
+  while :; do
+    cat >conftest.$ac_ext <<_ACEOF
+/* confdefs.h.  */
+_ACEOF
+cat confdefs.h >>conftest.$ac_ext
+cat >>conftest.$ac_ext <<_ACEOF
+/* end confdefs.h.  */
+$ac_includes_default
+int
+main ()
+{
+static int test_array [1 - 2 * !(((long) (sizeof (off64_t))) >= $ac_mid)];
+test_array [0] = 0
+
+  ;
+  return 0;
+}
+_ACEOF
+rm -f conftest.$ac_objext
+if { (eval echo "$as_me:$LINENO: \"$ac_compile\"") >&5
+  (eval $ac_compile) 2>conftest.er1
+  ac_status=$?
+  grep -v '^ *+' conftest.er1 >conftest.err
+  rm -f conftest.er1
+  cat conftest.err >&5
+  echo "$as_me:$LINENO: \$? = $ac_status" >&5
+  (exit $ac_status); } &&
+        { ac_try='test -z "$ac_c_werror_flag"
+                        || test ! -s conftest.err'
+  { (eval echo "$as_me:$LINENO: \"$ac_try\"") >&5
+  (eval $ac_try) 2>&5
+  ac_status=$?
+  echo "$as_me:$LINENO: \$? = $ac_status" >&5
+  (exit $ac_status); }; } &&
+        { ac_try='test -s conftest.$ac_objext'
+  { (eval echo "$as_me:$LINENO: \"$ac_try\"") >&5
+  (eval $ac_try) 2>&5
+  ac_status=$?
+  echo "$as_me:$LINENO: \$? = $ac_status" >&5
+  (exit $ac_status); }; }; then
+  ac_lo=$ac_mid; break
+else
+  echo "$as_me: failed program was:" >&5
+sed 's/^/| /' conftest.$ac_ext >&5
+
+ac_hi=`expr '(' $ac_mid ')' - 1`
+                      if test $ac_mid -le $ac_hi; then
+                        ac_lo= ac_hi=
+                        break
+                      fi
+                      ac_mid=`expr 2 '*' $ac_mid`
+fi
+rm -f conftest.err conftest.$ac_objext conftest.$ac_ext
+  done
+else
+  echo "$as_me: failed program was:" >&5
+sed 's/^/| /' conftest.$ac_ext >&5
+
+ac_lo= ac_hi=
+fi
+rm -f conftest.err conftest.$ac_objext conftest.$ac_ext
+fi
+rm -f conftest.err conftest.$ac_objext conftest.$ac_ext
+# Binary search between lo and hi bounds.
+while test "x$ac_lo" != "x$ac_hi"; do
+  ac_mid=`expr '(' $ac_hi - $ac_lo ')' / 2 + $ac_lo`
+  cat >conftest.$ac_ext <<_ACEOF
+/* confdefs.h.  */
+_ACEOF
+cat confdefs.h >>conftest.$ac_ext
+cat >>conftest.$ac_ext <<_ACEOF
+/* end confdefs.h.  */
+$ac_includes_default
+int
+main ()
+{
+static int test_array [1 - 2 * !(((long) (sizeof (off64_t))) <= $ac_mid)];
+test_array [0] = 0
+
+  ;
+  return 0;
+}
+_ACEOF
+rm -f conftest.$ac_objext
+if { (eval echo "$as_me:$LINENO: \"$ac_compile\"") >&5
+  (eval $ac_compile) 2>conftest.er1
+  ac_status=$?
+  grep -v '^ *+' conftest.er1 >conftest.err
+  rm -f conftest.er1
+  cat conftest.err >&5
+  echo "$as_me:$LINENO: \$? = $ac_status" >&5
+  (exit $ac_status); } &&
+        { ac_try='test -z "$ac_c_werror_flag"
+                        || test ! -s conftest.err'
+  { (eval echo "$as_me:$LINENO: \"$ac_try\"") >&5
+  (eval $ac_try) 2>&5
+  ac_status=$?
+  echo "$as_me:$LINENO: \$? = $ac_status" >&5
+  (exit $ac_status); }; } &&
+        { ac_try='test -s conftest.$ac_objext'
+  { (eval echo "$as_me:$LINENO: \"$ac_try\"") >&5
+  (eval $ac_try) 2>&5
+  ac_status=$?
+  echo "$as_me:$LINENO: \$? = $ac_status" >&5
+  (exit $ac_status); }; }; then
+  ac_hi=$ac_mid
+else
+  echo "$as_me: failed program was:" >&5
+sed 's/^/| /' conftest.$ac_ext >&5
+
+ac_lo=`expr '(' $ac_mid ')' + 1`
+fi
+rm -f conftest.err conftest.$ac_objext conftest.$ac_ext
+done
+case $ac_lo in
+?*) ac_cv_sizeof_off64_t=$ac_lo;;
+'') { { echo "$as_me:$LINENO: error: cannot compute sizeof (off64_t), 77
+See \`config.log' for more details." >&5
+echo "$as_me: error: cannot compute sizeof (off64_t), 77
+See \`config.log' for more details." >&2;}
+   { (exit 1); exit 1; }; } ;;
+esac
+else
+  if test "$cross_compiling" = yes; then
+  { { echo "$as_me:$LINENO: error: cannot run test program while cross compiling
+See \`config.log' for more details." >&5
+echo "$as_me: error: cannot run test program while cross compiling
+See \`config.log' for more details." >&2;}
+   { (exit 1); exit 1; }; }
+else
+  cat >conftest.$ac_ext <<_ACEOF
+/* confdefs.h.  */
+_ACEOF
+cat confdefs.h >>conftest.$ac_ext
+cat >>conftest.$ac_ext <<_ACEOF
+/* end confdefs.h.  */
+$ac_includes_default
+long longval () { return (long) (sizeof (off64_t)); }
+unsigned long ulongval () { return (long) (sizeof (off64_t)); }
+#include <stdio.h>
+#include <stdlib.h>
+int
+main ()
+{
+
+  FILE *f = fopen ("conftest.val", "w");
+  if (! f)
+    exit (1);
+  if (((long) (sizeof (off64_t))) < 0)
+    {
+      long i = longval ();
+      if (i != ((long) (sizeof (off64_t))))
+       exit (1);
+      fprintf (f, "%ld\n", i);
+    }
+  else
+    {
+      unsigned long i = ulongval ();
+      if (i != ((long) (sizeof (off64_t))))
+       exit (1);
+      fprintf (f, "%lu\n", i);
+    }
+  exit (ferror (f) || fclose (f) != 0);
+
+  ;
+  return 0;
+}
+_ACEOF
+rm -f conftest$ac_exeext
+if { (eval echo "$as_me:$LINENO: \"$ac_link\"") >&5
+  (eval $ac_link) 2>&5
+  ac_status=$?
+  echo "$as_me:$LINENO: \$? = $ac_status" >&5
+  (exit $ac_status); } && { ac_try='./conftest$ac_exeext'
+  { (eval echo "$as_me:$LINENO: \"$ac_try\"") >&5
+  (eval $ac_try) 2>&5
+  ac_status=$?
+  echo "$as_me:$LINENO: \$? = $ac_status" >&5
+  (exit $ac_status); }; }; then
+  ac_cv_sizeof_off64_t=`cat conftest.val`
+else
+  echo "$as_me: program exited with status $ac_status" >&5
+echo "$as_me: failed program was:" >&5
+sed 's/^/| /' conftest.$ac_ext >&5
+
+( exit $ac_status )
+{ { echo "$as_me:$LINENO: error: cannot compute sizeof (off64_t), 77
+See \`config.log' for more details." >&5
+echo "$as_me: error: cannot compute sizeof (off64_t), 77
+See \`config.log' for more details." >&2;}
+   { (exit 1); exit 1; }; }
+fi
+rm -f core *.core gmon.out bb.out conftest$ac_exeext conftest.$ac_objext conftest.$ac_ext
+fi
+fi
+rm -f conftest.val
+else
+  ac_cv_sizeof_off64_t=0
+fi
+fi
+echo "$as_me:$LINENO: result: $ac_cv_sizeof_off64_t" >&5
+echo "${ECHO_T}$ac_cv_sizeof_off64_t" >&6
+cat >>confdefs.h <<_ACEOF
+#define SIZEOF_OFF64_T $ac_cv_sizeof_off64_t
+_ACEOF
+
+       # Fake default value.
+
+                       TYPEOF_SF_COUNT_T="unknown"
+                       if test "x$ac_cv_sizeof_loff_t" = "x8" ; then
+                               TYPEOF_SF_COUNT_T="loff_t"
+                               SIZEOF_SF_COUNT_T=8
+                       elif test "x$ac_cv_sizeof_off64_t" = "x8" ; then
+                               TYPEOF_SF_COUNT_T="off64_t"
+                               SIZEOF_SF_COUNT_T=8
+                               fi
+
+                       # Save the old sizeof (off_t) value  and then unset it to see if it
+                       # changes when Large File Support is enabled.
+
+                       pre_largefile_sizeof_off_t=$ac_cv_sizeof_off_t
+                       unset ac_cv_sizeof_off_t
+
+
+   # Check whether --enable-largefile or --disable-largefile was given.
+if test "${enable_largefile+set}" = set; then
+  enableval="$enable_largefile"
+
+fi;
+   if test "$enable_largefile" != no; then
+     if test -n "$ac_tool_prefix"; then
+  # Extract the first word of "${ac_tool_prefix}getconf", so it can be a program name with args.
+set dummy ${ac_tool_prefix}getconf; ac_word=$2
+echo "$as_me:$LINENO: checking for $ac_word" >&5
+echo $ECHO_N "checking for $ac_word... $ECHO_C" >&6
+if test "${ac_cv_prog_GETCONF+set}" = set; then
+  echo $ECHO_N "(cached) $ECHO_C" >&6
+else
+  if test -n "$GETCONF"; then
+  ac_cv_prog_GETCONF="$GETCONF" # Let the user override the test.
+else
+as_save_IFS=$IFS; IFS=$PATH_SEPARATOR
+for as_dir in $PATH
+do
+  IFS=$as_save_IFS
+  test -z "$as_dir" && as_dir=.
+  for ac_exec_ext in '' $ac_executable_extensions; do
+  if $as_executable_p "$as_dir/$ac_word$ac_exec_ext"; then
+    ac_cv_prog_GETCONF="${ac_tool_prefix}getconf"
+    echo "$as_me:$LINENO: found $as_dir/$ac_word$ac_exec_ext" >&5
+    break 2
+  fi
+done
+done
+
+fi
+fi
+GETCONF=$ac_cv_prog_GETCONF
+if test -n "$GETCONF"; then
+  echo "$as_me:$LINENO: result: $GETCONF" >&5
+echo "${ECHO_T}$GETCONF" >&6
+else
+  echo "$as_me:$LINENO: result: no" >&5
+echo "${ECHO_T}no" >&6
+fi
+
+fi
+if test -z "$ac_cv_prog_GETCONF"; then
+  ac_ct_GETCONF=$GETCONF
+  # Extract the first word of "getconf", so it can be a program name with args.
+set dummy getconf; ac_word=$2
+echo "$as_me:$LINENO: checking for $ac_word" >&5
+echo $ECHO_N "checking for $ac_word... $ECHO_C" >&6
+if test "${ac_cv_prog_ac_ct_GETCONF+set}" = set; then
+  echo $ECHO_N "(cached) $ECHO_C" >&6
+else
+  if test -n "$ac_ct_GETCONF"; then
+  ac_cv_prog_ac_ct_GETCONF="$ac_ct_GETCONF" # Let the user override the test.
+else
+as_save_IFS=$IFS; IFS=$PATH_SEPARATOR
+for as_dir in $PATH
+do
+  IFS=$as_save_IFS
+  test -z "$as_dir" && as_dir=.
+  for ac_exec_ext in '' $ac_executable_extensions; do
+  if $as_executable_p "$as_dir/$ac_word$ac_exec_ext"; then
+    ac_cv_prog_ac_ct_GETCONF="getconf"
+    echo "$as_me:$LINENO: found $as_dir/$ac_word$ac_exec_ext" >&5
+    break 2
+  fi
+done
+done
+
+fi
+fi
+ac_ct_GETCONF=$ac_cv_prog_ac_ct_GETCONF
+if test -n "$ac_ct_GETCONF"; then
+  echo "$as_me:$LINENO: result: $ac_ct_GETCONF" >&5
+echo "${ECHO_T}$ac_ct_GETCONF" >&6
+else
+  echo "$as_me:$LINENO: result: no" >&5
+echo "${ECHO_T}no" >&6
+fi
+
+  GETCONF=$ac_ct_GETCONF
+else
+  GETCONF="$ac_cv_prog_GETCONF"
+fi
+
+     echo "$as_me:$LINENO: checking for CFLAGS value to request large file support" >&5
+echo $ECHO_N "checking for CFLAGS value to request large file support... $ECHO_C" >&6
+if test "${ac_cv_sys_largefile_CFLAGS+set}" = set; then
+  echo $ECHO_N "(cached) $ECHO_C" >&6
+else
+  ac_cv_sys_largefile_CFLAGS=`($GETCONF LFS_CFLAGS) 2>/dev/null` || {
+       ac_cv_sys_largefile_CFLAGS=no
+       case "$host_os" in
+          # IRIX 6.2 and later require cc -n32.
+          irix6.[2-9]* | irix6.1[0-9]* | irix[7-9].* | irix[1-9][0-9]*)
+            if test "$GCC" != yes; then
+              ac_cv_sys_largefile_CFLAGS=-n32
+            fi
+            ac_save_CC="$CC"
+            CC="$CC $ac_cv_sys_largefile_CFLAGS"
+            cat >conftest.$ac_ext <<_ACEOF
+/* confdefs.h.  */
+_ACEOF
+cat confdefs.h >>conftest.$ac_ext
+cat >>conftest.$ac_ext <<_ACEOF
+/* end confdefs.h.  */
+
+int
+main ()
+{
+
+  ;
+  return 0;
+}
+_ACEOF
+rm -f conftest.$ac_objext conftest$ac_exeext
+if { (eval echo "$as_me:$LINENO: \"$ac_link\"") >&5
+  (eval $ac_link) 2>conftest.er1
+  ac_status=$?
+  grep -v '^ *+' conftest.er1 >conftest.err
+  rm -f conftest.er1
+  cat conftest.err >&5
+  echo "$as_me:$LINENO: \$? = $ac_status" >&5
+  (exit $ac_status); } &&
+        { ac_try='test -z "$ac_c_werror_flag"
+                        || test ! -s conftest.err'
+  { (eval echo "$as_me:$LINENO: \"$ac_try\"") >&5
+  (eval $ac_try) 2>&5
+  ac_status=$?
+  echo "$as_me:$LINENO: \$? = $ac_status" >&5
+  (exit $ac_status); }; } &&
+        { ac_try='test -s conftest$ac_exeext'
+  { (eval echo "$as_me:$LINENO: \"$ac_try\"") >&5
+  (eval $ac_try) 2>&5
+  ac_status=$?
+  echo "$as_me:$LINENO: \$? = $ac_status" >&5
+  (exit $ac_status); }; }; then
+  :
+else
+  echo "$as_me: failed program was:" >&5
+sed 's/^/| /' conftest.$ac_ext >&5
+
+ac_cv_sys_largefile_CFLAGS=no
+fi
+rm -f conftest.err conftest.$ac_objext \
+      conftest$ac_exeext conftest.$ac_ext
+            CC="$ac_save_CC"
+          esac
+      }
+fi
+echo "$as_me:$LINENO: result: $ac_cv_sys_largefile_CFLAGS" >&5
+echo "${ECHO_T}$ac_cv_sys_largefile_CFLAGS" >&6
+     echo "$as_me:$LINENO: checking for LDFLAGS value to request large file support" >&5
+echo $ECHO_N "checking for LDFLAGS value to request large file support... $ECHO_C" >&6
+if test "${ac_cv_sys_largefile_LDFLAGS+set}" = set; then
+  echo $ECHO_N "(cached) $ECHO_C" >&6
+else
+  ac_cv_sys_largefile_LDFLAGS=`($GETCONF LFS_LDFLAGS) 2>/dev/null` || {
+       ac_cv_sys_largefile_LDFLAGS=no
+
+      }
+fi
+echo "$as_me:$LINENO: result: $ac_cv_sys_largefile_LDFLAGS" >&5
+echo "${ECHO_T}$ac_cv_sys_largefile_LDFLAGS" >&6
+     echo "$as_me:$LINENO: checking for LIBS value to request large file support" >&5
+echo $ECHO_N "checking for LIBS value to request large file support... $ECHO_C" >&6
+if test "${ac_cv_sys_largefile_LIBS+set}" = set; then
+  echo $ECHO_N "(cached) $ECHO_C" >&6
+else
+  ac_cv_sys_largefile_LIBS=`($GETCONF LFS_LIBS) 2>/dev/null` || {
+       ac_cv_sys_largefile_LIBS=no
+
+      }
+fi
+echo "$as_me:$LINENO: result: $ac_cv_sys_largefile_LIBS" >&5
+echo "${ECHO_T}$ac_cv_sys_largefile_LIBS" >&6
+
+     for ac_flag in $ac_cv_sys_largefile_CFLAGS no; do
+       case "$ac_flag" in
+       no) ;;
+       -D_FILE_OFFSET_BITS=*) ;;
+       -D_LARGEFILE_SOURCE | -D_LARGEFILE_SOURCE=*) ;;
+       -D_LARGE_FILES | -D_LARGE_FILES=*) ;;
+       -D?* | -I?*)
+        case "$ac_flag" in
+   no) ;;
+   ?*)
+     case "$CPPFLAGS" in
+     '') CPPFLAGS="$ac_flag" ;;
+     *) CPPFLAGS=$CPPFLAGS' '"$ac_flag" ;;
+     esac ;;
+   esac ;;
+       *)
+        case "$ac_flag" in
+   no) ;;
+   ?*)
+     case "$CFLAGS" in
+     '') CFLAGS="$ac_flag" ;;
+     *) CFLAGS=$CFLAGS' '"$ac_flag" ;;
+     esac ;;
+   esac ;;
+       esac
+     done
+     case "$ac_cv_sys_largefile_LDFLAGS" in
+   no) ;;
+   ?*)
+     case "$LDFLAGS" in
+     '') LDFLAGS="$ac_cv_sys_largefile_LDFLAGS" ;;
+     *) LDFLAGS=$LDFLAGS' '"$ac_cv_sys_largefile_LDFLAGS" ;;
+     esac ;;
+   esac
+     case "$ac_cv_sys_largefile_LIBS" in
+   no) ;;
+   ?*)
+     case "$LIBS" in
+     '') LIBS="$ac_cv_sys_largefile_LIBS" ;;
+     *) LIBS=$LIBS' '"$ac_cv_sys_largefile_LIBS" ;;
+     esac ;;
+   esac
+     echo "$as_me:$LINENO: checking for _FILE_OFFSET_BITS" >&5
+echo $ECHO_N "checking for _FILE_OFFSET_BITS... $ECHO_C" >&6
+if test "${ac_cv_sys_file_offset_bits+set}" = set; then
+  echo $ECHO_N "(cached) $ECHO_C" >&6
+else
+  ac_cv_sys_file_offset_bits=no
+
+      for ac_flag in $ac_cv_sys_largefile_CFLAGS no; do
+       case "$ac_flag" in
+       -D_FILE_OFFSET_BITS)
+         ac_cv_sys_file_offset_bits=1 ;;
+       -D_FILE_OFFSET_BITS=*)
+         ac_cv_sys_file_offset_bits=`expr " $ac_flag" : '[^=]*=\(.*\)'` ;;
+       esac
+      done
+
+fi
+echo "$as_me:$LINENO: result: $ac_cv_sys_file_offset_bits" >&5
+echo "${ECHO_T}$ac_cv_sys_file_offset_bits" >&6
+   if test "$ac_cv_sys_file_offset_bits" != no; then
+
+cat >>confdefs.h <<_ACEOF
+#define _FILE_OFFSET_BITS $ac_cv_sys_file_offset_bits
+_ACEOF
+
+   fi
+       case "$host_os" in
+       # HP-UX 10.20 and later
+       hpux10.[2-9][0-9]* | hpux1[1-9]* | hpux[2-9][0-9]*)
+         ac_cv_sys_file_offset_bits=64 ;;
+       esac
+     echo "$as_me:$LINENO: checking for _LARGEFILE_SOURCE" >&5
+echo $ECHO_N "checking for _LARGEFILE_SOURCE... $ECHO_C" >&6
+if test "${ac_cv_sys_largefile_source+set}" = set; then
+  echo $ECHO_N "(cached) $ECHO_C" >&6
+else
+  ac_cv_sys_largefile_source=no
+      case "$host_os" in
+       # HP-UX 10.20 and later
+       hpux10.[2-9][0-9]* | hpux1[1-9]* | hpux[2-9][0-9]*)
+         ac_cv_sys_largefile_source=1 ;;
+       esac
+      for ac_flag in $ac_cv_sys_largefile_CFLAGS no; do
+       case "$ac_flag" in
+       -D_LARGEFILE_SOURCE)
+         ac_cv_sys_largefile_source=1 ;;
+       -D_LARGEFILE_SOURCE=*)
+         ac_cv_sys_largefile_source=`expr " $ac_flag" : '[^=]*=\(.*\)'` ;;
+       esac
+      done
+
+fi
+echo "$as_me:$LINENO: result: $ac_cv_sys_largefile_source" >&5
+echo "${ECHO_T}$ac_cv_sys_largefile_source" >&6
+   if test "$ac_cv_sys_largefile_source" != no; then
+
+cat >>confdefs.h <<_ACEOF
+#define _LARGEFILE_SOURCE $ac_cv_sys_largefile_source
+_ACEOF
+
+   fi
+     echo "$as_me:$LINENO: checking for _LARGE_FILES" >&5
+echo $ECHO_N "checking for _LARGE_FILES... $ECHO_C" >&6
+if test "${ac_cv_sys_large_files+set}" = set; then
+  echo $ECHO_N "(cached) $ECHO_C" >&6
+else
+  ac_cv_sys_large_files=no
+      case "$host_os" in
+       # AIX 4.2 and later
+       aix4.[2-9]* | aix4.1[0-9]* | aix[5-9].* | aix[1-9][0-9]*)
+         ac_cv_sys_large_files=1 ;;
+       esac
+      for ac_flag in $ac_cv_sys_largefile_CFLAGS no; do
+       case "$ac_flag" in
+       -D_LARGE_FILES)
+         ac_cv_sys_large_files=1 ;;
+       -D_LARGE_FILES=*)
+         ac_cv_sys_large_files=`expr " $ac_flag" : '[^=]*=\(.*\)'` ;;
+       esac
+      done
+
+fi
+echo "$as_me:$LINENO: result: $ac_cv_sys_large_files" >&5
+echo "${ECHO_T}$ac_cv_sys_large_files" >&6
+   if test "$ac_cv_sys_large_files" != no; then
+
+cat >>confdefs.h <<_ACEOF
+#define _LARGE_FILES $ac_cv_sys_large_files
+_ACEOF
+
+   fi
+   fi
+
+
+                       if test "x$ac_cv_sys_largefile_CFLAGS" = "xno" ; then
+                               ac_cv_sys_largefile_CFLAGS=""
+                               fi
+                       if test "x$ac_cv_sys_largefile_LDFLAGS" = "xno" ; then
+                               ac_cv_sys_largefile_LDFLAGS=""
+                               fi
+                       if test "x$ac_cv_sys_largefile_LIBS" = "xno" ; then
+                               ac_cv_sys_largefile_LIBS=""
+                               fi
+
+                       echo "$as_me:$LINENO: checking for off_t" >&5
+echo $ECHO_N "checking for off_t... $ECHO_C" >&6
+if test "${ac_cv_type_off_t+set}" = set; then
+  echo $ECHO_N "(cached) $ECHO_C" >&6
+else
+  cat >conftest.$ac_ext <<_ACEOF
+/* confdefs.h.  */
+_ACEOF
+cat confdefs.h >>conftest.$ac_ext
+cat >>conftest.$ac_ext <<_ACEOF
+/* end confdefs.h.  */
+$ac_includes_default
+int
+main ()
+{
+if ((off_t *) 0)
+  return 0;
+if (sizeof (off_t))
+  return 0;
+  ;
+  return 0;
+}
+_ACEOF
+rm -f conftest.$ac_objext
+if { (eval echo "$as_me:$LINENO: \"$ac_compile\"") >&5
+  (eval $ac_compile) 2>conftest.er1
+  ac_status=$?
+  grep -v '^ *+' conftest.er1 >conftest.err
+  rm -f conftest.er1
+  cat conftest.err >&5
+  echo "$as_me:$LINENO: \$? = $ac_status" >&5
+  (exit $ac_status); } &&
+        { ac_try='test -z "$ac_c_werror_flag"
+                        || test ! -s conftest.err'
+  { (eval echo "$as_me:$LINENO: \"$ac_try\"") >&5
+  (eval $ac_try) 2>&5
+  ac_status=$?
+  echo "$as_me:$LINENO: \$? = $ac_status" >&5
+  (exit $ac_status); }; } &&
+        { ac_try='test -s conftest.$ac_objext'
+  { (eval echo "$as_me:$LINENO: \"$ac_try\"") >&5
+  (eval $ac_try) 2>&5
+  ac_status=$?
+  echo "$as_me:$LINENO: \$? = $ac_status" >&5
+  (exit $ac_status); }; }; then
+  ac_cv_type_off_t=yes
+else
+  echo "$as_me: failed program was:" >&5
+sed 's/^/| /' conftest.$ac_ext >&5
+
+ac_cv_type_off_t=no
+fi
+rm -f conftest.err conftest.$ac_objext conftest.$ac_ext
+fi
+echo "$as_me:$LINENO: result: $ac_cv_type_off_t" >&5
+echo "${ECHO_T}$ac_cv_type_off_t" >&6
+
+echo "$as_me:$LINENO: checking size of off_t" >&5
+echo $ECHO_N "checking size of off_t... $ECHO_C" >&6
+if test "${ac_cv_sizeof_off_t+set}" = set; then
+  echo $ECHO_N "(cached) $ECHO_C" >&6
+else
+  if test "$ac_cv_type_off_t" = yes; then
+  # The cast to unsigned long works around a bug in the HP C Compiler
+  # version HP92453-01 B.11.11.23709.GP, which incorrectly rejects
+  # declarations like `int a3[[(sizeof (unsigned char)) >= 0]];'.
+  # This bug is HP SR number 8606223364.
+  if test "$cross_compiling" = yes; then
+  # Depending upon the size, compute the lo and hi bounds.
+cat >conftest.$ac_ext <<_ACEOF
+/* confdefs.h.  */
+_ACEOF
+cat confdefs.h >>conftest.$ac_ext
+cat >>conftest.$ac_ext <<_ACEOF
+/* end confdefs.h.  */
+$ac_includes_default
+int
+main ()
+{
+static int test_array [1 - 2 * !(((long) (sizeof (off_t))) >= 0)];
+test_array [0] = 0
+
+  ;
+  return 0;
+}
+_ACEOF
+rm -f conftest.$ac_objext
+if { (eval echo "$as_me:$LINENO: \"$ac_compile\"") >&5
+  (eval $ac_compile) 2>conftest.er1
+  ac_status=$?
+  grep -v '^ *+' conftest.er1 >conftest.err
+  rm -f conftest.er1
+  cat conftest.err >&5
+  echo "$as_me:$LINENO: \$? = $ac_status" >&5
+  (exit $ac_status); } &&
+        { ac_try='test -z "$ac_c_werror_flag"
+                        || test ! -s conftest.err'
+  { (eval echo "$as_me:$LINENO: \"$ac_try\"") >&5
+  (eval $ac_try) 2>&5
+  ac_status=$?
+  echo "$as_me:$LINENO: \$? = $ac_status" >&5
+  (exit $ac_status); }; } &&
+        { ac_try='test -s conftest.$ac_objext'
+  { (eval echo "$as_me:$LINENO: \"$ac_try\"") >&5
+  (eval $ac_try) 2>&5
+  ac_status=$?
+  echo "$as_me:$LINENO: \$? = $ac_status" >&5
+  (exit $ac_status); }; }; then
+  ac_lo=0 ac_mid=0
+  while :; do
+    cat >conftest.$ac_ext <<_ACEOF
+/* confdefs.h.  */
+_ACEOF
+cat confdefs.h >>conftest.$ac_ext
+cat >>conftest.$ac_ext <<_ACEOF
+/* end confdefs.h.  */
+$ac_includes_default
+int
+main ()
+{
+static int test_array [1 - 2 * !(((long) (sizeof (off_t))) <= $ac_mid)];
+test_array [0] = 0
+
+  ;
+  return 0;
+}
+_ACEOF
+rm -f conftest.$ac_objext
+if { (eval echo "$as_me:$LINENO: \"$ac_compile\"") >&5
+  (eval $ac_compile) 2>conftest.er1
+  ac_status=$?
+  grep -v '^ *+' conftest.er1 >conftest.err
+  rm -f conftest.er1
+  cat conftest.err >&5
+  echo "$as_me:$LINENO: \$? = $ac_status" >&5
+  (exit $ac_status); } &&
+        { ac_try='test -z "$ac_c_werror_flag"
+                        || test ! -s conftest.err'
+  { (eval echo "$as_me:$LINENO: \"$ac_try\"") >&5
+  (eval $ac_try) 2>&5
+  ac_status=$?
+  echo "$as_me:$LINENO: \$? = $ac_status" >&5
+  (exit $ac_status); }; } &&
+        { ac_try='test -s conftest.$ac_objext'
+  { (eval echo "$as_me:$LINENO: \"$ac_try\"") >&5
+  (eval $ac_try) 2>&5
+  ac_status=$?
+  echo "$as_me:$LINENO: \$? = $ac_status" >&5
+  (exit $ac_status); }; }; then
+  ac_hi=$ac_mid; break
+else
+  echo "$as_me: failed program was:" >&5
+sed 's/^/| /' conftest.$ac_ext >&5
+
+ac_lo=`expr $ac_mid + 1`
+                   if test $ac_lo -le $ac_mid; then
+                     ac_lo= ac_hi=
+                     break
+                   fi
+                   ac_mid=`expr 2 '*' $ac_mid + 1`
+fi
+rm -f conftest.err conftest.$ac_objext conftest.$ac_ext
+  done
+else
+  echo "$as_me: failed program was:" >&5
+sed 's/^/| /' conftest.$ac_ext >&5
+
+cat >conftest.$ac_ext <<_ACEOF
+/* confdefs.h.  */
+_ACEOF
+cat confdefs.h >>conftest.$ac_ext
+cat >>conftest.$ac_ext <<_ACEOF
+/* end confdefs.h.  */
+$ac_includes_default
+int
+main ()
+{
+static int test_array [1 - 2 * !(((long) (sizeof (off_t))) < 0)];
+test_array [0] = 0
+
+  ;
+  return 0;
+}
+_ACEOF
+rm -f conftest.$ac_objext
+if { (eval echo "$as_me:$LINENO: \"$ac_compile\"") >&5
+  (eval $ac_compile) 2>conftest.er1
+  ac_status=$?
+  grep -v '^ *+' conftest.er1 >conftest.err
+  rm -f conftest.er1
+  cat conftest.err >&5
+  echo "$as_me:$LINENO: \$? = $ac_status" >&5
+  (exit $ac_status); } &&
+        { ac_try='test -z "$ac_c_werror_flag"
+                        || test ! -s conftest.err'
+  { (eval echo "$as_me:$LINENO: \"$ac_try\"") >&5
+  (eval $ac_try) 2>&5
+  ac_status=$?
+  echo "$as_me:$LINENO: \$? = $ac_status" >&5
+  (exit $ac_status); }; } &&
+        { ac_try='test -s conftest.$ac_objext'
+  { (eval echo "$as_me:$LINENO: \"$ac_try\"") >&5
+  (eval $ac_try) 2>&5
+  ac_status=$?
+  echo "$as_me:$LINENO: \$? = $ac_status" >&5
+  (exit $ac_status); }; }; then
+  ac_hi=-1 ac_mid=-1
+  while :; do
+    cat >conftest.$ac_ext <<_ACEOF
+/* confdefs.h.  */
+_ACEOF
+cat confdefs.h >>conftest.$ac_ext
+cat >>conftest.$ac_ext <<_ACEOF
+/* end confdefs.h.  */
+$ac_includes_default
+int
+main ()
+{
+static int test_array [1 - 2 * !(((long) (sizeof (off_t))) >= $ac_mid)];
+test_array [0] = 0
+
+  ;
+  return 0;
+}
+_ACEOF
+rm -f conftest.$ac_objext
+if { (eval echo "$as_me:$LINENO: \"$ac_compile\"") >&5
+  (eval $ac_compile) 2>conftest.er1
+  ac_status=$?
+  grep -v '^ *+' conftest.er1 >conftest.err
+  rm -f conftest.er1
+  cat conftest.err >&5
+  echo "$as_me:$LINENO: \$? = $ac_status" >&5
+  (exit $ac_status); } &&
+        { ac_try='test -z "$ac_c_werror_flag"
+                        || test ! -s conftest.err'
+  { (eval echo "$as_me:$LINENO: \"$ac_try\"") >&5
+  (eval $ac_try) 2>&5
+  ac_status=$?
+  echo "$as_me:$LINENO: \$? = $ac_status" >&5
+  (exit $ac_status); }; } &&
+        { ac_try='test -s conftest.$ac_objext'
+  { (eval echo "$as_me:$LINENO: \"$ac_try\"") >&5
+  (eval $ac_try) 2>&5
+  ac_status=$?
+  echo "$as_me:$LINENO: \$? = $ac_status" >&5
+  (exit $ac_status); }; }; then
+  ac_lo=$ac_mid; break
+else
+  echo "$as_me: failed program was:" >&5
+sed 's/^/| /' conftest.$ac_ext >&5
+
+ac_hi=`expr '(' $ac_mid ')' - 1`
+                      if test $ac_mid -le $ac_hi; then
+                        ac_lo= ac_hi=
+                        break
+                      fi
+                      ac_mid=`expr 2 '*' $ac_mid`
+fi
+rm -f conftest.err conftest.$ac_objext conftest.$ac_ext
+  done
+else
+  echo "$as_me: failed program was:" >&5
+sed 's/^/| /' conftest.$ac_ext >&5
+
+ac_lo= ac_hi=
+fi
+rm -f conftest.err conftest.$ac_objext conftest.$ac_ext
+fi
+rm -f conftest.err conftest.$ac_objext conftest.$ac_ext
+# Binary search between lo and hi bounds.
+while test "x$ac_lo" != "x$ac_hi"; do
+  ac_mid=`expr '(' $ac_hi - $ac_lo ')' / 2 + $ac_lo`
+  cat >conftest.$ac_ext <<_ACEOF
+/* confdefs.h.  */
+_ACEOF
+cat confdefs.h >>conftest.$ac_ext
+cat >>conftest.$ac_ext <<_ACEOF
+/* end confdefs.h.  */
+$ac_includes_default
+int
+main ()
+{
+static int test_array [1 - 2 * !(((long) (sizeof (off_t))) <= $ac_mid)];
+test_array [0] = 0
+
+  ;
+  return 0;
+}
+_ACEOF
+rm -f conftest.$ac_objext
+if { (eval echo "$as_me:$LINENO: \"$ac_compile\"") >&5
+  (eval $ac_compile) 2>conftest.er1
+  ac_status=$?
+  grep -v '^ *+' conftest.er1 >conftest.err
+  rm -f conftest.er1
+  cat conftest.err >&5
+  echo "$as_me:$LINENO: \$? = $ac_status" >&5
+  (exit $ac_status); } &&
+        { ac_try='test -z "$ac_c_werror_flag"
+                        || test ! -s conftest.err'
+  { (eval echo "$as_me:$LINENO: \"$ac_try\"") >&5
+  (eval $ac_try) 2>&5
+  ac_status=$?
+  echo "$as_me:$LINENO: \$? = $ac_status" >&5
+  (exit $ac_status); }; } &&
+        { ac_try='test -s conftest.$ac_objext'
+  { (eval echo "$as_me:$LINENO: \"$ac_try\"") >&5
+  (eval $ac_try) 2>&5
+  ac_status=$?
+  echo "$as_me:$LINENO: \$? = $ac_status" >&5
+  (exit $ac_status); }; }; then
+  ac_hi=$ac_mid
+else
+  echo "$as_me: failed program was:" >&5
+sed 's/^/| /' conftest.$ac_ext >&5
+
+ac_lo=`expr '(' $ac_mid ')' + 1`
+fi
+rm -f conftest.err conftest.$ac_objext conftest.$ac_ext
+done
+case $ac_lo in
+?*) ac_cv_sizeof_off_t=$ac_lo;;
+'') { { echo "$as_me:$LINENO: error: cannot compute sizeof (off_t), 77
+See \`config.log' for more details." >&5
+echo "$as_me: error: cannot compute sizeof (off_t), 77
+See \`config.log' for more details." >&2;}
+   { (exit 1); exit 1; }; } ;;
+esac
+else
+  if test "$cross_compiling" = yes; then
+  { { echo "$as_me:$LINENO: error: cannot run test program while cross compiling
+See \`config.log' for more details." >&5
+echo "$as_me: error: cannot run test program while cross compiling
+See \`config.log' for more details." >&2;}
+   { (exit 1); exit 1; }; }
+else
+  cat >conftest.$ac_ext <<_ACEOF
+/* confdefs.h.  */
+_ACEOF
+cat confdefs.h >>conftest.$ac_ext
+cat >>conftest.$ac_ext <<_ACEOF
+/* end confdefs.h.  */
+$ac_includes_default
+long longval () { return (long) (sizeof (off_t)); }
+unsigned long ulongval () { return (long) (sizeof (off_t)); }
+#include <stdio.h>
+#include <stdlib.h>
+int
+main ()
+{
+
+  FILE *f = fopen ("conftest.val", "w");
+  if (! f)
+    exit (1);
+  if (((long) (sizeof (off_t))) < 0)
+    {
+      long i = longval ();
+      if (i != ((long) (sizeof (off_t))))
+       exit (1);
+      fprintf (f, "%ld\n", i);
+    }
+  else
+    {
+      unsigned long i = ulongval ();
+      if (i != ((long) (sizeof (off_t))))
+       exit (1);
+      fprintf (f, "%lu\n", i);
+    }
+  exit (ferror (f) || fclose (f) != 0);
+
+  ;
+  return 0;
+}
+_ACEOF
+rm -f conftest$ac_exeext
+if { (eval echo "$as_me:$LINENO: \"$ac_link\"") >&5
+  (eval $ac_link) 2>&5
+  ac_status=$?
+  echo "$as_me:$LINENO: \$? = $ac_status" >&5
+  (exit $ac_status); } && { ac_try='./conftest$ac_exeext'
+  { (eval echo "$as_me:$LINENO: \"$ac_try\"") >&5
+  (eval $ac_try) 2>&5
+  ac_status=$?
+  echo "$as_me:$LINENO: \$? = $ac_status" >&5
+  (exit $ac_status); }; }; then
+  ac_cv_sizeof_off_t=`cat conftest.val`
+else
+  echo "$as_me: program exited with status $ac_status" >&5
+echo "$as_me: failed program was:" >&5
+sed 's/^/| /' conftest.$ac_ext >&5
+
+( exit $ac_status )
+{ { echo "$as_me:$LINENO: error: cannot compute sizeof (off_t), 77
+See \`config.log' for more details." >&5
+echo "$as_me: error: cannot compute sizeof (off_t), 77
+See \`config.log' for more details." >&2;}
+   { (exit 1); exit 1; }; }
+fi
+rm -f core *.core gmon.out bb.out conftest$ac_exeext conftest.$ac_objext conftest.$ac_ext
+fi
+fi
+rm -f conftest.val
+else
+  ac_cv_sizeof_off_t=0
+fi
+fi
+echo "$as_me:$LINENO: result: $ac_cv_sizeof_off_t" >&5
+echo "${ECHO_T}$ac_cv_sizeof_off_t" >&6
+cat >>confdefs.h <<_ACEOF
+#define SIZEOF_OFF_T $ac_cv_sizeof_off_t
+_ACEOF
+
+       # Fake default value.
+
+                       if test "x$ac_cv_sizeof_off_t" = "x8" ; then
+                               SF_COUNT_MAX="0x7FFFFFFFFFFFFFFFLL"
+                       elif test "x$ac_cv_sizeof_off_t" = "x$pre_largefile_sizeof_off_t" ; then
+                               { echo "$as_me:$LINENO: WARNING: This machine does not seem to support 64 bit file offsets." >&5
+echo "$as_me: WARNING: This machine does not seem to support 64 bit file offsets." >&2;}
+                               TYPEOF_SF_COUNT_T="off_t"
+                               SIZEOF_SF_COUNT_T=$ac_cv_sizeof_off_t
+                       elif test "x$TYPEOF_SF_COUNT_T" = "xunknown" ; then
+                               echo
+                               echo "*** The configure process has determined that this system is capable"
+                               echo "*** of Large File Support but has not been able to find a type which"
+                               echo "*** is an unambiguous 64 bit file offset."
+                               echo "*** Please contact the author to help resolve this problem."
+                               echo
+                               { { echo "$as_me:$LINENO: error: Bad file offset type." >&5
+echo "$as_me: error: Bad file offset type." >&2;}
+   { (exit 1); exit 1; }; }
+                               fi
+                       fi
+               ;;
+       esac
+
+if test $SIZEOF_SF_COUNT_T = 4 ; then
+       SF_COUNT_MAX="0x7FFFFFFF"
+       fi
+
+
+cat >>confdefs.h <<_ACEOF
+#define TYPEOF_SF_COUNT_T ${TYPEOF_SF_COUNT_T}
+_ACEOF
+
+
+
+
+cat >>confdefs.h <<_ACEOF
+#define SIZEOF_SF_COUNT_T ${SIZEOF_SF_COUNT_T}
+_ACEOF
+
+
+
+
+cat >>confdefs.h <<_ACEOF
+#define SF_COUNT_MAX ${SF_COUNT_MAX}
+_ACEOF
+
+
+
+echo "$as_me:$LINENO: checking for ssize_t" >&5
+echo $ECHO_N "checking for ssize_t... $ECHO_C" >&6
+if test "${ac_cv_type_ssize_t+set}" = set; then
+  echo $ECHO_N "(cached) $ECHO_C" >&6
+else
+  cat >conftest.$ac_ext <<_ACEOF
+/* confdefs.h.  */
+_ACEOF
+cat confdefs.h >>conftest.$ac_ext
+cat >>conftest.$ac_ext <<_ACEOF
+/* end confdefs.h.  */
+$ac_includes_default
+int
+main ()
+{
+if ((ssize_t *) 0)
+  return 0;
+if (sizeof (ssize_t))
+  return 0;
+  ;
+  return 0;
+}
+_ACEOF
+rm -f conftest.$ac_objext
+if { (eval echo "$as_me:$LINENO: \"$ac_compile\"") >&5
+  (eval $ac_compile) 2>conftest.er1
+  ac_status=$?
+  grep -v '^ *+' conftest.er1 >conftest.err
+  rm -f conftest.er1
+  cat conftest.err >&5
+  echo "$as_me:$LINENO: \$? = $ac_status" >&5
+  (exit $ac_status); } &&
+        { ac_try='test -z "$ac_c_werror_flag"
+                        || test ! -s conftest.err'
+  { (eval echo "$as_me:$LINENO: \"$ac_try\"") >&5
+  (eval $ac_try) 2>&5
+  ac_status=$?
+  echo "$as_me:$LINENO: \$? = $ac_status" >&5
+  (exit $ac_status); }; } &&
+        { ac_try='test -s conftest.$ac_objext'
+  { (eval echo "$as_me:$LINENO: \"$ac_try\"") >&5
+  (eval $ac_try) 2>&5
+  ac_status=$?
+  echo "$as_me:$LINENO: \$? = $ac_status" >&5
+  (exit $ac_status); }; }; then
+  ac_cv_type_ssize_t=yes
+else
+  echo "$as_me: failed program was:" >&5
+sed 's/^/| /' conftest.$ac_ext >&5
+
+ac_cv_type_ssize_t=no
+fi
+rm -f conftest.err conftest.$ac_objext conftest.$ac_ext
+fi
+echo "$as_me:$LINENO: result: $ac_cv_type_ssize_t" >&5
+echo "${ECHO_T}$ac_cv_type_ssize_t" >&6
+if test $ac_cv_type_ssize_t = yes; then
+
+cat >>confdefs.h <<_ACEOF
+#define HAVE_SSIZE_T 1
+_ACEOF
+
+
+fi
+
+echo "$as_me:$LINENO: checking for ssize_t" >&5
+echo $ECHO_N "checking for ssize_t... $ECHO_C" >&6
+if test "${ac_cv_type_ssize_t+set}" = set; then
+  echo $ECHO_N "(cached) $ECHO_C" >&6
+else
+  cat >conftest.$ac_ext <<_ACEOF
+/* confdefs.h.  */
+_ACEOF
+cat confdefs.h >>conftest.$ac_ext
+cat >>conftest.$ac_ext <<_ACEOF
+/* end confdefs.h.  */
+$ac_includes_default
+int
+main ()
+{
+if ((ssize_t *) 0)
+  return 0;
+if (sizeof (ssize_t))
+  return 0;
+  ;
+  return 0;
+}
+_ACEOF
+rm -f conftest.$ac_objext
+if { (eval echo "$as_me:$LINENO: \"$ac_compile\"") >&5
+  (eval $ac_compile) 2>conftest.er1
+  ac_status=$?
+  grep -v '^ *+' conftest.er1 >conftest.err
+  rm -f conftest.er1
+  cat conftest.err >&5
+  echo "$as_me:$LINENO: \$? = $ac_status" >&5
+  (exit $ac_status); } &&
+        { ac_try='test -z "$ac_c_werror_flag"
+                        || test ! -s conftest.err'
+  { (eval echo "$as_me:$LINENO: \"$ac_try\"") >&5
+  (eval $ac_try) 2>&5
+  ac_status=$?
+  echo "$as_me:$LINENO: \$? = $ac_status" >&5
+  (exit $ac_status); }; } &&
+        { ac_try='test -s conftest.$ac_objext'
+  { (eval echo "$as_me:$LINENO: \"$ac_try\"") >&5
+  (eval $ac_try) 2>&5
+  ac_status=$?
+  echo "$as_me:$LINENO: \$? = $ac_status" >&5
+  (exit $ac_status); }; }; then
+  ac_cv_type_ssize_t=yes
+else
+  echo "$as_me: failed program was:" >&5
+sed 's/^/| /' conftest.$ac_ext >&5
+
+ac_cv_type_ssize_t=no
+fi
+rm -f conftest.err conftest.$ac_objext conftest.$ac_ext
+fi
+echo "$as_me:$LINENO: result: $ac_cv_type_ssize_t" >&5
+echo "${ECHO_T}$ac_cv_type_ssize_t" >&6
+
+echo "$as_me:$LINENO: checking size of ssize_t" >&5
+echo $ECHO_N "checking size of ssize_t... $ECHO_C" >&6
+if test "${ac_cv_sizeof_ssize_t+set}" = set; then
+  echo $ECHO_N "(cached) $ECHO_C" >&6
+else
+  if test "$ac_cv_type_ssize_t" = yes; then
+  # The cast to unsigned long works around a bug in the HP C Compiler
+  # version HP92453-01 B.11.11.23709.GP, which incorrectly rejects
+  # declarations like `int a3[[(sizeof (unsigned char)) >= 0]];'.
+  # This bug is HP SR number 8606223364.
+  if test "$cross_compiling" = yes; then
+  # Depending upon the size, compute the lo and hi bounds.
+cat >conftest.$ac_ext <<_ACEOF
+/* confdefs.h.  */
+_ACEOF
+cat confdefs.h >>conftest.$ac_ext
+cat >>conftest.$ac_ext <<_ACEOF
+/* end confdefs.h.  */
+$ac_includes_default
+int
+main ()
+{
+static int test_array [1 - 2 * !(((long) (sizeof (ssize_t))) >= 0)];
+test_array [0] = 0
+
+  ;
+  return 0;
+}
+_ACEOF
+rm -f conftest.$ac_objext
+if { (eval echo "$as_me:$LINENO: \"$ac_compile\"") >&5
+  (eval $ac_compile) 2>conftest.er1
+  ac_status=$?
+  grep -v '^ *+' conftest.er1 >conftest.err
+  rm -f conftest.er1
+  cat conftest.err >&5
+  echo "$as_me:$LINENO: \$? = $ac_status" >&5
+  (exit $ac_status); } &&
+        { ac_try='test -z "$ac_c_werror_flag"
+                        || test ! -s conftest.err'
+  { (eval echo "$as_me:$LINENO: \"$ac_try\"") >&5
+  (eval $ac_try) 2>&5
+  ac_status=$?
+  echo "$as_me:$LINENO: \$? = $ac_status" >&5
+  (exit $ac_status); }; } &&
+        { ac_try='test -s conftest.$ac_objext'
+  { (eval echo "$as_me:$LINENO: \"$ac_try\"") >&5
+  (eval $ac_try) 2>&5
+  ac_status=$?
+  echo "$as_me:$LINENO: \$? = $ac_status" >&5
+  (exit $ac_status); }; }; then
+  ac_lo=0 ac_mid=0
+  while :; do
+    cat >conftest.$ac_ext <<_ACEOF
+/* confdefs.h.  */
+_ACEOF
+cat confdefs.h >>conftest.$ac_ext
+cat >>conftest.$ac_ext <<_ACEOF
+/* end confdefs.h.  */
+$ac_includes_default
+int
+main ()
+{
+static int test_array [1 - 2 * !(((long) (sizeof (ssize_t))) <= $ac_mid)];
+test_array [0] = 0
+
+  ;
+  return 0;
+}
+_ACEOF
+rm -f conftest.$ac_objext
+if { (eval echo "$as_me:$LINENO: \"$ac_compile\"") >&5
+  (eval $ac_compile) 2>conftest.er1
+  ac_status=$?
+  grep -v '^ *+' conftest.er1 >conftest.err
+  rm -f conftest.er1
+  cat conftest.err >&5
+  echo "$as_me:$LINENO: \$? = $ac_status" >&5
+  (exit $ac_status); } &&
+        { ac_try='test -z "$ac_c_werror_flag"
+                        || test ! -s conftest.err'
+  { (eval echo "$as_me:$LINENO: \"$ac_try\"") >&5
+  (eval $ac_try) 2>&5
+  ac_status=$?
+  echo "$as_me:$LINENO: \$? = $ac_status" >&5
+  (exit $ac_status); }; } &&
+        { ac_try='test -s conftest.$ac_objext'
+  { (eval echo "$as_me:$LINENO: \"$ac_try\"") >&5
+  (eval $ac_try) 2>&5
+  ac_status=$?
+  echo "$as_me:$LINENO: \$? = $ac_status" >&5
+  (exit $ac_status); }; }; then
+  ac_hi=$ac_mid; break
+else
+  echo "$as_me: failed program was:" >&5
+sed 's/^/| /' conftest.$ac_ext >&5
+
+ac_lo=`expr $ac_mid + 1`
+                   if test $ac_lo -le $ac_mid; then
+                     ac_lo= ac_hi=
+                     break
+                   fi
+                   ac_mid=`expr 2 '*' $ac_mid + 1`
+fi
+rm -f conftest.err conftest.$ac_objext conftest.$ac_ext
+  done
+else
+  echo "$as_me: failed program was:" >&5
+sed 's/^/| /' conftest.$ac_ext >&5
+
+cat >conftest.$ac_ext <<_ACEOF
+/* confdefs.h.  */
+_ACEOF
+cat confdefs.h >>conftest.$ac_ext
+cat >>conftest.$ac_ext <<_ACEOF
+/* end confdefs.h.  */
+$ac_includes_default
+int
+main ()
+{
+static int test_array [1 - 2 * !(((long) (sizeof (ssize_t))) < 0)];
+test_array [0] = 0
+
+  ;
+  return 0;
+}
+_ACEOF
+rm -f conftest.$ac_objext
+if { (eval echo "$as_me:$LINENO: \"$ac_compile\"") >&5
+  (eval $ac_compile) 2>conftest.er1
+  ac_status=$?
+  grep -v '^ *+' conftest.er1 >conftest.err
+  rm -f conftest.er1
+  cat conftest.err >&5
+  echo "$as_me:$LINENO: \$? = $ac_status" >&5
+  (exit $ac_status); } &&
+        { ac_try='test -z "$ac_c_werror_flag"
+                        || test ! -s conftest.err'
+  { (eval echo "$as_me:$LINENO: \"$ac_try\"") >&5
+  (eval $ac_try) 2>&5
+  ac_status=$?
+  echo "$as_me:$LINENO: \$? = $ac_status" >&5
+  (exit $ac_status); }; } &&
+        { ac_try='test -s conftest.$ac_objext'
+  { (eval echo "$as_me:$LINENO: \"$ac_try\"") >&5
+  (eval $ac_try) 2>&5
+  ac_status=$?
+  echo "$as_me:$LINENO: \$? = $ac_status" >&5
+  (exit $ac_status); }; }; then
+  ac_hi=-1 ac_mid=-1
+  while :; do
+    cat >conftest.$ac_ext <<_ACEOF
+/* confdefs.h.  */
+_ACEOF
+cat confdefs.h >>conftest.$ac_ext
+cat >>conftest.$ac_ext <<_ACEOF
+/* end confdefs.h.  */
+$ac_includes_default
+int
+main ()
+{
+static int test_array [1 - 2 * !(((long) (sizeof (ssize_t))) >= $ac_mid)];
+test_array [0] = 0
+
+  ;
+  return 0;
+}
+_ACEOF
+rm -f conftest.$ac_objext
+if { (eval echo "$as_me:$LINENO: \"$ac_compile\"") >&5
+  (eval $ac_compile) 2>conftest.er1
+  ac_status=$?
+  grep -v '^ *+' conftest.er1 >conftest.err
+  rm -f conftest.er1
+  cat conftest.err >&5
+  echo "$as_me:$LINENO: \$? = $ac_status" >&5
+  (exit $ac_status); } &&
+        { ac_try='test -z "$ac_c_werror_flag"
+                        || test ! -s conftest.err'
+  { (eval echo "$as_me:$LINENO: \"$ac_try\"") >&5
+  (eval $ac_try) 2>&5
+  ac_status=$?
+  echo "$as_me:$LINENO: \$? = $ac_status" >&5
+  (exit $ac_status); }; } &&
+        { ac_try='test -s conftest.$ac_objext'
+  { (eval echo "$as_me:$LINENO: \"$ac_try\"") >&5
+  (eval $ac_try) 2>&5
+  ac_status=$?
+  echo "$as_me:$LINENO: \$? = $ac_status" >&5
+  (exit $ac_status); }; }; then
+  ac_lo=$ac_mid; break
+else
+  echo "$as_me: failed program was:" >&5
+sed 's/^/| /' conftest.$ac_ext >&5
+
+ac_hi=`expr '(' $ac_mid ')' - 1`
+                      if test $ac_mid -le $ac_hi; then
+                        ac_lo= ac_hi=
+                        break
+                      fi
+                      ac_mid=`expr 2 '*' $ac_mid`
+fi
+rm -f conftest.err conftest.$ac_objext conftest.$ac_ext
+  done
+else
+  echo "$as_me: failed program was:" >&5
+sed 's/^/| /' conftest.$ac_ext >&5
+
+ac_lo= ac_hi=
+fi
+rm -f conftest.err conftest.$ac_objext conftest.$ac_ext
+fi
+rm -f conftest.err conftest.$ac_objext conftest.$ac_ext
+# Binary search between lo and hi bounds.
+while test "x$ac_lo" != "x$ac_hi"; do
+  ac_mid=`expr '(' $ac_hi - $ac_lo ')' / 2 + $ac_lo`
+  cat >conftest.$ac_ext <<_ACEOF
+/* confdefs.h.  */
+_ACEOF
+cat confdefs.h >>conftest.$ac_ext
+cat >>conftest.$ac_ext <<_ACEOF
+/* end confdefs.h.  */
+$ac_includes_default
+int
+main ()
+{
+static int test_array [1 - 2 * !(((long) (sizeof (ssize_t))) <= $ac_mid)];
+test_array [0] = 0
+
+  ;
+  return 0;
+}
+_ACEOF
+rm -f conftest.$ac_objext
+if { (eval echo "$as_me:$LINENO: \"$ac_compile\"") >&5
+  (eval $ac_compile) 2>conftest.er1
+  ac_status=$?
+  grep -v '^ *+' conftest.er1 >conftest.err
+  rm -f conftest.er1
+  cat conftest.err >&5
+  echo "$as_me:$LINENO: \$? = $ac_status" >&5
+  (exit $ac_status); } &&
+        { ac_try='test -z "$ac_c_werror_flag"
+                        || test ! -s conftest.err'
+  { (eval echo "$as_me:$LINENO: \"$ac_try\"") >&5
+  (eval $ac_try) 2>&5
+  ac_status=$?
+  echo "$as_me:$LINENO: \$? = $ac_status" >&5
+  (exit $ac_status); }; } &&
+        { ac_try='test -s conftest.$ac_objext'
+  { (eval echo "$as_me:$LINENO: \"$ac_try\"") >&5
+  (eval $ac_try) 2>&5
+  ac_status=$?
+  echo "$as_me:$LINENO: \$? = $ac_status" >&5
+  (exit $ac_status); }; }; then
+  ac_hi=$ac_mid
+else
+  echo "$as_me: failed program was:" >&5
+sed 's/^/| /' conftest.$ac_ext >&5
+
+ac_lo=`expr '(' $ac_mid ')' + 1`
+fi
+rm -f conftest.err conftest.$ac_objext conftest.$ac_ext
+done
+case $ac_lo in
+?*) ac_cv_sizeof_ssize_t=$ac_lo;;
+'') { { echo "$as_me:$LINENO: error: cannot compute sizeof (ssize_t), 77
+See \`config.log' for more details." >&5
+echo "$as_me: error: cannot compute sizeof (ssize_t), 77
+See \`config.log' for more details." >&2;}
+   { (exit 1); exit 1; }; } ;;
+esac
+else
+  if test "$cross_compiling" = yes; then
+  { { echo "$as_me:$LINENO: error: cannot run test program while cross compiling
+See \`config.log' for more details." >&5
+echo "$as_me: error: cannot run test program while cross compiling
+See \`config.log' for more details." >&2;}
+   { (exit 1); exit 1; }; }
+else
+  cat >conftest.$ac_ext <<_ACEOF
+/* confdefs.h.  */
+_ACEOF
+cat confdefs.h >>conftest.$ac_ext
+cat >>conftest.$ac_ext <<_ACEOF
+/* end confdefs.h.  */
+$ac_includes_default
+long longval () { return (long) (sizeof (ssize_t)); }
+unsigned long ulongval () { return (long) (sizeof (ssize_t)); }
+#include <stdio.h>
+#include <stdlib.h>
+int
+main ()
+{
+
+  FILE *f = fopen ("conftest.val", "w");
+  if (! f)
+    exit (1);
+  if (((long) (sizeof (ssize_t))) < 0)
+    {
+      long i = longval ();
+      if (i != ((long) (sizeof (ssize_t))))
+       exit (1);
+      fprintf (f, "%ld\n", i);
+    }
+  else
+    {
+      unsigned long i = ulongval ();
+      if (i != ((long) (sizeof (ssize_t))))
+       exit (1);
+      fprintf (f, "%lu\n", i);
+    }
+  exit (ferror (f) || fclose (f) != 0);
+
+  ;
+  return 0;
+}
+_ACEOF
+rm -f conftest$ac_exeext
+if { (eval echo "$as_me:$LINENO: \"$ac_link\"") >&5
+  (eval $ac_link) 2>&5
+  ac_status=$?
+  echo "$as_me:$LINENO: \$? = $ac_status" >&5
+  (exit $ac_status); } && { ac_try='./conftest$ac_exeext'
+  { (eval echo "$as_me:$LINENO: \"$ac_try\"") >&5
+  (eval $ac_try) 2>&5
+  ac_status=$?
+  echo "$as_me:$LINENO: \$? = $ac_status" >&5
+  (exit $ac_status); }; }; then
+  ac_cv_sizeof_ssize_t=`cat conftest.val`
+else
+  echo "$as_me: program exited with status $ac_status" >&5
+echo "$as_me: failed program was:" >&5
+sed 's/^/| /' conftest.$ac_ext >&5
+
+( exit $ac_status )
+{ { echo "$as_me:$LINENO: error: cannot compute sizeof (ssize_t), 77
+See \`config.log' for more details." >&5
+echo "$as_me: error: cannot compute sizeof (ssize_t), 77
+See \`config.log' for more details." >&2;}
+   { (exit 1); exit 1; }; }
+fi
+rm -f core *.core gmon.out bb.out conftest$ac_exeext conftest.$ac_objext conftest.$ac_ext
+fi
+fi
+rm -f conftest.val
+else
+  ac_cv_sizeof_ssize_t=0
+fi
+fi
+echo "$as_me:$LINENO: result: $ac_cv_sizeof_ssize_t" >&5
+echo "${ECHO_T}$ac_cv_sizeof_ssize_t" >&6
+cat >>confdefs.h <<_ACEOF
+#define SIZEOF_SSIZE_T $ac_cv_sizeof_ssize_t
+_ACEOF
+
+
+
+#====================================================================================
+# Determine endian-ness of target processor.
+
+echo "$as_me:$LINENO: checking processor byte ordering" >&5
+echo $ECHO_N "checking processor byte ordering... $ECHO_C" >&6
+if test "${ac_cv_c_byte_order+set}" = set; then
+  echo $ECHO_N "(cached) $ECHO_C" >&6
+else
+  # Initialize to unknown
+ac_cv_c_byte_order=unknown
+
+if test x$ac_cv_header_endian_h = xyes ; then
+
+       # First try <endian.h> which should set BYTE_ORDER.
+
+       cat >conftest.$ac_ext <<_ACEOF
+/* confdefs.h.  */
+_ACEOF
+cat confdefs.h >>conftest.$ac_ext
+cat >>conftest.$ac_ext <<_ACEOF
+/* end confdefs.h.  */
+
+               #include <endian.h>
+               #if BYTE_ORDER != LITTLE_ENDIAN
+                       not big endian
+               #endif
+
+int
+main ()
+{
+return 0 ;
+  ;
+  return 0;
+}
+_ACEOF
+rm -f conftest.$ac_objext conftest$ac_exeext
+if { (eval echo "$as_me:$LINENO: \"$ac_link\"") >&5
+  (eval $ac_link) 2>conftest.er1
+  ac_status=$?
+  grep -v '^ *+' conftest.er1 >conftest.err
+  rm -f conftest.er1
+  cat conftest.err >&5
+  echo "$as_me:$LINENO: \$? = $ac_status" >&5
+  (exit $ac_status); } &&
+        { ac_try='test -z "$ac_c_werror_flag"
+                        || test ! -s conftest.err'
+  { (eval echo "$as_me:$LINENO: \"$ac_try\"") >&5
+  (eval $ac_try) 2>&5
+  ac_status=$?
+  echo "$as_me:$LINENO: \$? = $ac_status" >&5
+  (exit $ac_status); }; } &&
+        { ac_try='test -s conftest$ac_exeext'
+  { (eval echo "$as_me:$LINENO: \"$ac_try\"") >&5
+  (eval $ac_try) 2>&5
+  ac_status=$?
+  echo "$as_me:$LINENO: \$? = $ac_status" >&5
+  (exit $ac_status); }; }; then
+  ac_cv_c_byte_order=little
+
+else
+  echo "$as_me: failed program was:" >&5
+sed 's/^/| /' conftest.$ac_ext >&5
+
+fi
+rm -f conftest.err conftest.$ac_objext \
+      conftest$ac_exeext conftest.$ac_ext
+
+       cat >conftest.$ac_ext <<_ACEOF
+/* confdefs.h.  */
+_ACEOF
+cat confdefs.h >>conftest.$ac_ext
+cat >>conftest.$ac_ext <<_ACEOF
+/* end confdefs.h.  */
+
+               #include <endian.h>
+               #if BYTE_ORDER != BIG_ENDIAN
+                       not big endian
+               #endif
+
+int
+main ()
+{
+return 0 ;
+  ;
+  return 0;
+}
+_ACEOF
+rm -f conftest.$ac_objext conftest$ac_exeext
+if { (eval echo "$as_me:$LINENO: \"$ac_link\"") >&5
+  (eval $ac_link) 2>conftest.er1
+  ac_status=$?
+  grep -v '^ *+' conftest.er1 >conftest.err
+  rm -f conftest.er1
+  cat conftest.err >&5
+  echo "$as_me:$LINENO: \$? = $ac_status" >&5
+  (exit $ac_status); } &&
+        { ac_try='test -z "$ac_c_werror_flag"
+                        || test ! -s conftest.err'
+  { (eval echo "$as_me:$LINENO: \"$ac_try\"") >&5
+  (eval $ac_try) 2>&5
+  ac_status=$?
+  echo "$as_me:$LINENO: \$? = $ac_status" >&5
+  (exit $ac_status); }; } &&
+        { ac_try='test -s conftest$ac_exeext'
+  { (eval echo "$as_me:$LINENO: \"$ac_try\"") >&5
+  (eval $ac_try) 2>&5
+  ac_status=$?
+  echo "$as_me:$LINENO: \$? = $ac_status" >&5
+  (exit $ac_status); }; }; then
+  ac_cv_c_byte_order=big
+
+else
+  echo "$as_me: failed program was:" >&5
+sed 's/^/| /' conftest.$ac_ext >&5
+
+fi
+rm -f conftest.err conftest.$ac_objext \
+      conftest$ac_exeext conftest.$ac_ext
+
+       fi
+
+if test $ac_cv_c_byte_order = unknown ; then
+
+       cat >conftest.$ac_ext <<_ACEOF
+/* confdefs.h.  */
+_ACEOF
+cat confdefs.h >>conftest.$ac_ext
+cat >>conftest.$ac_ext <<_ACEOF
+/* end confdefs.h.  */
+
+               #include <sys/types.h>
+               #include <sys/param.h>
+               #if !BYTE_ORDER || !BIG_ENDIAN || !LITTLE_ENDIAN
+                       bogus endian macros
+               #endif
+
+int
+main ()
+{
+return 0 ;
+  ;
+  return 0;
+}
+_ACEOF
+rm -f conftest.$ac_objext conftest$ac_exeext
+if { (eval echo "$as_me:$LINENO: \"$ac_link\"") >&5
+  (eval $ac_link) 2>conftest.er1
+  ac_status=$?
+  grep -v '^ *+' conftest.er1 >conftest.err
+  rm -f conftest.er1
+  cat conftest.err >&5
+  echo "$as_me:$LINENO: \$? = $ac_status" >&5
+  (exit $ac_status); } &&
+        { ac_try='test -z "$ac_c_werror_flag"
+                        || test ! -s conftest.err'
+  { (eval echo "$as_me:$LINENO: \"$ac_try\"") >&5
+  (eval $ac_try) 2>&5
+  ac_status=$?
+  echo "$as_me:$LINENO: \$? = $ac_status" >&5
+  (exit $ac_status); }; } &&
+        { ac_try='test -s conftest$ac_exeext'
+  { (eval echo "$as_me:$LINENO: \"$ac_try\"") >&5
+  (eval $ac_try) 2>&5
+  ac_status=$?
+  echo "$as_me:$LINENO: \$? = $ac_status" >&5
+  (exit $ac_status); }; }; then
+  cat >conftest.$ac_ext <<_ACEOF
+/* confdefs.h.  */
+_ACEOF
+cat confdefs.h >>conftest.$ac_ext
+cat >>conftest.$ac_ext <<_ACEOF
+/* end confdefs.h.  */
+
+                       #include <sys/types.h>
+                       #include <sys/param.h>
+                       #if BYTE_ORDER != LITTLE_ENDIAN
+                               not big endian
+                       #endif
+
+int
+main ()
+{
+return 0 ;
+  ;
+  return 0;
+}
+_ACEOF
+rm -f conftest.$ac_objext conftest$ac_exeext
+if { (eval echo "$as_me:$LINENO: \"$ac_link\"") >&5
+  (eval $ac_link) 2>conftest.er1
+  ac_status=$?
+  grep -v '^ *+' conftest.er1 >conftest.err
+  rm -f conftest.er1
+  cat conftest.err >&5
+  echo "$as_me:$LINENO: \$? = $ac_status" >&5
+  (exit $ac_status); } &&
+        { ac_try='test -z "$ac_c_werror_flag"
+                        || test ! -s conftest.err'
+  { (eval echo "$as_me:$LINENO: \"$ac_try\"") >&5
+  (eval $ac_try) 2>&5
+  ac_status=$?
+  echo "$as_me:$LINENO: \$? = $ac_status" >&5
+  (exit $ac_status); }; } &&
+        { ac_try='test -s conftest$ac_exeext'
+  { (eval echo "$as_me:$LINENO: \"$ac_try\"") >&5
+  (eval $ac_try) 2>&5
+  ac_status=$?
+  echo "$as_me:$LINENO: \$? = $ac_status" >&5
+  (exit $ac_status); }; }; then
+  ac_cv_c_byte_order=little
+
+else
+  echo "$as_me: failed program was:" >&5
+sed 's/^/| /' conftest.$ac_ext >&5
+
+fi
+rm -f conftest.err conftest.$ac_objext \
+      conftest$ac_exeext conftest.$ac_ext
+
+               cat >conftest.$ac_ext <<_ACEOF
+/* confdefs.h.  */
+_ACEOF
+cat confdefs.h >>conftest.$ac_ext
+cat >>conftest.$ac_ext <<_ACEOF
+/* end confdefs.h.  */
+
+                       #include <sys/types.h>
+                       #include <sys/param.h>
+                       #if BYTE_ORDER != LITTLE_ENDIAN
+                               not big endian
+                       #endif
+
+int
+main ()
+{
+return 0 ;
+  ;
+  return 0;
+}
+_ACEOF
+rm -f conftest.$ac_objext conftest$ac_exeext
+if { (eval echo "$as_me:$LINENO: \"$ac_link\"") >&5
+  (eval $ac_link) 2>conftest.er1
+  ac_status=$?
+  grep -v '^ *+' conftest.er1 >conftest.err
+  rm -f conftest.er1
+  cat conftest.err >&5
+  echo "$as_me:$LINENO: \$? = $ac_status" >&5
+  (exit $ac_status); } &&
+        { ac_try='test -z "$ac_c_werror_flag"
+                        || test ! -s conftest.err'
+  { (eval echo "$as_me:$LINENO: \"$ac_try\"") >&5
+  (eval $ac_try) 2>&5
+  ac_status=$?
+  echo "$as_me:$LINENO: \$? = $ac_status" >&5
+  (exit $ac_status); }; } &&
+        { ac_try='test -s conftest$ac_exeext'
+  { (eval echo "$as_me:$LINENO: \"$ac_try\"") >&5
+  (eval $ac_try) 2>&5
+  ac_status=$?
+  echo "$as_me:$LINENO: \$? = $ac_status" >&5
+  (exit $ac_status); }; }; then
+  ac_cv_c_byte_order=little
+
+else
+  echo "$as_me: failed program was:" >&5
+sed 's/^/| /' conftest.$ac_ext >&5
+
+fi
+rm -f conftest.err conftest.$ac_objext \
+      conftest$ac_exeext conftest.$ac_ext
+
+
+else
+  echo "$as_me: failed program was:" >&5
+sed 's/^/| /' conftest.$ac_ext >&5
+
+fi
+rm -f conftest.err conftest.$ac_objext \
+      conftest$ac_exeext conftest.$ac_ext
+
+       fi
+
+if test $ac_cv_c_byte_order = unknown ; then
+       if test $cross_compiling = yes ; then
+               # This is the last resort. Try to guess the target processor endian-ness
+               # by looking at the target CPU type.
+
+               case "$target_cpu" in
+                       alpha* | i?86* | mipsel* | ia64*)
+                               ac_cv_c_big_endian=0
+                               ac_cv_c_little_endian=1
+                               ;;
+
+                       m68* | mips* | powerpc* | hppa* | sparc*)
+                               ac_cv_c_big_endian=1
+                               ac_cv_c_little_endian=0
+                               ;;
+
+                       esac
+
+       else
+               if test "$cross_compiling" = yes; then
+  ac_cv_c_byte_order=unknown
+
+else
+  cat >conftest.$ac_ext <<_ACEOF
+/* confdefs.h.  */
+_ACEOF
+cat confdefs.h >>conftest.$ac_ext
+cat >>conftest.$ac_ext <<_ACEOF
+/* end confdefs.h.  */
+
+               int main (void)
+               {       /* Are we little or big endian?  From Harbison&Steele.  */
+                       union
+                       {       long l ;
+                               char c [sizeof (long)] ;
+                       } u ;
+                       u.l = 1 ;
+                       return (u.c [sizeof (long) - 1] == 1);
+                       }
+
+_ACEOF
+rm -f conftest$ac_exeext
+if { (eval echo "$as_me:$LINENO: \"$ac_link\"") >&5
+  (eval $ac_link) 2>&5
+  ac_status=$?
+  echo "$as_me:$LINENO: \$? = $ac_status" >&5
+  (exit $ac_status); } && { ac_try='./conftest$ac_exeext'
+  { (eval echo "$as_me:$LINENO: \"$ac_try\"") >&5
+  (eval $ac_try) 2>&5
+  ac_status=$?
+  echo "$as_me:$LINENO: \$? = $ac_status" >&5
+  (exit $ac_status); }; }; then
+  :
+else
+  echo "$as_me: program exited with status $ac_status" >&5
+echo "$as_me: failed program was:" >&5
+sed 's/^/| /' conftest.$ac_ext >&5
+
+( exit $ac_status )
+ac_cv_c_byte_order=big
+fi
+rm -f core *.core gmon.out bb.out conftest$ac_exeext conftest.$ac_objext conftest.$ac_ext
+fi
+
+               if test "$cross_compiling" = yes; then
+  ac_cv_c_byte_order=unknown
+
+else
+  cat >conftest.$ac_ext <<_ACEOF
+/* confdefs.h.  */
+_ACEOF
+cat confdefs.h >>conftest.$ac_ext
+cat >>conftest.$ac_ext <<_ACEOF
+/* end confdefs.h.  */
+int main (void)
+               {       /* Are we little or big endian?  From Harbison&Steele.  */
+                       union
+                       {       long l ;
+                               char c [sizeof (long)] ;
+                       } u ;
+                       u.l = 1 ;
+                       return (u.c [0] == 1);
+                       }
+_ACEOF
+rm -f conftest$ac_exeext
+if { (eval echo "$as_me:$LINENO: \"$ac_link\"") >&5
+  (eval $ac_link) 2>&5
+  ac_status=$?
+  echo "$as_me:$LINENO: \$? = $ac_status" >&5
+  (exit $ac_status); } && { ac_try='./conftest$ac_exeext'
+  { (eval echo "$as_me:$LINENO: \"$ac_try\"") >&5
+  (eval $ac_try) 2>&5
+  ac_status=$?
+  echo "$as_me:$LINENO: \$? = $ac_status" >&5
+  (exit $ac_status); }; }; then
+  :
+else
+  echo "$as_me: program exited with status $ac_status" >&5
+echo "$as_me: failed program was:" >&5
+sed 's/^/| /' conftest.$ac_ext >&5
+
+( exit $ac_status )
+ac_cv_c_byte_order=little
+fi
+rm -f core *.core gmon.out bb.out conftest$ac_exeext conftest.$ac_objext conftest.$ac_ext
+fi
+               fi
+       fi
+
+
+fi
+echo "$as_me:$LINENO: result: $ac_cv_c_byte_order" >&5
+echo "${ECHO_T}$ac_cv_c_byte_order" >&6
+
+
+if test $ac_cv_c_byte_order = big ; then
+       ac_cv_c_big_endian=1
+       ac_cv_c_little_endian=0
+elif test $ac_cv_c_byte_order = little ; then
+       ac_cv_c_big_endian=0
+       ac_cv_c_little_endian=1
+else
+       ac_cv_c_big_endian=0
+       ac_cv_c_little_endian=0
+
+       echo "$as_me: WARNING: *****************************************************************" >&2
+       echo "$as_me: WARNING: *** Not able to determine endian-ness of target processor.       " >&2
+       echo "$as_me: WARNING: *** The constants CPU_IS_BIG_ENDIAN and CPU_IS_LITTLE_ENDIAN in  " >&2
+       echo "$as_me: WARNING: *** src/config.h may need to be hand editied.                    " >&2
+       echo "$as_me: WARNING: *****************************************************************" >&2
+       fi
+
+
+
+
+cat >>confdefs.h <<_ACEOF
+#define CPU_IS_BIG_ENDIAN ${ac_cv_c_big_endian}
+_ACEOF
+
+
+cat >>confdefs.h <<_ACEOF
+#define CPU_IS_LITTLE_ENDIAN ${ac_cv_c_little_endian}
+_ACEOF
+
+
+#====================================================================================
+# Check for functions.
+
+
+
+
+
+for ac_func in malloc calloc realloc free
+do
+as_ac_var=`echo "ac_cv_func_$ac_func" | $as_tr_sh`
+echo "$as_me:$LINENO: checking for $ac_func" >&5
+echo $ECHO_N "checking for $ac_func... $ECHO_C" >&6
+if eval "test \"\${$as_ac_var+set}\" = set"; then
+  echo $ECHO_N "(cached) $ECHO_C" >&6
+else
+  cat >conftest.$ac_ext <<_ACEOF
+/* confdefs.h.  */
+_ACEOF
+cat confdefs.h >>conftest.$ac_ext
+cat >>conftest.$ac_ext <<_ACEOF
+/* end confdefs.h.  */
+/* Define $ac_func to an innocuous variant, in case <limits.h> declares $ac_func.
+   For example, HP-UX 11i <limits.h> declares gettimeofday.  */
+#define $ac_func innocuous_$ac_func
+
+/* System header to define __stub macros and hopefully few prototypes,
+    which can conflict with char $ac_func (); below.
+    Prefer <limits.h> to <assert.h> if __STDC__ is defined, since
+    <limits.h> exists even on freestanding compilers.  */
+
+#ifdef __STDC__
+# include <limits.h>
+#else
+# include <assert.h>
+#endif
+
+#undef $ac_func
+
+/* Override any gcc2 internal prototype to avoid an error.  */
+#ifdef __cplusplus
+extern "C"
+{
+#endif
+/* We use char because int might match the return type of a gcc2
+   builtin and then its argument prototype would still apply.  */
+char $ac_func ();
+/* The GNU C library defines this for functions which it implements
+    to always fail with ENOSYS.  Some functions are actually named
+    something starting with __ and the normal name is an alias.  */
+#if defined (__stub_$ac_func) || defined (__stub___$ac_func)
+choke me
+#else
+char (*f) () = $ac_func;
+#endif
+#ifdef __cplusplus
+}
+#endif
+
+int
+main ()
+{
+return f != $ac_func;
+  ;
+  return 0;
+}
+_ACEOF
+rm -f conftest.$ac_objext conftest$ac_exeext
+if { (eval echo "$as_me:$LINENO: \"$ac_link\"") >&5
+  (eval $ac_link) 2>conftest.er1
+  ac_status=$?
+  grep -v '^ *+' conftest.er1 >conftest.err
+  rm -f conftest.er1
+  cat conftest.err >&5
+  echo "$as_me:$LINENO: \$? = $ac_status" >&5
+  (exit $ac_status); } &&
+        { ac_try='test -z "$ac_c_werror_flag"
+                        || test ! -s conftest.err'
+  { (eval echo "$as_me:$LINENO: \"$ac_try\"") >&5
+  (eval $ac_try) 2>&5
+  ac_status=$?
+  echo "$as_me:$LINENO: \$? = $ac_status" >&5
+  (exit $ac_status); }; } &&
+        { ac_try='test -s conftest$ac_exeext'
+  { (eval echo "$as_me:$LINENO: \"$ac_try\"") >&5
+  (eval $ac_try) 2>&5
+  ac_status=$?
+  echo "$as_me:$LINENO: \$? = $ac_status" >&5
+  (exit $ac_status); }; }; then
+  eval "$as_ac_var=yes"
+else
+  echo "$as_me: failed program was:" >&5
+sed 's/^/| /' conftest.$ac_ext >&5
+
+eval "$as_ac_var=no"
+fi
+rm -f conftest.err conftest.$ac_objext \
+      conftest$ac_exeext conftest.$ac_ext
+fi
+echo "$as_me:$LINENO: result: `eval echo '${'$as_ac_var'}'`" >&5
+echo "${ECHO_T}`eval echo '${'$as_ac_var'}'`" >&6
+if test `eval echo '${'$as_ac_var'}'` = yes; then
+  cat >>confdefs.h <<_ACEOF
+#define `echo "HAVE_$ac_func" | $as_tr_cpp` 1
+_ACEOF
+
+fi
+done
+
+
+
+
+
+
+
+for ac_func in open read write lseek pread pwrite
+do
+as_ac_var=`echo "ac_cv_func_$ac_func" | $as_tr_sh`
+echo "$as_me:$LINENO: checking for $ac_func" >&5
+echo $ECHO_N "checking for $ac_func... $ECHO_C" >&6
+if eval "test \"\${$as_ac_var+set}\" = set"; then
+  echo $ECHO_N "(cached) $ECHO_C" >&6
+else
+  cat >conftest.$ac_ext <<_ACEOF
+/* confdefs.h.  */
+_ACEOF
+cat confdefs.h >>conftest.$ac_ext
+cat >>conftest.$ac_ext <<_ACEOF
+/* end confdefs.h.  */
+/* Define $ac_func to an innocuous variant, in case <limits.h> declares $ac_func.
+   For example, HP-UX 11i <limits.h> declares gettimeofday.  */
+#define $ac_func innocuous_$ac_func
+
+/* System header to define __stub macros and hopefully few prototypes,
+    which can conflict with char $ac_func (); below.
+    Prefer <limits.h> to <assert.h> if __STDC__ is defined, since
+    <limits.h> exists even on freestanding compilers.  */
+
+#ifdef __STDC__
+# include <limits.h>
+#else
+# include <assert.h>
+#endif
+
+#undef $ac_func
+
+/* Override any gcc2 internal prototype to avoid an error.  */
+#ifdef __cplusplus
+extern "C"
+{
+#endif
+/* We use char because int might match the return type of a gcc2
+   builtin and then its argument prototype would still apply.  */
+char $ac_func ();
+/* The GNU C library defines this for functions which it implements
+    to always fail with ENOSYS.  Some functions are actually named
+    something starting with __ and the normal name is an alias.  */
+#if defined (__stub_$ac_func) || defined (__stub___$ac_func)
+choke me
+#else
+char (*f) () = $ac_func;
+#endif
+#ifdef __cplusplus
+}
+#endif
+
+int
+main ()
+{
+return f != $ac_func;
+  ;
+  return 0;
+}
+_ACEOF
+rm -f conftest.$ac_objext conftest$ac_exeext
+if { (eval echo "$as_me:$LINENO: \"$ac_link\"") >&5
+  (eval $ac_link) 2>conftest.er1
+  ac_status=$?
+  grep -v '^ *+' conftest.er1 >conftest.err
+  rm -f conftest.er1
+  cat conftest.err >&5
+  echo "$as_me:$LINENO: \$? = $ac_status" >&5
+  (exit $ac_status); } &&
+        { ac_try='test -z "$ac_c_werror_flag"
+                        || test ! -s conftest.err'
+  { (eval echo "$as_me:$LINENO: \"$ac_try\"") >&5
+  (eval $ac_try) 2>&5
+  ac_status=$?
+  echo "$as_me:$LINENO: \$? = $ac_status" >&5
+  (exit $ac_status); }; } &&
+        { ac_try='test -s conftest$ac_exeext'
+  { (eval echo "$as_me:$LINENO: \"$ac_try\"") >&5
+  (eval $ac_try) 2>&5
+  ac_status=$?
+  echo "$as_me:$LINENO: \$? = $ac_status" >&5
+  (exit $ac_status); }; }; then
+  eval "$as_ac_var=yes"
+else
+  echo "$as_me: failed program was:" >&5
+sed 's/^/| /' conftest.$ac_ext >&5
+
+eval "$as_ac_var=no"
+fi
+rm -f conftest.err conftest.$ac_objext \
+      conftest$ac_exeext conftest.$ac_ext
+fi
+echo "$as_me:$LINENO: result: `eval echo '${'$as_ac_var'}'`" >&5
+echo "${ECHO_T}`eval echo '${'$as_ac_var'}'`" >&6
+if test `eval echo '${'$as_ac_var'}'` = yes; then
+  cat >>confdefs.h <<_ACEOF
+#define `echo "HAVE_$ac_func" | $as_tr_cpp` 1
+_ACEOF
+
+fi
+done
+
+
+
+
+
+for ac_func in fstat ftruncate fsync fdatasync
+do
+as_ac_var=`echo "ac_cv_func_$ac_func" | $as_tr_sh`
+echo "$as_me:$LINENO: checking for $ac_func" >&5
+echo $ECHO_N "checking for $ac_func... $ECHO_C" >&6
+if eval "test \"\${$as_ac_var+set}\" = set"; then
+  echo $ECHO_N "(cached) $ECHO_C" >&6
+else
+  cat >conftest.$ac_ext <<_ACEOF
+/* confdefs.h.  */
+_ACEOF
+cat confdefs.h >>conftest.$ac_ext
+cat >>conftest.$ac_ext <<_ACEOF
+/* end confdefs.h.  */
+/* Define $ac_func to an innocuous variant, in case <limits.h> declares $ac_func.
+   For example, HP-UX 11i <limits.h> declares gettimeofday.  */
+#define $ac_func innocuous_$ac_func
+
+/* System header to define __stub macros and hopefully few prototypes,
+    which can conflict with char $ac_func (); below.
+    Prefer <limits.h> to <assert.h> if __STDC__ is defined, since
+    <limits.h> exists even on freestanding compilers.  */
+
+#ifdef __STDC__
+# include <limits.h>
+#else
+# include <assert.h>
+#endif
+
+#undef $ac_func
+
+/* Override any gcc2 internal prototype to avoid an error.  */
+#ifdef __cplusplus
+extern "C"
+{
+#endif
+/* We use char because int might match the return type of a gcc2
+   builtin and then its argument prototype would still apply.  */
+char $ac_func ();
+/* The GNU C library defines this for functions which it implements
+    to always fail with ENOSYS.  Some functions are actually named
+    something starting with __ and the normal name is an alias.  */
+#if defined (__stub_$ac_func) || defined (__stub___$ac_func)
+choke me
+#else
+char (*f) () = $ac_func;
+#endif
+#ifdef __cplusplus
+}
+#endif
+
+int
+main ()
+{
+return f != $ac_func;
+  ;
+  return 0;
+}
+_ACEOF
+rm -f conftest.$ac_objext conftest$ac_exeext
+if { (eval echo "$as_me:$LINENO: \"$ac_link\"") >&5
+  (eval $ac_link) 2>conftest.er1
+  ac_status=$?
+  grep -v '^ *+' conftest.er1 >conftest.err
+  rm -f conftest.er1
+  cat conftest.err >&5
+  echo "$as_me:$LINENO: \$? = $ac_status" >&5
+  (exit $ac_status); } &&
+        { ac_try='test -z "$ac_c_werror_flag"
+                        || test ! -s conftest.err'
+  { (eval echo "$as_me:$LINENO: \"$ac_try\"") >&5
+  (eval $ac_try) 2>&5
+  ac_status=$?
+  echo "$as_me:$LINENO: \$? = $ac_status" >&5
+  (exit $ac_status); }; } &&
+        { ac_try='test -s conftest$ac_exeext'
+  { (eval echo "$as_me:$LINENO: \"$ac_try\"") >&5
+  (eval $ac_try) 2>&5
+  ac_status=$?
+  echo "$as_me:$LINENO: \$? = $ac_status" >&5
+  (exit $ac_status); }; }; then
+  eval "$as_ac_var=yes"
+else
+  echo "$as_me: failed program was:" >&5
+sed 's/^/| /' conftest.$ac_ext >&5
+
+eval "$as_ac_var=no"
+fi
+rm -f conftest.err conftest.$ac_objext \
+      conftest$ac_exeext conftest.$ac_ext
+fi
+echo "$as_me:$LINENO: result: `eval echo '${'$as_ac_var'}'`" >&5
+echo "${ECHO_T}`eval echo '${'$as_ac_var'}'`" >&6
+if test `eval echo '${'$as_ac_var'}'` = yes; then
+  cat >>confdefs.h <<_ACEOF
+#define `echo "HAVE_$ac_func" | $as_tr_cpp` 1
+_ACEOF
+
+fi
+done
+
+
+
+for ac_func in snprintf vsnprintf
+do
+as_ac_var=`echo "ac_cv_func_$ac_func" | $as_tr_sh`
+echo "$as_me:$LINENO: checking for $ac_func" >&5
+echo $ECHO_N "checking for $ac_func... $ECHO_C" >&6
+if eval "test \"\${$as_ac_var+set}\" = set"; then
+  echo $ECHO_N "(cached) $ECHO_C" >&6
+else
+  cat >conftest.$ac_ext <<_ACEOF
+/* confdefs.h.  */
+_ACEOF
+cat confdefs.h >>conftest.$ac_ext
+cat >>conftest.$ac_ext <<_ACEOF
+/* end confdefs.h.  */
+/* Define $ac_func to an innocuous variant, in case <limits.h> declares $ac_func.
+   For example, HP-UX 11i <limits.h> declares gettimeofday.  */
+#define $ac_func innocuous_$ac_func
+
+/* System header to define __stub macros and hopefully few prototypes,
+    which can conflict with char $ac_func (); below.
+    Prefer <limits.h> to <assert.h> if __STDC__ is defined, since
+    <limits.h> exists even on freestanding compilers.  */
+
+#ifdef __STDC__
+# include <limits.h>
+#else
+# include <assert.h>
+#endif
+
+#undef $ac_func
+
+/* Override any gcc2 internal prototype to avoid an error.  */
+#ifdef __cplusplus
+extern "C"
+{
+#endif
+/* We use char because int might match the return type of a gcc2
+   builtin and then its argument prototype would still apply.  */
+char $ac_func ();
+/* The GNU C library defines this for functions which it implements
+    to always fail with ENOSYS.  Some functions are actually named
+    something starting with __ and the normal name is an alias.  */
+#if defined (__stub_$ac_func) || defined (__stub___$ac_func)
+choke me
+#else
+char (*f) () = $ac_func;
+#endif
+#ifdef __cplusplus
+}
+#endif
+
+int
+main ()
+{
+return f != $ac_func;
+  ;
+  return 0;
+}
+_ACEOF
+rm -f conftest.$ac_objext conftest$ac_exeext
+if { (eval echo "$as_me:$LINENO: \"$ac_link\"") >&5
+  (eval $ac_link) 2>conftest.er1
+  ac_status=$?
+  grep -v '^ *+' conftest.er1 >conftest.err
+  rm -f conftest.er1
+  cat conftest.err >&5
+  echo "$as_me:$LINENO: \$? = $ac_status" >&5
+  (exit $ac_status); } &&
+        { ac_try='test -z "$ac_c_werror_flag"
+                        || test ! -s conftest.err'
+  { (eval echo "$as_me:$LINENO: \"$ac_try\"") >&5
+  (eval $ac_try) 2>&5
+  ac_status=$?
+  echo "$as_me:$LINENO: \$? = $ac_status" >&5
+  (exit $ac_status); }; } &&
+        { ac_try='test -s conftest$ac_exeext'
+  { (eval echo "$as_me:$LINENO: \"$ac_try\"") >&5
+  (eval $ac_try) 2>&5
+  ac_status=$?
+  echo "$as_me:$LINENO: \$? = $ac_status" >&5
+  (exit $ac_status); }; }; then
+  eval "$as_ac_var=yes"
+else
+  echo "$as_me: failed program was:" >&5
+sed 's/^/| /' conftest.$ac_ext >&5
+
+eval "$as_ac_var=no"
+fi
+rm -f conftest.err conftest.$ac_objext \
+      conftest$ac_exeext conftest.$ac_ext
+fi
+echo "$as_me:$LINENO: result: `eval echo '${'$as_ac_var'}'`" >&5
+echo "${ECHO_T}`eval echo '${'$as_ac_var'}'`" >&6
+if test `eval echo '${'$as_ac_var'}'` = yes; then
+  cat >>confdefs.h <<_ACEOF
+#define `echo "HAVE_$ac_func" | $as_tr_cpp` 1
+_ACEOF
+
+fi
+done
+
+
+
+for ac_func in gmtime gmtime_r
+do
+as_ac_var=`echo "ac_cv_func_$ac_func" | $as_tr_sh`
+echo "$as_me:$LINENO: checking for $ac_func" >&5
+echo $ECHO_N "checking for $ac_func... $ECHO_C" >&6
+if eval "test \"\${$as_ac_var+set}\" = set"; then
+  echo $ECHO_N "(cached) $ECHO_C" >&6
+else
+  cat >conftest.$ac_ext <<_ACEOF
+/* confdefs.h.  */
+_ACEOF
+cat confdefs.h >>conftest.$ac_ext
+cat >>conftest.$ac_ext <<_ACEOF
+/* end confdefs.h.  */
+/* Define $ac_func to an innocuous variant, in case <limits.h> declares $ac_func.
+   For example, HP-UX 11i <limits.h> declares gettimeofday.  */
+#define $ac_func innocuous_$ac_func
+
+/* System header to define __stub macros and hopefully few prototypes,
+    which can conflict with char $ac_func (); below.
+    Prefer <limits.h> to <assert.h> if __STDC__ is defined, since
+    <limits.h> exists even on freestanding compilers.  */
+
+#ifdef __STDC__
+# include <limits.h>
+#else
+# include <assert.h>
+#endif
+
+#undef $ac_func
+
+/* Override any gcc2 internal prototype to avoid an error.  */
+#ifdef __cplusplus
+extern "C"
+{
+#endif
+/* We use char because int might match the return type of a gcc2
+   builtin and then its argument prototype would still apply.  */
+char $ac_func ();
+/* The GNU C library defines this for functions which it implements
+    to always fail with ENOSYS.  Some functions are actually named
+    something starting with __ and the normal name is an alias.  */
+#if defined (__stub_$ac_func) || defined (__stub___$ac_func)
+choke me
+#else
+char (*f) () = $ac_func;
+#endif
+#ifdef __cplusplus
+}
+#endif
+
+int
+main ()
+{
+return f != $ac_func;
+  ;
+  return 0;
+}
+_ACEOF
+rm -f conftest.$ac_objext conftest$ac_exeext
+if { (eval echo "$as_me:$LINENO: \"$ac_link\"") >&5
+  (eval $ac_link) 2>conftest.er1
+  ac_status=$?
+  grep -v '^ *+' conftest.er1 >conftest.err
+  rm -f conftest.er1
+  cat conftest.err >&5
+  echo "$as_me:$LINENO: \$? = $ac_status" >&5
+  (exit $ac_status); } &&
+        { ac_try='test -z "$ac_c_werror_flag"
+                        || test ! -s conftest.err'
+  { (eval echo "$as_me:$LINENO: \"$ac_try\"") >&5
+  (eval $ac_try) 2>&5
+  ac_status=$?
+  echo "$as_me:$LINENO: \$? = $ac_status" >&5
+  (exit $ac_status); }; } &&
+        { ac_try='test -s conftest$ac_exeext'
+  { (eval echo "$as_me:$LINENO: \"$ac_try\"") >&5
+  (eval $ac_try) 2>&5
+  ac_status=$?
+  echo "$as_me:$LINENO: \$? = $ac_status" >&5
+  (exit $ac_status); }; }; then
+  eval "$as_ac_var=yes"
+else
+  echo "$as_me: failed program was:" >&5
+sed 's/^/| /' conftest.$ac_ext >&5
+
+eval "$as_ac_var=no"
+fi
+rm -f conftest.err conftest.$ac_objext \
+      conftest$ac_exeext conftest.$ac_ext
+fi
+echo "$as_me:$LINENO: result: `eval echo '${'$as_ac_var'}'`" >&5
+echo "${ECHO_T}`eval echo '${'$as_ac_var'}'`" >&6
+if test `eval echo '${'$as_ac_var'}'` = yes; then
+  cat >>confdefs.h <<_ACEOF
+#define `echo "HAVE_$ac_func" | $as_tr_cpp` 1
+_ACEOF
+
+fi
+done
+
+
+
+for ac_func in mmap getpagesize
+do
+as_ac_var=`echo "ac_cv_func_$ac_func" | $as_tr_sh`
+echo "$as_me:$LINENO: checking for $ac_func" >&5
+echo $ECHO_N "checking for $ac_func... $ECHO_C" >&6
+if eval "test \"\${$as_ac_var+set}\" = set"; then
+  echo $ECHO_N "(cached) $ECHO_C" >&6
+else
+  cat >conftest.$ac_ext <<_ACEOF
+/* confdefs.h.  */
+_ACEOF
+cat confdefs.h >>conftest.$ac_ext
+cat >>conftest.$ac_ext <<_ACEOF
+/* end confdefs.h.  */
+/* Define $ac_func to an innocuous variant, in case <limits.h> declares $ac_func.
+   For example, HP-UX 11i <limits.h> declares gettimeofday.  */
+#define $ac_func innocuous_$ac_func
+
+/* System header to define __stub macros and hopefully few prototypes,
+    which can conflict with char $ac_func (); below.
+    Prefer <limits.h> to <assert.h> if __STDC__ is defined, since
+    <limits.h> exists even on freestanding compilers.  */
+
+#ifdef __STDC__
+# include <limits.h>
+#else
+# include <assert.h>
+#endif
+
+#undef $ac_func
+
+/* Override any gcc2 internal prototype to avoid an error.  */
+#ifdef __cplusplus
+extern "C"
+{
+#endif
+/* We use char because int might match the return type of a gcc2
+   builtin and then its argument prototype would still apply.  */
+char $ac_func ();
+/* The GNU C library defines this for functions which it implements
+    to always fail with ENOSYS.  Some functions are actually named
+    something starting with __ and the normal name is an alias.  */
+#if defined (__stub_$ac_func) || defined (__stub___$ac_func)
+choke me
+#else
+char (*f) () = $ac_func;
+#endif
+#ifdef __cplusplus
+}
+#endif
+
+int
+main ()
+{
+return f != $ac_func;
+  ;
+  return 0;
+}
+_ACEOF
+rm -f conftest.$ac_objext conftest$ac_exeext
+if { (eval echo "$as_me:$LINENO: \"$ac_link\"") >&5
+  (eval $ac_link) 2>conftest.er1
+  ac_status=$?
+  grep -v '^ *+' conftest.er1 >conftest.err
+  rm -f conftest.er1
+  cat conftest.err >&5
+  echo "$as_me:$LINENO: \$? = $ac_status" >&5
+  (exit $ac_status); } &&
+        { ac_try='test -z "$ac_c_werror_flag"
+                        || test ! -s conftest.err'
+  { (eval echo "$as_me:$LINENO: \"$ac_try\"") >&5
+  (eval $ac_try) 2>&5
+  ac_status=$?
+  echo "$as_me:$LINENO: \$? = $ac_status" >&5
+  (exit $ac_status); }; } &&
+        { ac_try='test -s conftest$ac_exeext'
+  { (eval echo "$as_me:$LINENO: \"$ac_try\"") >&5
+  (eval $ac_try) 2>&5
+  ac_status=$?
+  echo "$as_me:$LINENO: \$? = $ac_status" >&5
+  (exit $ac_status); }; }; then
+  eval "$as_ac_var=yes"
+else
+  echo "$as_me: failed program was:" >&5
+sed 's/^/| /' conftest.$ac_ext >&5
+
+eval "$as_ac_var=no"
+fi
+rm -f conftest.err conftest.$ac_objext \
+      conftest$ac_exeext conftest.$ac_ext
+fi
+echo "$as_me:$LINENO: result: `eval echo '${'$as_ac_var'}'`" >&5
+echo "${ECHO_T}`eval echo '${'$as_ac_var'}'`" >&6
+if test `eval echo '${'$as_ac_var'}'` = yes; then
+  cat >>confdefs.h <<_ACEOF
+#define `echo "HAVE_$ac_func" | $as_tr_cpp` 1
+_ACEOF
+
+fi
+done
+
+
+for ac_func in setlocale
+do
+as_ac_var=`echo "ac_cv_func_$ac_func" | $as_tr_sh`
+echo "$as_me:$LINENO: checking for $ac_func" >&5
+echo $ECHO_N "checking for $ac_func... $ECHO_C" >&6
+if eval "test \"\${$as_ac_var+set}\" = set"; then
+  echo $ECHO_N "(cached) $ECHO_C" >&6
+else
+  cat >conftest.$ac_ext <<_ACEOF
+/* confdefs.h.  */
+_ACEOF
+cat confdefs.h >>conftest.$ac_ext
+cat >>conftest.$ac_ext <<_ACEOF
+/* end confdefs.h.  */
+/* Define $ac_func to an innocuous variant, in case <limits.h> declares $ac_func.
+   For example, HP-UX 11i <limits.h> declares gettimeofday.  */
+#define $ac_func innocuous_$ac_func
+
+/* System header to define __stub macros and hopefully few prototypes,
+    which can conflict with char $ac_func (); below.
+    Prefer <limits.h> to <assert.h> if __STDC__ is defined, since
+    <limits.h> exists even on freestanding compilers.  */
+
+#ifdef __STDC__
+# include <limits.h>
+#else
+# include <assert.h>
+#endif
+
+#undef $ac_func
+
+/* Override any gcc2 internal prototype to avoid an error.  */
+#ifdef __cplusplus
+extern "C"
+{
+#endif
+/* We use char because int might match the return type of a gcc2
+   builtin and then its argument prototype would still apply.  */
+char $ac_func ();
+/* The GNU C library defines this for functions which it implements
+    to always fail with ENOSYS.  Some functions are actually named
+    something starting with __ and the normal name is an alias.  */
+#if defined (__stub_$ac_func) || defined (__stub___$ac_func)
+choke me
+#else
+char (*f) () = $ac_func;
+#endif
+#ifdef __cplusplus
+}
+#endif
+
+int
+main ()
+{
+return f != $ac_func;
+  ;
+  return 0;
+}
+_ACEOF
+rm -f conftest.$ac_objext conftest$ac_exeext
+if { (eval echo "$as_me:$LINENO: \"$ac_link\"") >&5
+  (eval $ac_link) 2>conftest.er1
+  ac_status=$?
+  grep -v '^ *+' conftest.er1 >conftest.err
+  rm -f conftest.er1
+  cat conftest.err >&5
+  echo "$as_me:$LINENO: \$? = $ac_status" >&5
+  (exit $ac_status); } &&
+        { ac_try='test -z "$ac_c_werror_flag"
+                        || test ! -s conftest.err'
+  { (eval echo "$as_me:$LINENO: \"$ac_try\"") >&5
+  (eval $ac_try) 2>&5
+  ac_status=$?
+  echo "$as_me:$LINENO: \$? = $ac_status" >&5
+  (exit $ac_status); }; } &&
+        { ac_try='test -s conftest$ac_exeext'
+  { (eval echo "$as_me:$LINENO: \"$ac_try\"") >&5
+  (eval $ac_try) 2>&5
+  ac_status=$?
+  echo "$as_me:$LINENO: \$? = $ac_status" >&5
+  (exit $ac_status); }; }; then
+  eval "$as_ac_var=yes"
+else
+  echo "$as_me: failed program was:" >&5
+sed 's/^/| /' conftest.$ac_ext >&5
+
+eval "$as_ac_var=no"
+fi
+rm -f conftest.err conftest.$ac_objext \
+      conftest$ac_exeext conftest.$ac_ext
+fi
+echo "$as_me:$LINENO: result: `eval echo '${'$as_ac_var'}'`" >&5
+echo "${ECHO_T}`eval echo '${'$as_ac_var'}'`" >&6
+if test `eval echo '${'$as_ac_var'}'` = yes; then
+  cat >>confdefs.h <<_ACEOF
+#define `echo "HAVE_$ac_func" | $as_tr_cpp` 1
+_ACEOF
+
+fi
+done
+
+
+
+echo "$as_me:$LINENO: checking for floor in -lm" >&5
+echo $ECHO_N "checking for floor in -lm... $ECHO_C" >&6
+if test "${ac_cv_lib_m_floor+set}" = set; then
+  echo $ECHO_N "(cached) $ECHO_C" >&6
+else
+  ac_check_lib_save_LIBS=$LIBS
+LIBS="-lm  $LIBS"
+cat >conftest.$ac_ext <<_ACEOF
+/* confdefs.h.  */
+_ACEOF
+cat confdefs.h >>conftest.$ac_ext
+cat >>conftest.$ac_ext <<_ACEOF
+/* end confdefs.h.  */
+
+/* Override any gcc2 internal prototype to avoid an error.  */
+#ifdef __cplusplus
+extern "C"
+#endif
+/* We use char because int might match the return type of a gcc2
+   builtin and then its argument prototype would still apply.  */
+char floor ();
+int
+main ()
+{
+floor ();
+  ;
+  return 0;
+}
+_ACEOF
+rm -f conftest.$ac_objext conftest$ac_exeext
+if { (eval echo "$as_me:$LINENO: \"$ac_link\"") >&5
+  (eval $ac_link) 2>conftest.er1
+  ac_status=$?
+  grep -v '^ *+' conftest.er1 >conftest.err
+  rm -f conftest.er1
+  cat conftest.err >&5
+  echo "$as_me:$LINENO: \$? = $ac_status" >&5
+  (exit $ac_status); } &&
+        { ac_try='test -z "$ac_c_werror_flag"
+                        || test ! -s conftest.err'
+  { (eval echo "$as_me:$LINENO: \"$ac_try\"") >&5
+  (eval $ac_try) 2>&5
+  ac_status=$?
+  echo "$as_me:$LINENO: \$? = $ac_status" >&5
+  (exit $ac_status); }; } &&
+        { ac_try='test -s conftest$ac_exeext'
+  { (eval echo "$as_me:$LINENO: \"$ac_try\"") >&5
+  (eval $ac_try) 2>&5
+  ac_status=$?
+  echo "$as_me:$LINENO: \$? = $ac_status" >&5
+  (exit $ac_status); }; }; then
+  ac_cv_lib_m_floor=yes
+else
+  echo "$as_me: failed program was:" >&5
+sed 's/^/| /' conftest.$ac_ext >&5
+
+ac_cv_lib_m_floor=no
+fi
+rm -f conftest.err conftest.$ac_objext \
+      conftest$ac_exeext conftest.$ac_ext
+LIBS=$ac_check_lib_save_LIBS
+fi
+echo "$as_me:$LINENO: result: $ac_cv_lib_m_floor" >&5
+echo "${ECHO_T}$ac_cv_lib_m_floor" >&6
+if test $ac_cv_lib_m_floor = yes; then
+  cat >>confdefs.h <<_ACEOF
+#define HAVE_LIBM 1
+_ACEOF
+
+  LIBS="-lm $LIBS"
+
+fi
+
+
+
+
+for ac_func in floor ceil fmod
+do
+as_ac_var=`echo "ac_cv_func_$ac_func" | $as_tr_sh`
+echo "$as_me:$LINENO: checking for $ac_func" >&5
+echo $ECHO_N "checking for $ac_func... $ECHO_C" >&6
+if eval "test \"\${$as_ac_var+set}\" = set"; then
+  echo $ECHO_N "(cached) $ECHO_C" >&6
+else
+  cat >conftest.$ac_ext <<_ACEOF
+/* confdefs.h.  */
+_ACEOF
+cat confdefs.h >>conftest.$ac_ext
+cat >>conftest.$ac_ext <<_ACEOF
+/* end confdefs.h.  */
+/* Define $ac_func to an innocuous variant, in case <limits.h> declares $ac_func.
+   For example, HP-UX 11i <limits.h> declares gettimeofday.  */
+#define $ac_func innocuous_$ac_func
+
+/* System header to define __stub macros and hopefully few prototypes,
+    which can conflict with char $ac_func (); below.
+    Prefer <limits.h> to <assert.h> if __STDC__ is defined, since
+    <limits.h> exists even on freestanding compilers.  */
+
+#ifdef __STDC__
+# include <limits.h>
+#else
+# include <assert.h>
+#endif
+
+#undef $ac_func
+
+/* Override any gcc2 internal prototype to avoid an error.  */
+#ifdef __cplusplus
+extern "C"
+{
+#endif
+/* We use char because int might match the return type of a gcc2
+   builtin and then its argument prototype would still apply.  */
+char $ac_func ();
+/* The GNU C library defines this for functions which it implements
+    to always fail with ENOSYS.  Some functions are actually named
+    something starting with __ and the normal name is an alias.  */
+#if defined (__stub_$ac_func) || defined (__stub___$ac_func)
+choke me
+#else
+char (*f) () = $ac_func;
+#endif
+#ifdef __cplusplus
+}
+#endif
+
+int
+main ()
+{
+return f != $ac_func;
+  ;
+  return 0;
+}
+_ACEOF
+rm -f conftest.$ac_objext conftest$ac_exeext
+if { (eval echo "$as_me:$LINENO: \"$ac_link\"") >&5
+  (eval $ac_link) 2>conftest.er1
+  ac_status=$?
+  grep -v '^ *+' conftest.er1 >conftest.err
+  rm -f conftest.er1
+  cat conftest.err >&5
+  echo "$as_me:$LINENO: \$? = $ac_status" >&5
+  (exit $ac_status); } &&
+        { ac_try='test -z "$ac_c_werror_flag"
+                        || test ! -s conftest.err'
+  { (eval echo "$as_me:$LINENO: \"$ac_try\"") >&5
+  (eval $ac_try) 2>&5
+  ac_status=$?
+  echo "$as_me:$LINENO: \$? = $ac_status" >&5
+  (exit $ac_status); }; } &&
+        { ac_try='test -s conftest$ac_exeext'
+  { (eval echo "$as_me:$LINENO: \"$ac_try\"") >&5
+  (eval $ac_try) 2>&5
+  ac_status=$?
+  echo "$as_me:$LINENO: \$? = $ac_status" >&5
+  (exit $ac_status); }; }; then
+  eval "$as_ac_var=yes"
+else
+  echo "$as_me: failed program was:" >&5
+sed 's/^/| /' conftest.$ac_ext >&5
+
+eval "$as_ac_var=no"
+fi
+rm -f conftest.err conftest.$ac_objext \
+      conftest$ac_exeext conftest.$ac_ext
+fi
+echo "$as_me:$LINENO: result: `eval echo '${'$as_ac_var'}'`" >&5
+echo "${ECHO_T}`eval echo '${'$as_ac_var'}'`" >&6
+if test `eval echo '${'$as_ac_var'}'` = yes; then
+  cat >>confdefs.h <<_ACEOF
+#define `echo "HAVE_$ac_func" | $as_tr_cpp` 1
+_ACEOF
+
+fi
+done
+
+
+case "$host_os" in
+       cygwin*)
+               { echo "$as_me:$LINENO: WARNING: Not using built-in lrint() and lrintf() because they are broken on Cygwin." >&5
+echo "$as_me: WARNING: Not using built-in lrint() and lrintf() because they are broken on Cygwin." >&2;}
+               ;;
+       *)
+               echo "$as_me:$LINENO: checking for lrint" >&5
+echo $ECHO_N "checking for lrint... $ECHO_C" >&6
+if test "${ac_cv_c99_lrint+set}" = set; then
+  echo $ECHO_N "(cached) $ECHO_C" >&6
+else
+
+lrint_save_CFLAGS=$CFLAGS
+CFLAGS="-O2 -lm"
+cat >conftest.$ac_ext <<_ACEOF
+/* confdefs.h.  */
+_ACEOF
+cat confdefs.h >>conftest.$ac_ext
+cat >>conftest.$ac_ext <<_ACEOF
+/* end confdefs.h.  */
+
+#define                _ISOC9X_SOURCE  1
+#define        _ISOC99_SOURCE  1
+#define                __USE_ISOC99    1
+#define        __USE_ISOC9X    1
+
+#include <math.h>
+
+int
+main ()
+{
+if (!lrint(3.14159)) lrint(2.7183);
+  ;
+  return 0;
+}
+_ACEOF
+rm -f conftest.$ac_objext conftest$ac_exeext
+if { (eval echo "$as_me:$LINENO: \"$ac_link\"") >&5
+  (eval $ac_link) 2>conftest.er1
+  ac_status=$?
+  grep -v '^ *+' conftest.er1 >conftest.err
+  rm -f conftest.er1
+  cat conftest.err >&5
+  echo "$as_me:$LINENO: \$? = $ac_status" >&5
+  (exit $ac_status); } &&
+        { ac_try='test -z "$ac_c_werror_flag"
+                        || test ! -s conftest.err'
+  { (eval echo "$as_me:$LINENO: \"$ac_try\"") >&5
+  (eval $ac_try) 2>&5
+  ac_status=$?
+  echo "$as_me:$LINENO: \$? = $ac_status" >&5
+  (exit $ac_status); }; } &&
+        { ac_try='test -s conftest$ac_exeext'
+  { (eval echo "$as_me:$LINENO: \"$ac_try\"") >&5
+  (eval $ac_try) 2>&5
+  ac_status=$?
+  echo "$as_me:$LINENO: \$? = $ac_status" >&5
+  (exit $ac_status); }; }; then
+  ac_cv_c99_lrint=yes
+else
+  echo "$as_me: failed program was:" >&5
+sed 's/^/| /' conftest.$ac_ext >&5
+
+ac_cv_c99_lrint=no
+fi
+rm -f conftest.err conftest.$ac_objext \
+      conftest$ac_exeext conftest.$ac_ext
+
+CFLAGS=$lrint_save_CFLAGS
+
+
+fi
+echo "$as_me:$LINENO: result: $ac_cv_c99_lrint" >&5
+echo "${ECHO_T}$ac_cv_c99_lrint" >&6
+
+if test "$ac_cv_c99_lrint" = yes; then
+
+cat >>confdefs.h <<\_ACEOF
+#define HAVE_LRINT 1
+_ACEOF
+
+fi
+
+               echo "$as_me:$LINENO: checking for lrintf" >&5
+echo $ECHO_N "checking for lrintf... $ECHO_C" >&6
+if test "${ac_cv_c99_lrintf+set}" = set; then
+  echo $ECHO_N "(cached) $ECHO_C" >&6
+else
+
+lrintf_save_CFLAGS=$CFLAGS
+CFLAGS="-O2 -lm"
+cat >conftest.$ac_ext <<_ACEOF
+/* confdefs.h.  */
+_ACEOF
+cat confdefs.h >>conftest.$ac_ext
+cat >>conftest.$ac_ext <<_ACEOF
+/* end confdefs.h.  */
+
+#define                _ISOC9X_SOURCE  1
+#define        _ISOC99_SOURCE  1
+#define                __USE_ISOC99    1
+#define        __USE_ISOC9X    1
+
+#include <math.h>
+
+int
+main ()
+{
+if (!lrintf(3.14159)) lrintf(2.7183);
+  ;
+  return 0;
+}
+_ACEOF
+rm -f conftest.$ac_objext conftest$ac_exeext
+if { (eval echo "$as_me:$LINENO: \"$ac_link\"") >&5
+  (eval $ac_link) 2>conftest.er1
+  ac_status=$?
+  grep -v '^ *+' conftest.er1 >conftest.err
+  rm -f conftest.er1
+  cat conftest.err >&5
+  echo "$as_me:$LINENO: \$? = $ac_status" >&5
+  (exit $ac_status); } &&
+        { ac_try='test -z "$ac_c_werror_flag"
+                        || test ! -s conftest.err'
+  { (eval echo "$as_me:$LINENO: \"$ac_try\"") >&5
+  (eval $ac_try) 2>&5
+  ac_status=$?
+  echo "$as_me:$LINENO: \$? = $ac_status" >&5
+  (exit $ac_status); }; } &&
+        { ac_try='test -s conftest$ac_exeext'
+  { (eval echo "$as_me:$LINENO: \"$ac_try\"") >&5
+  (eval $ac_try) 2>&5
+  ac_status=$?
+  echo "$as_me:$LINENO: \$? = $ac_status" >&5
+  (exit $ac_status); }; }; then
+  ac_cv_c99_lrintf=yes
+else
+  echo "$as_me: failed program was:" >&5
+sed 's/^/| /' conftest.$ac_ext >&5
+
+ac_cv_c99_lrintf=no
+fi
+rm -f conftest.err conftest.$ac_objext \
+      conftest$ac_exeext conftest.$ac_ext
+
+CFLAGS=$lrintf_save_CFLAGS
+
+
+fi
+echo "$as_me:$LINENO: result: $ac_cv_c99_lrintf" >&5
+echo "${ECHO_T}$ac_cv_c99_lrintf" >&6
+
+if test "$ac_cv_c99_lrintf" = yes; then
+
+cat >>confdefs.h <<\_ACEOF
+#define HAVE_LRINTF 1
+_ACEOF
+
+fi
+
+
+               if test "x$ac_cv_c99_lrint" = "xno" ; then
+                       if test "x$ac_cv_c99_lrintf" = "xno" ; then
+                               { echo "$as_me:$LINENO: WARNING: *** Missing C99 standard functions lrint() and lrintf()." >&5
+echo "$as_me: WARNING: *** Missing C99 standard functions lrint() and lrintf()." >&2;}
+                               { echo "$as_me:$LINENO: WARNING: *** This may cause benign compiler warnings on some systems (ie Solaris)." >&5
+echo "$as_me: WARNING: *** This may cause benign compiler warnings on some systems (ie Solaris)." >&2;}
+                               fi
+                       fi
+               ;;
+       esac
+
+#====================================================================================
+# Check for libsqlite3 (only used in regtest).
+
+ac_cv_sqlite3=no
+if test x$enable_sqlite != xno ; then
+
+  succeeded=no
+
+  if test -z "$PKG_CONFIG"; then
+    # Extract the first word of "pkg-config", so it can be a program name with args.
+set dummy pkg-config; ac_word=$2
+echo "$as_me:$LINENO: checking for $ac_word" >&5
+echo $ECHO_N "checking for $ac_word... $ECHO_C" >&6
+if test "${ac_cv_path_PKG_CONFIG+set}" = set; then
+  echo $ECHO_N "(cached) $ECHO_C" >&6
+else
+  case $PKG_CONFIG in
+  [\\/]* | ?:[\\/]*)
+  ac_cv_path_PKG_CONFIG="$PKG_CONFIG" # Let the user override the test with a path.
+  ;;
+  *)
+  as_save_IFS=$IFS; IFS=$PATH_SEPARATOR
+for as_dir in $PATH
+do
+  IFS=$as_save_IFS
+  test -z "$as_dir" && as_dir=.
+  for ac_exec_ext in '' $ac_executable_extensions; do
+  if $as_executable_p "$as_dir/$ac_word$ac_exec_ext"; then
+    ac_cv_path_PKG_CONFIG="$as_dir/$ac_word$ac_exec_ext"
+    echo "$as_me:$LINENO: found $as_dir/$ac_word$ac_exec_ext" >&5
+    break 2
+  fi
+done
+done
+
+  test -z "$ac_cv_path_PKG_CONFIG" && ac_cv_path_PKG_CONFIG="no"
+  ;;
+esac
+fi
+PKG_CONFIG=$ac_cv_path_PKG_CONFIG
+
+if test -n "$PKG_CONFIG"; then
+  echo "$as_me:$LINENO: result: $PKG_CONFIG" >&5
+echo "${ECHO_T}$PKG_CONFIG" >&6
+else
+  echo "$as_me:$LINENO: result: no" >&5
+echo "${ECHO_T}no" >&6
+fi
+
+  fi
+
+  if test "$PKG_CONFIG" = "no" ; then
+     echo "*** The pkg-config script could not be found. Make sure it is"
+     echo "*** in your path, or set the PKG_CONFIG environment variable"
+     echo "*** to the full path to pkg-config."
+     echo "*** Or see http://www.freedesktop.org/software/pkgconfig to get pkg-config."
+  else
+     PKG_CONFIG_MIN_VERSION=0.9.0
+     if $PKG_CONFIG --atleast-pkgconfig-version $PKG_CONFIG_MIN_VERSION; then
+        echo "$as_me:$LINENO: checking for sqlite3 >= 3.2" >&5
+echo $ECHO_N "checking for sqlite3 >= 3.2... $ECHO_C" >&6
+
+        if $PKG_CONFIG --exists "sqlite3 >= 3.2" ; then
+            echo "$as_me:$LINENO: result: yes" >&5
+echo "${ECHO_T}yes" >&6
+            succeeded=yes
+
+            echo "$as_me:$LINENO: checking SQLITE3_CFLAGS" >&5
+echo $ECHO_N "checking SQLITE3_CFLAGS... $ECHO_C" >&6
+            SQLITE3_CFLAGS=`$PKG_CONFIG --cflags "sqlite3 >= 3.2"`
+            echo "$as_me:$LINENO: result: $SQLITE3_CFLAGS" >&5
+echo "${ECHO_T}$SQLITE3_CFLAGS" >&6
+
+            echo "$as_me:$LINENO: checking SQLITE3_LIBS" >&5
+echo $ECHO_N "checking SQLITE3_LIBS... $ECHO_C" >&6
+            SQLITE3_LIBS=`$PKG_CONFIG --libs "sqlite3 >= 3.2"`
+            echo "$as_me:$LINENO: result: $SQLITE3_LIBS" >&5
+echo "${ECHO_T}$SQLITE3_LIBS" >&6
+        else
+            SQLITE3_CFLAGS=""
+            SQLITE3_LIBS=""
+            ## If we have a custom action on failure, don't print errors, but
+            ## do set a variable so people can do so.
+            SQLITE3_PKG_ERRORS=`$PKG_CONFIG --errors-to-stdout --print-errors "sqlite3 >= 3.2"`
+
+        fi
+
+
+
+     else
+        echo "*** Your version of pkg-config is too old. You need version $PKG_CONFIG_MIN_VERSION or newer."
+        echo "*** See http://www.freedesktop.org/software/pkgconfig"
+     fi
+  fi
+
+  if test $succeeded = yes; then
+     ac_cv_sqlite3=yes
+  else
+     ac_cv_sqlite3=no
+  fi
+
+       fi
+
+if test x$ac_cv_sqlite3 = "xyes" ; then
+       HAVE_SQLITE3=1
+else
+       HAVE_SQLITE3=0
+       fi
+
+
+cat >>confdefs.h <<_ACEOF
+#define HAVE_SQLITE3 $HAVE_SQLITE3
+_ACEOF
+
+
+#====================================================================================
+# Determine if the processor can do clipping on float to int conversions.
+
+if test x$enable_cpu_clip != "xno" ; then
+       echo "$as_me:$LINENO: checking processor clipping capabilities" >&5
+echo $ECHO_N "checking processor clipping capabilities... $ECHO_C" >&6
+if test "${ac_cv_c_clip_type+set}" = set; then
+  echo $ECHO_N "(cached) $ECHO_C" >&6
+else
+  # Initialize to unknown
+ac_cv_c_clip_positive=unknown
+ac_cv_c_clip_negative=unknown
+
+if test $ac_cv_c_clip_positive = unknown ; then
+       if test "$cross_compiling" = yes; then
+  ac_cv_c_clip_positive=unknown
+
+else
+  cat >conftest.$ac_ext <<_ACEOF
+/* confdefs.h.  */
+_ACEOF
+cat confdefs.h >>conftest.$ac_ext
+cat >>conftest.$ac_ext <<_ACEOF
+/* end confdefs.h.  */
+
+       #define _ISOC9X_SOURCE  1
+       #define _ISOC99_SOURCE  1
+       #define __USE_ISOC99    1
+       #define __USE_ISOC9X    1
+       #include <math.h>
+       int main (void)
+       {       double  fval ;
+               int k, ival ;
+
+               fval = 1.0 * 0x7FFFFFFF ;
+               for (k = 0 ; k < 100 ; k++)
+               {       ival = (lrint (fval)) >> 24 ;
+                       if (ival != 127)
+                               return 1 ;
+
+                       fval *= 1.2499999 ;
+                       } ;
+
+                       return 0 ;
+               }
+
+_ACEOF
+rm -f conftest$ac_exeext
+if { (eval echo "$as_me:$LINENO: \"$ac_link\"") >&5
+  (eval $ac_link) 2>&5
+  ac_status=$?
+  echo "$as_me:$LINENO: \$? = $ac_status" >&5
+  (exit $ac_status); } && { ac_try='./conftest$ac_exeext'
+  { (eval echo "$as_me:$LINENO: \"$ac_try\"") >&5
+  (eval $ac_try) 2>&5
+  ac_status=$?
+  echo "$as_me:$LINENO: \$? = $ac_status" >&5
+  (exit $ac_status); }; }; then
+  ac_cv_c_clip_positive=yes
+else
+  echo "$as_me: program exited with status $ac_status" >&5
+echo "$as_me: failed program was:" >&5
+sed 's/^/| /' conftest.$ac_ext >&5
+
+( exit $ac_status )
+ac_cv_c_clip_positive=no
+fi
+rm -f core *.core gmon.out bb.out conftest$ac_exeext conftest.$ac_objext conftest.$ac_ext
+fi
+
+       if test "$cross_compiling" = yes; then
+  ac_cv_c_clip_negative=unknown
+
+else
+  cat >conftest.$ac_ext <<_ACEOF
+/* confdefs.h.  */
+_ACEOF
+cat confdefs.h >>conftest.$ac_ext
+cat >>conftest.$ac_ext <<_ACEOF
+/* end confdefs.h.  */
+
+       #define _ISOC9X_SOURCE  1
+       #define _ISOC99_SOURCE  1
+       #define __USE_ISOC99    1
+       #define __USE_ISOC9X    1
+       #include <math.h>
+       int main (void)
+       {       double  fval ;
+               int k, ival ;
+
+               fval = -8.0 * 0x10000000 ;
+               for (k = 0 ; k < 100 ; k++)
+               {       ival = (lrint (fval)) >> 24 ;
+                       if (ival != -128)
+                               return 1 ;
+
+                       fval *= 1.2499999 ;
+                       } ;
+
+                       return 0 ;
+               }
+
+_ACEOF
+rm -f conftest$ac_exeext
+if { (eval echo "$as_me:$LINENO: \"$ac_link\"") >&5
+  (eval $ac_link) 2>&5
+  ac_status=$?
+  echo "$as_me:$LINENO: \$? = $ac_status" >&5
+  (exit $ac_status); } && { ac_try='./conftest$ac_exeext'
+  { (eval echo "$as_me:$LINENO: \"$ac_try\"") >&5
+  (eval $ac_try) 2>&5
+  ac_status=$?
+  echo "$as_me:$LINENO: \$? = $ac_status" >&5
+  (exit $ac_status); }; }; then
+  ac_cv_c_clip_negative=yes
+else
+  echo "$as_me: program exited with status $ac_status" >&5
+echo "$as_me: failed program was:" >&5
+sed 's/^/| /' conftest.$ac_ext >&5
+
+( exit $ac_status )
+ac_cv_c_clip_negative=no
+fi
+rm -f core *.core gmon.out bb.out conftest$ac_exeext conftest.$ac_objext conftest.$ac_ext
+fi
+       fi
+
+if test $ac_cv_c_clip_positive = yes ; then
+       ac_cv_c_clip_positive=1
+else
+       ac_cv_c_clip_positive=0
+       fi
+
+if test $ac_cv_c_clip_negative = yes ; then
+       ac_cv_c_clip_negative=1
+else
+       ac_cv_c_clip_negative=0
+       fi
+
+
+case "$ac_cv_c_clip_positive$ac_cv_c_clip_negative" in
+       "00")
+               ac_cv_c_clip_type="none"
+               ;;
+       "10")
+               ac_cv_c_clip_type="positive"
+               ;;
+       "01")
+               ac_cv_c_clip_type="negative"
+               ;;
+       "11")
+               ac_cv_c_clip_type="both"
+               ;;
+       esac
+
+
+
+fi
+echo "$as_me:$LINENO: result: $ac_cv_c_clip_type" >&5
+echo "${ECHO_T}$ac_cv_c_clip_type" >&6
+
+
+
+else
+       echo "checking processor clipping capabilities... disabled"
+       ac_cv_c_clip_positive=0
+       ac_cv_c_clip_negative=0
+       fi
+
+
+cat >>confdefs.h <<_ACEOF
+#define CPU_CLIPS_POSITIVE ${ac_cv_c_clip_positive}
+_ACEOF
+
+
+cat >>confdefs.h <<_ACEOF
+#define CPU_CLIPS_NEGATIVE ${ac_cv_c_clip_negative}
+_ACEOF
+
+
+#====================================================================================
+# Target OS specific stuff.
+
+OS_SPECIFIC_CFLAGS=""
+OS_SPECIFIC_LINKS=""
+os_is_win32=0
+os_is_macosx=0
+use_windows_api=0
+
+case "$host_os" in
+       darwin* | rhapsody*)
+               os_is_macosx=1
+               OS_SPECIFIC_CFLAGS="-fpascal-strings -I/Developer/Headers/FlatCarbon"
+               OS_SPECIFIC_LINKS="-framework CoreAudio"
+               ;;
+       mingw*)
+               os_is_win32=1
+               use_windows_api=1
+               OS_SPECIFIC_LINKS="-lwinmm"
+               ;;
+       cygwin*)
+               os_is_win32=1
+               OS_SPECIFIC_LINKS="-lwinmm"
+               ;;
+       esac
+
+
+cat >>confdefs.h <<_ACEOF
+#define OS_IS_WIN32 ${os_is_win32}
+_ACEOF
+
+
+cat >>confdefs.h <<_ACEOF
+#define OS_IS_MACOSX ${os_is_macosx}
+_ACEOF
+
+
+cat >>confdefs.h <<_ACEOF
+#define USE_WINDOWS_API ${use_windows_api}
+_ACEOF
+
+
+#====================================================================================
+# Check for ALSA.
+
+ALSA_LIBS=""
+
+if test x$enable_alsa != xno ; then
+
+for ac_header in alsa/asoundlib.h
+do
+as_ac_Header=`echo "ac_cv_header_$ac_header" | $as_tr_sh`
+if eval "test \"\${$as_ac_Header+set}\" = set"; then
+  echo "$as_me:$LINENO: checking for $ac_header" >&5
+echo $ECHO_N "checking for $ac_header... $ECHO_C" >&6
+if eval "test \"\${$as_ac_Header+set}\" = set"; then
+  echo $ECHO_N "(cached) $ECHO_C" >&6
+fi
+echo "$as_me:$LINENO: result: `eval echo '${'$as_ac_Header'}'`" >&5
+echo "${ECHO_T}`eval echo '${'$as_ac_Header'}'`" >&6
+else
+  # Is the header compilable?
+echo "$as_me:$LINENO: checking $ac_header usability" >&5
+echo $ECHO_N "checking $ac_header usability... $ECHO_C" >&6
+cat >conftest.$ac_ext <<_ACEOF
+/* confdefs.h.  */
+_ACEOF
+cat confdefs.h >>conftest.$ac_ext
+cat >>conftest.$ac_ext <<_ACEOF
+/* end confdefs.h.  */
+$ac_includes_default
+#include <$ac_header>
+_ACEOF
+rm -f conftest.$ac_objext
+if { (eval echo "$as_me:$LINENO: \"$ac_compile\"") >&5
+  (eval $ac_compile) 2>conftest.er1
+  ac_status=$?
+  grep -v '^ *+' conftest.er1 >conftest.err
+  rm -f conftest.er1
+  cat conftest.err >&5
+  echo "$as_me:$LINENO: \$? = $ac_status" >&5
+  (exit $ac_status); } &&
+        { ac_try='test -z "$ac_c_werror_flag"
+                        || test ! -s conftest.err'
+  { (eval echo "$as_me:$LINENO: \"$ac_try\"") >&5
+  (eval $ac_try) 2>&5
+  ac_status=$?
+  echo "$as_me:$LINENO: \$? = $ac_status" >&5
+  (exit $ac_status); }; } &&
+        { ac_try='test -s conftest.$ac_objext'
+  { (eval echo "$as_me:$LINENO: \"$ac_try\"") >&5
+  (eval $ac_try) 2>&5
+  ac_status=$?
+  echo "$as_me:$LINENO: \$? = $ac_status" >&5
+  (exit $ac_status); }; }; then
+  ac_header_compiler=yes
+else
+  echo "$as_me: failed program was:" >&5
+sed 's/^/| /' conftest.$ac_ext >&5
+
+ac_header_compiler=no
+fi
+rm -f conftest.err conftest.$ac_objext conftest.$ac_ext
+echo "$as_me:$LINENO: result: $ac_header_compiler" >&5
+echo "${ECHO_T}$ac_header_compiler" >&6
+
+# Is the header present?
+echo "$as_me:$LINENO: checking $ac_header presence" >&5
+echo $ECHO_N "checking $ac_header presence... $ECHO_C" >&6
+cat >conftest.$ac_ext <<_ACEOF
+/* confdefs.h.  */
+_ACEOF
+cat confdefs.h >>conftest.$ac_ext
+cat >>conftest.$ac_ext <<_ACEOF
+/* end confdefs.h.  */
+#include <$ac_header>
+_ACEOF
+if { (eval echo "$as_me:$LINENO: \"$ac_cpp conftest.$ac_ext\"") >&5
+  (eval $ac_cpp conftest.$ac_ext) 2>conftest.er1
+  ac_status=$?
+  grep -v '^ *+' conftest.er1 >conftest.err
+  rm -f conftest.er1
+  cat conftest.err >&5
+  echo "$as_me:$LINENO: \$? = $ac_status" >&5
+  (exit $ac_status); } >/dev/null; then
+  if test -s conftest.err; then
+    ac_cpp_err=$ac_c_preproc_warn_flag
+    ac_cpp_err=$ac_cpp_err$ac_c_werror_flag
+  else
+    ac_cpp_err=
+  fi
+else
+  ac_cpp_err=yes
+fi
+if test -z "$ac_cpp_err"; then
+  ac_header_preproc=yes
+else
+  echo "$as_me: failed program was:" >&5
+sed 's/^/| /' conftest.$ac_ext >&5
+
+  ac_header_preproc=no
+fi
+rm -f conftest.err conftest.$ac_ext
+echo "$as_me:$LINENO: result: $ac_header_preproc" >&5
+echo "${ECHO_T}$ac_header_preproc" >&6
+
+# So?  What about this header?
+case $ac_header_compiler:$ac_header_preproc:$ac_c_preproc_warn_flag in
+  yes:no: )
+    { echo "$as_me:$LINENO: WARNING: $ac_header: accepted by the compiler, rejected by the preprocessor!" >&5
+echo "$as_me: WARNING: $ac_header: accepted by the compiler, rejected by the preprocessor!" >&2;}
+    { echo "$as_me:$LINENO: WARNING: $ac_header: proceeding with the compiler's result" >&5
+echo "$as_me: WARNING: $ac_header: proceeding with the compiler's result" >&2;}
+    ac_header_preproc=yes
+    ;;
+  no:yes:* )
+    { echo "$as_me:$LINENO: WARNING: $ac_header: present but cannot be compiled" >&5
+echo "$as_me: WARNING: $ac_header: present but cannot be compiled" >&2;}
+    { echo "$as_me:$LINENO: WARNING: $ac_header:     check for missing prerequisite headers?" >&5
+echo "$as_me: WARNING: $ac_header:     check for missing prerequisite headers?" >&2;}
+    { echo "$as_me:$LINENO: WARNING: $ac_header: see the Autoconf documentation" >&5
+echo "$as_me: WARNING: $ac_header: see the Autoconf documentation" >&2;}
+    { echo "$as_me:$LINENO: WARNING: $ac_header:     section \"Present But Cannot Be Compiled\"" >&5
+echo "$as_me: WARNING: $ac_header:     section \"Present But Cannot Be Compiled\"" >&2;}
+    { echo "$as_me:$LINENO: WARNING: $ac_header: proceeding with the preprocessor's result" >&5
+echo "$as_me: WARNING: $ac_header: proceeding with the preprocessor's result" >&2;}
+    { echo "$as_me:$LINENO: WARNING: $ac_header: in the future, the compiler will take precedence" >&5
+echo "$as_me: WARNING: $ac_header: in the future, the compiler will take precedence" >&2;}
+    (
+      cat <<\_ASBOX
+## -------------------------------- ##
+## Report this to ardour@ardour.org ##
+## -------------------------------- ##
+_ASBOX
+    ) |
+      sed "s/^/$as_me: WARNING:     /" >&2
+    ;;
+esac
+echo "$as_me:$LINENO: checking for $ac_header" >&5
+echo $ECHO_N "checking for $ac_header... $ECHO_C" >&6
+if eval "test \"\${$as_ac_Header+set}\" = set"; then
+  echo $ECHO_N "(cached) $ECHO_C" >&6
+else
+  eval "$as_ac_Header=\$ac_header_preproc"
+fi
+echo "$as_me:$LINENO: result: `eval echo '${'$as_ac_Header'}'`" >&5
+echo "${ECHO_T}`eval echo '${'$as_ac_Header'}'`" >&6
+
+fi
+if test `eval echo '${'$as_ac_Header'}'` = yes; then
+  cat >>confdefs.h <<_ACEOF
+#define `echo "HAVE_$ac_header" | $as_tr_cpp` 1
+_ACEOF
+
+fi
+
+done
+
+       if test x$ac_cv_header_alsa_asoundlib_h = xyes ; then
+               ALSA_LIBS="-lasound"
+               fi
+       fi
+
+#====================================================================================
+# Check for FLAC
+
+FLAC_LIBS=""
+
+if test x$enable_flac != xno ; then
+
+for ac_header in FLAC/all.h
+do
+as_ac_Header=`echo "ac_cv_header_$ac_header" | $as_tr_sh`
+if eval "test \"\${$as_ac_Header+set}\" = set"; then
+  echo "$as_me:$LINENO: checking for $ac_header" >&5
+echo $ECHO_N "checking for $ac_header... $ECHO_C" >&6
+if eval "test \"\${$as_ac_Header+set}\" = set"; then
+  echo $ECHO_N "(cached) $ECHO_C" >&6
+fi
+echo "$as_me:$LINENO: result: `eval echo '${'$as_ac_Header'}'`" >&5
+echo "${ECHO_T}`eval echo '${'$as_ac_Header'}'`" >&6
+else
+  # Is the header compilable?
+echo "$as_me:$LINENO: checking $ac_header usability" >&5
+echo $ECHO_N "checking $ac_header usability... $ECHO_C" >&6
+cat >conftest.$ac_ext <<_ACEOF
+/* confdefs.h.  */
+_ACEOF
+cat confdefs.h >>conftest.$ac_ext
+cat >>conftest.$ac_ext <<_ACEOF
+/* end confdefs.h.  */
+$ac_includes_default
+#include <$ac_header>
+_ACEOF
+rm -f conftest.$ac_objext
+if { (eval echo "$as_me:$LINENO: \"$ac_compile\"") >&5
+  (eval $ac_compile) 2>conftest.er1
+  ac_status=$?
+  grep -v '^ *+' conftest.er1 >conftest.err
+  rm -f conftest.er1
+  cat conftest.err >&5
+  echo "$as_me:$LINENO: \$? = $ac_status" >&5
+  (exit $ac_status); } &&
+        { ac_try='test -z "$ac_c_werror_flag"
+                        || test ! -s conftest.err'
+  { (eval echo "$as_me:$LINENO: \"$ac_try\"") >&5
+  (eval $ac_try) 2>&5
+  ac_status=$?
+  echo "$as_me:$LINENO: \$? = $ac_status" >&5
+  (exit $ac_status); }; } &&
+        { ac_try='test -s conftest.$ac_objext'
+  { (eval echo "$as_me:$LINENO: \"$ac_try\"") >&5
+  (eval $ac_try) 2>&5
+  ac_status=$?
+  echo "$as_me:$LINENO: \$? = $ac_status" >&5
+  (exit $ac_status); }; }; then
+  ac_header_compiler=yes
+else
+  echo "$as_me: failed program was:" >&5
+sed 's/^/| /' conftest.$ac_ext >&5
+
+ac_header_compiler=no
+fi
+rm -f conftest.err conftest.$ac_objext conftest.$ac_ext
+echo "$as_me:$LINENO: result: $ac_header_compiler" >&5
+echo "${ECHO_T}$ac_header_compiler" >&6
+
+# Is the header present?
+echo "$as_me:$LINENO: checking $ac_header presence" >&5
+echo $ECHO_N "checking $ac_header presence... $ECHO_C" >&6
+cat >conftest.$ac_ext <<_ACEOF
+/* confdefs.h.  */
+_ACEOF
+cat confdefs.h >>conftest.$ac_ext
+cat >>conftest.$ac_ext <<_ACEOF
+/* end confdefs.h.  */
+#include <$ac_header>
+_ACEOF
+if { (eval echo "$as_me:$LINENO: \"$ac_cpp conftest.$ac_ext\"") >&5
+  (eval $ac_cpp conftest.$ac_ext) 2>conftest.er1
+  ac_status=$?
+  grep -v '^ *+' conftest.er1 >conftest.err
+  rm -f conftest.er1
+  cat conftest.err >&5
+  echo "$as_me:$LINENO: \$? = $ac_status" >&5
+  (exit $ac_status); } >/dev/null; then
+  if test -s conftest.err; then
+    ac_cpp_err=$ac_c_preproc_warn_flag
+    ac_cpp_err=$ac_cpp_err$ac_c_werror_flag
+  else
+    ac_cpp_err=
+  fi
+else
+  ac_cpp_err=yes
+fi
+if test -z "$ac_cpp_err"; then
+  ac_header_preproc=yes
+else
+  echo "$as_me: failed program was:" >&5
+sed 's/^/| /' conftest.$ac_ext >&5
+
+  ac_header_preproc=no
+fi
+rm -f conftest.err conftest.$ac_ext
+echo "$as_me:$LINENO: result: $ac_header_preproc" >&5
+echo "${ECHO_T}$ac_header_preproc" >&6
+
+# So?  What about this header?
+case $ac_header_compiler:$ac_header_preproc:$ac_c_preproc_warn_flag in
+  yes:no: )
+    { echo "$as_me:$LINENO: WARNING: $ac_header: accepted by the compiler, rejected by the preprocessor!" >&5
+echo "$as_me: WARNING: $ac_header: accepted by the compiler, rejected by the preprocessor!" >&2;}
+    { echo "$as_me:$LINENO: WARNING: $ac_header: proceeding with the compiler's result" >&5
+echo "$as_me: WARNING: $ac_header: proceeding with the compiler's result" >&2;}
+    ac_header_preproc=yes
+    ;;
+  no:yes:* )
+    { echo "$as_me:$LINENO: WARNING: $ac_header: present but cannot be compiled" >&5
+echo "$as_me: WARNING: $ac_header: present but cannot be compiled" >&2;}
+    { echo "$as_me:$LINENO: WARNING: $ac_header:     check for missing prerequisite headers?" >&5
+echo "$as_me: WARNING: $ac_header:     check for missing prerequisite headers?" >&2;}
+    { echo "$as_me:$LINENO: WARNING: $ac_header: see the Autoconf documentation" >&5
+echo "$as_me: WARNING: $ac_header: see the Autoconf documentation" >&2;}
+    { echo "$as_me:$LINENO: WARNING: $ac_header:     section \"Present But Cannot Be Compiled\"" >&5
+echo "$as_me: WARNING: $ac_header:     section \"Present But Cannot Be Compiled\"" >&2;}
+    { echo "$as_me:$LINENO: WARNING: $ac_header: proceeding with the preprocessor's result" >&5
+echo "$as_me: WARNING: $ac_header: proceeding with the preprocessor's result" >&2;}
+    { echo "$as_me:$LINENO: WARNING: $ac_header: in the future, the compiler will take precedence" >&5
+echo "$as_me: WARNING: $ac_header: in the future, the compiler will take precedence" >&2;}
+    (
+      cat <<\_ASBOX
+## -------------------------------- ##
+## Report this to ardour@ardour.org ##
+## -------------------------------- ##
+_ASBOX
+    ) |
+      sed "s/^/$as_me: WARNING:     /" >&2
+    ;;
+esac
+echo "$as_me:$LINENO: checking for $ac_header" >&5
+echo $ECHO_N "checking for $ac_header... $ECHO_C" >&6
+if eval "test \"\${$as_ac_Header+set}\" = set"; then
+  echo $ECHO_N "(cached) $ECHO_C" >&6
+else
+  eval "$as_ac_Header=\$ac_header_preproc"
+fi
+echo "$as_me:$LINENO: result: `eval echo '${'$as_ac_Header'}'`" >&5
+echo "${ECHO_T}`eval echo '${'$as_ac_Header'}'`" >&6
+
+fi
+if test `eval echo '${'$as_ac_Header'}'` = yes; then
+  cat >>confdefs.h <<_ACEOF
+#define `echo "HAVE_$ac_header" | $as_tr_cpp` 1
+_ACEOF
+
+fi
+
+done
+
+       if test x$ac_cv_header_FLAC_all_h = xyes ; then
+               echo "$as_me:$LINENO: checking for FLAC__seekable_stream_encoder_set_tell_callback in -lFLAC" >&5
+echo $ECHO_N "checking for FLAC__seekable_stream_encoder_set_tell_callback in -lFLAC... $ECHO_C" >&6
+if test "${ac_cv_lib_FLAC_FLAC__seekable_stream_encoder_set_tell_callback+set}" = set; then
+  echo $ECHO_N "(cached) $ECHO_C" >&6
+else
+  ac_check_lib_save_LIBS=$LIBS
+LIBS="-lFLAC  $LIBS"
+cat >conftest.$ac_ext <<_ACEOF
+/* confdefs.h.  */
+_ACEOF
+cat confdefs.h >>conftest.$ac_ext
+cat >>conftest.$ac_ext <<_ACEOF
+/* end confdefs.h.  */
+
+/* Override any gcc2 internal prototype to avoid an error.  */
+#ifdef __cplusplus
+extern "C"
+#endif
+/* We use char because int might match the return type of a gcc2
+   builtin and then its argument prototype would still apply.  */
+char FLAC__seekable_stream_encoder_set_tell_callback ();
+int
+main ()
+{
+FLAC__seekable_stream_encoder_set_tell_callback ();
+  ;
+  return 0;
+}
+_ACEOF
+rm -f conftest.$ac_objext conftest$ac_exeext
+if { (eval echo "$as_me:$LINENO: \"$ac_link\"") >&5
+  (eval $ac_link) 2>conftest.er1
+  ac_status=$?
+  grep -v '^ *+' conftest.er1 >conftest.err
+  rm -f conftest.er1
+  cat conftest.err >&5
+  echo "$as_me:$LINENO: \$? = $ac_status" >&5
+  (exit $ac_status); } &&
+        { ac_try='test -z "$ac_c_werror_flag"
+                        || test ! -s conftest.err'
+  { (eval echo "$as_me:$LINENO: \"$ac_try\"") >&5
+  (eval $ac_try) 2>&5
+  ac_status=$?
+  echo "$as_me:$LINENO: \$? = $ac_status" >&5
+  (exit $ac_status); }; } &&
+        { ac_try='test -s conftest$ac_exeext'
+  { (eval echo "$as_me:$LINENO: \"$ac_try\"") >&5
+  (eval $ac_try) 2>&5
+  ac_status=$?
+  echo "$as_me:$LINENO: \$? = $ac_status" >&5
+  (exit $ac_status); }; }; then
+  ac_cv_lib_FLAC_FLAC__seekable_stream_encoder_set_tell_callback=yes
+else
+  echo "$as_me: failed program was:" >&5
+sed 's/^/| /' conftest.$ac_ext >&5
+
+ac_cv_lib_FLAC_FLAC__seekable_stream_encoder_set_tell_callback=no
+fi
+rm -f conftest.err conftest.$ac_objext \
+      conftest$ac_exeext conftest.$ac_ext
+LIBS=$ac_check_lib_save_LIBS
+fi
+echo "$as_me:$LINENO: result: $ac_cv_lib_FLAC_FLAC__seekable_stream_encoder_set_tell_callback" >&5
+echo "${ECHO_T}$ac_cv_lib_FLAC_FLAC__seekable_stream_encoder_set_tell_callback" >&6
+if test $ac_cv_lib_FLAC_FLAC__seekable_stream_encoder_set_tell_callback = yes; then
+  HAVE_FLAC_1_1_1="yes"
+fi
+
+               if test "x$HAVE_FLAC_1_1_1" = xyes ; then
+
+cat >>confdefs.h <<\_ACEOF
+#define HAVE_FLAC_1_1_1 1
+_ACEOF
+
+                       fi
+               FLAC_LIBS="-lFLAC"
+               fi
+       fi
+
+#====================================================================================
+# Test for sanity when cross-compiling.
+
+if test x$cross_compiling = xyes ; then
+       { echo "$as_me:$LINENO: WARNING: ******************************************************************" >&5
+echo "$as_me: WARNING: ******************************************************************" >&2;}
+       { echo "$as_me:$LINENO: WARNING: *** We are cross-compiling, so have to assume sizeof (short) == 2 " >&5
+echo "$as_me: WARNING: *** We are cross-compiling, so have to assume sizeof (short) == 2 " >&2;}
+       { echo "$as_me:$LINENO: WARNING: *** and sizeof (int) == 4. If this is not the case there is no    " >&5
+echo "$as_me: WARNING: *** and sizeof (int) == 4. If this is not the case there is no    " >&2;}
+       { echo "$as_me:$LINENO: WARNING: *** chance of this working. Please contact the mantainer.         " >&5
+echo "$as_me: WARNING: *** chance of this working. Please contact the mantainer.         " >&2;}
+       { echo "$as_me:$LINENO: WARNING: ******************************************************************" >&5
+echo "$as_me: WARNING: ******************************************************************" >&2;}
+       fi
+
+if test $ac_cv_sizeof_short != 2 ; then
+       { echo "$as_me:$LINENO: WARNING: ******************************************************************" >&5
+echo "$as_me: WARNING: ******************************************************************" >&2;}
+       { echo "$as_me:$LINENO: WARNING: *** sizeof (short) != 2.                                          " >&5
+echo "$as_me: WARNING: *** sizeof (short) != 2.                                          " >&2;}
+       { echo "$as_me:$LINENO: WARNING: ******************************************************************" >&5
+echo "$as_me: WARNING: ******************************************************************" >&2;}
+       fi
+
+if test $ac_cv_sizeof_int != 4 ; then
+       { echo "$as_me:$LINENO: WARNING: ******************************************************************" >&5
+echo "$as_me: WARNING: ******************************************************************" >&2;}
+       { echo "$as_me:$LINENO: WARNING: *** sizeof (int) != 4                                             " >&5
+echo "$as_me: WARNING: *** sizeof (int) != 4                                             " >&2;}
+       { echo "$as_me:$LINENO: WARNING: ******************************************************************" >&5
+echo "$as_me: WARNING: ******************************************************************" >&2;}
+       fi
+
+if test $ac_cv_sizeof_float != 4 ; then
+       { echo "$as_me:$LINENO: WARNING: ******************************************************************" >&5
+echo "$as_me: WARNING: ******************************************************************" >&2;}
+       { echo "$as_me:$LINENO: WARNING: *** sizeof (float) != 4.                                          " >&5
+echo "$as_me: WARNING: *** sizeof (float) != 4.                                          " >&2;}
+       { echo "$as_me:$LINENO: WARNING: ******************************************************************" >&5
+echo "$as_me: WARNING: ******************************************************************" >&2;}
+       fi
+
+if test $ac_cv_sizeof_double != 8 ; then
+       { echo "$as_me:$LINENO: WARNING: ******************************************************************" >&5
+echo "$as_me: WARNING: ******************************************************************" >&2;}
+       { echo "$as_me:$LINENO: WARNING: *** sizeof (double) != 8.                                         " >&5
+echo "$as_me: WARNING: *** sizeof (double) != 8.                                         " >&2;}
+       { echo "$as_me:$LINENO: WARNING: ******************************************************************" >&5
+echo "$as_me: WARNING: ******************************************************************" >&2;}
+       fi
+
+if test x"$ac_cv_prog_autogen" = "xno" ; then
+       { echo "$as_me:$LINENO: WARNING: Touching files in directory tests/." >&5
+echo "$as_me: WARNING: Touching files in directory tests/." >&2;}
+       touch tests/*.c tests/*.h
+       fi
+
+#====================================================================================
+# Settings for the HTML documentation.
+
+htmldocdir=$prefix/share/doc/libsndfile1-dev/html
+
+if test $prefix = "NONE" ; then
+       htmldocdir=/usr/local/share/doc/libsndfile1-dev/html
+else
+       htmldocdir=$prefix/share/doc/libsndfile1-dev/html
+       fi
+
+if test x$enable_bow_docs = "xyes" ; then
+       HTML_BGCOLOUR="white"
+       HTML_FGCOLOUR="black"
+else
+       HTML_BGCOLOUR="black"
+       HTML_FGCOLOUR="white"
+       fi
+
+#====================================================================================
+# Now use the information from the checking stage.
+
+if test x$ac_cv_c_compiler_gnu = xyes ; then
+       echo "$as_me:$LINENO: checking if $CC accepts -std=gnu99" >&5
+echo $ECHO_N "checking if $CC accepts -std=gnu99... $ECHO_C" >&6
+       ac_add_cflags__old_cflags="$CFLAGS"
+       CFLAGS="$CFLAGS -std=gnu99"
+       cat >conftest.$ac_ext <<_ACEOF
+/* confdefs.h.  */
+_ACEOF
+cat confdefs.h >>conftest.$ac_ext
+cat >>conftest.$ac_ext <<_ACEOF
+/* end confdefs.h.  */
+#include <stdio.h>
+int
+main ()
+{
+printf("Hello, World!\n"); return 0;
+  ;
+  return 0;
+}
+_ACEOF
+rm -f conftest.$ac_objext conftest$ac_exeext
+if { (eval echo "$as_me:$LINENO: \"$ac_link\"") >&5
+  (eval $ac_link) 2>conftest.er1
+  ac_status=$?
+  grep -v '^ *+' conftest.er1 >conftest.err
+  rm -f conftest.er1
+  cat conftest.err >&5
+  echo "$as_me:$LINENO: \$? = $ac_status" >&5
+  (exit $ac_status); } &&
+        { ac_try='test -z "$ac_c_werror_flag"
+                        || test ! -s conftest.err'
+  { (eval echo "$as_me:$LINENO: \"$ac_try\"") >&5
+  (eval $ac_try) 2>&5
+  ac_status=$?
+  echo "$as_me:$LINENO: \$? = $ac_status" >&5
+  (exit $ac_status); }; } &&
+        { ac_try='test -s conftest$ac_exeext'
+  { (eval echo "$as_me:$LINENO: \"$ac_try\"") >&5
+  (eval $ac_try) 2>&5
+  ac_status=$?
+  echo "$as_me:$LINENO: \$? = $ac_status" >&5
+  (exit $ac_status); }; }; then
+  echo "$as_me:$LINENO: result: yes" >&5
+echo "${ECHO_T}yes" >&6
+else
+  echo "$as_me: failed program was:" >&5
+sed 's/^/| /' conftest.$ac_ext >&5
+
+echo "$as_me:$LINENO: result: no" >&5
+echo "${ECHO_T}no" >&6
+               CFLAGS="$ac_add_cflags__old_cflags"
+fi
+rm -f conftest.err conftest.$ac_objext \
+      conftest$ac_exeext conftest.$ac_ext
+
+
+       CFLAGS="$CFLAGS -W -Wall"
+
+       echo "$as_me:$LINENO: checking if $CC accepts -Wdeclaration-after-statement" >&5
+echo $ECHO_N "checking if $CC accepts -Wdeclaration-after-statement... $ECHO_C" >&6
+       ac_add_cflags__old_cflags="$CFLAGS"
+       CFLAGS="$CFLAGS -Wdeclaration-after-statement"
+       cat >conftest.$ac_ext <<_ACEOF
+/* confdefs.h.  */
+_ACEOF
+cat confdefs.h >>conftest.$ac_ext
+cat >>conftest.$ac_ext <<_ACEOF
+/* end confdefs.h.  */
+#include <stdio.h>
+int
+main ()
+{
+printf("Hello, World!\n"); return 0;
+  ;
+  return 0;
+}
+_ACEOF
+rm -f conftest.$ac_objext conftest$ac_exeext
+if { (eval echo "$as_me:$LINENO: \"$ac_link\"") >&5
+  (eval $ac_link) 2>conftest.er1
+  ac_status=$?
+  grep -v '^ *+' conftest.er1 >conftest.err
+  rm -f conftest.er1
+  cat conftest.err >&5
+  echo "$as_me:$LINENO: \$? = $ac_status" >&5
+  (exit $ac_status); } &&
+        { ac_try='test -z "$ac_c_werror_flag"
+                        || test ! -s conftest.err'
+  { (eval echo "$as_me:$LINENO: \"$ac_try\"") >&5
+  (eval $ac_try) 2>&5
+  ac_status=$?
+  echo "$as_me:$LINENO: \$? = $ac_status" >&5
+  (exit $ac_status); }; } &&
+        { ac_try='test -s conftest$ac_exeext'
+  { (eval echo "$as_me:$LINENO: \"$ac_try\"") >&5
+  (eval $ac_try) 2>&5
+  ac_status=$?
+  echo "$as_me:$LINENO: \$? = $ac_status" >&5
+  (exit $ac_status); }; }; then
+  echo "$as_me:$LINENO: result: yes" >&5
+echo "${ECHO_T}yes" >&6
+else
+  echo "$as_me: failed program was:" >&5
+sed 's/^/| /' conftest.$ac_ext >&5
+
+echo "$as_me:$LINENO: result: no" >&5
+echo "${ECHO_T}no" >&6
+               CFLAGS="$ac_add_cflags__old_cflags"
+fi
+rm -f conftest.err conftest.$ac_objext \
+      conftest$ac_exeext conftest.$ac_ext
+
+
+       if test x$enable_gcc_werror = "xyes" ; then
+               CFLAGS="-Werror $CFLAGS"
+               fi
+
+       CFLAGS="$CFLAGS -Wstrict-prototypes -Wmissing-prototypes -Waggregate-return -Wcast-align -Wcast-qual -Wnested-externs -Wshadow -Wbad-function-cast -Wwrite-strings"
+       # -Wpointer-arith -Wundef -Wmissing-declarations -Winline -Wconversion"
+
+       if test "x$enable_gcc_opt" = "xno" ; then
+               temp_CFLAGS=`echo $CFLAGS | sed "s/O2/O0/"`
+               CFLAGS=$temp_CFLAGS
+               { echo "$as_me:$LINENO: WARNING: *** Compiler optimisations switched off. ***" >&5
+echo "$as_me: WARNING: *** Compiler optimisations switched off. ***" >&2;}
+               fi
+
+       # OS specific tweaks.
+       case "$host_os" in
+               darwin* | rhapsody*)
+                       # Disable -Wall, -pedantic and -Wshadow for Apple Darwin/Rhapsody.
+                       # System headers on these systems are broken.
+                       temp_CFLAGS=`echo $CFLAGS | sed "s/-Wall -pedantic//" | sed "s/-Wshadow//" | sed "s/-Waggregate-return//"`
+                       CFLAGS=$temp_CFLAGS
+                       SHLIB_VERSION_ARG="-Wl,-exported_symbols_list -Wl,\$(srcdir)/Symbols.darwin"
+                       ;;
+               linux*)
+                       SHLIB_VERSION_ARG="-Wl,--version-script=\$(srcdir)/Symbols.linux"
+                       ;;
+               mingw*)
+                       SHLIB_VERSION_ARG="-Wl,\$(srcdir)/libsndfile.def"
+                       ;;
+               cygwin*)
+                       SHLIB_VERSION_ARG="-Wl,\$(srcdir)/cygsndfile.def"
+                       ;;
+               *)
+                       ;;
+               esac
+       if test x$enable_gcc_pipe != "xno" ; then
+               CFLAGS="$CFLAGS -pipe"
+               fi
+
+
+cat >>confdefs.h <<\_ACEOF
+#define COMPILER_IS_GCC 1
+_ACEOF
+
+       GCC_MAJOR_VERSION=`$CC -dumpversion | sed "s/\..*//"`
+
+cat >>confdefs.h <<_ACEOF
+#define GCC_MAJOR_VERSION ${GCC_MAJOR_VERSION}
+_ACEOF
+
+       fi
+
+CFLAGS="$CFLAGS $OS_SPECIFIC_CFLAGS"
+
+if test x"$CFLAGS" = x ; then
+       echo "Error in configure script. CFLAGS has been screwed up."
+       exit
+       fi
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+                    ac_config_files="$ac_config_files src/sndfile.h sndfile.pc"
+
+cat >confcache <<\_ACEOF
+# This file is a shell script that caches the results of configure
+# tests run on this system so they can be shared between configure
+# scripts and configure runs, see configure's option --config-cache.
+# It is not useful on other systems.  If it contains results you don't
+# want to keep, you may remove or edit it.
+#
+# config.status only pays attention to the cache file if you give it
+# the --recheck option to rerun configure.
+#
+# `ac_cv_env_foo' variables (set or unset) will be overridden when
+# loading this file, other *unset* `ac_cv_foo' will be assigned the
+# following values.
+
+_ACEOF
+
+# The following way of writing the cache mishandles newlines in values,
+# but we know of no workaround that is simple, portable, and efficient.
+# So, don't put newlines in cache variables' values.
+# Ultrix sh set writes to stderr and can't be redirected directly,
+# and sets the high bit in the cache file unless we assign to the vars.
+{
+  (set) 2>&1 |
+    case `(ac_space=' '; set | grep ac_space) 2>&1` in
+    *ac_space=\ *)
+      # `set' does not quote correctly, so add quotes (double-quote
+      # substitution turns \\\\ into \\, and sed turns \\ into \).
+      sed -n \
+       "s/'/'\\\\''/g;
+         s/^\\([_$as_cr_alnum]*_cv_[_$as_cr_alnum]*\\)=\\(.*\\)/\\1='\\2'/p"
+      ;;
+    *)
+      # `set' quotes correctly as required by POSIX, so do not add quotes.
+      sed -n \
+       "s/^\\([_$as_cr_alnum]*_cv_[_$as_cr_alnum]*\\)=\\(.*\\)/\\1=\\2/p"
+      ;;
+    esac;
+} |
+  sed '
+     t clear
+     : clear
+     s/^\([^=]*\)=\(.*[{}].*\)$/test "${\1+set}" = set || &/
+     t end
+     /^ac_cv_env/!s/^\([^=]*\)=\(.*\)$/\1=${\1=\2}/
+     : end' >>confcache
+if diff $cache_file confcache >/dev/null 2>&1; then :; else
+  if test -w $cache_file; then
+    test "x$cache_file" != "x/dev/null" && echo "updating cache $cache_file"
+    cat confcache >$cache_file
+  else
+    echo "not updating unwritable cache $cache_file"
+  fi
+fi
+rm -f confcache
+
+test "x$prefix" = xNONE && prefix=$ac_default_prefix
+# Let make expand exec_prefix.
+test "x$exec_prefix" = xNONE && exec_prefix='${prefix}'
+
+# VPATH may cause trouble with some makes, so we remove $(srcdir),
+# ${srcdir} and @srcdir@ from VPATH if srcdir is ".", strip leading and
+# trailing colons and then remove the whole line if VPATH becomes empty
+# (actually we leave an empty line to preserve line numbers).
+if test "x$srcdir" = x.; then
+  ac_vpsub='/^[         ]*VPATH[        ]*=/{
+s/:*\$(srcdir):*/:/;
+s/:*\${srcdir}:*/:/;
+s/:*@srcdir@:*/:/;
+s/^\([^=]*=[    ]*\):*/\1/;
+s/:*$//;
+s/^[^=]*=[      ]*$//;
+}'
+fi
+
+DEFS=-DHAVE_CONFIG_H
+
+ac_libobjs=
+ac_ltlibobjs=
+for ac_i in : $LIBOBJS; do test "x$ac_i" = x: && continue
+  # 1. Remove the extension, and $U if already installed.
+  ac_i=`echo "$ac_i" |
+        sed 's/\$U\././;s/\.o$//;s/\.obj$//'`
+  # 2. Add them.
+  ac_libobjs="$ac_libobjs $ac_i\$U.$ac_objext"
+  ac_ltlibobjs="$ac_ltlibobjs $ac_i"'$U.lo'
+done
+LIBOBJS=$ac_libobjs
+
+LTLIBOBJS=$ac_ltlibobjs
+
+
+
+: ${CONFIG_STATUS=./config.status}
+ac_clean_files_save=$ac_clean_files
+ac_clean_files="$ac_clean_files $CONFIG_STATUS"
+{ echo "$as_me:$LINENO: creating $CONFIG_STATUS" >&5
+echo "$as_me: creating $CONFIG_STATUS" >&6;}
+cat >$CONFIG_STATUS <<_ACEOF
+#! $SHELL
+# Generated by $as_me.
+# Run this file to recreate the current configuration.
+# Compiler output produced by configure, useful for debugging
+# configure, is in config.log if it exists.
+
+debug=false
+ac_cs_recheck=false
+ac_cs_silent=false
+SHELL=\${CONFIG_SHELL-$SHELL}
+_ACEOF
+
+cat >>$CONFIG_STATUS <<\_ACEOF
+## --------------------- ##
+## M4sh Initialization.  ##
+## --------------------- ##
+
+# Be Bourne compatible
+if test -n "${ZSH_VERSION+set}" && (emulate sh) >/dev/null 2>&1; then
+  emulate sh
+  NULLCMD=:
+  # Zsh 3.x and 4.x performs word splitting on ${1+"$@"}, which
+  # is contrary to our usage.  Disable this feature.
+  alias -g '${1+"$@"}'='"$@"'
+elif test -n "${BASH_VERSION+set}" && (set -o posix) >/dev/null 2>&1; then
+  set -o posix
+fi
+DUALCASE=1; export DUALCASE # for MKS sh
+
+# Support unset when possible.
+if ( (MAIL=60; unset MAIL) || exit) >/dev/null 2>&1; then
+  as_unset=unset
+else
+  as_unset=false
+fi
+
+
+# Work around bugs in pre-3.0 UWIN ksh.
+$as_unset ENV MAIL MAILPATH
+PS1='$ '
+PS2='> '
+PS4='+ '
+
+# NLS nuisances.
+for as_var in \
+  LANG LANGUAGE LC_ADDRESS LC_ALL LC_COLLATE LC_CTYPE LC_IDENTIFICATION \
+  LC_MEASUREMENT LC_MESSAGES LC_MONETARY LC_NAME LC_NUMERIC LC_PAPER \
+  LC_TELEPHONE LC_TIME
+do
+  if (set +x; test -z "`(eval $as_var=C; export $as_var) 2>&1`"); then
+    eval $as_var=C; export $as_var
+  else
+    $as_unset $as_var
+  fi
+done
+
+# Required to use basename.
+if expr a : '\(a\)' >/dev/null 2>&1; then
+  as_expr=expr
+else
+  as_expr=false
+fi
+
+if (basename /) >/dev/null 2>&1 && test "X`basename / 2>&1`" = "X/"; then
+  as_basename=basename
+else
+  as_basename=false
+fi
+
+
+# Name of the executable.
+as_me=`$as_basename "$0" ||
+$as_expr X/"$0" : '.*/\([^/][^/]*\)/*$' \| \
+        X"$0" : 'X\(//\)$' \| \
+        X"$0" : 'X\(/\)$' \| \
+        .     : '\(.\)' 2>/dev/null ||
+echo X/"$0" |
+    sed '/^.*\/\([^/][^/]*\)\/*$/{ s//\1/; q; }
+         /^X\/\(\/\/\)$/{ s//\1/; q; }
+         /^X\/\(\/\).*/{ s//\1/; q; }
+         s/.*/./; q'`
+
+
+# PATH needs CR, and LINENO needs CR and PATH.
+# Avoid depending upon Character Ranges.
+as_cr_letters='abcdefghijklmnopqrstuvwxyz'
+as_cr_LETTERS='ABCDEFGHIJKLMNOPQRSTUVWXYZ'
+as_cr_Letters=$as_cr_letters$as_cr_LETTERS
+as_cr_digits='0123456789'
+as_cr_alnum=$as_cr_Letters$as_cr_digits
+
+# The user is always right.
+if test "${PATH_SEPARATOR+set}" != set; then
+  echo "#! /bin/sh" >conf$$.sh
+  echo  "exit 0"   >>conf$$.sh
+  chmod +x conf$$.sh
+  if (PATH="/nonexistent;."; conf$$.sh) >/dev/null 2>&1; then
+    PATH_SEPARATOR=';'
+  else
+    PATH_SEPARATOR=:
+  fi
+  rm -f conf$$.sh
+fi
+
+
+  as_lineno_1=$LINENO
+  as_lineno_2=$LINENO
+  as_lineno_3=`(expr $as_lineno_1 + 1) 2>/dev/null`
+  test "x$as_lineno_1" != "x$as_lineno_2" &&
+  test "x$as_lineno_3"  = "x$as_lineno_2"  || {
+  # Find who we are.  Look in the path if we contain no path at all
+  # relative or not.
+  case $0 in
+    *[\\/]* ) as_myself=$0 ;;
+    *) as_save_IFS=$IFS; IFS=$PATH_SEPARATOR
+for as_dir in $PATH
+do
+  IFS=$as_save_IFS
+  test -z "$as_dir" && as_dir=.
+  test -r "$as_dir/$0" && as_myself=$as_dir/$0 && break
+done
+
+       ;;
+  esac
+  # We did not find ourselves, most probably we were run as `sh COMMAND'
+  # in which case we are not to be found in the path.
+  if test "x$as_myself" = x; then
+    as_myself=$0
+  fi
+  if test ! -f "$as_myself"; then
+    { { echo "$as_me:$LINENO: error: cannot find myself; rerun with an absolute path" >&5
+echo "$as_me: error: cannot find myself; rerun with an absolute path" >&2;}
+   { (exit 1); exit 1; }; }
+  fi
+  case $CONFIG_SHELL in
+  '')
+    as_save_IFS=$IFS; IFS=$PATH_SEPARATOR
+for as_dir in /bin$PATH_SEPARATOR/usr/bin$PATH_SEPARATOR$PATH
+do
+  IFS=$as_save_IFS
+  test -z "$as_dir" && as_dir=.
+  for as_base in sh bash ksh sh5; do
+        case $as_dir in
+        /*)
+          if ("$as_dir/$as_base" -c '
+  as_lineno_1=$LINENO
+  as_lineno_2=$LINENO
+  as_lineno_3=`(expr $as_lineno_1 + 1) 2>/dev/null`
+  test "x$as_lineno_1" != "x$as_lineno_2" &&
+  test "x$as_lineno_3"  = "x$as_lineno_2" ') 2>/dev/null; then
+            $as_unset BASH_ENV || test "${BASH_ENV+set}" != set || { BASH_ENV=; export BASH_ENV; }
+            $as_unset ENV || test "${ENV+set}" != set || { ENV=; export ENV; }
+            CONFIG_SHELL=$as_dir/$as_base
+            export CONFIG_SHELL
+            exec "$CONFIG_SHELL" "$0" ${1+"$@"}
+          fi;;
+        esac
+       done
+done
+;;
+  esac
+
+  # Create $as_me.lineno as a copy of $as_myself, but with $LINENO
+  # uniformly replaced by the line number.  The first 'sed' inserts a
+  # line-number line before each line; the second 'sed' does the real
+  # work.  The second script uses 'N' to pair each line-number line
+  # with the numbered line, and appends trailing '-' during
+  # substitution so that $LINENO is not a special case at line end.
+  # (Raja R Harinath suggested sed '=', and Paul Eggert wrote the
+  # second 'sed' script.  Blame Lee E. McMahon for sed's syntax.  :-)
+  sed '=' <$as_myself |
+    sed '
+      N
+      s,$,-,
+      : loop
+      s,^\(['$as_cr_digits']*\)\(.*\)[$]LINENO\([^'$as_cr_alnum'_]\),\1\2\1\3,
+      t loop
+      s,-$,,
+      s,^['$as_cr_digits']*\n,,
+    ' >$as_me.lineno &&
+  chmod +x $as_me.lineno ||
+    { { echo "$as_me:$LINENO: error: cannot create $as_me.lineno; rerun with a POSIX shell" >&5
+echo "$as_me: error: cannot create $as_me.lineno; rerun with a POSIX shell" >&2;}
+   { (exit 1); exit 1; }; }
+
+  # Don't try to exec as it changes $[0], causing all sort of problems
+  # (the dirname of $[0] is not the place where we might find the
+  # original and so on.  Autoconf is especially sensible to this).
+  . ./$as_me.lineno
+  # Exit status is that of the last command.
+  exit
+}
+
+
+case `echo "testing\c"; echo 1,2,3`,`echo -n testing; echo 1,2,3` in
+  *c*,-n*) ECHO_N= ECHO_C='
+' ECHO_T='     ' ;;
+  *c*,*  ) ECHO_N=-n ECHO_C= ECHO_T= ;;
+  *)       ECHO_N= ECHO_C='\c' ECHO_T= ;;
+esac
+
+if expr a : '\(a\)' >/dev/null 2>&1; then
+  as_expr=expr
+else
+  as_expr=false
+fi
+
+rm -f conf$$ conf$$.exe conf$$.file
+echo >conf$$.file
+if ln -s conf$$.file conf$$ 2>/dev/null; then
+  # We could just check for DJGPP; but this test a) works b) is more generic
+  # and c) will remain valid once DJGPP supports symlinks (DJGPP 2.04).
+  if test -f conf$$.exe; then
+    # Don't use ln at all; we don't have any links
+    as_ln_s='cp -p'
+  else
+    as_ln_s='ln -s'
+  fi
+elif ln conf$$.file conf$$ 2>/dev/null; then
+  as_ln_s=ln
+else
+  as_ln_s='cp -p'
+fi
+rm -f conf$$ conf$$.exe conf$$.file
+
+if mkdir -p . 2>/dev/null; then
+  as_mkdir_p=:
+else
+  test -d ./-p && rmdir ./-p
+  as_mkdir_p=false
+fi
+
+as_executable_p="test -f"
+
+# Sed expression to map a string onto a valid CPP name.
+as_tr_cpp="eval sed 'y%*$as_cr_letters%P$as_cr_LETTERS%;s%[^_$as_cr_alnum]%_%g'"
+
+# Sed expression to map a string onto a valid variable name.
+as_tr_sh="eval sed 'y%*+%pp%;s%[^_$as_cr_alnum]%_%g'"
+
+
+# IFS
+# We need space, tab and new line, in precisely that order.
+as_nl='
+'
+IFS="  $as_nl"
+
+# CDPATH.
+$as_unset CDPATH
+
+exec 6>&1
+
+# Open the log real soon, to keep \$[0] and so on meaningful, and to
+# report actual input values of CONFIG_FILES etc. instead of their
+# values after options handling.  Logging --version etc. is OK.
+exec 5>>config.log
+{
+  echo
+  sed 'h;s/./-/g;s/^.../## /;s/...$/ ##/;p;x;p;x' <<_ASBOX
+## Running $as_me. ##
+_ASBOX
+} >&5
+cat >&5 <<_CSEOF
+
+This file was extended by libsndfile $as_me ardour-special, which was
+generated by GNU Autoconf 2.59.  Invocation command line was
+
+  CONFIG_FILES    = $CONFIG_FILES
+  CONFIG_HEADERS  = $CONFIG_HEADERS
+  CONFIG_LINKS    = $CONFIG_LINKS
+  CONFIG_COMMANDS = $CONFIG_COMMANDS
+  $ $0 $@
+
+_CSEOF
+echo "on `(hostname || uname -n) 2>/dev/null | sed 1q`" >&5
+echo >&5
+_ACEOF
+
+# Files that config.status was made for.
+if test -n "$ac_config_files"; then
+  echo "config_files=\"$ac_config_files\"" >>$CONFIG_STATUS
+fi
+
+if test -n "$ac_config_headers"; then
+  echo "config_headers=\"$ac_config_headers\"" >>$CONFIG_STATUS
+fi
+
+if test -n "$ac_config_links"; then
+  echo "config_links=\"$ac_config_links\"" >>$CONFIG_STATUS
+fi
+
+if test -n "$ac_config_commands"; then
+  echo "config_commands=\"$ac_config_commands\"" >>$CONFIG_STATUS
+fi
+
+cat >>$CONFIG_STATUS <<\_ACEOF
+
+ac_cs_usage="\
+\`$as_me' instantiates files from templates according to the
+current configuration.
+
+Usage: $0 [OPTIONS] [FILE]...
+
+  -h, --help       print this help, then exit
+  -V, --version    print version number, then exit
+  -q, --quiet      do not print progress messages
+  -d, --debug      don't remove temporary files
+      --recheck    update $as_me by reconfiguring in the same conditions
+  --file=FILE[:TEMPLATE]
+                  instantiate the configuration file FILE
+  --header=FILE[:TEMPLATE]
+                  instantiate the configuration header FILE
+
+Configuration files:
+$config_files
+
+Configuration headers:
+$config_headers
+
+Report bugs to <bug-autoconf@gnu.org>."
+_ACEOF
+
+cat >>$CONFIG_STATUS <<_ACEOF
+ac_cs_version="\\
+libsndfile config.status ardour-special
+configured by $0, generated by GNU Autoconf 2.59,
+  with options \\"`echo "$ac_configure_args" | sed 's/[\\""\`\$]/\\\\&/g'`\\"
+
+Copyright (C) 2003 Free Software Foundation, Inc.
+This config.status script is free software; the Free Software Foundation
+gives unlimited permission to copy, distribute and modify it."
+srcdir=$srcdir
+INSTALL="$INSTALL"
+_ACEOF
+
+cat >>$CONFIG_STATUS <<\_ACEOF
+# If no file are specified by the user, then we need to provide default
+# value.  By we need to know if files were specified by the user.
+ac_need_defaults=:
+while test $# != 0
+do
+  case $1 in
+  --*=*)
+    ac_option=`expr "x$1" : 'x\([^=]*\)='`
+    ac_optarg=`expr "x$1" : 'x[^=]*=\(.*\)'`
+    ac_shift=:
+    ;;
+  -*)
+    ac_option=$1
+    ac_optarg=$2
+    ac_shift=shift
+    ;;
+  *) # This is not an option, so the user has probably given explicit
+     # arguments.
+     ac_option=$1
+     ac_need_defaults=false;;
+  esac
+
+  case $ac_option in
+  # Handling of the options.
+_ACEOF
+cat >>$CONFIG_STATUS <<\_ACEOF
+  -recheck | --recheck | --rechec | --reche | --rech | --rec | --re | --r)
+    ac_cs_recheck=: ;;
+  --version | --vers* | -V )
+    echo "$ac_cs_version"; exit 0 ;;
+  --he | --h)
+    # Conflict between --help and --header
+    { { echo "$as_me:$LINENO: error: ambiguous option: $1
+Try \`$0 --help' for more information." >&5
+echo "$as_me: error: ambiguous option: $1
+Try \`$0 --help' for more information." >&2;}
+   { (exit 1); exit 1; }; };;
+  --help | --hel | -h )
+    echo "$ac_cs_usage"; exit 0 ;;
+  --debug | --d* | -d )
+    debug=: ;;
+  --file | --fil | --fi | --f )
+    $ac_shift
+    CONFIG_FILES="$CONFIG_FILES $ac_optarg"
+    ac_need_defaults=false;;
+  --header | --heade | --head | --hea )
+    $ac_shift
+    CONFIG_HEADERS="$CONFIG_HEADERS $ac_optarg"
+    ac_need_defaults=false;;
+  -q | -quiet | --quiet | --quie | --qui | --qu | --q \
+  | -silent | --silent | --silen | --sile | --sil | --si | --s)
+    ac_cs_silent=: ;;
+
+  # This is an error.
+  -*) { { echo "$as_me:$LINENO: error: unrecognized option: $1
+Try \`$0 --help' for more information." >&5
+echo "$as_me: error: unrecognized option: $1
+Try \`$0 --help' for more information." >&2;}
+   { (exit 1); exit 1; }; } ;;
+
+  *) ac_config_targets="$ac_config_targets $1" ;;
+
+  esac
+  shift
+done
+
+ac_configure_extra_args=
+
+if $ac_cs_silent; then
+  exec 6>/dev/null
+  ac_configure_extra_args="$ac_configure_extra_args --silent"
+fi
+
+_ACEOF
+cat >>$CONFIG_STATUS <<_ACEOF
+if \$ac_cs_recheck; then
+  echo "running $SHELL $0 " $ac_configure_args \$ac_configure_extra_args " --no-create --no-recursion" >&6
+  exec $SHELL $0 $ac_configure_args \$ac_configure_extra_args --no-create --no-recursion
+fi
+
+_ACEOF
+
+
+
+
+
+cat >>$CONFIG_STATUS <<\_ACEOF
+for ac_config_target in $ac_config_targets
+do
+  case "$ac_config_target" in
+  # Handling of arguments.
+  "src/sndfile.h" ) CONFIG_FILES="$CONFIG_FILES src/sndfile.h" ;;
+  "sndfile.pc" ) CONFIG_FILES="$CONFIG_FILES sndfile.pc" ;;
+  "src/config.h" ) CONFIG_HEADERS="$CONFIG_HEADERS src/config.h" ;;
+  *) { { echo "$as_me:$LINENO: error: invalid argument: $ac_config_target" >&5
+echo "$as_me: error: invalid argument: $ac_config_target" >&2;}
+   { (exit 1); exit 1; }; };;
+  esac
+done
+
+# If the user did not use the arguments to specify the items to instantiate,
+# then the envvar interface is used.  Set only those that are not.
+# We use the long form for the default assignment because of an extremely
+# bizarre bug on SunOS 4.1.3.
+if $ac_need_defaults; then
+  test "${CONFIG_FILES+set}" = set || CONFIG_FILES=$config_files
+  test "${CONFIG_HEADERS+set}" = set || CONFIG_HEADERS=$config_headers
+fi
+
+# Have a temporary directory for convenience.  Make it in the build tree
+# simply because there is no reason to put it here, and in addition,
+# creating and moving files from /tmp can sometimes cause problems.
+# Create a temporary directory, and hook for its removal unless debugging.
+$debug ||
+{
+  trap 'exit_status=$?; rm -rf $tmp && exit $exit_status' 0
+  trap '{ (exit 1); exit 1; }' 1 2 13 15
+}
+
+# Create a (secure) tmp directory for tmp files.
+
+{
+  tmp=`(umask 077 && mktemp -d -q "./confstatXXXXXX") 2>/dev/null` &&
+  test -n "$tmp" && test -d "$tmp"
+}  ||
+{
+  tmp=./confstat$$-$RANDOM
+  (umask 077 && mkdir $tmp)
+} ||
+{
+   echo "$me: cannot create a temporary directory in ." >&2
+   { (exit 1); exit 1; }
+}
+
+_ACEOF
+
+cat >>$CONFIG_STATUS <<_ACEOF
+
+#
+# CONFIG_FILES section.
+#
+
+# No need to generate the scripts if there are no CONFIG_FILES.
+# This happens for instance when ./config.status config.h
+if test -n "\$CONFIG_FILES"; then
+  # Protect against being on the right side of a sed subst in config.status.
+  sed 's/,@/@@/; s/@,/@@/; s/,;t t\$/@;t t/; /@;t t\$/s/[\\\\&,]/\\\\&/g;
+   s/@@/,@/; s/@@/@,/; s/@;t t\$/,;t t/' >\$tmp/subs.sed <<\\CEOF
+s,@SHELL@,$SHELL,;t t
+s,@PATH_SEPARATOR@,$PATH_SEPARATOR,;t t
+s,@PACKAGE_NAME@,$PACKAGE_NAME,;t t
+s,@PACKAGE_TARNAME@,$PACKAGE_TARNAME,;t t
+s,@PACKAGE_VERSION@,$PACKAGE_VERSION,;t t
+s,@PACKAGE_STRING@,$PACKAGE_STRING,;t t
+s,@PACKAGE_BUGREPORT@,$PACKAGE_BUGREPORT,;t t
+s,@exec_prefix@,$exec_prefix,;t t
+s,@prefix@,$prefix,;t t
+s,@program_transform_name@,$program_transform_name,;t t
+s,@bindir@,$bindir,;t t
+s,@sbindir@,$sbindir,;t t
+s,@libexecdir@,$libexecdir,;t t
+s,@datadir@,$datadir,;t t
+s,@sysconfdir@,$sysconfdir,;t t
+s,@sharedstatedir@,$sharedstatedir,;t t
+s,@localstatedir@,$localstatedir,;t t
+s,@libdir@,$libdir,;t t
+s,@includedir@,$includedir,;t t
+s,@oldincludedir@,$oldincludedir,;t t
+s,@infodir@,$infodir,;t t
+s,@mandir@,$mandir,;t t
+s,@build_alias@,$build_alias,;t t
+s,@host_alias@,$host_alias,;t t
+s,@target_alias@,$target_alias,;t t
+s,@DEFS@,$DEFS,;t t
+s,@ECHO_C@,$ECHO_C,;t t
+s,@ECHO_N@,$ECHO_N,;t t
+s,@ECHO_T@,$ECHO_T,;t t
+s,@LIBS@,$LIBS,;t t
+s,@build@,$build,;t t
+s,@build_cpu@,$build_cpu,;t t
+s,@build_vendor@,$build_vendor,;t t
+s,@build_os@,$build_os,;t t
+s,@host@,$host,;t t
+s,@host_cpu@,$host_cpu,;t t
+s,@host_vendor@,$host_vendor,;t t
+s,@host_os@,$host_os,;t t
+s,@target@,$target,;t t
+s,@target_cpu@,$target_cpu,;t t
+s,@target_vendor@,$target_vendor,;t t
+s,@target_os@,$target_os,;t t
+s,@CC@,$CC,;t t
+s,@CFLAGS@,$CFLAGS,;t t
+s,@LDFLAGS@,$LDFLAGS,;t t
+s,@CPPFLAGS@,$CPPFLAGS,;t t
+s,@ac_ct_CC@,$ac_ct_CC,;t t
+s,@EXEEXT@,$EXEEXT,;t t
+s,@OBJEXT@,$OBJEXT,;t t
+s,@autogen@,$autogen,;t t
+s,@INSTALL_PROGRAM@,$INSTALL_PROGRAM,;t t
+s,@INSTALL_SCRIPT@,$INSTALL_SCRIPT,;t t
+s,@INSTALL_DATA@,$INSTALL_DATA,;t t
+s,@LN_S@,$LN_S,;t t
+s,@CPP@,$CPP,;t t
+s,@EGREP@,$EGREP,;t t
+s,@GETCONF@,$GETCONF,;t t
+s,@ac_ct_GETCONF@,$ac_ct_GETCONF,;t t
+s,@TYPEOF_SF_COUNT_T@,$TYPEOF_SF_COUNT_T,;t t
+s,@SIZEOF_SF_COUNT_T@,$SIZEOF_SF_COUNT_T,;t t
+s,@SF_COUNT_MAX@,$SF_COUNT_MAX,;t t
+s,@PKG_CONFIG@,$PKG_CONFIG,;t t
+s,@SQLITE3_CFLAGS@,$SQLITE3_CFLAGS,;t t
+s,@SQLITE3_LIBS@,$SQLITE3_LIBS,;t t
+s,@htmldocdir@,$htmldocdir,;t t
+s,@HTML_BGCOLOUR@,$HTML_BGCOLOUR,;t t
+s,@HTML_FGCOLOUR@,$HTML_FGCOLOUR,;t t
+s,@SHLIB_VERSION_ARG@,$SHLIB_VERSION_ARG,;t t
+s,@SHARED_VERSION_INFO@,$SHARED_VERSION_INFO,;t t
+s,@OS_SPECIFIC_CFLAGS@,$OS_SPECIFIC_CFLAGS,;t t
+s,@OS_SPECIFIC_LINKS@,$OS_SPECIFIC_LINKS,;t t
+s,@ALSA_LIBS@,$ALSA_LIBS,;t t
+s,@FLAC_LIBS@,$FLAC_LIBS,;t t
+s,@ENABLE_EXPERIMENTAL_CODE@,$ENABLE_EXPERIMENTAL_CODE,;t t
+s,@COMPILER_IS_GCC@,$COMPILER_IS_GCC,;t t
+s,@GCC_MAJOR_VERSION@,$GCC_MAJOR_VERSION,;t t
+s,@LIBTOOL_DEPS@,$LIBTOOL_DEPS,;t t
+s,@LIBOBJS@,$LIBOBJS,;t t
+s,@LTLIBOBJS@,$LTLIBOBJS,;t t
+CEOF
+
+_ACEOF
+
+  cat >>$CONFIG_STATUS <<\_ACEOF
+  # Split the substitutions into bite-sized pieces for seds with
+  # small command number limits, like on Digital OSF/1 and HP-UX.
+  ac_max_sed_lines=48
+  ac_sed_frag=1 # Number of current file.
+  ac_beg=1 # First line for current file.
+  ac_end=$ac_max_sed_lines # Line after last line for current file.
+  ac_more_lines=:
+  ac_sed_cmds=
+  while $ac_more_lines; do
+    if test $ac_beg -gt 1; then
+      sed "1,${ac_beg}d; ${ac_end}q" $tmp/subs.sed >$tmp/subs.frag
+    else
+      sed "${ac_end}q" $tmp/subs.sed >$tmp/subs.frag
+    fi
+    if test ! -s $tmp/subs.frag; then
+      ac_more_lines=false
+    else
+      # The purpose of the label and of the branching condition is to
+      # speed up the sed processing (if there are no `@' at all, there
+      # is no need to browse any of the substitutions).
+      # These are the two extra sed commands mentioned above.
+      (echo ':t
+  /@[a-zA-Z_][a-zA-Z_0-9]*@/!b' && cat $tmp/subs.frag) >$tmp/subs-$ac_sed_frag.sed
+      if test -z "$ac_sed_cmds"; then
+       ac_sed_cmds="sed -f $tmp/subs-$ac_sed_frag.sed"
+      else
+       ac_sed_cmds="$ac_sed_cmds | sed -f $tmp/subs-$ac_sed_frag.sed"
+      fi
+      ac_sed_frag=`expr $ac_sed_frag + 1`
+      ac_beg=$ac_end
+      ac_end=`expr $ac_end + $ac_max_sed_lines`
+    fi
+  done
+  if test -z "$ac_sed_cmds"; then
+    ac_sed_cmds=cat
+  fi
+fi # test -n "$CONFIG_FILES"
+
+_ACEOF
+cat >>$CONFIG_STATUS <<\_ACEOF
+for ac_file in : $CONFIG_FILES; do test "x$ac_file" = x: && continue
+  # Support "outfile[:infile[:infile...]]", defaulting infile="outfile.in".
+  case $ac_file in
+  - | *:- | *:-:* ) # input from stdin
+       cat >$tmp/stdin
+       ac_file_in=`echo "$ac_file" | sed 's,[^:]*:,,'`
+       ac_file=`echo "$ac_file" | sed 's,:.*,,'` ;;
+  *:* ) ac_file_in=`echo "$ac_file" | sed 's,[^:]*:,,'`
+       ac_file=`echo "$ac_file" | sed 's,:.*,,'` ;;
+  * )   ac_file_in=$ac_file.in ;;
+  esac
+
+  # Compute @srcdir@, @top_srcdir@, and @INSTALL@ for subdirectories.
+  ac_dir=`(dirname "$ac_file") 2>/dev/null ||
+$as_expr X"$ac_file" : 'X\(.*[^/]\)//*[^/][^/]*/*$' \| \
+        X"$ac_file" : 'X\(//\)[^/]' \| \
+        X"$ac_file" : 'X\(//\)$' \| \
+        X"$ac_file" : 'X\(/\)' \| \
+        .     : '\(.\)' 2>/dev/null ||
+echo X"$ac_file" |
+    sed '/^X\(.*[^/]\)\/\/*[^/][^/]*\/*$/{ s//\1/; q; }
+         /^X\(\/\/\)[^/].*/{ s//\1/; q; }
+         /^X\(\/\/\)$/{ s//\1/; q; }
+         /^X\(\/\).*/{ s//\1/; q; }
+         s/.*/./; q'`
+  { if $as_mkdir_p; then
+    mkdir -p "$ac_dir"
+  else
+    as_dir="$ac_dir"
+    as_dirs=
+    while test ! -d "$as_dir"; do
+      as_dirs="$as_dir $as_dirs"
+      as_dir=`(dirname "$as_dir") 2>/dev/null ||
+$as_expr X"$as_dir" : 'X\(.*[^/]\)//*[^/][^/]*/*$' \| \
+        X"$as_dir" : 'X\(//\)[^/]' \| \
+        X"$as_dir" : 'X\(//\)$' \| \
+        X"$as_dir" : 'X\(/\)' \| \
+        .     : '\(.\)' 2>/dev/null ||
+echo X"$as_dir" |
+    sed '/^X\(.*[^/]\)\/\/*[^/][^/]*\/*$/{ s//\1/; q; }
+         /^X\(\/\/\)[^/].*/{ s//\1/; q; }
+         /^X\(\/\/\)$/{ s//\1/; q; }
+         /^X\(\/\).*/{ s//\1/; q; }
+         s/.*/./; q'`
+    done
+    test ! -n "$as_dirs" || mkdir $as_dirs
+  fi || { { echo "$as_me:$LINENO: error: cannot create directory \"$ac_dir\"" >&5
+echo "$as_me: error: cannot create directory \"$ac_dir\"" >&2;}
+   { (exit 1); exit 1; }; }; }
+
+  ac_builddir=.
+
+if test "$ac_dir" != .; then
+  ac_dir_suffix=/`echo "$ac_dir" | sed 's,^\.[\\/],,'`
+  # A "../" for each directory in $ac_dir_suffix.
+  ac_top_builddir=`echo "$ac_dir_suffix" | sed 's,/[^\\/]*,../,g'`
+else
+  ac_dir_suffix= ac_top_builddir=
+fi
+
+case $srcdir in
+  .)  # No --srcdir option.  We are building in place.
+    ac_srcdir=.
+    if test -z "$ac_top_builddir"; then
+       ac_top_srcdir=.
+    else
+       ac_top_srcdir=`echo $ac_top_builddir | sed 's,/$,,'`
+    fi ;;
+  [\\/]* | ?:[\\/]* )  # Absolute path.
+    ac_srcdir=$srcdir$ac_dir_suffix;
+    ac_top_srcdir=$srcdir ;;
+  *) # Relative path.
+    ac_srcdir=$ac_top_builddir$srcdir$ac_dir_suffix
+    ac_top_srcdir=$ac_top_builddir$srcdir ;;
+esac
+
+# Do not use `cd foo && pwd` to compute absolute paths, because
+# the directories may not exist.
+case `pwd` in
+.) ac_abs_builddir="$ac_dir";;
+*)
+  case "$ac_dir" in
+  .) ac_abs_builddir=`pwd`;;
+  [\\/]* | ?:[\\/]* ) ac_abs_builddir="$ac_dir";;
+  *) ac_abs_builddir=`pwd`/"$ac_dir";;
+  esac;;
+esac
+case $ac_abs_builddir in
+.) ac_abs_top_builddir=${ac_top_builddir}.;;
+*)
+  case ${ac_top_builddir}. in
+  .) ac_abs_top_builddir=$ac_abs_builddir;;
+  [\\/]* | ?:[\\/]* ) ac_abs_top_builddir=${ac_top_builddir}.;;
+  *) ac_abs_top_builddir=$ac_abs_builddir/${ac_top_builddir}.;;
+  esac;;
+esac
+case $ac_abs_builddir in
+.) ac_abs_srcdir=$ac_srcdir;;
+*)
+  case $ac_srcdir in
+  .) ac_abs_srcdir=$ac_abs_builddir;;
+  [\\/]* | ?:[\\/]* ) ac_abs_srcdir=$ac_srcdir;;
+  *) ac_abs_srcdir=$ac_abs_builddir/$ac_srcdir;;
+  esac;;
+esac
+case $ac_abs_builddir in
+.) ac_abs_top_srcdir=$ac_top_srcdir;;
+*)
+  case $ac_top_srcdir in
+  .) ac_abs_top_srcdir=$ac_abs_builddir;;
+  [\\/]* | ?:[\\/]* ) ac_abs_top_srcdir=$ac_top_srcdir;;
+  *) ac_abs_top_srcdir=$ac_abs_builddir/$ac_top_srcdir;;
+  esac;;
+esac
+
+
+  case $INSTALL in
+  [\\/$]* | ?:[\\/]* ) ac_INSTALL=$INSTALL ;;
+  *) ac_INSTALL=$ac_top_builddir$INSTALL ;;
+  esac
+
+  if test x"$ac_file" != x-; then
+    { echo "$as_me:$LINENO: creating $ac_file" >&5
+echo "$as_me: creating $ac_file" >&6;}
+    rm -f "$ac_file"
+  fi
+  # Let's still pretend it is `configure' which instantiates (i.e., don't
+  # use $as_me), people would be surprised to read:
+  #    /* config.h.  Generated by config.status.  */
+  if test x"$ac_file" = x-; then
+    configure_input=
+  else
+    configure_input="$ac_file.  "
+  fi
+  configure_input=$configure_input"Generated from `echo $ac_file_in |
+                                    sed 's,.*/,,'` by configure."
+
+  # First look for the input files in the build tree, otherwise in the
+  # src tree.
+  ac_file_inputs=`IFS=:
+    for f in $ac_file_in; do
+      case $f in
+      -) echo $tmp/stdin ;;
+      [\\/$]*)
+        # Absolute (can't be DOS-style, as IFS=:)
+        test -f "$f" || { { echo "$as_me:$LINENO: error: cannot find input file: $f" >&5
+echo "$as_me: error: cannot find input file: $f" >&2;}
+   { (exit 1); exit 1; }; }
+        echo "$f";;
+      *) # Relative
+        if test -f "$f"; then
+          # Build tree
+          echo "$f"
+        elif test -f "$srcdir/$f"; then
+          # Source tree
+          echo "$srcdir/$f"
+        else
+          # /dev/null tree
+          { { echo "$as_me:$LINENO: error: cannot find input file: $f" >&5
+echo "$as_me: error: cannot find input file: $f" >&2;}
+   { (exit 1); exit 1; }; }
+        fi;;
+      esac
+    done` || { (exit 1); exit 1; }
+_ACEOF
+cat >>$CONFIG_STATUS <<_ACEOF
+  sed "$ac_vpsub
+$extrasub
+_ACEOF
+cat >>$CONFIG_STATUS <<\_ACEOF
+:t
+/@[a-zA-Z_][a-zA-Z_0-9]*@/!b
+s,@configure_input@,$configure_input,;t t
+s,@srcdir@,$ac_srcdir,;t t
+s,@abs_srcdir@,$ac_abs_srcdir,;t t
+s,@top_srcdir@,$ac_top_srcdir,;t t
+s,@abs_top_srcdir@,$ac_abs_top_srcdir,;t t
+s,@builddir@,$ac_builddir,;t t
+s,@abs_builddir@,$ac_abs_builddir,;t t
+s,@top_builddir@,$ac_top_builddir,;t t
+s,@abs_top_builddir@,$ac_abs_top_builddir,;t t
+s,@INSTALL@,$ac_INSTALL,;t t
+" $ac_file_inputs | (eval "$ac_sed_cmds") >$tmp/out
+  rm -f $tmp/stdin
+  if test x"$ac_file" != x-; then
+    mv $tmp/out $ac_file
+  else
+    cat $tmp/out
+    rm -f $tmp/out
+  fi
+
+done
+_ACEOF
+cat >>$CONFIG_STATUS <<\_ACEOF
+
+#
+# CONFIG_HEADER section.
+#
+
+# These sed commands are passed to sed as "A NAME B NAME C VALUE D", where
+# NAME is the cpp macro being defined and VALUE is the value it is being given.
+#
+# ac_d sets the value in "#define NAME VALUE" lines.
+ac_dA='s,^\([   ]*\)#\([        ]*define[       ][      ]*\)'
+ac_dB='[        ].*$,\1#\2'
+ac_dC=' '
+ac_dD=',;t'
+# ac_u turns "#undef NAME" without trailing blanks into "#define NAME VALUE".
+ac_uA='s,^\([   ]*\)#\([        ]*\)undef\([    ][      ]*\)'
+ac_uB='$,\1#\2define\3'
+ac_uC=' '
+ac_uD=',;t'
+
+for ac_file in : $CONFIG_HEADERS; do test "x$ac_file" = x: && continue
+  # Support "outfile[:infile[:infile...]]", defaulting infile="outfile.in".
+  case $ac_file in
+  - | *:- | *:-:* ) # input from stdin
+       cat >$tmp/stdin
+       ac_file_in=`echo "$ac_file" | sed 's,[^:]*:,,'`
+       ac_file=`echo "$ac_file" | sed 's,:.*,,'` ;;
+  *:* ) ac_file_in=`echo "$ac_file" | sed 's,[^:]*:,,'`
+       ac_file=`echo "$ac_file" | sed 's,:.*,,'` ;;
+  * )   ac_file_in=$ac_file.in ;;
+  esac
+
+  test x"$ac_file" != x- && { echo "$as_me:$LINENO: creating $ac_file" >&5
+echo "$as_me: creating $ac_file" >&6;}
+
+  # First look for the input files in the build tree, otherwise in the
+  # src tree.
+  ac_file_inputs=`IFS=:
+    for f in $ac_file_in; do
+      case $f in
+      -) echo $tmp/stdin ;;
+      [\\/$]*)
+        # Absolute (can't be DOS-style, as IFS=:)
+        test -f "$f" || { { echo "$as_me:$LINENO: error: cannot find input file: $f" >&5
+echo "$as_me: error: cannot find input file: $f" >&2;}
+   { (exit 1); exit 1; }; }
+        # Do quote $f, to prevent DOS paths from being IFS'd.
+        echo "$f";;
+      *) # Relative
+        if test -f "$f"; then
+          # Build tree
+          echo "$f"
+        elif test -f "$srcdir/$f"; then
+          # Source tree
+          echo "$srcdir/$f"
+        else
+          # /dev/null tree
+          { { echo "$as_me:$LINENO: error: cannot find input file: $f" >&5
+echo "$as_me: error: cannot find input file: $f" >&2;}
+   { (exit 1); exit 1; }; }
+        fi;;
+      esac
+    done` || { (exit 1); exit 1; }
+  # Remove the trailing spaces.
+  sed 's/[      ]*$//' $ac_file_inputs >$tmp/in
+
+_ACEOF
+
+# Transform confdefs.h into two sed scripts, `conftest.defines' and
+# `conftest.undefs', that substitutes the proper values into
+# config.h.in to produce config.h.  The first handles `#define'
+# templates, and the second `#undef' templates.
+# And first: Protect against being on the right side of a sed subst in
+# config.status.  Protect against being in an unquoted here document
+# in config.status.
+rm -f conftest.defines conftest.undefs
+# Using a here document instead of a string reduces the quoting nightmare.
+# Putting comments in sed scripts is not portable.
+#
+# `end' is used to avoid that the second main sed command (meant for
+# 0-ary CPP macros) applies to n-ary macro definitions.
+# See the Autoconf documentation for `clear'.
+cat >confdef2sed.sed <<\_ACEOF
+s/[\\&,]/\\&/g
+s,[\\$`],\\&,g
+t clear
+: clear
+s,^[    ]*#[    ]*define[       ][      ]*\([^  (][^    (]*\)\(([^)]*)\)[       ]*\(.*\)$,${ac_dA}\1${ac_dB}\1\2${ac_dC}\3${ac_dD},gp
+t end
+s,^[    ]*#[    ]*define[       ][      ]*\([^  ][^     ]*\)[   ]*\(.*\)$,${ac_dA}\1${ac_dB}\1${ac_dC}\2${ac_dD},gp
+: end
+_ACEOF
+# If some macros were called several times there might be several times
+# the same #defines, which is useless.  Nevertheless, we may not want to
+# sort them, since we want the *last* AC-DEFINE to be honored.
+uniq confdefs.h | sed -n -f confdef2sed.sed >conftest.defines
+sed 's/ac_d/ac_u/g' conftest.defines >conftest.undefs
+rm -f confdef2sed.sed
+
+# This sed command replaces #undef with comments.  This is necessary, for
+# example, in the case of _POSIX_SOURCE, which is predefined and required
+# on some systems where configure will not decide to define it.
+cat >>conftest.undefs <<\_ACEOF
+s,^[    ]*#[    ]*undef[        ][      ]*[a-zA-Z_][a-zA-Z_0-9]*,/* & */,
+_ACEOF
+
+# Break up conftest.defines because some shells have a limit on the size
+# of here documents, and old seds have small limits too (100 cmds).
+echo '  # Handle all the #define templates only if necessary.' >>$CONFIG_STATUS
+echo '  if grep "^[     ]*#[    ]*define" $tmp/in >/dev/null; then' >>$CONFIG_STATUS
+echo '  # If there are no defines, we may have an empty if/fi' >>$CONFIG_STATUS
+echo '  :' >>$CONFIG_STATUS
+rm -f conftest.tail
+while grep . conftest.defines >/dev/null
+do
+  # Write a limited-size here document to $tmp/defines.sed.
+  echo '  cat >$tmp/defines.sed <<CEOF' >>$CONFIG_STATUS
+  # Speed up: don't consider the non `#define' lines.
+  echo '/^[     ]*#[    ]*define/!b' >>$CONFIG_STATUS
+  # Work around the forget-to-reset-the-flag bug.
+  echo 't clr' >>$CONFIG_STATUS
+  echo ': clr' >>$CONFIG_STATUS
+  sed ${ac_max_here_lines}q conftest.defines >>$CONFIG_STATUS
+  echo 'CEOF
+  sed -f $tmp/defines.sed $tmp/in >$tmp/out
+  rm -f $tmp/in
+  mv $tmp/out $tmp/in
+' >>$CONFIG_STATUS
+  sed 1,${ac_max_here_lines}d conftest.defines >conftest.tail
+  rm -f conftest.defines
+  mv conftest.tail conftest.defines
+done
+rm -f conftest.defines
+echo '  fi # grep' >>$CONFIG_STATUS
+echo >>$CONFIG_STATUS
+
+# Break up conftest.undefs because some shells have a limit on the size
+# of here documents, and old seds have small limits too (100 cmds).
+echo '  # Handle all the #undef templates' >>$CONFIG_STATUS
+rm -f conftest.tail
+while grep . conftest.undefs >/dev/null
+do
+  # Write a limited-size here document to $tmp/undefs.sed.
+  echo '  cat >$tmp/undefs.sed <<CEOF' >>$CONFIG_STATUS
+  # Speed up: don't consider the non `#undef'
+  echo '/^[     ]*#[    ]*undef/!b' >>$CONFIG_STATUS
+  # Work around the forget-to-reset-the-flag bug.
+  echo 't clr' >>$CONFIG_STATUS
+  echo ': clr' >>$CONFIG_STATUS
+  sed ${ac_max_here_lines}q conftest.undefs >>$CONFIG_STATUS
+  echo 'CEOF
+  sed -f $tmp/undefs.sed $tmp/in >$tmp/out
+  rm -f $tmp/in
+  mv $tmp/out $tmp/in
+' >>$CONFIG_STATUS
+  sed 1,${ac_max_here_lines}d conftest.undefs >conftest.tail
+  rm -f conftest.undefs
+  mv conftest.tail conftest.undefs
+done
+rm -f conftest.undefs
+
+cat >>$CONFIG_STATUS <<\_ACEOF
+  # Let's still pretend it is `configure' which instantiates (i.e., don't
+  # use $as_me), people would be surprised to read:
+  #    /* config.h.  Generated by config.status.  */
+  if test x"$ac_file" = x-; then
+    echo "/* Generated by configure.  */" >$tmp/config.h
+  else
+    echo "/* $ac_file.  Generated by configure.  */" >$tmp/config.h
+  fi
+  cat $tmp/in >>$tmp/config.h
+  rm -f $tmp/in
+  if test x"$ac_file" != x-; then
+    if diff $ac_file $tmp/config.h >/dev/null 2>&1; then
+      { echo "$as_me:$LINENO: $ac_file is unchanged" >&5
+echo "$as_me: $ac_file is unchanged" >&6;}
+    else
+      ac_dir=`(dirname "$ac_file") 2>/dev/null ||
+$as_expr X"$ac_file" : 'X\(.*[^/]\)//*[^/][^/]*/*$' \| \
+        X"$ac_file" : 'X\(//\)[^/]' \| \
+        X"$ac_file" : 'X\(//\)$' \| \
+        X"$ac_file" : 'X\(/\)' \| \
+        .     : '\(.\)' 2>/dev/null ||
+echo X"$ac_file" |
+    sed '/^X\(.*[^/]\)\/\/*[^/][^/]*\/*$/{ s//\1/; q; }
+         /^X\(\/\/\)[^/].*/{ s//\1/; q; }
+         /^X\(\/\/\)$/{ s//\1/; q; }
+         /^X\(\/\).*/{ s//\1/; q; }
+         s/.*/./; q'`
+      { if $as_mkdir_p; then
+    mkdir -p "$ac_dir"
+  else
+    as_dir="$ac_dir"
+    as_dirs=
+    while test ! -d "$as_dir"; do
+      as_dirs="$as_dir $as_dirs"
+      as_dir=`(dirname "$as_dir") 2>/dev/null ||
+$as_expr X"$as_dir" : 'X\(.*[^/]\)//*[^/][^/]*/*$' \| \
+        X"$as_dir" : 'X\(//\)[^/]' \| \
+        X"$as_dir" : 'X\(//\)$' \| \
+        X"$as_dir" : 'X\(/\)' \| \
+        .     : '\(.\)' 2>/dev/null ||
+echo X"$as_dir" |
+    sed '/^X\(.*[^/]\)\/\/*[^/][^/]*\/*$/{ s//\1/; q; }
+         /^X\(\/\/\)[^/].*/{ s//\1/; q; }
+         /^X\(\/\/\)$/{ s//\1/; q; }
+         /^X\(\/\).*/{ s//\1/; q; }
+         s/.*/./; q'`
+    done
+    test ! -n "$as_dirs" || mkdir $as_dirs
+  fi || { { echo "$as_me:$LINENO: error: cannot create directory \"$ac_dir\"" >&5
+echo "$as_me: error: cannot create directory \"$ac_dir\"" >&2;}
+   { (exit 1); exit 1; }; }; }
+
+      rm -f $ac_file
+      mv $tmp/config.h $ac_file
+    fi
+  else
+    cat $tmp/config.h
+    rm -f $tmp/config.h
+  fi
+done
+_ACEOF
+
+cat >>$CONFIG_STATUS <<\_ACEOF
+
+{ (exit 0); exit 0; }
+_ACEOF
+chmod +x $CONFIG_STATUS
+ac_clean_files=$ac_clean_files_save
+
+
+# configure is writing to config.log, and then calls config.status.
+# config.status does its own redirection, appending to config.log.
+# Unfortunately, on DOS this fails, as config.log is still kept open
+# by configure, so config.status won't be able to write to it; its
+# output is simply discarded.  So we exec the FD to /dev/null,
+# effectively closing config.log, so it can be properly (re)opened and
+# appended to by config.status.  When coming back to configure, we
+# need to make the FD available again.
+if test "$no_create" != yes; then
+  ac_cs_success=:
+  ac_config_status_args=
+  test "$silent" = yes &&
+    ac_config_status_args="$ac_config_status_args --quiet"
+  exec 5>/dev/null
+  $SHELL $CONFIG_STATUS $ac_config_status_args || ac_cs_success=false
+  exec 5>>config.log
+  # Use ||, not &&, to avoid exiting from the if with $? = 1, which
+  # would make configure fail if this is the last instruction.
+  $ac_cs_success || { (exit 1); exit 1; }
+fi
+
+
+#====================================================================================
+
+echo "$as_me:$LINENO: result:
+-=-=-=-=-=-=-=-=-=-= Configuration Complete =-=-=-=-=-=-=-=-=-=-
+
+  Configuration summary :
+
+    Version : ..................... ${VERSION}
+    Experimental code : ........... ${enable_experimental:-no}
+" >&5
+echo "${ECHO_T}
+-=-=-=-=-=-=-=-=-=-= Configuration Complete =-=-=-=-=-=-=-=-=-=-
+
+  Configuration summary :
+
+    Version : ..................... ${VERSION}
+    Experimental code : ........... ${enable_experimental:-no}
+" >&6
+
+if test x$ac_cv_c_compiler_gnu = xyes ; then
+       echo -e "  Tools :\n"
+       echo "    Compiler is GCC : ............. ${ac_cv_c_compiler_gnu}"
+       echo "    GCC major version : ........... ${GCC_MAJOR_VERSION}"
+       if test $GCC_MAJOR_VERSION -lt 3 ; then
+               echo -e "\n    ** This compiler version allows applications to write"
+               echo "    ** to static strings within the library."
+               echo "    ** Compile with GCC version 3.X to avoid this problem."
+               fi
+       fi
+
+if test $libdir = "\${exec_prefix}/lib" ; then
+       libdir="$prefix/lib"
+       fi
+
+if test $bindir = "\${exec_prefix}/bin" ; then
+       bindir="$prefix/bin"
+       fi
+
+echo "$as_me:$LINENO: result:
+  Installation directories :
+
+    Library directory : ........... $libdir
+    Program directory : ........... $bindir
+    Pkgconfig directory : ......... $libdir/pkgconfig
+    HTML docs directory : ......... $htmldocdir
+" >&5
+echo "${ECHO_T}
+  Installation directories :
+
+    Library directory : ........... $libdir
+    Program directory : ........... $bindir
+    Pkgconfig directory : ......... $libdir/pkgconfig
+    HTML docs directory : ......... $htmldocdir
+" >&6
+
+if test x$prefix != "x/usr" ; then
+       echo "Compiling some other packages against libsndfile may require"
+       echo -e "the addition of \"$libdir/pkgconfig\" to the"
+       echo -e "PKG_CONFIG_PATH environment variable.\n"
+       fi
+
+#====================================================================================
+
diff --git a/libs/libsndfile/configure.ac b/libs/libsndfile/configure.ac
new file mode 100644 (file)
index 0000000..c6cb55f
--- /dev/null
@@ -0,0 +1,541 @@
+# Copyright (C) 1999-2006 Erik de Castro Lopo (erikd AT mega-nerd DOT com).
+
+dnl Require autoconf version
+AC_PREREQ(2.59)
+
+AC_INIT([libsndfile],[ardour-special],[ardour@ardour.org])
+AC_CONFIG_SRCDIR([src/sndfile.c])
+AC_CANONICAL_TARGET([])
+
+AC_CONFIG_HEADERS(src/config.h)
+
+AC_LANG([C])
+
+#------------------------------------------------------------------------------------
+# Rules for library version information:
+#
+#  1. Start with version information of `0:0:0' for each libtool library.
+#  2. Update the version information only immediately before a public release of
+#     your software. More frequent updates are unnecessary, and only guarantee
+#     that the current interface number gets larger faster.
+#  3. If the library source code has changed at all since the last update, then
+#     increment revision (`c:r:a' becomes `c:r+1:a').
+#  4. If any interfaces have been added, removed, or changed since the last update,
+#     increment current, and set revision to 0.
+#  5. If any interfaces have been added since the last public release, then increment
+#     age.
+#  6. If any interfaces have been removed since the last public release, then set age
+#     to 0.
+
+SHARED_VERSION_INFO="1:16:0"
+
+AC_PROG_CC
+#AM_PROG_LIBTOOL
+
+AC_CHECK_PROG(autogen, autogen, yes, no)
+
+AC_PROG_INSTALL
+AC_PROG_LN_S
+
+AC_HEADER_STDC
+
+AC_CHECK_HEADERS(endian.h)
+AC_CHECK_HEADERS(byteswap.h)
+AC_CHECK_HEADERS(locale.h)
+AC_CHECK_HEADERS(inttypes.h)
+
+AC_HEADER_SYS_WAIT
+
+AC_CHECK_DECLS(S_IRGRP)
+AC_DEFINE_UNQUOTED([HAVE_DECL_S_IRGRP],${HAVE_DECL_S_IRGRP},
+               [Set to 1 if S_IRGRP is defined.])
+
+#====================================================================================
+# Check for support of the struct hack.
+
+AC_C99_FLEXIBLE_ARRAY
+
+if test x$ac_cv_c99_flexible_array = xyes ; then
+       AC_DEFINE([HAVE_FLEXIBLE_ARRAY],1, [Set to 1 if the compile supports the struct hack.])
+else
+       AC_MSG_WARN([[*** This compiler does not support the 1999 ISO C Standard ***]])
+       AC_MSG_WARN([[*** feature known as the flexible array struct member.     ***]])
+       AC_DEFINE([HAVE_FLEXIBLE_ARRAY],0)
+       fi
+
+#====================================================================================
+# Couple of initializations here. Fill in real values later.
+
+SHLIB_VERSION_ARG=""
+
+#====================================================================================
+# Finished checking, handle options.
+
+AC_ARG_ENABLE(experimental,
+       AC_HELP_STRING([--enable-experimental], [enable experimental code]))
+
+EXPERIMENTAL_CODE=0
+if test x$enable_experimental = xyes ; then
+       EXPERIMENTAL_CODE=1
+       fi
+AC_DEFINE_UNQUOTED([ENABLE_EXPERIMENTAL_CODE],${EXPERIMENTAL_CODE}, [Set to 1 to enable experimental code.])
+
+AC_ARG_ENABLE(gcc-werror,
+       AC_HELP_STRING([--enable-gcc-werror], [enable -Werror in all Makefiles]))
+
+AC_ARG_ENABLE(gcc-pipe,
+       AC_HELP_STRING([--disable-gcc-pipe], [disable gcc -pipe option]))
+
+AC_ARG_ENABLE(gcc-opt,
+       AC_HELP_STRING([--disable-gcc-opt], [disable gcc optimisations]))
+
+AC_ARG_ENABLE(cpu-clip,
+       AC_HELP_STRING([--disable-cpu-clip], [disable tricky cpu specific clipper]))
+
+AC_ARG_ENABLE(bow-docs,
+       AC_HELP_STRING([--enable-bow-docs], [enable black-on-white html docs]))
+
+AC_ARG_ENABLE(sqlite,
+       AC_HELP_STRING([--disable-sqlite], [disable use of sqlite]))
+
+AC_ARG_ENABLE(flac,
+       AC_HELP_STRING([--disable-flac], [disable use of FLAC]))
+
+AC_ARG_ENABLE(alsa,
+       AC_HELP_STRING([--disable-alsa], [disable use of ALSA]))
+
+#====================================================================================
+# Check types and their sizes.
+
+AC_CHECK_SIZEOF(short,2)
+AC_CHECK_SIZEOF(int,4)
+AC_CHECK_SIZEOF(long,4)
+AC_CHECK_SIZEOF(float,4)
+AC_CHECK_SIZEOF(double,4)
+AC_CHECK_SIZEOF(void*,8)
+AC_CHECK_SIZEOF(size_t,4)
+AC_CHECK_SIZEOF(int64_t,8)
+AC_CHECK_SIZEOF(long long,8)
+
+#====================================================================================
+# Find an appropriate type for sf_count_t.
+# On systems supporting files larger than 2 Gig, sf_count_t must be a 64 bit value.
+# Unfortunately there is more than one way of ensuring this so need to do some
+# pretty rigourous testing here.
+
+unset ac_cv_sizeof_off_t
+
+AC_CHECK_SIZEOF(off_t,1)       # Fake default value.
+
+case "$host_os" in
+       mingw*)
+               TYPEOF_SF_COUNT_T="__int64"
+               SF_COUNT_MAX="0x7FFFFFFFFFFFFFFFLL"
+               SIZEOF_SF_COUNT_T=8
+               ;;
+       *)
+               if test "x$ac_cv_sizeof_off_t" = "x8" ; then
+                       # If sizeof (off_t) is 8, no further checking is needed.
+                       TYPEOF_SF_COUNT_T="off_t"
+                       SF_COUNT_MAX="0x7FFFFFFFFFFFFFFFLL"
+                       SIZEOF_SF_COUNT_T=8
+               else
+                       # Check for common 64 bit file offset types.
+                       AC_CHECK_SIZEOF(loff_t,1)       # Fake default value.
+                       AC_CHECK_SIZEOF(off64_t,1)      # Fake default value.
+
+                       TYPEOF_SF_COUNT_T="unknown"
+                       if test "x$ac_cv_sizeof_loff_t" = "x8" ; then
+                               TYPEOF_SF_COUNT_T="loff_t"
+                               SIZEOF_SF_COUNT_T=8
+                       elif test "x$ac_cv_sizeof_off64_t" = "x8" ; then
+                               TYPEOF_SF_COUNT_T="off64_t"
+                               SIZEOF_SF_COUNT_T=8
+                               fi
+
+                       # Save the old sizeof (off_t) value  and then unset it to see if it
+                       # changes when Large File Support is enabled.
+
+                       pre_largefile_sizeof_off_t=$ac_cv_sizeof_off_t
+                       unset ac_cv_sizeof_off_t
+
+                       AC_SYS_EXTRA_LARGEFILE
+
+                       if test "x$ac_cv_sys_largefile_CFLAGS" = "xno" ; then
+                               ac_cv_sys_largefile_CFLAGS=""
+                               fi
+                       if test "x$ac_cv_sys_largefile_LDFLAGS" = "xno" ; then
+                               ac_cv_sys_largefile_LDFLAGS=""
+                               fi
+                       if test "x$ac_cv_sys_largefile_LIBS" = "xno" ; then
+                               ac_cv_sys_largefile_LIBS=""
+                               fi
+
+                       AC_CHECK_SIZEOF(off_t,1)        # Fake default value.
+
+                       if test "x$ac_cv_sizeof_off_t" = "x8" ; then
+                               SF_COUNT_MAX="0x7FFFFFFFFFFFFFFFLL"
+                       elif test "x$ac_cv_sizeof_off_t" = "x$pre_largefile_sizeof_off_t" ; then
+                               AC_MSG_WARN([[This machine does not seem to support 64 bit file offsets.]])
+                               TYPEOF_SF_COUNT_T="off_t"
+                               SIZEOF_SF_COUNT_T=$ac_cv_sizeof_off_t
+                       elif test "x$TYPEOF_SF_COUNT_T" = "xunknown" ; then
+                               echo
+                               echo "*** The configure process has determined that this system is capable"
+                               echo "*** of Large File Support but has not been able to find a type which"
+                               echo "*** is an unambiguous 64 bit file offset."
+                               echo "*** Please contact the author to help resolve this problem."
+                               echo
+                               AC_MSG_ERROR([[Bad file offset type.]])
+                               fi
+                       fi
+               ;;
+       esac
+
+if test $SIZEOF_SF_COUNT_T = 4 ; then
+       SF_COUNT_MAX="0x7FFFFFFF"
+       fi
+
+AC_DEFINE_UNQUOTED([TYPEOF_SF_COUNT_T],${TYPEOF_SF_COUNT_T}, [Set to long if unknown.])
+AC_SUBST(TYPEOF_SF_COUNT_T)
+
+AC_DEFINE_UNQUOTED([SIZEOF_SF_COUNT_T],${SIZEOF_SF_COUNT_T}, [Set to sizeof (long) if unknown.])
+AC_SUBST(SIZEOF_SF_COUNT_T)
+
+AC_DEFINE_UNQUOTED([SF_COUNT_MAX],${SF_COUNT_MAX}, [Set to maximum allowed value of sf_count_t type.])
+AC_SUBST(SF_COUNT_MAX)
+
+AC_CHECK_TYPES(ssize_t)
+AC_CHECK_SIZEOF(ssize_t,4)
+
+#====================================================================================
+# Determine endian-ness of target processor.
+
+AC_C_FIND_ENDIAN
+
+AC_DEFINE_UNQUOTED(CPU_IS_BIG_ENDIAN, ${ac_cv_c_big_endian},
+       [Target processor is big endian.])
+AC_DEFINE_UNQUOTED(CPU_IS_LITTLE_ENDIAN, ${ac_cv_c_little_endian},
+       [Target processor is little endian.])
+
+#====================================================================================
+# Check for functions.
+
+AC_CHECK_FUNCS(malloc calloc realloc free)
+AC_CHECK_FUNCS(open read write lseek pread pwrite)
+AC_CHECK_FUNCS(fstat ftruncate fsync fdatasync)
+AC_CHECK_FUNCS(snprintf vsnprintf)
+AC_CHECK_FUNCS(gmtime gmtime_r)
+AC_CHECK_FUNCS(mmap getpagesize)
+AC_CHECK_FUNCS(setlocale)
+
+AC_CHECK_LIB([m],floor)
+AC_CHECK_FUNCS(floor ceil fmod)
+
+case "$host_os" in
+       cygwin*)
+               AC_MSG_WARN([[Not using built-in lrint() and lrintf() because they are broken on Cygwin.]])
+               ;;
+       *)
+               AC_C99_FUNC_LRINT
+               AC_C99_FUNC_LRINTF
+
+               if test "x$ac_cv_c99_lrint" = "xno" ; then
+                       if test "x$ac_cv_c99_lrintf" = "xno" ; then
+                               AC_MSG_WARN([[*** Missing C99 standard functions lrint() and lrintf().]])
+                               AC_MSG_WARN([[*** This may cause benign compiler warnings on some systems (ie Solaris).]])
+                               fi
+                       fi
+               ;;
+       esac
+
+#====================================================================================
+# Check for libsqlite3 (only used in regtest).
+
+ac_cv_sqlite3=no
+if test x$enable_sqlite != xno ; then
+       PKG_CHECK_MODULES(SQLITE3, sqlite3 >= 3.2, ac_cv_sqlite3=yes, ac_cv_sqlite3=no)
+       fi
+
+if test x$ac_cv_sqlite3 = "xyes" ; then
+       HAVE_SQLITE3=1
+else
+       HAVE_SQLITE3=0
+       fi
+
+AC_DEFINE_UNQUOTED([HAVE_SQLITE3],$HAVE_SQLITE3,[Set to 1 if you have libsqlite3.])
+
+#====================================================================================
+# Determine if the processor can do clipping on float to int conversions.
+
+if test x$enable_cpu_clip != "xno" ; then
+       AC_C_CLIP_MODE
+else
+       echo "checking processor clipping capabilities... disabled"
+       ac_cv_c_clip_positive=0
+       ac_cv_c_clip_negative=0
+       fi
+
+AC_DEFINE_UNQUOTED(CPU_CLIPS_POSITIVE, ${ac_cv_c_clip_positive},
+       [Target processor clips on positive float to int conversion.])
+AC_DEFINE_UNQUOTED(CPU_CLIPS_NEGATIVE, ${ac_cv_c_clip_negative},
+       [Target processor clips on negative float to int conversion.])
+
+#====================================================================================
+# Target OS specific stuff.
+
+OS_SPECIFIC_CFLAGS=""
+OS_SPECIFIC_LINKS=""
+os_is_win32=0
+os_is_macosx=0
+use_windows_api=0
+
+case "$host_os" in
+       darwin* | rhapsody*)
+               os_is_macosx=1
+               OS_SPECIFIC_CFLAGS="-fpascal-strings -I/Developer/Headers/FlatCarbon"
+               OS_SPECIFIC_LINKS="-framework CoreAudio"
+               ;;
+       mingw*)
+               os_is_win32=1
+               use_windows_api=1
+               OS_SPECIFIC_LINKS="-lwinmm"
+               ;;
+       cygwin*)
+               os_is_win32=1
+               OS_SPECIFIC_LINKS="-lwinmm"
+               ;;
+       esac
+
+AC_DEFINE_UNQUOTED(OS_IS_WIN32, ${os_is_win32}, [Set to 1 if compiling for Win32])
+AC_DEFINE_UNQUOTED(OS_IS_MACOSX, ${os_is_macosx}, [Set to 1 if compiling for MacOSX])
+AC_DEFINE_UNQUOTED(USE_WINDOWS_API, ${use_windows_api}, [Set to 1 to use the native windows API])
+
+#====================================================================================
+# Check for ALSA.
+
+ALSA_LIBS=""
+
+if test x$enable_alsa != xno ; then
+       AC_CHECK_HEADERS(alsa/asoundlib.h)
+       if test x$ac_cv_header_alsa_asoundlib_h = xyes ; then
+               ALSA_LIBS="-lasound"
+               fi
+       fi
+
+#====================================================================================
+# Check for FLAC
+
+FLAC_LIBS=""
+
+if test x$enable_flac != xno ; then
+       AC_CHECK_HEADERS(FLAC/all.h)
+       if test x$ac_cv_header_FLAC_all_h = xyes ; then
+               AC_CHECK_LIB(FLAC, FLAC__seekable_stream_encoder_set_tell_callback, HAVE_FLAC_1_1_1="yes")
+               if test "x$HAVE_FLAC_1_1_1" = xyes ; then
+                       AC_DEFINE(HAVE_FLAC_1_1_1, [1], [Define to 1 if you have libflac 1.1.1])
+                       fi
+               FLAC_LIBS="-lFLAC"
+               fi
+       fi
+
+#====================================================================================
+# Test for sanity when cross-compiling.
+
+if test x$cross_compiling = xyes ; then
+       AC_MSG_WARN([[******************************************************************]])
+       AC_MSG_WARN([[*** We are cross-compiling, so have to assume sizeof (short) == 2 ]])
+       AC_MSG_WARN([[*** and sizeof (int) == 4. If this is not the case there is no    ]])
+       AC_MSG_WARN([[*** chance of this working. Please contact the mantainer.         ]])
+       AC_MSG_WARN([[******************************************************************]])
+       fi
+
+if test $ac_cv_sizeof_short != 2 ; then
+       AC_MSG_WARN([[******************************************************************]])
+       AC_MSG_WARN([[*** sizeof (short) != 2.                                          ]])
+       AC_MSG_WARN([[******************************************************************]])
+       fi
+
+if test $ac_cv_sizeof_int != 4 ; then
+       AC_MSG_WARN([[******************************************************************]])
+       AC_MSG_WARN([[*** sizeof (int) != 4                                             ]])
+       AC_MSG_WARN([[******************************************************************]])
+       fi
+
+if test $ac_cv_sizeof_float != 4 ; then
+       AC_MSG_WARN([[******************************************************************]])
+       AC_MSG_WARN([[*** sizeof (float) != 4.                                          ]])
+       AC_MSG_WARN([[******************************************************************]])
+       fi
+
+if test $ac_cv_sizeof_double != 8 ; then
+       AC_MSG_WARN([[******************************************************************]])
+       AC_MSG_WARN([[*** sizeof (double) != 8.                                         ]])
+       AC_MSG_WARN([[******************************************************************]])
+       fi
+
+if test x"$ac_cv_prog_autogen" = "xno" ; then
+       AC_MSG_WARN([[Touching files in directory tests/.]])
+       touch tests/*.c tests/*.h
+       fi
+
+#====================================================================================
+# Settings for the HTML documentation.
+
+htmldocdir=$prefix/share/doc/libsndfile1-dev/html
+
+if test $prefix = "NONE" ; then
+       htmldocdir=/usr/local/share/doc/libsndfile1-dev/html
+else
+       htmldocdir=$prefix/share/doc/libsndfile1-dev/html
+       fi
+
+if test x$enable_bow_docs = "xyes" ; then
+       HTML_BGCOLOUR="white"
+       HTML_FGCOLOUR="black"
+else
+       HTML_BGCOLOUR="black"
+       HTML_FGCOLOUR="white"
+       fi
+
+#====================================================================================
+# Now use the information from the checking stage.
+
+if test x$ac_cv_c_compiler_gnu = xyes ; then
+       AC_ADD_CFLAGS(-std=gnu99)
+
+       CFLAGS="$CFLAGS -W -Wall"
+
+       AC_ADD_CFLAGS(-Wdeclaration-after-statement)
+
+       if test x$enable_gcc_werror = "xyes" ; then
+               CFLAGS="-Werror $CFLAGS"
+               fi
+
+       CFLAGS="$CFLAGS -Wstrict-prototypes -Wmissing-prototypes -Waggregate-return -Wcast-align -Wcast-qual -Wnested-externs -Wshadow -Wbad-function-cast -Wwrite-strings"
+       # -Wpointer-arith -Wundef -Wmissing-declarations -Winline -Wconversion"
+
+       if test "x$enable_gcc_opt" = "xno" ; then
+               temp_CFLAGS=`echo $CFLAGS | sed "s/O2/O0/"`
+               CFLAGS=$temp_CFLAGS
+               AC_MSG_WARN([[*** Compiler optimisations switched off. ***]])
+               fi
+
+       # OS specific tweaks.
+       case "$host_os" in
+               darwin* | rhapsody*)
+                       # Disable -Wall, -pedantic and -Wshadow for Apple Darwin/Rhapsody.
+                       # System headers on these systems are broken.
+                       temp_CFLAGS=`echo $CFLAGS | sed "s/-Wall -pedantic//" | sed "s/-Wshadow//" | sed "s/-Waggregate-return//"`
+                       CFLAGS=$temp_CFLAGS
+                       SHLIB_VERSION_ARG="-Wl,-exported_symbols_list -Wl,\$(srcdir)/Symbols.darwin"
+                       ;;
+               linux*)
+                       SHLIB_VERSION_ARG="-Wl,--version-script=\$(srcdir)/Symbols.linux"
+                       ;;
+               mingw*)
+                       SHLIB_VERSION_ARG="-Wl,\$(srcdir)/libsndfile.def"
+                       ;;
+               cygwin*)
+                       SHLIB_VERSION_ARG="-Wl,\$(srcdir)/cygsndfile.def"
+                       ;;
+               *)
+                       ;;
+               esac
+       if test x$enable_gcc_pipe != "xno" ; then
+               CFLAGS="$CFLAGS -pipe"
+               fi
+
+       AC_DEFINE([COMPILER_IS_GCC],1, [Set to 1 if the compile is GNU GCC.])
+       GCC_MAJOR_VERSION=`$CC -dumpversion | sed "s/\..*//"`
+       AC_DEFINE_UNQUOTED([GCC_MAJOR_VERSION],${GCC_MAJOR_VERSION}, [Major version of GCC or 3 otherwise.])
+       fi
+
+CFLAGS="$CFLAGS $OS_SPECIFIC_CFLAGS"
+
+if test x"$CFLAGS" = x ; then
+       echo "Error in configure script. CFLAGS has been screwed up."
+       exit
+       fi
+
+AC_SUBST(htmldocdir)
+AC_SUBST(HTML_BGCOLOUR)
+AC_SUBST(HTML_FGCOLOUR)
+
+AC_SUBST(SHLIB_VERSION_ARG)
+AC_SUBST(SHARED_VERSION_INFO)
+AC_SUBST(OS_SPECIFIC_CFLAGS)
+AC_SUBST(OS_SPECIFIC_LINKS)
+AC_SUBST(ALSA_LIBS)
+AC_SUBST(FLAC_LIBS)
+AC_SUBST(ENABLE_EXPERIMENTAL_CODE)
+
+AC_SUBST(COMPILER_IS_GCC)
+AC_SUBST(GCC_MAJOR_VERSION)
+
+dnl The following line causes the libtool distributed with the source
+dnl to be replaced if the build system has a more recent version.
+AC_SUBST(LIBTOOL_DEPS)
+
+AC_CONFIG_FILES([ \
+                       src/sndfile.h 
+                       sndfile.pc \
+                       ])
+AC_OUTPUT
+
+#====================================================================================
+
+AC_MSG_RESULT([
+-=-=-=-=-=-=-=-=-=-= Configuration Complete =-=-=-=-=-=-=-=-=-=-
+
+  Configuration summary :
+
+    Version : ..................... ${VERSION}
+    Experimental code : ........... ${enable_experimental:-no}
+])
+
+if test x$ac_cv_c_compiler_gnu = xyes ; then
+       echo -e "  Tools :\n"
+       echo "    Compiler is GCC : ............. ${ac_cv_c_compiler_gnu}"
+       echo "    GCC major version : ........... ${GCC_MAJOR_VERSION}"
+       if test $GCC_MAJOR_VERSION -lt 3 ; then
+               echo -e "\n    ** This compiler version allows applications to write"
+               echo "    ** to static strings within the library."
+               echo "    ** Compile with GCC version 3.X to avoid this problem."
+               fi
+       fi
+
+if test $libdir = "\${exec_prefix}/lib" ; then
+       libdir="$prefix/lib"
+       fi
+
+if test $bindir = "\${exec_prefix}/bin" ; then
+       bindir="$prefix/bin"
+       fi
+
+AC_MSG_RESULT([[
+  Installation directories :
+
+    Library directory : ........... $libdir
+    Program directory : ........... $bindir
+    Pkgconfig directory : ......... $libdir/pkgconfig
+    HTML docs directory : ......... $htmldocdir
+]])
+
+if test x$prefix != "x/usr" ; then
+       echo "Compiling some other packages against libsndfile may require"
+       echo -e "the addition of \"$libdir/pkgconfig\" to the"
+       echo -e "PKG_CONFIG_PATH environment variable.\n"
+       fi
+
+#====================================================================================
+
+ifelse(dnl
+
+ Do not edit or modify anything in this comment block.
+ The arch-tag line is a file identity tag for the GNU Arch
+ revision control system.
+
+ arch-tag: 6391b316-6cfc-43c2-a18a-8defdc4ee359
+
+)dnl
diff --git a/libs/libsndfile/depcomp b/libs/libsndfile/depcomp
new file mode 100755 (executable)
index 0000000..edb5d38
--- /dev/null
@@ -0,0 +1,479 @@
+#! /bin/sh
+
+# depcomp - compile a program generating dependencies as side-effects
+# Copyright 1999, 2000, 2003 Free Software Foundation, Inc.
+
+# This program is free software; you can redistribute it and/or modify
+# it under the terms of the GNU General Public License as published by
+# the Free Software Foundation; either version 2, or (at your option)
+# any later version.
+
+# This program is distributed in the hope that it will be useful,
+# but WITHOUT ANY WARRANTY; without even the implied warranty of
+# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+# GNU General Public License for more details.
+
+# You should have received a copy of the GNU General Public License
+# along with this program; if not, write to the Free Software
+# Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA
+# 02111-1307, USA.
+
+# As a special exception to the GNU General Public License, if you
+# distribute this file as part of a program that contains a
+# configuration script generated by Autoconf, you may include it under
+# the same distribution terms that you use for the rest of that program.
+
+# Originally written by Alexandre Oliva <oliva@dcc.unicamp.br>.
+
+if test -z "$depmode" || test -z "$source" || test -z "$object"; then
+  echo "depcomp: Variables source, object and depmode must be set" 1>&2
+  exit 1
+fi
+# `libtool' can also be set to `yes' or `no'.
+
+if test -z "$depfile"; then
+   base=`echo "$object" | sed -e 's,^.*/,,' -e 's,\.\([^.]*\)$,.P\1,'`
+   dir=`echo "$object" | sed 's,/.*$,/,'`
+   if test "$dir" = "$object"; then
+      dir=
+   fi
+   # FIXME: should be _deps on DOS.
+   depfile="$dir.deps/$base"
+fi
+
+tmpdepfile=${tmpdepfile-`echo "$depfile" | sed 's/\.\([^.]*\)$/.T\1/'`}
+
+rm -f "$tmpdepfile"
+
+# Some modes work just like other modes, but use different flags.  We
+# parameterize here, but still list the modes in the big case below,
+# to make depend.m4 easier to write.  Note that we *cannot* use a case
+# here, because this file can only contain one case statement.
+if test "$depmode" = hp; then
+  # HP compiler uses -M and no extra arg.
+  gccflag=-M
+  depmode=gcc
+fi
+
+if test "$depmode" = dashXmstdout; then
+   # This is just like dashmstdout with a different argument.
+   dashmflag=-xM
+   depmode=dashmstdout
+fi
+
+case "$depmode" in
+gcc3)
+## gcc 3 implements dependency tracking that does exactly what
+## we want.  Yay!  Note: for some reason libtool 1.4 doesn't like
+## it if -MD -MP comes after the -MF stuff.  Hmm.
+  "$@" -MT "$object" -MD -MP -MF "$tmpdepfile"
+  stat=$?
+  if test $stat -eq 0; then :
+  else
+    rm -f "$tmpdepfile"
+    exit $stat
+  fi
+  mv "$tmpdepfile" "$depfile"
+  ;;
+
+gcc)
+## There are various ways to get dependency output from gcc.  Here's
+## why we pick this rather obscure method:
+## - Don't want to use -MD because we'd like the dependencies to end
+##   up in a subdir.  Having to rename by hand is ugly.
+##   (We might end up doing this anyway to support other compilers.)
+## - The DEPENDENCIES_OUTPUT environment variable makes gcc act like
+##   -MM, not -M (despite what the docs say).
+## - Using -M directly means running the compiler twice (even worse
+##   than renaming).
+  if test -z "$gccflag"; then
+    gccflag=-MD,
+  fi
+  "$@" -Wp,"$gccflag$tmpdepfile"
+  stat=$?
+  if test $stat -eq 0; then :
+  else
+    rm -f "$tmpdepfile"
+    exit $stat
+  fi
+  rm -f "$depfile"
+  echo "$object : \\" > "$depfile"
+  alpha=ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz
+## The second -e expression handles DOS-style file names with drive letters.
+  sed -e 's/^[^:]*: / /' \
+      -e 's/^['$alpha']:\/[^:]*: / /' < "$tmpdepfile" >> "$depfile"
+## This next piece of magic avoids the `deleted header file' problem.
+## The problem is that when a header file which appears in a .P file
+## is deleted, the dependency causes make to die (because there is
+## typically no way to rebuild the header).  We avoid this by adding
+## dummy dependencies for each header file.  Too bad gcc doesn't do
+## this for us directly.
+  tr ' ' '
+' < "$tmpdepfile" |
+## Some versions of gcc put a space before the `:'.  On the theory
+## that the space means something, we add a space to the output as
+## well.
+## Some versions of the HPUX 10.20 sed can't process this invocation
+## correctly.  Breaking it into two sed invocations is a workaround.
+    sed -e 's/^\\$//' -e '/^$/d' -e '/:$/d' | sed -e 's/$/ :/' >> "$depfile"
+  rm -f "$tmpdepfile"
+  ;;
+
+hp)
+  # This case exists only to let depend.m4 do its work.  It works by
+  # looking at the text of this script.  This case will never be run,
+  # since it is checked for above.
+  exit 1
+  ;;
+
+sgi)
+  if test "$libtool" = yes; then
+    "$@" "-Wp,-MDupdate,$tmpdepfile"
+  else
+    "$@" -MDupdate "$tmpdepfile"
+  fi
+  stat=$?
+  if test $stat -eq 0; then :
+  else
+    rm -f "$tmpdepfile"
+    exit $stat
+  fi
+  rm -f "$depfile"
+
+  if test -f "$tmpdepfile"; then  # yes, the sourcefile depend on other files
+    echo "$object : \\" > "$depfile"
+
+    # Clip off the initial element (the dependent).  Don't try to be
+    # clever and replace this with sed code, as IRIX sed won't handle
+    # lines with more than a fixed number of characters (4096 in
+    # IRIX 6.2 sed, 8192 in IRIX 6.5).  We also remove comment lines;
+    # the IRIX cc adds comments like `#:fec' to the end of the
+    # dependency line.
+    tr ' ' '
+' < "$tmpdepfile" \
+    | sed -e 's/^.*\.o://' -e 's/#.*$//' -e '/^$/ d' | \
+    tr '
+' ' ' >> $depfile
+    echo >> $depfile
+
+    # The second pass generates a dummy entry for each header file.
+    tr ' ' '
+' < "$tmpdepfile" \
+   | sed -e 's/^.*\.o://' -e 's/#.*$//' -e '/^$/ d' -e 's/$/:/' \
+   >> $depfile
+  else
+    # The sourcefile does not contain any dependencies, so just
+    # store a dummy comment line, to avoid errors with the Makefile
+    # "include basename.Plo" scheme.
+    echo "#dummy" > "$depfile"
+  fi
+  rm -f "$tmpdepfile"
+  ;;
+
+aix)
+  # The C for AIX Compiler uses -M and outputs the dependencies
+  # in a .u file.  In older versions, this file always lives in the
+  # current directory.  Also, the AIX compiler puts `$object:' at the
+  # start of each line; $object doesn't have directory information.
+  # Version 6 uses the directory in both cases.
+  stripped=`echo "$object" | sed 's/\(.*\)\..*$/\1/'`
+  tmpdepfile="$stripped.u"
+  if test "$libtool" = yes; then
+    "$@" -Wc,-M
+  else
+    "$@" -M
+  fi
+  stat=$?
+
+  if test -f "$tmpdepfile"; then :
+  else
+    stripped=`echo "$stripped" | sed 's,^.*/,,'`
+    tmpdepfile="$stripped.u"
+  fi
+
+  if test $stat -eq 0; then :
+  else
+    rm -f "$tmpdepfile"
+    exit $stat
+  fi
+
+  if test -f "$tmpdepfile"; then
+    outname="$stripped.o"
+    # Each line is of the form `foo.o: dependent.h'.
+    # Do two passes, one to just change these to
+    # `$object: dependent.h' and one to simply `dependent.h:'.
+    sed -e "s,^$outname:,$object :," < "$tmpdepfile" > "$depfile"
+    sed -e "s,^$outname: \(.*\)$,\1:," < "$tmpdepfile" >> "$depfile"
+  else
+    # The sourcefile does not contain any dependencies, so just
+    # store a dummy comment line, to avoid errors with the Makefile
+    # "include basename.Plo" scheme.
+    echo "#dummy" > "$depfile"
+  fi
+  rm -f "$tmpdepfile"
+  ;;
+
+icc)
+  # Intel's C compiler understands `-MD -MF file'.  However on
+  #    icc -MD -MF foo.d -c -o sub/foo.o sub/foo.c
+  # ICC 7.0 will fill foo.d with something like
+  #    foo.o: sub/foo.c
+  #    foo.o: sub/foo.h
+  # which is wrong.  We want:
+  #    sub/foo.o: sub/foo.c
+  #    sub/foo.o: sub/foo.h
+  #    sub/foo.c:
+  #    sub/foo.h:
+  # ICC 7.1 will output
+  #    foo.o: sub/foo.c sub/foo.h
+  # and will wrap long lines using \ :
+  #    foo.o: sub/foo.c ... \
+  #     sub/foo.h ... \
+  #     ...
+
+  "$@" -MD -MF "$tmpdepfile"
+  stat=$?
+  if test $stat -eq 0; then :
+  else
+    rm -f "$tmpdepfile"
+    exit $stat
+  fi
+  rm -f "$depfile"
+  # Each line is of the form `foo.o: dependent.h',
+  # or `foo.o: dep1.h dep2.h \', or ` dep3.h dep4.h \'.
+  # Do two passes, one to just change these to
+  # `$object: dependent.h' and one to simply `dependent.h:'.
+  sed "s,^[^:]*:,$object :," < "$tmpdepfile" > "$depfile"
+  # Some versions of the HPUX 10.20 sed can't process this invocation
+  # correctly.  Breaking it into two sed invocations is a workaround.
+  sed 's,^[^:]*: \(.*\)$,\1,;s/^\\$//;/^$/d;/:$/d' < "$tmpdepfile" |
+    sed -e 's/$/ :/' >> "$depfile"
+  rm -f "$tmpdepfile"
+  ;;
+
+tru64)
+   # The Tru64 compiler uses -MD to generate dependencies as a side
+   # effect.  `cc -MD -o foo.o ...' puts the dependencies into `foo.o.d'.
+   # At least on Alpha/Redhat 6.1, Compaq CCC V6.2-504 seems to put
+   # dependencies in `foo.d' instead, so we check for that too.
+   # Subdirectories are respected.
+   dir=`echo "$object" | sed -e 's|/[^/]*$|/|'`
+   test "x$dir" = "x$object" && dir=
+   base=`echo "$object" | sed -e 's|^.*/||' -e 's/\.o$//' -e 's/\.lo$//'`
+
+   if test "$libtool" = yes; then
+      tmpdepfile1="$dir.libs/$base.lo.d"
+      tmpdepfile2="$dir.libs/$base.d"
+      "$@" -Wc,-MD
+   else
+      tmpdepfile1="$dir$base.o.d"
+      tmpdepfile2="$dir$base.d"
+      "$@" -MD
+   fi
+
+   stat=$?
+   if test $stat -eq 0; then :
+   else
+      rm -f "$tmpdepfile1" "$tmpdepfile2"
+      exit $stat
+   fi
+
+   if test -f "$tmpdepfile1"; then
+      tmpdepfile="$tmpdepfile1"
+   else
+      tmpdepfile="$tmpdepfile2"
+   fi
+   if test -f "$tmpdepfile"; then
+      sed -e "s,^.*\.[a-z]*:,$object:," < "$tmpdepfile" > "$depfile"
+      # That's a tab and a space in the [].
+      sed -e 's,^.*\.[a-z]*:[   ]*,,' -e 's,$,:,' < "$tmpdepfile" >> "$depfile"
+   else
+      echo "#dummy" > "$depfile"
+   fi
+   rm -f "$tmpdepfile"
+   ;;
+
+#nosideeffect)
+  # This comment above is used by automake to tell side-effect
+  # dependency tracking mechanisms from slower ones.
+
+dashmstdout)
+  # Important note: in order to support this mode, a compiler *must*
+  # always write the preprocessed file to stdout, regardless of -o.
+  "$@" || exit $?
+
+  # Remove the call to Libtool.
+  if test "$libtool" = yes; then
+    while test $1 != '--mode=compile'; do
+      shift
+    done
+    shift
+  fi
+
+  # Remove `-o $object'.
+  IFS=" "
+  for arg
+  do
+    case $arg in
+    -o)
+      shift
+      ;;
+    $object)
+      shift
+      ;;
+    *)
+      set fnord "$@" "$arg"
+      shift # fnord
+      shift # $arg
+      ;;
+    esac
+  done
+
+  test -z "$dashmflag" && dashmflag=-M
+  # Require at least two characters before searching for `:'
+  # in the target name.  This is to cope with DOS-style filenames:
+  # a dependency such as `c:/foo/bar' could be seen as target `c' otherwise.
+  "$@" $dashmflag |
+    sed 's:^[  ]*[^: ][^:][^:]*\:[    ]*:'"$object"'\: :' > "$tmpdepfile"
+  rm -f "$depfile"
+  cat < "$tmpdepfile" > "$depfile"
+  tr ' ' '
+' < "$tmpdepfile" | \
+## Some versions of the HPUX 10.20 sed can't process this invocation
+## correctly.  Breaking it into two sed invocations is a workaround.
+    sed -e 's/^\\$//' -e '/^$/d' -e '/:$/d' | sed -e 's/$/ :/' >> "$depfile"
+  rm -f "$tmpdepfile"
+  ;;
+
+dashXmstdout)
+  # This case only exists to satisfy depend.m4.  It is never actually
+  # run, as this mode is specially recognized in the preamble.
+  exit 1
+  ;;
+
+makedepend)
+  "$@" || exit $?
+  # Remove any Libtool call
+  if test "$libtool" = yes; then
+    while test $1 != '--mode=compile'; do
+      shift
+    done
+    shift
+  fi
+  # X makedepend
+  shift
+  cleared=no
+  for arg in "$@"; do
+    case $cleared in
+    no)
+      set ""; shift
+      cleared=yes ;;
+    esac
+    case "$arg" in
+    -D*|-I*)
+      set fnord "$@" "$arg"; shift ;;
+    # Strip any option that makedepend may not understand.  Remove
+    # the object too, otherwise makedepend will parse it as a source file.
+    -*|$object)
+      ;;
+    *)
+      set fnord "$@" "$arg"; shift ;;
+    esac
+  done
+  obj_suffix="`echo $object | sed 's/^.*\././'`"
+  touch "$tmpdepfile"
+  ${MAKEDEPEND-makedepend} -o"$obj_suffix" -f"$tmpdepfile" "$@"
+  rm -f "$depfile"
+  cat < "$tmpdepfile" > "$depfile"
+  sed '1,2d' "$tmpdepfile" | tr ' ' '
+' | \
+## Some versions of the HPUX 10.20 sed can't process this invocation
+## correctly.  Breaking it into two sed invocations is a workaround.
+    sed -e 's/^\\$//' -e '/^$/d' -e '/:$/d' | sed -e 's/$/ :/' >> "$depfile"
+  rm -f "$tmpdepfile" "$tmpdepfile".bak
+  ;;
+
+cpp)
+  # Important note: in order to support this mode, a compiler *must*
+  # always write the preprocessed file to stdout.
+  "$@" || exit $?
+
+  # Remove the call to Libtool.
+  if test "$libtool" = yes; then
+    while test $1 != '--mode=compile'; do
+      shift
+    done
+    shift
+  fi
+
+  # Remove `-o $object'.
+  IFS=" "
+  for arg
+  do
+    case $arg in
+    -o)
+      shift
+      ;;
+    $object)
+      shift
+      ;;
+    *)
+      set fnord "$@" "$arg"
+      shift # fnord
+      shift # $arg
+      ;;
+    esac
+  done
+
+  "$@" -E |
+    sed -n '/^# [0-9][0-9]* "\([^"]*\)".*/ s:: \1 \\:p' |
+    sed '$ s: \\$::' > "$tmpdepfile"
+  rm -f "$depfile"
+  echo "$object : \\" > "$depfile"
+  cat < "$tmpdepfile" >> "$depfile"
+  sed < "$tmpdepfile" '/^$/d;s/^ //;s/ \\$//;s/$/ :/' >> "$depfile"
+  rm -f "$tmpdepfile"
+  ;;
+
+msvisualcpp)
+  # Important note: in order to support this mode, a compiler *must*
+  # always write the preprocessed file to stdout, regardless of -o,
+  # because we must use -o when running libtool.
+  "$@" || exit $?
+  IFS=" "
+  for arg
+  do
+    case "$arg" in
+    "-Gm"|"/Gm"|"-Gi"|"/Gi"|"-ZI"|"/ZI")
+       set fnord "$@"
+       shift
+       shift
+       ;;
+    *)
+       set fnord "$@" "$arg"
+       shift
+       shift
+       ;;
+    esac
+  done
+  "$@" -E |
+  sed -n '/^#line [0-9][0-9]* "\([^"]*\)"/ s::echo "`cygpath -u \\"\1\\"`":p' | sort | uniq > "$tmpdepfile"
+  rm -f "$depfile"
+  echo "$object : \\" > "$depfile"
+  . "$tmpdepfile" | sed 's% %\\ %g' | sed -n '/^\(.*\)$/ s::   \1 \\:p' >> "$depfile"
+  echo "       " >> "$depfile"
+  . "$tmpdepfile" | sed 's% %\\ %g' | sed -n '/^\(.*\)$/ s::\1\::p' >> "$depfile"
+  rm -f "$tmpdepfile"
+  ;;
+
+none)
+  exec "$@"
+  ;;
+
+*)
+  echo "Unknown depmode $depmode" 1>&2
+  exit 1
+  ;;
+esac
+
+exit 0
diff --git a/libs/libsndfile/install-sh b/libs/libsndfile/install-sh
new file mode 100755 (executable)
index 0000000..6ce63b9
--- /dev/null
@@ -0,0 +1,294 @@
+#!/bin/sh
+#
+# install - install a program, script, or datafile
+#
+# This originates from X11R5 (mit/util/scripts/install.sh), which was
+# later released in X11R6 (xc/config/util/install.sh) with the
+# following copyright and license.
+#
+# Copyright (C) 1994 X Consortium
+#
+# Permission is hereby granted, free of charge, to any person obtaining a copy
+# of this software and associated documentation files (the "Software"), to
+# deal in the Software without restriction, including without limitation the
+# rights to use, copy, modify, merge, publish, distribute, sublicense, and/or
+# sell copies of the Software, and to permit persons to whom the Software is
+# furnished to do so, subject to the following conditions:
+#
+# The above copyright notice and this permission notice shall be included in
+# all copies or substantial portions of the Software.
+#
+# THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
+# IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
+# FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT.  IN NO EVENT SHALL THE
+# X CONSORTIUM BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN
+# AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNEC-
+# TION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
+#
+# Except as contained in this notice, the name of the X Consortium shall not
+# be used in advertising or otherwise to promote the sale, use or other deal-
+# ings in this Software without prior written authorization from the X Consor-
+# tium.
+#
+#
+# FSF changes to this file are in the public domain.
+#
+# Calling this script install-sh is preferred over install.sh, to prevent
+# `make' implicit rules from creating a file called install from it
+# when there is no Makefile.
+#
+# This script is compatible with the BSD install script, but was written
+# from scratch.  It can only install one file at a time, a restriction
+# shared with many OS's install programs.
+
+
+# set DOITPROG to echo to test this script
+
+# Don't use :- since 4.3BSD and earlier shells don't like it.
+doit="${DOITPROG-}"
+
+
+# put in absolute paths if you don't have them in your path; or use env. vars.
+
+mvprog="${MVPROG-mv}"
+cpprog="${CPPROG-cp}"
+chmodprog="${CHMODPROG-chmod}"
+chownprog="${CHOWNPROG-chown}"
+chgrpprog="${CHGRPPROG-chgrp}"
+stripprog="${STRIPPROG-strip}"
+rmprog="${RMPROG-rm}"
+mkdirprog="${MKDIRPROG-mkdir}"
+
+transformbasename=""
+transform_arg=""
+instcmd="$mvprog"
+chmodcmd="$chmodprog 0755"
+chowncmd=""
+chgrpcmd=""
+stripcmd=""
+rmcmd="$rmprog -f"
+mvcmd="$mvprog"
+src=""
+dst=""
+dir_arg=""
+
+while [ x"$1" != x ]; do
+    case $1 in
+       -c) instcmd=$cpprog
+           shift
+           continue;;
+
+       -d) dir_arg=true
+           shift
+           continue;;
+
+       -m) chmodcmd="$chmodprog $2"
+           shift
+           shift
+           continue;;
+
+       -o) chowncmd="$chownprog $2"
+           shift
+           shift
+           continue;;
+
+       -g) chgrpcmd="$chgrpprog $2"
+           shift
+           shift
+           continue;;
+
+       -s) stripcmd=$stripprog
+           shift
+           continue;;
+
+       -t=*) transformarg=`echo $1 | sed 's/-t=//'`
+           shift
+           continue;;
+
+       -b=*) transformbasename=`echo $1 | sed 's/-b=//'`
+           shift
+           continue;;
+
+       *)  if [ x"$src" = x ]
+           then
+               src=$1
+           else
+               # this colon is to work around a 386BSD /bin/sh bug
+               :
+               dst=$1
+           fi
+           shift
+           continue;;
+    esac
+done
+
+if [ x"$src" = x ]
+then
+       echo "$0: no input file specified" >&2
+       exit 1
+else
+       :
+fi
+
+if [ x"$dir_arg" != x ]; then
+       dst=$src
+       src=""
+
+       if [ -d "$dst" ]; then
+               instcmd=:
+               chmodcmd=""
+       else
+               instcmd=$mkdirprog
+       fi
+else
+
+# Waiting for this to be detected by the "$instcmd $src $dsttmp" command
+# might cause directories to be created, which would be especially bad
+# if $src (and thus $dsttmp) contains '*'.
+
+       if [ -f "$src" ] || [ -d "$src" ]
+       then
+               :
+       else
+               echo "$0: $src does not exist" >&2
+               exit 1
+       fi
+
+       if [ x"$dst" = x ]
+       then
+               echo "$0: no destination specified" >&2
+               exit 1
+       else
+               :
+       fi
+
+# If destination is a directory, append the input filename; if your system
+# does not like double slashes in filenames, you may need to add some logic
+
+       if [ -d "$dst" ]
+       then
+               dst=$dst/`basename "$src"`
+       else
+               :
+       fi
+fi
+
+## this sed command emulates the dirname command
+dstdir=`echo "$dst" | sed -e 's,[^/]*$,,;s,/$,,;s,^$,.,'`
+
+# Make sure that the destination directory exists.
+#  this part is taken from Noah Friedman's mkinstalldirs script
+
+# Skip lots of stat calls in the usual case.
+if [ ! -d "$dstdir" ]; then
+defaultIFS='
+       '
+IFS="${IFS-$defaultIFS}"
+
+oIFS=$IFS
+# Some sh's can't handle IFS=/ for some reason.
+IFS='%'
+set - `echo "$dstdir" | sed -e 's@/@%@g' -e 's@^%@/@'`
+IFS=$oIFS
+
+pathcomp=''
+
+while [ $# -ne 0 ] ; do
+       pathcomp=$pathcomp$1
+       shift
+
+       if [ ! -d "$pathcomp" ] ;
+        then
+               $mkdirprog "$pathcomp"
+       else
+               :
+       fi
+
+       pathcomp=$pathcomp/
+done
+fi
+
+if [ x"$dir_arg" != x ]
+then
+       $doit $instcmd "$dst" &&
+
+       if [ x"$chowncmd" != x ]; then $doit $chowncmd "$dst"; else : ; fi &&
+       if [ x"$chgrpcmd" != x ]; then $doit $chgrpcmd "$dst"; else : ; fi &&
+       if [ x"$stripcmd" != x ]; then $doit $stripcmd "$dst"; else : ; fi &&
+       if [ x"$chmodcmd" != x ]; then $doit $chmodcmd "$dst"; else : ; fi
+else
+
+# If we're going to rename the final executable, determine the name now.
+
+       if [ x"$transformarg" = x ]
+       then
+               dstfile=`basename "$dst"`
+       else
+               dstfile=`basename "$dst" $transformbasename |
+                       sed $transformarg`$transformbasename
+       fi
+
+# don't allow the sed command to completely eliminate the filename
+
+       if [ x"$dstfile" = x ]
+       then
+               dstfile=`basename "$dst"`
+       else
+               :
+       fi
+
+# Make a couple of temp file names in the proper directory.
+
+       dsttmp=$dstdir/_inst.$$_
+       rmtmp=$dstdir/_rm.$$_
+
+# Trap to clean up temp files at exit.
+
+       trap 'status=$?; rm -f "$dsttmp" "$rmtmp" && exit $status' 0
+       trap '(exit $?); exit' 1 2 13 15
+
+# Move or copy the file name to the temp name
+
+       $doit $instcmd "$src" "$dsttmp" &&
+
+# and set any options; do chmod last to preserve setuid bits
+
+# If any of these fail, we abort the whole thing.  If we want to
+# ignore errors from any of these, just make sure not to ignore
+# errors from the above "$doit $instcmd $src $dsttmp" command.
+
+       if [ x"$chowncmd" != x ]; then $doit $chowncmd "$dsttmp"; else :;fi &&
+       if [ x"$chgrpcmd" != x ]; then $doit $chgrpcmd "$dsttmp"; else :;fi &&
+       if [ x"$stripcmd" != x ]; then $doit $stripcmd "$dsttmp"; else :;fi &&
+       if [ x"$chmodcmd" != x ]; then $doit $chmodcmd "$dsttmp"; else :;fi &&
+
+# Now remove or move aside any old file at destination location.  We try this
+# two ways since rm can't unlink itself on some systems and the destination
+# file might be busy for other reasons.  In this case, the final cleanup
+# might fail but the new file should still install successfully.
+
+{
+       if [ -f "$dstdir/$dstfile" ]
+       then
+               $doit $rmcmd -f "$dstdir/$dstfile" 2>/dev/null ||
+               $doit $mvcmd -f "$dstdir/$dstfile" "$rmtmp" 2>/dev/null ||
+               {
+                 echo "$0: cannot unlink or rename $dstdir/$dstfile" >&2
+                 (exit 1); exit
+               }
+       else
+               :
+       fi
+} &&
+
+# Now rename the file to the real destination.
+
+       $doit $mvcmd "$dsttmp" "$dstdir/$dstfile"
+
+fi &&
+
+# The final little trick to "correctly" pass the exit status to the exit trap.
+
+{
+       (exit 0); exit
+}
diff --git a/libs/libsndfile/libsndfile.spec.in b/libs/libsndfile/libsndfile.spec.in
new file mode 100644 (file)
index 0000000..ad47a5f
--- /dev/null
@@ -0,0 +1,69 @@
+
+%define name    @PACKAGE@
+%define version @VERSION@
+%define release 1
+
+Summary: A library to handle various audio file formats.
+Name: %{name}
+Version: %{version}
+Release: %{release}
+Copyright: LGPL
+Group: Libraries/Sound
+Source: http://www.mega-nerd.com/libsndfile/libsndfile-%{version}.tar.gz
+URL: http://www.mega-nerd.com/libsndfile/
+BuildRoot: /var/tmp/%{name}-%{version}
+
+%description
+libsndfile is a C library for reading and writing sound files such as
+AIFF, AU and WAV files through one standard interface. It can currently
+read/write 8, 16, 24 and 32-bit PCM files as well as 32-bit floating
+point WAV files and a number of compressed formats.
+
+%package devel
+Summary: Libraries, includes, etc to develop libsndfile applications
+Group: Libraries
+
+%description devel
+Libraries, include files, etc you can use to develop libsndfile applications.
+
+%prep
+%setup
+
+%build
+%configure
+make
+
+%install
+if [ -d $RPM_BUILD_ROOT ]; then rm -rf $RPM_BUILD_ROOT; fi
+mkdir -p $RPM_BUILD_ROOT
+make DESTDIR=$RPM_BUILD_ROOT install
+%clean
+if [ -d $RPM_BUILD_ROOT ]; then rm -rf $RPM_BUILD_ROOT; fi
+
+%files
+%defattr(-,root,root)
+%doc AUTHORS COPYING ChangeLog INSTALL NEWS README TODO doc
+%{_libdir}/libsndfile.so.*
+%{_bindir}/*
+%{_mandir}/man1/*
+%{_datadir}/octave/site/m/*
+%{_defaultdocdir}/libsndfile1-dev/html/*
+
+%files devel
+%defattr(-,root,root)
+%{_libdir}/libsndfile.a
+%{_libdir}/libsndfile.la
+%{_libdir}/libsndfile.so
+%{_includedir}/sndfile.h
+%{_libdir}/pkgconfig/sndfile.pc
+
+%changelog
+* Sun May 15 2005 Erik de Castro Lopo <erikd@mega-nerd.com>
+- Add html files to the files section.
+* Tue Sep 16 2003 Erik de Castro Lopo <erikd@mega-nerd.com>
+- Apply corrections from Andrew Schultz.
+* Mon Oct 21 2002 Erik de Castro Lopo <erikd@mega-nerd.com>
+- Force installation of sndfile.pc file.
+* Thu Jul 6 2000 Josh Green <jgreen@users.sourceforge.net>
+- Created libsndfile.spec.in
+
diff --git a/libs/libsndfile/missing b/libs/libsndfile/missing
new file mode 100755 (executable)
index 0000000..fc54c64
--- /dev/null
@@ -0,0 +1,336 @@
+#! /bin/sh
+# Common stub for a few missing GNU programs while installing.
+# Copyright (C) 1996, 1997, 1999, 2000, 2002, 2003 Free Software Foundation, Inc.
+# Originally by Fran,cois Pinard <pinard@iro.umontreal.ca>, 1996.
+
+# This program is free software; you can redistribute it and/or modify
+# it under the terms of the GNU General Public License as published by
+# the Free Software Foundation; either version 2, or (at your option)
+# any later version.
+
+# This program is distributed in the hope that it will be useful,
+# but WITHOUT ANY WARRANTY; without even the implied warranty of
+# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+# GNU General Public License for more details.
+
+# You should have received a copy of the GNU General Public License
+# along with this program; if not, write to the Free Software
+# Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA
+# 02111-1307, USA.
+
+# As a special exception to the GNU General Public License, if you
+# distribute this file as part of a program that contains a
+# configuration script generated by Autoconf, you may include it under
+# the same distribution terms that you use for the rest of that program.
+
+if test $# -eq 0; then
+  echo 1>&2 "Try \`$0 --help' for more information"
+  exit 1
+fi
+
+run=:
+
+# In the cases where this matters, `missing' is being run in the
+# srcdir already.
+if test -f configure.ac; then
+  configure_ac=configure.ac
+else
+  configure_ac=configure.in
+fi
+
+case "$1" in
+--run)
+  # Try to run requested program, and just exit if it succeeds.
+  run=
+  shift
+  "$@" && exit 0
+  ;;
+esac
+
+# If it does not exist, or fails to run (possibly an outdated version),
+# try to emulate it.
+case "$1" in
+
+  -h|--h|--he|--hel|--help)
+    echo "\
+$0 [OPTION]... PROGRAM [ARGUMENT]...
+
+Handle \`PROGRAM [ARGUMENT]...' for when PROGRAM is missing, or return an
+error status if there is no known handling for PROGRAM.
+
+Options:
+  -h, --help      display this help and exit
+  -v, --version   output version information and exit
+  --run           try to run the given command, and emulate it if it fails
+
+Supported PROGRAM values:
+  aclocal      touch file \`aclocal.m4'
+  autoconf     touch file \`configure'
+  autoheader   touch file \`config.h.in'
+  automake     touch all \`Makefile.in' files
+  bison        create \`y.tab.[ch]', if possible, from existing .[ch]
+  flex         create \`lex.yy.c', if possible, from existing .c
+  help2man     touch the output file
+  lex          create \`lex.yy.c', if possible, from existing .c
+  makeinfo     touch the output file
+  tar          try tar, gnutar, gtar, then tar without non-portable flags
+  yacc         create \`y.tab.[ch]', if possible, from existing .[ch]"
+    ;;
+
+  -v|--v|--ve|--ver|--vers|--versi|--versio|--version)
+    echo "missing 0.4 - GNU automake"
+    ;;
+
+  -*)
+    echo 1>&2 "$0: Unknown \`$1' option"
+    echo 1>&2 "Try \`$0 --help' for more information"
+    exit 1
+    ;;
+
+  aclocal*)
+    if test -z "$run" && ($1 --version) > /dev/null 2>&1; then
+       # We have it, but it failed.
+       exit 1
+    fi
+
+    echo 1>&2 "\
+WARNING: \`$1' is missing on your system.  You should only need it if
+         you modified \`acinclude.m4' or \`${configure_ac}'.  You might want
+         to install the \`Automake' and \`Perl' packages.  Grab them from
+         any GNU archive site."
+    touch aclocal.m4
+    ;;
+
+  autoconf)
+    if test -z "$run" && ($1 --version) > /dev/null 2>&1; then
+       # We have it, but it failed.
+       exit 1
+    fi
+
+    echo 1>&2 "\
+WARNING: \`$1' is missing on your system.  You should only need it if
+         you modified \`${configure_ac}'.  You might want to install the
+         \`Autoconf' and \`GNU m4' packages.  Grab them from any GNU
+         archive site."
+    touch configure
+    ;;
+
+  autoheader)
+    if test -z "$run" && ($1 --version) > /dev/null 2>&1; then
+       # We have it, but it failed.
+       exit 1
+    fi
+
+    echo 1>&2 "\
+WARNING: \`$1' is missing on your system.  You should only need it if
+         you modified \`acconfig.h' or \`${configure_ac}'.  You might want
+         to install the \`Autoconf' and \`GNU m4' packages.  Grab them
+         from any GNU archive site."
+    files=`sed -n 's/^[ ]*A[CM]_CONFIG_HEADER(\([^)]*\)).*/\1/p' ${configure_ac}`
+    test -z "$files" && files="config.h"
+    touch_files=
+    for f in $files; do
+      case "$f" in
+      *:*) touch_files="$touch_files "`echo "$f" |
+                                      sed -e 's/^[^:]*://' -e 's/:.*//'`;;
+      *) touch_files="$touch_files $f.in";;
+      esac
+    done
+    touch $touch_files
+    ;;
+
+  automake*)
+    if test -z "$run" && ($1 --version) > /dev/null 2>&1; then
+       # We have it, but it failed.
+       exit 1
+    fi
+
+    echo 1>&2 "\
+WARNING: \`$1' is missing on your system.  You should only need it if
+         you modified \`Makefile.am', \`acinclude.m4' or \`${configure_ac}'.
+         You might want to install the \`Automake' and \`Perl' packages.
+         Grab them from any GNU archive site."
+    find . -type f -name Makefile.am -print |
+          sed 's/\.am$/.in/' |
+          while read f; do touch "$f"; done
+    ;;
+
+  autom4te)
+    if test -z "$run" && ($1 --version) > /dev/null 2>&1; then
+       # We have it, but it failed.
+       exit 1
+    fi
+
+    echo 1>&2 "\
+WARNING: \`$1' is needed, and you do not seem to have it handy on your
+         system.  You might have modified some files without having the
+         proper tools for further handling them.
+         You can get \`$1' as part of \`Autoconf' from any GNU
+         archive site."
+
+    file=`echo "$*" | sed -n 's/.*--output[ =]*\([^ ]*\).*/\1/p'`
+    test -z "$file" && file=`echo "$*" | sed -n 's/.*-o[ ]*\([^ ]*\).*/\1/p'`
+    if test -f "$file"; then
+       touch $file
+    else
+       test -z "$file" || exec >$file
+       echo "#! /bin/sh"
+       echo "# Created by GNU Automake missing as a replacement of"
+       echo "#  $ $@"
+       echo "exit 0"
+       chmod +x $file
+       exit 1
+    fi
+    ;;
+
+  bison|yacc)
+    echo 1>&2 "\
+WARNING: \`$1' is missing on your system.  You should only need it if
+         you modified a \`.y' file.  You may need the \`Bison' package
+         in order for those modifications to take effect.  You can get
+         \`Bison' from any GNU archive site."
+    rm -f y.tab.c y.tab.h
+    if [ $# -ne 1 ]; then
+        eval LASTARG="\${$#}"
+       case "$LASTARG" in
+       *.y)
+           SRCFILE=`echo "$LASTARG" | sed 's/y$/c/'`
+           if [ -f "$SRCFILE" ]; then
+                cp "$SRCFILE" y.tab.c
+           fi
+           SRCFILE=`echo "$LASTARG" | sed 's/y$/h/'`
+           if [ -f "$SRCFILE" ]; then
+                cp "$SRCFILE" y.tab.h
+           fi
+         ;;
+       esac
+    fi
+    if [ ! -f y.tab.h ]; then
+       echo >y.tab.h
+    fi
+    if [ ! -f y.tab.c ]; then
+       echo 'main() { return 0; }' >y.tab.c
+    fi
+    ;;
+
+  lex|flex)
+    echo 1>&2 "\
+WARNING: \`$1' is missing on your system.  You should only need it if
+         you modified a \`.l' file.  You may need the \`Flex' package
+         in order for those modifications to take effect.  You can get
+         \`Flex' from any GNU archive site."
+    rm -f lex.yy.c
+    if [ $# -ne 1 ]; then
+        eval LASTARG="\${$#}"
+       case "$LASTARG" in
+       *.l)
+           SRCFILE=`echo "$LASTARG" | sed 's/l$/c/'`
+           if [ -f "$SRCFILE" ]; then
+                cp "$SRCFILE" lex.yy.c
+           fi
+         ;;
+       esac
+    fi
+    if [ ! -f lex.yy.c ]; then
+       echo 'main() { return 0; }' >lex.yy.c
+    fi
+    ;;
+
+  help2man)
+    if test -z "$run" && ($1 --version) > /dev/null 2>&1; then
+       # We have it, but it failed.
+       exit 1
+    fi
+
+    echo 1>&2 "\
+WARNING: \`$1' is missing on your system.  You should only need it if
+        you modified a dependency of a manual page.  You may need the
+        \`Help2man' package in order for those modifications to take
+        effect.  You can get \`Help2man' from any GNU archive site."
+
+    file=`echo "$*" | sed -n 's/.*-o \([^ ]*\).*/\1/p'`
+    if test -z "$file"; then
+       file=`echo "$*" | sed -n 's/.*--output=\([^ ]*\).*/\1/p'`
+    fi
+    if [ -f "$file" ]; then
+       touch $file
+    else
+       test -z "$file" || exec >$file
+       echo ".ab help2man is required to generate this page"
+       exit 1
+    fi
+    ;;
+
+  makeinfo)
+    if test -z "$run" && (makeinfo --version) > /dev/null 2>&1; then
+       # We have makeinfo, but it failed.
+       exit 1
+    fi
+
+    echo 1>&2 "\
+WARNING: \`$1' is missing on your system.  You should only need it if
+         you modified a \`.texi' or \`.texinfo' file, or any other file
+         indirectly affecting the aspect of the manual.  The spurious
+         call might also be the consequence of using a buggy \`make' (AIX,
+         DU, IRIX).  You might want to install the \`Texinfo' package or
+         the \`GNU make' package.  Grab either from any GNU archive site."
+    file=`echo "$*" | sed -n 's/.*-o \([^ ]*\).*/\1/p'`
+    if test -z "$file"; then
+      file=`echo "$*" | sed 's/.* \([^ ]*\) *$/\1/'`
+      file=`sed -n '/^@setfilename/ { s/.* \([^ ]*\) *$/\1/; p; q; }' $file`
+    fi
+    touch $file
+    ;;
+
+  tar)
+    shift
+    if test -n "$run"; then
+      echo 1>&2 "ERROR: \`tar' requires --run"
+      exit 1
+    fi
+
+    # We have already tried tar in the generic part.
+    # Look for gnutar/gtar before invocation to avoid ugly error
+    # messages.
+    if (gnutar --version > /dev/null 2>&1); then
+       gnutar "$@" && exit 0
+    fi
+    if (gtar --version > /dev/null 2>&1); then
+       gtar "$@" && exit 0
+    fi
+    firstarg="$1"
+    if shift; then
+       case "$firstarg" in
+       *o*)
+           firstarg=`echo "$firstarg" | sed s/o//`
+           tar "$firstarg" "$@" && exit 0
+           ;;
+       esac
+       case "$firstarg" in
+       *h*)
+           firstarg=`echo "$firstarg" | sed s/h//`
+           tar "$firstarg" "$@" && exit 0
+           ;;
+       esac
+    fi
+
+    echo 1>&2 "\
+WARNING: I can't seem to be able to run \`tar' with the given arguments.
+         You may want to install GNU tar or Free paxutils, or check the
+         command line arguments."
+    exit 1
+    ;;
+
+  *)
+    echo 1>&2 "\
+WARNING: \`$1' is needed, and you do not seem to have it handy on your
+         system.  You might have modified some files without having the
+         proper tools for further handling them.  Check the \`README' file,
+         it often tells you about the needed prerequisites for installing
+         this package.  You may also peek at any GNU archive site, in case
+         some other package would contain this missing \`$1' program."
+    exit 1
+    ;;
+esac
+
+exit 0
diff --git a/libs/libsndfile/mkinstalldirs b/libs/libsndfile/mkinstalldirs
new file mode 100755 (executable)
index 0000000..d2d5f21
--- /dev/null
@@ -0,0 +1,111 @@
+#! /bin/sh
+# mkinstalldirs --- make directory hierarchy
+# Author: Noah Friedman <friedman@prep.ai.mit.edu>
+# Created: 1993-05-16
+# Public domain
+
+errstatus=0
+dirmode=""
+
+usage="\
+Usage: mkinstalldirs [-h] [--help] [-m mode] dir ..."
+
+# process command line arguments
+while test $# -gt 0 ; do
+  case $1 in
+    -h | --help | --h*)         # -h for help
+      echo "$usage" 1>&2
+      exit 0
+      ;;
+    -m)                         # -m PERM arg
+      shift
+      test $# -eq 0 && { echo "$usage" 1>&2; exit 1; }
+      dirmode=$1
+      shift
+      ;;
+    --)                         # stop option processing
+      shift
+      break
+      ;;
+    -*)                         # unknown option
+      echo "$usage" 1>&2
+      exit 1
+      ;;
+    *)                          # first non-opt arg
+      break
+      ;;
+  esac
+done
+
+for file
+do
+  if test -d "$file"; then
+    shift
+  else
+    break
+  fi
+done
+
+case $# in
+  0) exit 0 ;;
+esac
+
+case $dirmode in
+  '')
+    if mkdir -p -- . 2>/dev/null; then
+      echo "mkdir -p -- $*"
+      exec mkdir -p -- "$@"
+    fi
+    ;;
+  *)
+    if mkdir -m "$dirmode" -p -- . 2>/dev/null; then
+      echo "mkdir -m $dirmode -p -- $*"
+      exec mkdir -m "$dirmode" -p -- "$@"
+    fi
+    ;;
+esac
+
+for file
+do
+  set fnord `echo ":$file" | sed -ne 's/^:\//#/;s/^://;s/\// /g;s/^#/\//;p'`
+  shift
+
+  pathcomp=
+  for d
+  do
+    pathcomp="$pathcomp$d"
+    case $pathcomp in
+      -*) pathcomp=./$pathcomp ;;
+    esac
+
+    if test ! -d "$pathcomp"; then
+      echo "mkdir $pathcomp"
+
+      mkdir "$pathcomp" || lasterr=$?
+
+      if test ! -d "$pathcomp"; then
+       errstatus=$lasterr
+      else
+       if test ! -z "$dirmode"; then
+         echo "chmod $dirmode $pathcomp"
+         lasterr=""
+         chmod "$dirmode" "$pathcomp" || lasterr=$?
+
+         if test ! -z "$lasterr"; then
+           errstatus=$lasterr
+         fi
+       fi
+      fi
+    fi
+
+    pathcomp="$pathcomp/"
+  done
+done
+
+exit $errstatus
+
+# Local Variables:
+# mode: shell-script
+# sh-indentation: 2
+# End:
+# mkinstalldirs ends here
diff --git a/libs/libsndfile/sndfile.pc.in b/libs/libsndfile/sndfile.pc.in
new file mode 100644 (file)
index 0000000..f2a833b
--- /dev/null
@@ -0,0 +1,11 @@
+prefix=@prefix@
+exec_prefix=@exec_prefix@
+libdir=@libdir@
+includedir=@includedir@
+
+Name: sndfile
+Description: A library for reading and writing audio files
+Requires: 
+Version: @VERSION@
+Libs: -L${libdir} -lsndfile
+Cflags: -I${includedir} 
diff --git a/libs/libsndfile/src/G72x/ChangeLog b/libs/libsndfile/src/G72x/ChangeLog
new file mode 100644 (file)
index 0000000..aa108df
--- /dev/null
@@ -0,0 +1,50 @@
+2001-06-05  Erik de Castro Lopo  <erikd@mega-nerd.com>
+
+       * g72x.c
+       Added {} in function update () to prevent 'ambiguous else' warning messages.
+
+2000-07-14  Erik de Castro Lopo  <erikd@mega-nerd.com>
+
+       * g72x.c
+       Modified g72x_init_state () to fit in with the new structure of the code.
+       Implemented g72x_encode_block () and g72x_decode_block ().
+
+2000-07-12  Erik de Castro Lopo  <erikd@mega-nerd.com>
+
+    * g72x.h
+    Moved nearly all definitions and function prototypes from this file have been 
+    moved to private.h.
+    Added an enum defining the 4 different G72x ADPCM codecs.
+    Added new function prototypes to define a cleaner interface to the encoder 
+    and decoder. This new interface also allows samples to be processed in blocks
+    rather than on a sample by sample basis like the original code.
+    
+    * private.h
+    Added prototypes moved from g72x.h.
+    Changed struct g72x_state to a typedef struct { .. } G72x_PRIVATE.
+    Added fields to G72x_PRIVATE required for working on blocks of samples.
+
+2000-06-07  Erik de Castro Lopo  <erikd@mega-nerd.com>
+
+    * g72x.c
+    Fixed all compiler warnings.
+    Removed functions tandem_adjust() which is not required by libsndfile.
+    
+    * g721.c
+    Fixed all compiler warnings.
+    Removed functions tandem_adjust_alaw() and tandem_adjust_ulaw () which are not 
+    required by libsndfile.
+    Removed second parameter to g721_encoder () which is not required.
+
+    * g72x.h
+    Removed in_coding and out_coding parameters from all functions. These allowed
+    g72x encoding/decoding to/from A-law or u-law and are not required by libsndfile.
+    Removed unneeded defines for A-law, u-law and linear encoding.
+
+    * g723_16.c
+    Removed second parameter (in_coding) for g723_16_encoder().    
+    Removed second parameter (out_coding) for g723_16_decoder().
+    
+    * private.h
+    New file containing prototypes and tyepdefs private to G72x code.
+    
diff --git a/libs/libsndfile/src/G72x/README b/libs/libsndfile/src/G72x/README
new file mode 100644 (file)
index 0000000..e69de29
diff --git a/libs/libsndfile/src/G72x/README.original b/libs/libsndfile/src/G72x/README.original
new file mode 100644 (file)
index 0000000..23b0e7d
--- /dev/null
@@ -0,0 +1,94 @@
+The files in this directory comprise ANSI-C language reference implementations
+of the CCITT (International Telegraph and Telephone Consultative Committee)
+G.711, G.721 and G.723 voice compressions.  They have been tested on Sun
+SPARCstations and passed 82 out of 84 test vectors published by CCITT
+(Dec. 20, 1988) for G.721 and G.723.  [The two remaining test vectors,
+which the G.721 decoder implementation for u-law samples did not pass,
+may be in error because they are identical to two other vectors for G.723_40.]
+
+This source code is released by Sun Microsystems, Inc. to the public domain.
+Please give your acknowledgement in product literature if this code is used
+in your product implementation.
+
+Sun Microsystems supports some CCITT audio formats in Solaris 2.0 system
+software.  However, Sun's implementations have been optimized for higher
+performance on SPARCstations.
+
+
+The source files for CCITT conversion routines in this directory are:
+
+       g72x.h          header file for g721.c, g723_24.c and g723_40.c
+       g711.c          CCITT G.711 u-law and A-law compression
+       g72x.c          common denominator of G.721 and G.723 ADPCM codes
+       g721.c          CCITT G.721 32Kbps ADPCM coder (with g72x.c)
+       g723_24.c       CCITT G.723 24Kbps ADPCM coder (with g72x.c)
+       g723_40.c       CCITT G.723 40Kbps ADPCM coder (with g72x.c)
+
+
+Simple conversions between u-law, A-law, and 16-bit linear PCM are invoked
+as follows:
+
+       unsigned char           ucode, acode;
+       short                   pcm_val;
+
+       ucode = linear2ulaw(pcm_val);
+       ucode = alaw2ulaw(acode);
+
+       acode = linear2alaw(pcm_val);
+       acode = ulaw2alaw(ucode);
+
+       pcm_val = ulaw2linear(ucode);
+       pcm_val = alaw2linear(acode);
+
+
+The other CCITT compression routines are invoked as follows:
+
+       #include "g72x.h"
+
+       struct g72x_state       state;
+       int                     sample, code;
+
+       g72x_init_state(&state);
+       code = {g721,g723_24,g723_40}_encoder(sample, coding, &state);
+       sample = {g721,g723_24,g723_40}_decoder(code, coding, &state);
+
+where
+       coding = AUDIO_ENCODING_ULAW    for 8-bit u-law samples
+                AUDIO_ENCODING_ALAW    for 8-bit A-law samples
+                AUDIO_ENCODING_LINEAR  for 16-bit linear PCM samples
+
+
+
+This directory also includes the following sample programs:
+
+       encode.c        CCITT ADPCM encoder
+       decode.c        CCITT ADPCM decoder
+       Makefile        makefile for the sample programs
+
+
+The sample programs contain examples of how to call the various compression
+routines and pack/unpack the bits.  The sample programs read byte streams from
+stdin and write to stdout.  The input/output data is raw data (no file header
+or other identifying information is embedded).  The sample programs are
+invoked as follows:
+
+       encode [-3|4|5] [-a|u|l] <infile >outfile
+       decode [-3|4|5] [-a|u|l] <infile >outfile
+where:
+       -3      encode to (decode from) G.723 24kbps (3-bit) data
+       -4      encode to (decode from) G.721 32kbps (4-bit) data [the default]
+       -5      encode to (decode from) G.723 40kbps (5-bit) data
+       -a      encode from (decode to) A-law data
+       -u      encode from (decode to) u-law data [the default]
+       -l      encode from (decode to) 16-bit linear data
+
+Examples:
+       # Read 16-bit linear and output G.721
+       encode -4 -l <pcmfile >g721file
+
+       # Read 40Kbps G.723 and output A-law
+       decode -5 -a <g723file >alawfile
+
+       # Compress and then decompress u-law data using 24Kbps G.723
+       encode -3 <ulawin | deoced -3 >ulawout
+
diff --git a/libs/libsndfile/src/G72x/g721.c b/libs/libsndfile/src/G72x/g721.c
new file mode 100644 (file)
index 0000000..4f51bb1
--- /dev/null
@@ -0,0 +1,162 @@
+/*
+ * This source code is a product of Sun Microsystems, Inc. and is provided
+ * for unrestricted use.  Users may copy or modify this source code without
+ * charge.
+ *
+ * SUN SOURCE CODE IS PROVIDED AS IS WITH NO WARRANTIES OF ANY KIND INCLUDING
+ * THE WARRANTIES OF DESIGN, MERCHANTIBILITY AND FITNESS FOR A PARTICULAR
+ * PURPOSE, OR ARISING FROM A COURSE OF DEALING, USAGE OR TRADE PRACTICE.
+ *
+ * Sun source code is provided with no support and without any obligation on
+ * the part of Sun Microsystems, Inc. to assist in its use, correction,
+ * modification or enhancement.
+ *
+ * SUN MICROSYSTEMS, INC. SHALL HAVE NO LIABILITY WITH RESPECT TO THE
+ * INFRINGEMENT OF COPYRIGHTS, TRADE SECRETS OR ANY PATENTS BY THIS SOFTWARE
+ * OR ANY PART THEREOF.
+ *
+ * In no event will Sun Microsystems, Inc. be liable for any lost revenue
+ * or profits or other special, indirect and consequential damages, even if
+ * Sun has been advised of the possibility of such damages.
+ *
+ * Sun Microsystems, Inc.
+ * 2550 Garcia Avenue
+ * Mountain View, California  94043
+ */
+
+/*
+ * g721.c
+ *
+ * Description:
+ *
+ * g721_encoder(), g721_decoder()
+ *
+ * These routines comprise an implementation of the CCITT G.721 ADPCM
+ * coding algorithm.  Essentially, this implementation is identical to
+ * the bit level description except for a few deviations which
+ * take advantage of work station attributes, such as hardware 2's
+ * complement arithmetic and large memory.  Specifically, certain time
+ * consuming operations such as multiplications are replaced
+ * with lookup tables and software 2's complement operations are
+ * replaced with hardware 2's complement.
+ *
+ * The deviation from the bit level specification (lookup tables)
+ * preserves the bit level performance specifications.
+ *
+ * As outlined in the G.721 Recommendation, the algorithm is broken
+ * down into modules.  Each section of code below is preceded by
+ * the name of the module which it is implementing.
+ *
+ */
+
+#include "g72x.h"
+#include "g72x_priv.h"
+
+static short qtab_721[7] = {-124, 80, 178, 246, 300, 349, 400};
+/*
+ * Maps G.721 code word to reconstructed scale factor normalized log
+ * magnitude values.
+ */
+static short   _dqlntab[16] = {-2048, 4, 135, 213, 273, 323, 373, 425,
+                               425, 373, 323, 273, 213, 135, 4, -2048};
+
+/* Maps G.721 code word to log of scale factor multiplier. */
+static short   _witab[16] = {-12, 18, 41, 64, 112, 198, 355, 1122,
+                               1122, 355, 198, 112, 64, 41, 18, -12};
+/*
+ * Maps G.721 code words to a set of values whose long and short
+ * term averages are computed and then compared to give an indication
+ * how stationary (steady state) the signal is.
+ */
+static short   _fitab[16] = {0, 0, 0, 0x200, 0x200, 0x200, 0x600, 0xE00,
+                               0xE00, 0x600, 0x200, 0x200, 0x200, 0, 0, 0};
+
+/*
+ * g721_encoder()
+ *
+ * Encodes the input vale of linear PCM, A-law or u-law data sl and returns
+ * the resulting code. -1 is returned for unknown input coding value.
+ */
+int
+g721_encoder(
+       int             sl,
+       G72x_STATE *state_ptr)
+{
+       short           sezi, se, sez;          /* ACCUM */
+       short           d;                      /* SUBTA */
+       short           sr;                     /* ADDB */
+       short           y;                      /* MIX */
+       short           dqsez;                  /* ADDC */
+       short           dq, i;
+
+       /* linearize input sample to 14-bit PCM */
+       sl >>= 2;                       /* 14-bit dynamic range */
+
+       sezi = predictor_zero(state_ptr);
+       sez = sezi >> 1;
+       se = (sezi + predictor_pole(state_ptr)) >> 1;   /* estimated signal */
+
+       d = sl - se;                            /* estimation difference */
+
+       /* quantize the prediction difference */
+       y = step_size(state_ptr);               /* quantizer step size */
+       i = quantize(d, y, qtab_721, 7);        /* i = ADPCM code */
+
+       dq = reconstruct(i & 8, _dqlntab[i], y);        /* quantized est diff */
+
+       sr = (dq < 0) ? se - (dq & 0x3FFF) : se + dq;   /* reconst. signal */
+
+       dqsez = sr + sez - se;                  /* pole prediction diff. */
+
+       update(4, y, _witab[i] << 5, _fitab[i], dq, sr, dqsez, state_ptr);
+
+       return (i);
+}
+
+/*
+ * g721_decoder()
+ *
+ * Description:
+ *
+ * Decodes a 4-bit code of G.721 encoded data of i and
+ * returns the resulting linear PCM, A-law or u-law value.
+ * return -1 for unknown out_coding value.
+ */
+int
+g721_decoder(
+       int             i,
+       G72x_STATE *state_ptr)
+{
+       short           sezi, sei, sez, se;     /* ACCUM */
+       short           y;                      /* MIX */
+       short           sr;                     /* ADDB */
+       short           dq;
+       short           dqsez;
+
+       i &= 0x0f;                      /* mask to get proper bits */
+       sezi = predictor_zero(state_ptr);
+       sez = sezi >> 1;
+       sei = sezi + predictor_pole(state_ptr);
+       se = sei >> 1;                  /* se = estimated signal */
+
+       y = step_size(state_ptr);       /* dynamic quantizer step size */
+
+       dq = reconstruct(i & 0x08, _dqlntab[i], y); /* quantized diff. */
+
+       sr = (dq < 0) ? (se - (dq & 0x3FFF)) : se + dq; /* reconst. signal */
+
+       dqsez = sr - se + sez;                  /* pole prediction diff. */
+
+       update(4, y, _witab[i] << 5, _fitab[i], dq, sr, dqsez, state_ptr);
+
+       /* sr was 14-bit dynamic range */
+       return (sr << 2);       
+}
+/*
+** Do not edit or modify anything in this comment block.
+** The arch-tag line is a file identity tag for the GNU Arch 
+** revision control system.
+**
+** arch-tag: 101b6e25-457d-490a-99ae-e2e74a26ea24
+*/
+
diff --git a/libs/libsndfile/src/G72x/g723_16.c b/libs/libsndfile/src/G72x/g723_16.c
new file mode 100644 (file)
index 0000000..0c31745
--- /dev/null
@@ -0,0 +1,169 @@
+/*
+ * This source code is a product of Sun Microsystems, Inc. and is provided
+ * for unrestricted use.  Users may copy or modify this source code without
+ * charge.
+ *
+ * SUN SOURCE CODE IS PROVIDED AS IS WITH NO WARRANTIES OF ANY KIND INCLUDING
+ * THE WARRANTIES OF DESIGN, MERCHANTIBILITY AND FITNESS FOR A PARTICULAR
+ * PURPOSE, OR ARISING FROM A COURSE OF DEALING, USAGE OR TRADE PRACTICE.
+ *
+ * Sun source code is provided with no support and without any obligation on
+ * the part of Sun Microsystems, Inc. to assist in its use, correction,
+ * modification or enhancement.
+ *
+ * SUN MICROSYSTEMS, INC. SHALL HAVE NO LIABILITY WITH RESPECT TO THE
+ * INFRINGEMENT OF COPYRIGHTS, TRADE SECRETS OR ANY PATENTS BY THIS SOFTWARE
+ * OR ANY PART THEREOF.
+ *
+ * In no event will Sun Microsystems, Inc. be liable for any lost revenue
+ * or profits or other special, indirect and consequential damages, even if
+ * Sun has been advised of the possibility of such damages.
+ *
+ * Sun Microsystems, Inc.
+ * 2550 Garcia Avenue
+ * Mountain View, California  94043
+ */
+/* 16kbps version created, used 24kbps code and changing as little as possible.
+ * G.726 specs are available from ITU's gopher or WWW site (http://www.itu.ch)
+ * If any errors are found, please contact me at mrand@tamu.edu
+ *      -Marc Randolph
+ */
+
+/*
+ * g723_16.c
+ *
+ * Description:
+ *
+ * g723_16_encoder(), g723_16_decoder()
+ *
+ * These routines comprise an implementation of the CCITT G.726 16 Kbps
+ * ADPCM coding algorithm.  Essentially, this implementation is identical to
+ * the bit level description except for a few deviations which take advantage
+ * of workstation attributes, such as hardware 2's complement arithmetic.
+ *
+ */
+
+#include "g72x.h"
+#include "g72x_priv.h"
+
+/*
+ * Maps G.723_16 code word to reconstructed scale factor normalized log
+ * magnitude values.  Comes from Table 11/G.726
+ */
+static short   _dqlntab[4] = { 116, 365, 365, 116}; 
+
+/* Maps G.723_16 code word to log of scale factor multiplier.
+ *
+ * _witab[4] is actually {-22 , 439, 439, -22}, but FILTD wants it
+ * as WI << 5  (multiplied by 32), so we'll do that here 
+ */
+static short   _witab[4] = {-704, 14048, 14048, -704};
+
+/*
+ * Maps G.723_16 code words to a set of values whose long and short
+ * term averages are computed and then compared to give an indication
+ * how stationary (steady state) the signal is.
+ */
+
+/* Comes from FUNCTF */
+static short   _fitab[4] = {0, 0xE00, 0xE00, 0};
+
+/* Comes from quantizer decision level tables (Table 7/G.726)
+ */
+static short qtab_723_16[1] = {261};
+
+
+/*
+ * g723_16_encoder()
+ *
+ * Encodes a linear PCM, A-law or u-law input sample and returns its 2-bit code.
+ * Returns -1 if invalid input coding value.
+ */
+int
+g723_16_encoder(
+       int             sl,
+       G72x_STATE *state_ptr)
+{
+       short           sei, sezi, se, sez;     /* ACCUM */
+       short           d;                      /* SUBTA */
+       short           y;                      /* MIX */
+       short           sr;                     /* ADDB */
+       short           dqsez;                  /* ADDC */
+       short           dq, i;
+
+               /* linearize input sample to 14-bit PCM */
+               sl >>= 2;               /* sl of 14-bit dynamic range */
+
+       sezi = predictor_zero(state_ptr);
+       sez = sezi >> 1;
+       sei = sezi + predictor_pole(state_ptr);
+       se = sei >> 1;                  /* se = estimated signal */
+
+       d = sl - se;                    /* d = estimation diff. */
+
+       /* quantize prediction difference d */
+       y = step_size(state_ptr);       /* quantizer step size */
+       i = quantize(d, y, qtab_723_16, 1);  /* i = ADPCM code */
+
+             /* Since quantize() only produces a three level output
+              * (1, 2, or 3), we must create the fourth one on our own
+              */
+       if (i == 3)                          /* i code for the zero region */
+         if ((d & 0x8000) == 0)             /* If d > 0, i=3 isn't right... */
+           i = 0;
+           
+       dq = reconstruct(i & 2, _dqlntab[i], y); /* quantized diff. */
+
+       sr = (dq < 0) ? se - (dq & 0x3FFF) : se + dq; /* reconstructed signal */
+
+       dqsez = sr + sez - se;          /* pole prediction diff. */
+
+       update(2, y, _witab[i], _fitab[i], dq, sr, dqsez, state_ptr);
+
+       return (i);
+}
+
+/*
+ * g723_16_decoder()
+ *
+ * Decodes a 2-bit CCITT G.723_16 ADPCM code and returns
+ * the resulting 16-bit linear PCM, A-law or u-law sample value.
+ * -1 is returned if the output coding is unknown.
+ */
+int
+g723_16_decoder(
+       int             i,
+       G72x_STATE *state_ptr)
+{
+       short           sezi, sei, sez, se;     /* ACCUM */
+       short           y;                      /* MIX */
+       short           sr;                     /* ADDB */
+       short           dq;
+       short           dqsez;
+
+       i &= 0x03;                      /* mask to get proper bits */
+       sezi = predictor_zero(state_ptr);
+       sez = sezi >> 1;
+       sei = sezi + predictor_pole(state_ptr);
+       se = sei >> 1;                  /* se = estimated signal */
+
+       y = step_size(state_ptr);       /* adaptive quantizer step size */
+       dq = reconstruct(i & 0x02, _dqlntab[i], y); /* unquantize pred diff */
+
+       sr = (dq < 0) ? (se - (dq & 0x3FFF)) : (se + dq); /* reconst. signal */
+
+       dqsez = sr - se + sez;                  /* pole prediction diff. */
+
+       update(2, y, _witab[i], _fitab[i], dq, sr, dqsez, state_ptr);
+
+               /* sr was of 14-bit dynamic range */
+               return (sr << 2);       
+}
+/*
+** Do not edit or modify anything in this comment block.
+** The arch-tag line is a file identity tag for the GNU Arch 
+** revision control system.
+**
+** arch-tag: ae265466-c3fc-4f83-bb32-edae488a5ca5
+*/
+
diff --git a/libs/libsndfile/src/G72x/g723_24.c b/libs/libsndfile/src/G72x/g723_24.c
new file mode 100644 (file)
index 0000000..8748459
--- /dev/null
@@ -0,0 +1,146 @@
+/*
+ * This source code is a product of Sun Microsystems, Inc. and is provided
+ * for unrestricted use.  Users may copy or modify this source code without
+ * charge.
+ *
+ * SUN SOURCE CODE IS PROVIDED AS IS WITH NO WARRANTIES OF ANY KIND INCLUDING
+ * THE WARRANTIES OF DESIGN, MERCHANTIBILITY AND FITNESS FOR A PARTICULAR
+ * PURPOSE, OR ARISING FROM A COURSE OF DEALING, USAGE OR TRADE PRACTICE.
+ *
+ * Sun source code is provided with no support and without any obligation on
+ * the part of Sun Microsystems, Inc. to assist in its use, correction,
+ * modification or enhancement.
+ *
+ * SUN MICROSYSTEMS, INC. SHALL HAVE NO LIABILITY WITH RESPECT TO THE
+ * INFRINGEMENT OF COPYRIGHTS, TRADE SECRETS OR ANY PATENTS BY THIS SOFTWARE
+ * OR ANY PART THEREOF.
+ *
+ * In no event will Sun Microsystems, Inc. be liable for any lost revenue
+ * or profits or other special, indirect and consequential damages, even if
+ * Sun has been advised of the possibility of such damages.
+ *
+ * Sun Microsystems, Inc.
+ * 2550 Garcia Avenue
+ * Mountain View, California  94043
+ */
+
+/*
+ * g723_24.c
+ *
+ * Description:
+ *
+ * g723_24_encoder(), g723_24_decoder()
+ *
+ * These routines comprise an implementation of the CCITT G.723 24 Kbps
+ * ADPCM coding algorithm.  Essentially, this implementation is identical to
+ * the bit level description except for a few deviations which take advantage
+ * of workstation attributes, such as hardware 2's complement arithmetic.
+ *
+ */
+
+#include "g72x.h"
+#include "g72x_priv.h"
+
+/*
+ * Maps G.723_24 code word to reconstructed scale factor normalized log
+ * magnitude values.
+ */
+static short   _dqlntab[8] = {-2048, 135, 273, 373, 373, 273, 135, -2048};
+
+/* Maps G.723_24 code word to log of scale factor multiplier. */
+static short   _witab[8] = {-128, 960, 4384, 18624, 18624, 4384, 960, -128};
+
+/*
+ * Maps G.723_24 code words to a set of values whose long and short
+ * term averages are computed and then compared to give an indication
+ * how stationary (steady state) the signal is.
+ */
+static short   _fitab[8] = {0, 0x200, 0x400, 0xE00, 0xE00, 0x400, 0x200, 0};
+
+static short qtab_723_24[3] = {8, 218, 331};
+
+/*
+ * g723_24_encoder()
+ *
+ * Encodes a linear PCM, A-law or u-law input sample and returns its 3-bit code.
+ * Returns -1 if invalid input coding value.
+ */
+int
+g723_24_encoder(
+       int             sl,
+       G72x_STATE *state_ptr)
+{
+       short           sei, sezi, se, sez;     /* ACCUM */
+       short           d;                      /* SUBTA */
+       short           y;                      /* MIX */
+       short           sr;                     /* ADDB */
+       short           dqsez;                  /* ADDC */
+       short           dq, i;
+
+       /* linearize input sample to 14-bit PCM */
+       sl >>= 2;               /* sl of 14-bit dynamic range */
+
+       sezi = predictor_zero(state_ptr);
+       sez = sezi >> 1;
+       sei = sezi + predictor_pole(state_ptr);
+       se = sei >> 1;                  /* se = estimated signal */
+
+       d = sl - se;                    /* d = estimation diff. */
+
+       /* quantize prediction difference d */
+       y = step_size(state_ptr);       /* quantizer step size */
+       i = quantize(d, y, qtab_723_24, 3);     /* i = ADPCM code */
+       dq = reconstruct(i & 4, _dqlntab[i], y); /* quantized diff. */
+
+       sr = (dq < 0) ? se - (dq & 0x3FFF) : se + dq; /* reconstructed signal */
+
+       dqsez = sr + sez - se;          /* pole prediction diff. */
+
+       update(3, y, _witab[i], _fitab[i], dq, sr, dqsez, state_ptr);
+
+       return (i);
+}
+
+/*
+ * g723_24_decoder()
+ *
+ * Decodes a 3-bit CCITT G.723_24 ADPCM code and returns
+ * the resulting 16-bit linear PCM, A-law or u-law sample value.
+ * -1 is returned if the output coding is unknown.
+ */
+int
+g723_24_decoder(
+       int             i,
+       G72x_STATE *state_ptr)
+{
+       short           sezi, sei, sez, se;     /* ACCUM */
+       short           y;                      /* MIX */
+       short           sr;                     /* ADDB */
+       short           dq;
+       short           dqsez;
+
+       i &= 0x07;                      /* mask to get proper bits */
+       sezi = predictor_zero(state_ptr);
+       sez = sezi >> 1;
+       sei = sezi + predictor_pole(state_ptr);
+       se = sei >> 1;                  /* se = estimated signal */
+
+       y = step_size(state_ptr);       /* adaptive quantizer step size */
+       dq = reconstruct(i & 0x04, _dqlntab[i], y); /* unquantize pred diff */
+
+       sr = (dq < 0) ? (se - (dq & 0x3FFF)) : (se + dq); /* reconst. signal */
+
+       dqsez = sr - se + sez;                  /* pole prediction diff. */
+
+       update(3, y, _witab[i], _fitab[i], dq, sr, dqsez, state_ptr);
+
+       return (sr << 2);       /* sr was of 14-bit dynamic range */
+}
+/*
+** Do not edit or modify anything in this comment block.
+** The arch-tag line is a file identity tag for the GNU Arch 
+** revision control system.
+**
+** arch-tag: 75389236-650b-4427-98f3-0df6e8fb24bc
+*/
+
diff --git a/libs/libsndfile/src/G72x/g723_40.c b/libs/libsndfile/src/G72x/g723_40.c
new file mode 100644 (file)
index 0000000..6ddb577
--- /dev/null
@@ -0,0 +1,160 @@
+/*
+ * This source code is a product of Sun Microsystems, Inc. and is provided
+ * for unrestricted use.  Users may copy or modify this source code without
+ * charge.
+ *
+ * SUN SOURCE CODE IS PROVIDED AS IS WITH NO WARRANTIES OF ANY KIND INCLUDING
+ * THE WARRANTIES OF DESIGN, MERCHANTIBILITY AND FITNESS FOR A PARTICULAR
+ * PURPOSE, OR ARISING FROM A COURSE OF DEALING, USAGE OR TRADE PRACTICE.
+ *
+ * Sun source code is provided with no support and without any obligation on
+ * the part of Sun Microsystems, Inc. to assist in its use, correction,
+ * modification or enhancement.
+ *
+ * SUN MICROSYSTEMS, INC. SHALL HAVE NO LIABILITY WITH RESPECT TO THE
+ * INFRINGEMENT OF COPYRIGHTS, TRADE SECRETS OR ANY PATENTS BY THIS SOFTWARE
+ * OR ANY PART THEREOF.
+ *
+ * In no event will Sun Microsystems, Inc. be liable for any lost revenue
+ * or profits or other special, indirect and consequential damages, even if
+ * Sun has been advised of the possibility of such damages.
+ *
+ * Sun Microsystems, Inc.
+ * 2550 Garcia Avenue
+ * Mountain View, California  94043
+ */
+
+/*
+ * g723_40.c
+ *
+ * Description:
+ *
+ * g723_40_encoder(), g723_40_decoder()
+ *
+ * These routines comprise an implementation of the CCITT G.723 40Kbps
+ * ADPCM coding algorithm.  Essentially, this implementation is identical to
+ * the bit level description except for a few deviations which
+ * take advantage of workstation attributes, such as hardware 2's
+ * complement arithmetic.
+ *
+ * The deviation from the bit level specification (lookup tables),
+ * preserves the bit level performance specifications.
+ *
+ * As outlined in the G.723 Recommendation, the algorithm is broken
+ * down into modules.  Each section of code below is preceded by
+ * the name of the module which it is implementing.
+ *
+ */
+
+#include "g72x.h"
+#include "g72x_priv.h"
+
+/*
+ * Maps G.723_40 code word to ructeconstructed scale factor normalized log
+ * magnitude values.
+ */
+static short   _dqlntab[32] = {-2048, -66, 28, 104, 169, 224, 274, 318,
+                               358, 395, 429, 459, 488, 514, 539, 566,
+                               566, 539, 514, 488, 459, 429, 395, 358,
+                               318, 274, 224, 169, 104, 28, -66, -2048};
+
+/* Maps G.723_40 code word to log of scale factor multiplier. */
+static short   _witab[32] = {448, 448, 768, 1248, 1280, 1312, 1856, 3200,
+                       4512, 5728, 7008, 8960, 11456, 14080, 16928, 22272,
+                       22272, 16928, 14080, 11456, 8960, 7008, 5728, 4512,
+                       3200, 1856, 1312, 1280, 1248, 768, 448, 448};
+
+/*
+ * Maps G.723_40 code words to a set of values whose long and short
+ * term averages are computed and then compared to give an indication
+ * how stationary (steady state) the signal is.
+ */
+static short   _fitab[32] = {0, 0, 0, 0, 0, 0x200, 0x200, 0x200,
+                       0x200, 0x200, 0x400, 0x600, 0x800, 0xA00, 0xC00, 0xC00,
+                       0xC00, 0xC00, 0xA00, 0x800, 0x600, 0x400, 0x200, 0x200,
+                       0x200, 0x200, 0x200, 0, 0, 0, 0, 0};
+
+static short qtab_723_40[15] = {-122, -16, 68, 139, 198, 250, 298, 339,
+                               378, 413, 445, 475, 502, 528, 553};
+
+/*
+ * g723_40_encoder()
+ *
+ * Encodes a 16-bit linear PCM, A-law or u-law input sample and retuens
+ * the resulting 5-bit CCITT G.723 40Kbps code.
+ * Returns -1 if the input coding value is invalid.
+ */
+int    g723_40_encoder (int sl, G72x_STATE *state_ptr)
+{
+       short           sei, sezi, se, sez;     /* ACCUM */
+       short           d;                      /* SUBTA */
+       short           y;                      /* MIX */
+       short           sr;                     /* ADDB */
+       short           dqsez;                  /* ADDC */
+       short           dq, i;
+
+       /* linearize input sample to 14-bit PCM */
+       sl >>= 2;               /* sl of 14-bit dynamic range */
+
+       sezi = predictor_zero(state_ptr);
+       sez = sezi >> 1;
+       sei = sezi + predictor_pole(state_ptr);
+       se = sei >> 1;                  /* se = estimated signal */
+
+       d = sl - se;                    /* d = estimation difference */
+
+       /* quantize prediction difference */
+       y = step_size(state_ptr);       /* adaptive quantizer step size */
+       i = quantize(d, y, qtab_723_40, 15);    /* i = ADPCM code */
+
+       dq = reconstruct(i & 0x10, _dqlntab[i], y);     /* quantized diff */
+
+       sr = (dq < 0) ? se - (dq & 0x7FFF) : se + dq; /* reconstructed signal */
+
+       dqsez = sr + sez - se;          /* dqsez = pole prediction diff. */
+
+       update(5, y, _witab[i], _fitab[i], dq, sr, dqsez, state_ptr);
+
+       return (i);
+}
+
+/*
+ * g723_40_decoder()
+ *
+ * Decodes a 5-bit CCITT G.723 40Kbps code and returns
+ * the resulting 16-bit linear PCM, A-law or u-law sample value.
+ * -1 is returned if the output coding is unknown.
+ */
+int    g723_40_decoder (int i, G72x_STATE *state_ptr)
+{
+       short           sezi, sei, sez, se;     /* ACCUM */
+       short           y ;                     /* MIX */
+       short           sr;                     /* ADDB */
+       short           dq;
+       short           dqsez;
+
+       i &= 0x1f;                      /* mask to get proper bits */
+       sezi = predictor_zero(state_ptr);
+       sez = sezi >> 1;
+       sei = sezi + predictor_pole(state_ptr);
+       se = sei >> 1;                  /* se = estimated signal */
+
+       y = step_size(state_ptr);       /* adaptive quantizer step size */
+       dq = reconstruct(i & 0x10, _dqlntab[i], y);     /* estimation diff. */
+
+       sr = (dq < 0) ? (se - (dq & 0x7FFF)) : (se + dq); /* reconst. signal */
+
+       dqsez = sr - se + sez;          /* pole prediction diff. */
+
+       update(5, y, _witab[i], _fitab[i], dq, sr, dqsez, state_ptr);
+
+       return (sr << 2);       /* sr was of 14-bit dynamic range */
+}
+/*
+** Do not edit or modify anything in this comment block.
+** The arch-tag line is a file identity tag for the GNU Arch 
+** revision control system.
+**
+** arch-tag: eb8d9a00-32bf-4dd2-b287-01b0336d72bf
+*/
+
diff --git a/libs/libsndfile/src/G72x/g72x.c b/libs/libsndfile/src/G72x/g72x.c
new file mode 100644 (file)
index 0000000..ea01d79
--- /dev/null
@@ -0,0 +1,652 @@
+/*
+ * This source code is a product of Sun Microsystems, Inc. and is provided
+ * for unrestricted use.  Users may copy or modify this source code without
+ * charge.
+ *
+ * SUN SOURCE CODE IS PROVIDED AS IS WITH NO WARRANTIES OF ANY KIND INCLUDING
+ * THE WARRANTIES OF DESIGN, MERCHANTIBILITY AND FITNESS FOR A PARTICULAR
+ * PURPOSE, OR ARISING FROM A COURSE OF DEALING, USAGE OR TRADE PRACTICE.
+ *
+ * Sun source code is provided with no support and without any obligation on
+ * the part of Sun Microsystems, Inc. to assist in its use, correction,
+ * modification or enhancement.
+ *
+ * SUN MICROSYSTEMS, INC. SHALL HAVE NO LIABILITY WITH RESPECT TO THE
+ * INFRINGEMENT OF COPYRIGHTS, TRADE SECRETS OR ANY PATENTS BY THIS SOFTWARE
+ * OR ANY PART THEREOF.
+ *
+ * In no event will Sun Microsystems, Inc. be liable for any lost revenue
+ * or profits or other special, indirect and consequential damages, even if
+ * Sun has been advised of the possibility of such damages.
+ *
+ * Sun Microsystems, Inc.
+ * 2550 Garcia Avenue
+ * Mountain View, California  94043
+ */
+
+/*
+ * g72x.c
+ *
+ * Common routines for G.721 and G.723 conversions.
+ */
+
+#include <stdio.h>
+#include <stdlib.h>
+#include <string.h>
+
+#include "g72x.h"
+#include "g72x_priv.h"
+
+static G72x_STATE * g72x_state_new (void) ;
+static int unpack_bytes (int bits, int blocksize, const unsigned char * block, short * samples) ;
+static int pack_bytes (int bits, const short * samples, unsigned char * block) ;
+
+static
+short power2 [15] =
+{      1, 2, 4, 8, 0x10, 0x20, 0x40, 0x80,
+       0x100, 0x200, 0x400, 0x800, 0x1000, 0x2000, 0x4000
+} ;
+
+/*
+ * quan()
+ *
+ * quantizes the input val against the table of size short integers.
+ * It returns i if table[i - 1] <= val < table[i].
+ *
+ * Using linear search for simple coding.
+ */
+static
+int quan (int val, short *table, int size)
+{
+       int             i;
+
+       for (i = 0; i < size; i++)
+               if (val < *table++)
+                       break;
+       return (i);
+}
+
+/*
+ * fmult()
+ *
+ * returns the integer product of the 14-bit integer "an" and
+ * "floating point" representation (4-bit exponent, 6-bit mantessa) "srn".
+ */
+static
+int fmult (int an, int srn)
+{
+       short           anmag, anexp, anmant;
+       short           wanexp, wanmant;
+       short           retval;
+
+       anmag = (an > 0) ? an : ((-an) & 0x1FFF);
+       anexp = quan(anmag, power2, 15) - 6;
+       anmant = (anmag == 0) ? 32 :
+           (anexp >= 0) ? anmag >> anexp : anmag << -anexp;
+       wanexp = anexp + ((srn >> 6) & 0xF) - 13;
+
+       /*
+       ** The original was :
+       **              wanmant = (anmant * (srn & 0x37) + 0x30) >> 4 ;
+       ** but could see no valid reason for the + 0x30.
+       ** Removed it and it improved the SNR of the codec.
+       */
+
+       wanmant = (anmant * (srn & 0x37)) >> 4 ;
+
+       retval = (wanexp >= 0) ? ((wanmant << wanexp) & 0x7FFF) :
+           (wanmant >> -wanexp);
+
+       return (((an ^ srn) < 0) ? -retval : retval);
+}
+
+static G72x_STATE * g72x_state_new (void)
+{      return calloc (1, sizeof (G72x_STATE)) ;
+}
+
+/*
+ * private_init_state()
+ *
+ * This routine initializes and/or resets the G72x_PRIVATE structure
+ * pointed to by 'state_ptr'.
+ * All the initial state values are specified in the CCITT G.721 document.
+ */
+void private_init_state (G72x_STATE *state_ptr)
+{
+       int             cnta;
+
+       state_ptr->yl = 34816;
+       state_ptr->yu = 544;
+       state_ptr->dms = 0;
+       state_ptr->dml = 0;
+       state_ptr->ap = 0;
+       for (cnta = 0; cnta < 2; cnta++) {
+               state_ptr->a[cnta] = 0;
+               state_ptr->pk[cnta] = 0;
+               state_ptr->sr[cnta] = 32;
+       }
+       for (cnta = 0; cnta < 6; cnta++) {
+               state_ptr->b[cnta] = 0;
+               state_ptr->dq[cnta] = 32;
+       }
+       state_ptr->td = 0;
+}      /* private_init_state */
+
+struct g72x_state * g72x_reader_init (int codec, int *blocksize, int *samplesperblock)
+{      G72x_STATE *pstate ;
+
+       if ((pstate = g72x_state_new ()) == NULL)
+               return NULL ;
+
+       private_init_state (pstate) ;
+
+       pstate->encoder = NULL ;
+
+       switch (codec)
+       {       case G723_16_BITS_PER_SAMPLE : /* 2 bits per sample. */
+                               pstate->decoder = g723_16_decoder ;
+                               *blocksize = G723_16_BYTES_PER_BLOCK ;
+                               *samplesperblock = G723_16_SAMPLES_PER_BLOCK ;
+                               pstate->codec_bits = 2 ;
+                               pstate->blocksize = G723_16_BYTES_PER_BLOCK ;
+                               pstate->samplesperblock = G723_16_SAMPLES_PER_BLOCK ;
+                               break ;
+
+               case G723_24_BITS_PER_SAMPLE : /* 3 bits per sample. */
+                               pstate->decoder = g723_24_decoder ;
+                               *blocksize = G723_24_BYTES_PER_BLOCK ;
+                               *samplesperblock = G723_24_SAMPLES_PER_BLOCK ;
+                               pstate->codec_bits = 3 ;
+                               pstate->blocksize = G723_24_BYTES_PER_BLOCK ;
+                               pstate->samplesperblock = G723_24_SAMPLES_PER_BLOCK ;
+                               break ;
+
+               case G721_32_BITS_PER_SAMPLE : /* 4 bits per sample. */
+                               pstate->decoder = g721_decoder ;
+                               *blocksize = G721_32_BYTES_PER_BLOCK ;
+                               *samplesperblock = G721_32_SAMPLES_PER_BLOCK ;
+                               pstate->codec_bits = 4 ;
+                               pstate->blocksize = G721_32_BYTES_PER_BLOCK ;
+                               pstate->samplesperblock = G721_32_SAMPLES_PER_BLOCK ;
+                               break ;
+
+               case G721_40_BITS_PER_SAMPLE : /* 5 bits per sample. */
+                               pstate->decoder = g723_40_decoder ;
+                               *blocksize = G721_40_BYTES_PER_BLOCK ;
+                               *samplesperblock = G721_40_SAMPLES_PER_BLOCK ;
+                               pstate->codec_bits = 5 ;
+                               pstate->blocksize = G721_40_BYTES_PER_BLOCK ;
+                               pstate->samplesperblock = G721_40_SAMPLES_PER_BLOCK ;
+                               break ;
+
+               default :
+                               free (pstate) ;
+                               return NULL ;
+               } ;
+
+       return pstate ;
+}      /* g72x_reader_init */
+
+struct g72x_state * g72x_writer_init (int codec, int *blocksize, int *samplesperblock)
+{      G72x_STATE *pstate ;
+
+       if ((pstate = g72x_state_new ()) == NULL)
+               return NULL ;
+
+       private_init_state (pstate) ;
+       pstate->decoder = NULL ;
+
+       switch (codec)
+       {       case G723_16_BITS_PER_SAMPLE : /* 2 bits per sample. */
+                               pstate->encoder = g723_16_encoder ;
+                               *blocksize = G723_16_BYTES_PER_BLOCK ;
+                               *samplesperblock = G723_16_SAMPLES_PER_BLOCK ;
+                               pstate->codec_bits = 2 ;
+                               pstate->blocksize = G723_16_BYTES_PER_BLOCK ;
+                               pstate->samplesperblock = G723_16_SAMPLES_PER_BLOCK ;
+                               break ;
+
+               case G723_24_BITS_PER_SAMPLE : /* 3 bits per sample. */
+                               pstate->encoder = g723_24_encoder ;
+                               *blocksize = G723_24_BYTES_PER_BLOCK ;
+                               *samplesperblock = G723_24_SAMPLES_PER_BLOCK ;
+                               pstate->codec_bits = 3 ;
+                               pstate->blocksize = G723_24_BYTES_PER_BLOCK ;
+                               pstate->samplesperblock = G723_24_SAMPLES_PER_BLOCK ;
+                               break ;
+
+               case G721_32_BITS_PER_SAMPLE : /* 4 bits per sample. */
+                               pstate->encoder = g721_encoder ;
+                               *blocksize = G721_32_BYTES_PER_BLOCK ;
+                               *samplesperblock = G721_32_SAMPLES_PER_BLOCK ;
+                               pstate->codec_bits = 4 ;
+                               pstate->blocksize = G721_32_BYTES_PER_BLOCK ;
+                               pstate->samplesperblock = G721_32_SAMPLES_PER_BLOCK ;
+                               break ;
+
+               case G721_40_BITS_PER_SAMPLE : /* 5 bits per sample. */
+                               pstate->encoder = g723_40_encoder ;
+                               *blocksize = G721_40_BYTES_PER_BLOCK ;
+                               *samplesperblock = G721_40_SAMPLES_PER_BLOCK ;
+                               pstate->codec_bits = 5 ;
+                               pstate->blocksize = G721_40_BYTES_PER_BLOCK ;
+                               pstate->samplesperblock = G721_40_SAMPLES_PER_BLOCK ;
+                               break ;
+
+               default :
+                               free (pstate) ;
+                               return NULL ;
+               } ;
+
+       return pstate ;
+}      /* g72x_writer_init */
+
+int g72x_decode_block (G72x_STATE *pstate, const unsigned char *block, short *samples)
+{      int     k, count ;
+
+       count = unpack_bytes (pstate->codec_bits, pstate->blocksize, block, samples) ;
+
+       for (k = 0 ; k < count ; k++)
+               samples [k] = pstate->decoder (samples [k], pstate) ;
+
+       return 0 ;
+}      /* g72x_decode_block */
+
+int g72x_encode_block (G72x_STATE *pstate, short *samples, unsigned char *block)
+{      int k, count ;
+
+       for (k = 0 ; k < pstate->samplesperblock ; k++)
+               samples [k] = pstate->encoder (samples [k], pstate) ;
+
+       count = pack_bytes (pstate->codec_bits, samples, block) ;
+
+       return count ;
+}      /* g72x_encode_block */
+
+/*
+ * predictor_zero()
+ *
+ * computes the estimated signal from 6-zero predictor.
+ *
+ */
+int  predictor_zero (G72x_STATE *state_ptr)
+{
+       int             i;
+       int             sezi;
+
+       sezi = fmult(state_ptr->b[0] >> 2, state_ptr->dq[0]);
+       for (i = 1; i < 6; i++)                 /* ACCUM */
+               sezi += fmult(state_ptr->b[i] >> 2, state_ptr->dq[i]);
+       return (sezi);
+}
+/*
+ * predictor_pole()
+ *
+ * computes the estimated signal from 2-pole predictor.
+ *
+ */
+int  predictor_pole(G72x_STATE *state_ptr)
+{
+       return (fmult(state_ptr->a[1] >> 2, state_ptr->sr[1]) +
+           fmult(state_ptr->a[0] >> 2, state_ptr->sr[0]));
+}
+/*
+ * step_size()
+ *
+ * computes the quantization step size of the adaptive quantizer.
+ *
+ */
+int  step_size (G72x_STATE *state_ptr)
+{
+       int             y;
+       int             dif;
+       int             al;
+
+       if (state_ptr->ap >= 256)
+               return (state_ptr->yu);
+       else {
+               y = state_ptr->yl >> 6;
+               dif = state_ptr->yu - y;
+               al = state_ptr->ap >> 2;
+               if (dif > 0)
+                       y += (dif * al) >> 6;
+               else if (dif < 0)
+                       y += (dif * al + 0x3F) >> 6;
+               return (y);
+       }
+}
+
+/*
+ * quantize()
+ *
+ * Given a raw sample, 'd', of the difference signal and a
+ * quantization step size scale factor, 'y', this routine returns the
+ * ADPCM codeword to which that sample gets quantized.  The step
+ * size scale factor division operation is done in the log base 2 domain
+ * as a subtraction.
+ */
+int quantize(
+       int             d,      /* Raw difference signal sample */
+       int             y,      /* Step size multiplier */
+       short   *table, /* quantization table */
+       int             size)   /* table size of short integers */
+{
+       short           dqm;    /* Magnitude of 'd' */
+       short           expon;  /* Integer part of base 2 log of 'd' */
+       short           mant;   /* Fractional part of base 2 log */
+       short           dl;     /* Log of magnitude of 'd' */
+       short           dln;    /* Step size scale factor normalized log */
+       int             i;
+
+       /*
+        * LOG
+        *
+        * Compute base 2 log of 'd', and store in 'dl'.
+        */
+       dqm = abs(d);
+       expon = quan(dqm >> 1, power2, 15);
+       mant = ((dqm << 7) >> expon) & 0x7F;    /* Fractional portion. */
+       dl = (expon << 7) + mant;
+
+       /*
+        * SUBTB
+        *
+        * "Divide" by step size multiplier.
+        */
+       dln = dl - (y >> 2);
+
+       /*
+        * QUAN
+        *
+        * Obtain codword i for 'd'.
+        */
+       i = quan(dln, table, size);
+       if (d < 0)                      /* take 1's complement of i */
+               return ((size << 1) + 1 - i);
+       else if (i == 0)                /* take 1's complement of 0 */
+               return ((size << 1) + 1); /* new in 1988 */
+       else
+               return (i);
+}
+/*
+ * reconstruct()
+ *
+ * Returns reconstructed difference signal 'dq' obtained from
+ * codeword 'i' and quantization step size scale factor 'y'.
+ * Multiplication is performed in log base 2 domain as addition.
+ */
+int
+reconstruct(
+       int             sign,   /* 0 for non-negative value */
+       int             dqln,   /* G.72x codeword */
+       int             y)      /* Step size multiplier */
+{
+       short           dql;    /* Log of 'dq' magnitude */
+       short           dex;    /* Integer part of log */
+       short           dqt;
+       short           dq;     /* Reconstructed difference signal sample */
+
+       dql = dqln + (y >> 2);  /* ADDA */
+
+       if (dql < 0) {
+               return ((sign) ? -0x8000 : 0);
+       } else {                /* ANTILOG */
+               dex = (dql >> 7) & 15;
+               dqt = 128 + (dql & 127);
+               dq = (dqt << 7) >> (14 - dex);
+               return ((sign) ? (dq - 0x8000) : dq);
+       }
+}
+
+
+/*
+ * update()
+ *
+ * updates the state variables for each output code
+ */
+void
+update(
+       int             code_size,      /* distinguish 723_40 with others */
+       int             y,              /* quantizer step size */
+       int             wi,             /* scale factor multiplier */
+       int             fi,             /* for long/short term energies */
+       int             dq,             /* quantized prediction difference */
+       int             sr,             /* reconstructed signal */
+       int             dqsez,          /* difference from 2-pole predictor */
+       G72x_STATE *state_ptr)  /* coder state pointer */
+{
+       int             cnt;
+       short           mag, expon;     /* Adaptive predictor, FLOAT A */
+       short           a2p = 0;        /* LIMC */
+       short           a1ul;           /* UPA1 */
+       short           pks1;           /* UPA2 */
+       short           fa1;
+       char            tr;             /* tone/transition detector */
+       short           ylint, thr2, dqthr;
+       short           ylfrac, thr1;
+       short           pk0;
+
+       pk0 = (dqsez < 0) ? 1 : 0;      /* needed in updating predictor poles */
+
+       mag = dq & 0x7FFF;              /* prediction difference magnitude */
+       /* TRANS */
+       ylint = state_ptr->yl >> 15;    /* exponent part of yl */
+       ylfrac = (state_ptr->yl >> 10) & 0x1F;  /* fractional part of yl */
+       thr1 = (32 + ylfrac) << ylint;          /* threshold */
+       thr2 = (ylint > 9) ? 31 << 10 : thr1;   /* limit thr2 to 31 << 10 */
+       dqthr = (thr2 + (thr2 >> 1)) >> 1;      /* dqthr = 0.75 * thr2 */
+       if (state_ptr->td == 0)         /* signal supposed voice */
+               tr = 0;
+       else if (mag <= dqthr)          /* supposed data, but small mag */
+               tr = 0;                 /* treated as voice */
+       else                            /* signal is data (modem) */
+               tr = 1;
+
+       /*
+        * Quantizer scale factor adaptation.
+        */
+
+       /* FUNCTW & FILTD & DELAY */
+       /* update non-steady state step size multiplier */
+       state_ptr->yu = y + ((wi - y) >> 5);
+
+       /* LIMB */
+       if (state_ptr->yu < 544)        /* 544 <= yu <= 5120 */
+               state_ptr->yu = 544;
+       else if (state_ptr->yu > 5120)
+               state_ptr->yu = 5120;
+
+       /* FILTE & DELAY */
+       /* update steady state step size multiplier */
+       state_ptr->yl += state_ptr->yu + ((-state_ptr->yl) >> 6);
+
+       /*
+        * Adaptive predictor coefficients.
+        */
+       if (tr == 1) {                  /* reset a's and b's for modem signal */
+               state_ptr->a[0] = 0;
+               state_ptr->a[1] = 0;
+               state_ptr->b[0] = 0;
+               state_ptr->b[1] = 0;
+               state_ptr->b[2] = 0;
+               state_ptr->b[3] = 0;
+               state_ptr->b[4] = 0;
+               state_ptr->b[5] = 0;
+       } else {                        /* update a's and b's */
+               pks1 = pk0 ^ state_ptr->pk[0];          /* UPA2 */
+
+               /* update predictor pole a[1] */
+               a2p = state_ptr->a[1] - (state_ptr->a[1] >> 7);
+               if (dqsez != 0) {
+                       fa1 = (pks1) ? state_ptr->a[0] : -state_ptr->a[0];
+                       if (fa1 < -8191)        /* a2p = function of fa1 */
+                               a2p -= 0x100;
+                       else if (fa1 > 8191)
+                               a2p += 0xFF;
+                       else
+                               a2p += fa1 >> 5;
+
+                       if (pk0 ^ state_ptr->pk[1])
+                       {       /* LIMC */
+                               if (a2p <= -12160)
+                                       a2p = -12288;
+                               else if (a2p >= 12416)
+                                       a2p = 12288;
+                               else
+                                       a2p -= 0x80;
+                               }
+                       else if (a2p <= -12416)
+                               a2p = -12288;
+                       else if (a2p >= 12160)
+                               a2p = 12288;
+                       else
+                               a2p += 0x80;
+               }
+
+               /* TRIGB & DELAY */
+               state_ptr->a[1] = a2p;
+
+               /* UPA1 */
+               /* update predictor pole a[0] */
+               state_ptr->a[0] -= state_ptr->a[0] >> 8;
+               if (dqsez != 0)
+               {       if (pks1 == 0)
+                               state_ptr->a[0] += 192;
+                       else
+                               state_ptr->a[0] -= 192;
+                       } ;
+
+               /* LIMD */
+               a1ul = 15360 - a2p;
+               if (state_ptr->a[0] < -a1ul)
+                       state_ptr->a[0] = -a1ul;
+               else if (state_ptr->a[0] > a1ul)
+                       state_ptr->a[0] = a1ul;
+
+               /* UPB : update predictor zeros b[6] */
+               for (cnt = 0; cnt < 6; cnt++) {
+                       if (code_size == 5)             /* for 40Kbps G.723 */
+                               state_ptr->b[cnt] -= state_ptr->b[cnt] >> 9;
+                       else                    /* for G.721 and 24Kbps G.723 */
+                               state_ptr->b[cnt] -= state_ptr->b[cnt] >> 8;
+                       if (dq & 0x7FFF) {                      /* XOR */
+                               if ((dq ^ state_ptr->dq[cnt]) >= 0)
+                                       state_ptr->b[cnt] += 128;
+                               else
+                                       state_ptr->b[cnt] -= 128;
+                       }
+               }
+       }
+
+       for (cnt = 5; cnt > 0; cnt--)
+               state_ptr->dq[cnt] = state_ptr->dq[cnt-1];
+       /* FLOAT A : convert dq[0] to 4-bit exp, 6-bit mantissa f.p. */
+       if (mag == 0) {
+               state_ptr->dq[0] = (dq >= 0) ? 0x20 : 0xFC20;
+       } else {
+               expon = quan(mag, power2, 15);
+               state_ptr->dq[0] = (dq >= 0) ?
+                   (expon << 6) + ((mag << 6) >> expon) :
+                   (expon << 6) + ((mag << 6) >> expon) - 0x400;
+       }
+
+       state_ptr->sr[1] = state_ptr->sr[0];
+       /* FLOAT B : convert sr to 4-bit exp., 6-bit mantissa f.p. */
+       if (sr == 0) {
+               state_ptr->sr[0] = 0x20;
+       } else if (sr > 0) {
+               expon = quan(sr, power2, 15);
+               state_ptr->sr[0] = (expon << 6) + ((sr << 6) >> expon);
+       } else if (sr > -32768) {
+               mag = -sr;
+               expon = quan(mag, power2, 15);
+               state_ptr->sr[0] =  (expon << 6) + ((mag << 6) >> expon) - 0x400;
+       } else
+               state_ptr->sr[0] = (short) 0xFC20;
+
+       /* DELAY A */
+       state_ptr->pk[1] = state_ptr->pk[0];
+       state_ptr->pk[0] = pk0;
+
+       /* TONE */
+       if (tr == 1)            /* this sample has been treated as data */
+               state_ptr->td = 0;      /* next one will be treated as voice */
+       else if (a2p < -11776)  /* small sample-to-sample correlation */
+               state_ptr->td = 1;      /* signal may be data */
+       else                            /* signal is voice */
+               state_ptr->td = 0;
+
+       /*
+        * Adaptation speed control.
+        */
+       state_ptr->dms += (fi - state_ptr->dms) >> 5;           /* FILTA */
+       state_ptr->dml += (((fi << 2) - state_ptr->dml) >> 7);  /* FILTB */
+
+       if (tr == 1)
+               state_ptr->ap = 256;
+       else if (y < 1536)                                      /* SUBTC */
+               state_ptr->ap += (0x200 - state_ptr->ap) >> 4;
+       else if (state_ptr->td == 1)
+               state_ptr->ap += (0x200 - state_ptr->ap) >> 4;
+       else if (abs((state_ptr->dms << 2) - state_ptr->dml) >=
+           (state_ptr->dml >> 3))
+               state_ptr->ap += (0x200 - state_ptr->ap) >> 4;
+       else
+               state_ptr->ap += (-state_ptr->ap) >> 4;
+
+       return ;
+} /* update */
+
+/*------------------------------------------------------------------------------
+*/
+
+static int
+unpack_bytes (int bits, int blocksize, const unsigned char * block, short * samples)
+{      unsigned int    in_buffer = 0 ;
+       unsigned char   in_byte ;
+       int                             k, in_bits = 0, bindex = 0 ;
+
+       for (k = 0 ; bindex <= blocksize && k < G72x_BLOCK_SIZE ; k++)
+       {       if (in_bits < bits)
+               {       in_byte = block [bindex++] ;
+
+                       in_buffer |= (in_byte << in_bits);
+                       in_bits += 8;
+                       }
+               samples [k] = in_buffer & ((1 << bits) - 1);
+               in_buffer >>= bits;
+               in_bits -= bits;
+               } ;
+
+       return k ;
+} /* unpack_bytes */
+
+static int
+pack_bytes (int bits, const short * samples, unsigned char * block)
+{
+       unsigned int    out_buffer = 0 ;
+       int                             k, bindex = 0, out_bits = 0 ;
+       unsigned char   out_byte ;
+
+       for (k = 0 ; k < G72x_BLOCK_SIZE ; k++)
+       {       out_buffer |= (samples [k] << out_bits) ;
+               out_bits += bits ;
+               if (out_bits >= 8)
+               {       out_byte = out_buffer & 0xFF ;
+                       out_bits -= 8 ;
+                       out_buffer >>= 8 ;
+                       block [bindex++] = out_byte ;
+                       }
+               } ;
+
+       return bindex ;
+} /* pack_bytes */
+
+/*
+** Do not edit or modify anything in this comment block.
+** The arch-tag line is a file identity tag for the GNU Arch
+** revision control system.
+**
+** arch-tag: 6298dc75-fd0f-4062-9b90-f73ed69f22d4
+*/
+
diff --git a/libs/libsndfile/src/G72x/g72x.h b/libs/libsndfile/src/G72x/g72x.h
new file mode 100644 (file)
index 0000000..e6319e6
--- /dev/null
@@ -0,0 +1,99 @@
+/*
+** Copyright (C) 1999-2005 Erik de Castro Lopo <erikd@mega-nerd.com>
+**
+** This program is free software; you can redistribute it and/or modify
+** it under the terms of the GNU Lesser General Public License as published by
+** the Free Software Foundation; either version 2.1 of the License, or
+** (at your option) any later version.
+**
+** This program is distributed in the hope that it will be useful,
+** but WITHOUT ANY WARRANTY; without even the implied warranty of
+** MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+** GNU Lesser General Public License for more details.
+**
+** You should have received a copy of the GNU Lesser General Public License
+** along with this program; if not, write to the Free Software
+** Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA.
+*/
+
+/*
+** This file is not the same as the original file from Sun Microsystems. Nearly
+** all the original definitions and function prototypes that were in the file
+** of this name have been moved to g72x_priv.h.
+*/
+
+#ifndef G72X_HEADER_FILE
+#define        G72X_HEADER_FILE
+
+/*
+** Number of samples per block to process.
+** Must be a common multiple of possible bits per sample : 2, 3, 4, 5 and 8.
+*/
+#define        G72x_BLOCK_SIZE         (3 * 5 * 8)
+
+/*
+**     Identifiers for the differing kinds of G72x ADPCM codecs.
+**     The identifiers also define the number of encoded bits per sample.
+*/
+
+enum
+{      G723_16_BITS_PER_SAMPLE = 2,
+       G723_24_BITS_PER_SAMPLE = 3,
+       G723_40_BITS_PER_SAMPLE = 5,
+
+       G721_32_BITS_PER_SAMPLE = 4,
+       G721_40_BITS_PER_SAMPLE = 5,
+
+       G723_16_SAMPLES_PER_BLOCK = G72x_BLOCK_SIZE,
+       G723_24_SAMPLES_PER_BLOCK = G723_24_BITS_PER_SAMPLE * (G72x_BLOCK_SIZE / G723_24_BITS_PER_SAMPLE),
+       G723_40_SAMPLES_PER_BLOCK = G723_40_BITS_PER_SAMPLE * (G72x_BLOCK_SIZE / G723_40_BITS_PER_SAMPLE),
+
+       G721_32_SAMPLES_PER_BLOCK = G72x_BLOCK_SIZE,
+       G721_40_SAMPLES_PER_BLOCK = G721_40_BITS_PER_SAMPLE * (G72x_BLOCK_SIZE / G721_40_BITS_PER_SAMPLE),
+
+       G723_16_BYTES_PER_BLOCK = (G723_16_BITS_PER_SAMPLE * G72x_BLOCK_SIZE) / 8,
+       G723_24_BYTES_PER_BLOCK = (G723_24_BITS_PER_SAMPLE * G72x_BLOCK_SIZE) / 8,
+       G723_40_BYTES_PER_BLOCK = (G723_40_BITS_PER_SAMPLE * G72x_BLOCK_SIZE) / 8,
+
+       G721_32_BYTES_PER_BLOCK = (G721_32_BITS_PER_SAMPLE * G72x_BLOCK_SIZE) / 8,
+       G721_40_BYTES_PER_BLOCK = (G721_40_BITS_PER_SAMPLE * G72x_BLOCK_SIZE) / 8
+} ;
+
+/* Forward declaration of of g72x_state. */
+
+struct g72x_state ;
+
+/* External function definitions. */
+
+struct g72x_state * g72x_reader_init (int codec, int *blocksize, int *samplesperblock) ;
+struct g72x_state * g72x_writer_init (int codec, int *blocksize, int *samplesperblock) ;
+/*
+**     Initialize the ADPCM state table for the given codec.
+**     Return 0 on success, 1 on fail.
+*/
+
+int g72x_decode_block (struct g72x_state *pstate, const unsigned char *block, short *samples) ;
+/*
+**     The caller fills data->block with data->bytes bytes before calling the
+**     function. The value data->bytes must be an integer multiple of
+**     data->blocksize and be <= data->max_bytes.
+**     When it returns, the caller can read out data->samples samples.
+*/
+
+int g72x_encode_block (struct g72x_state *pstate, short *samples, unsigned char *block) ;
+/*
+**     The caller fills state->samples some integer multiple data->samples_per_block
+**     (up to G72x_BLOCK_SIZE) samples before calling the function.
+**     When it returns, the caller can read out bytes encoded bytes.
+*/
+
+#endif /* !G72X_HEADER_FILE */
+
+/*
+** Do not edit or modify anything in this comment block.
+** The arch-tag line is a file identity tag for the GNU Arch
+** revision control system.
+**
+** arch-tag: 6ca84e5f-f932-4ba1-87ee-37056d921621
+*/
+
diff --git a/libs/libsndfile/src/G72x/g72x_priv.h b/libs/libsndfile/src/G72x/g72x_priv.h
new file mode 100644 (file)
index 0000000..a88e96d
--- /dev/null
@@ -0,0 +1,118 @@
+/*
+ * This source code is a product of Sun Microsystems, Inc. and is provided
+ * for unrestricted use.  Users may copy or modify this source code without
+ * charge.
+ *
+ * SUN SOURCE CODE IS PROVIDED AS IS WITH NO WARRANTIES OF ANY KIND INCLUDING
+ * THE WARRANTIES OF DESIGN, MERCHANTIBILITY AND FITNESS FOR A PARTICULAR
+ * PURPOSE, OR ARISING FROM A COURSE OF DEALING, USAGE OR TRADE PRACTICE.
+ *
+ * Sun source code is provided with no support and without any obligation on
+ * the part of Sun Microsystems, Inc. to assist in its use, correction,
+ * modification or enhancement.
+ *
+ * SUN MICROSYSTEMS, INC. SHALL HAVE NO LIABILITY WITH RESPECT TO THE
+ * INFRINGEMENT OF COPYRIGHTS, TRADE SECRETS OR ANY PATENTS BY THIS SOFTWARE
+ * OR ANY PART THEREOF.
+ *
+ * In no event will Sun Microsystems, Inc. be liable for any lost revenue
+ * or profits or other special, indirect and consequential damages, even if
+ * Sun has been advised of the possibility of such damages.
+ *
+ * Sun Microsystems, Inc.
+ * 2550 Garcia Avenue
+ * Mountain View, California  94043
+ */
+
+#ifndef G72X_PRIVATE_H
+#define G72X_PRIVATE_H
+
+#ifdef __cplusplus
+#error "This code is not designed to be compiled with a C++ compiler."
+#endif
+
+/*
+** The following is the definition of the state structure used by the
+** G.721/G.723 encoder and decoder to preserve their internal state
+** between successive calls.  The meanings of the majority of the state
+** structure fields are explained in detail in the CCITT Recommendation
+** G.721.  The field names are essentially identical to variable names
+** in the bit level description of the coding algorithm included in this
+** Recommendation.
+*/
+
+struct g72x_state
+{      long  yl;       /* Locked or steady state step size multiplier. */
+       short yu;       /* Unlocked or non-steady state step size multiplier. */
+       short dms;      /* Short term energy estimate. */
+       short dml;      /* Long term energy estimate. */
+       short ap;       /* Linear weighting coefficient of 'yl' and 'yu'. */
+
+       short a[2];     /* Coefficients of pole portion of prediction filter. */
+       short b[6];     /* Coefficients of zero portion of prediction filter. */
+       short pk[2];    /*
+                                       ** Signs of previous two samples of a partially
+                                       ** reconstructed signal.
+                                       **/
+       short dq[6];    /*
+                                       ** Previous 6 samples of the quantized difference
+                                       ** signal represented in an internal floating point
+                                       ** format.
+                                       **/
+       short sr[2];    /*
+                                       ** Previous 2 samples of the quantized difference
+                                       ** signal represented in an internal floating point
+                                       ** format.
+                                       */
+       char td;        /* delayed tone detect, new in 1988 version */
+
+       /*      The following struct members were added for libsndfile. The original
+       **      code worked by calling a set of functions on a sample by sample basis
+       **      which is slow on architectures like Intel x86. For libsndfile, this
+       **      was changed so that the encoding and decoding routines could work on
+       **      a block of samples at a time to reduce the function call overhead.
+       */
+       int             (*encoder) (int, struct g72x_state* state) ;
+       int             (*decoder) (int, struct g72x_state* state) ;
+
+       int             codec_bits, blocksize, samplesperblock ;
+} ;
+
+typedef struct g72x_state G72x_STATE ;
+
+int    predictor_zero (G72x_STATE *state_ptr);
+
+int    predictor_pole (G72x_STATE *state_ptr);
+
+int    step_size (G72x_STATE *state_ptr);
+
+int    quantize (int d, int    y, short *table, int size);
+
+int    reconstruct (int sign, int dqln,        int y);
+
+void update (int code_size, int y, int wi, int fi, int dq, int sr, int dqsez, G72x_STATE *state_ptr);
+
+int g721_encoder       (int sample, G72x_STATE *state_ptr);
+int g721_decoder       (int code, G72x_STATE *state_ptr);
+
+int g723_16_encoder    (int sample, G72x_STATE *state_ptr);
+int g723_16_decoder    (int code, G72x_STATE *state_ptr);
+
+int g723_24_encoder    (int sample, G72x_STATE *state_ptr);
+int g723_24_decoder    (int code, G72x_STATE *state_ptr);
+
+int g723_40_encoder    (int sample, G72x_STATE *state_ptr);
+int g723_40_decoder    (int code, G72x_STATE *state_ptr);
+
+void private_init_state (G72x_STATE *state_ptr) ;
+
+#endif /* G72X_PRIVATE_H */
+
+/*
+** Do not edit or modify anything in this comment block.
+** The arch-tag line is a file identity tag for the GNU Arch
+** revision control system.
+**
+** arch-tag: d9ad4da7-0fa3-471d-8020-720b5cfb5e5b
+*/
+
diff --git a/libs/libsndfile/src/G72x/g72x_test.c b/libs/libsndfile/src/G72x/g72x_test.c
new file mode 100644 (file)
index 0000000..caf5846
--- /dev/null
@@ -0,0 +1,222 @@
+/*
+** Copyright (C) 1999-2004 Erik de Castro Lopo <erikd@mega-nerd.com>
+**  
+** This program is free software; you can redistribute it and/or modify
+** it under the terms of the GNU General Public License as published by
+** the Free Software Foundation; either version 2 of the License, or
+** (at your option) any later version.
+** 
+** This program is distributed in the hope that it will be useful,
+** but WITHOUT ANY WARRANTY; without even the implied warranty of
+** MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+** GNU General Public License for more details.
+** 
+** You should have received a copy of the GNU General Public License
+** along with this program; if not, write to the Free Software 
+** Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA.
+*/
+#include <stdio.h>
+#include <unistd.h>
+#include <stdlib.h>
+#include <string.h>
+#include <math.h>
+
+#include "g72x.h"
+#include "g72x_priv.h"
+
+#ifndef                M_PI
+#define                M_PI            3.14159265358979323846264338
+#endif
+
+#define                BUFFER_SIZE             (1<<14) /* Should be (1<<14) */
+#define                SAMPLE_RATE             11025
+
+
+static void g721_test  (void) ;
+static void g723_test  (double margin) ;
+
+static void    gen_signal_double (double *data, double scale, int datalen) ;
+static int error_function (double data, double orig, double margin) ;
+
+static int     oct_save_short  (short *a, short *b, int len) ;
+
+int
+main (int argc, char *argv [])
+{      int             bDoAll = 0 ;
+       int             nTests = 0 ;
+
+       if (argc != 2)
+       {       printf ("Usage : %s <test>\n", argv [0]) ;
+               printf ("    Where <test> is one of the following:\n") ;
+               printf ("           g721  - test G721 encoder and decoder\n") ;
+               printf ("           g723  - test G721 encoder and decoder\n") ;
+               printf ("           all   - perform all tests\n") ;
+               exit (1) ;
+               } ;
+
+       bDoAll=!strcmp (argv [1], "all");
+
+       if (bDoAll || ! strcmp (argv [1], "g721"))
+       {       g721_test       () ;
+               nTests++ ;
+               } ;
+
+       if (bDoAll || ! strcmp (argv [1], "g723"))
+       {       g723_test       (0.53) ;
+               nTests++ ;
+               } ;
+
+       if (nTests == 0)
+       {       printf ("Mono : ************************************\n") ;
+               printf ("Mono : *  No '%s' test defined.\n", argv [1]) ;
+               printf ("Mono : ************************************\n") ;
+               return 1 ;
+               } ;
+
+       return 0 ;
+} /* main */
+
+static void 
+g721_test      (void)
+{
+       return ;
+} /* g721_test */
+
+static void 
+g723_test      (double margin)
+{      static double   orig_buffer [BUFFER_SIZE] ;
+       static short    orig [BUFFER_SIZE] ;
+       static short    data [BUFFER_SIZE] ;
+
+       G72x_STATE encoder_state, decoder_state ;
+       
+       long    k ;
+       int     code, position, max_err ;
+
+       private_init_state (&encoder_state) ;
+       encoder_state.encoder = g723_24_encoder ;
+       encoder_state.codec_bits = 3 ;
+
+       private_init_state (&decoder_state) ;
+       decoder_state.decoder = g723_24_decoder ;
+       decoder_state.codec_bits = 3 ;
+
+       memset (data, 0, BUFFER_SIZE * sizeof (short)) ;
+       memset (orig, 0, BUFFER_SIZE * sizeof (short)) ;
+       
+       printf ("    g723_test    : ") ;
+       fflush (stdout) ;
+       
+       gen_signal_double (orig_buffer, 32000.0, BUFFER_SIZE) ;
+       for (k = 0 ; k < BUFFER_SIZE ; k++)
+               orig [k] = (short) orig_buffer [k] ;
+
+       /* Write and read data here. */
+       position = 0 ;
+       max_err = 0 ;
+       for (k = 0 ; k < BUFFER_SIZE ; k++)
+       {       code = encoder_state.encoder (orig [k], &encoder_state) ;
+               data [k] = decoder_state.decoder (code, &decoder_state) ;
+               if (abs (orig [k] - data [k]) > max_err)
+               {       position = k ;
+                       max_err = abs (orig [k] - data [k]) ;
+                       } ;
+               } ;
+
+       printf ("\n\nMax error of %d at postion %d.\n", max_err, position) ;
+
+       for (k = 0 ; k < BUFFER_SIZE ; k++)
+       {       if (error_function (data [k], orig [k], margin))
+               {       printf ("Line %d: Incorrect sample A (#%ld : %d should be %d).\n", __LINE__, k, data [k], orig [k]) ;
+                       oct_save_short (orig, data, BUFFER_SIZE) ;
+                       exit (1) ;
+                       } ;
+               } ;
+
+
+       printf ("ok\n") ;
+
+       return ;
+} /* g723_test */
+
+
+#define                SIGNAL_MAXVAL   30000.0
+#define                DECAY_COUNT             1000
+
+static void    
+gen_signal_double (double *gendata, double scale, int gendatalen)
+{      int             k, ramplen ;
+       double  amp = 0.0 ;
+       
+       ramplen = DECAY_COUNT ;
+       
+       for (k = 0 ; k < gendatalen ; k++)
+       {       if (k <= ramplen)
+                       amp = scale * k / ((double) ramplen) ;
+               else if (k > gendatalen - ramplen)
+                       amp = scale * (gendatalen - k) / ((double) ramplen) ;
+
+               gendata [k] = amp * (0.4 * sin (33.3 * 2.0 * M_PI * ((double) (k+1)) / ((double) SAMPLE_RATE))
+                                               + 0.3 * cos (201.1 * 2.0 * M_PI * ((double) (k+1)) / ((double) SAMPLE_RATE))) ;
+               } ;
+       
+       return ;
+} /* gen_signal_double */
+
+static int 
+error_function (double data, double orig, double margin)
+{      double error ;
+
+       if (fabs (orig) <= 500.0)
+               error = fabs (fabs (data) - fabs(orig)) / 2000.0 ;
+       else if (fabs (orig) <= 1000.0)
+               error = fabs (data - orig) / 3000.0 ;
+       else
+               error = fabs (data - orig) / fabs (orig) ;
+               
+       if (error > margin)
+       {       printf ("\n\n*******************\nError : %f\n", error) ;
+               return 1 ;
+               } ;
+       return 0 ;
+} /* error_function */
+
+static int             
+oct_save_short (short *a, short *b, int len)
+{      FILE    *file ;
+       int             k ;
+
+       if (! (file = fopen ("error.dat", "w")))
+               return 1 ;
+               
+       fprintf (file, "# Not created by Octave\n") ;
+       
+       fprintf (file, "# name: a\n") ;
+       fprintf (file, "# type: matrix\n") ;
+       fprintf (file, "# rows: %d\n", len) ;
+       fprintf (file, "# columns: 1\n") ;
+       
+       for (k = 0 ; k < len ; k++)
+               fprintf (file, "% d\n", a [k]) ;
+
+       fprintf (file, "# name: b\n") ;
+       fprintf (file, "# type: matrix\n") ;
+       fprintf (file, "# rows: %d\n", len) ;
+       fprintf (file, "# columns: 1\n") ;
+       
+       for (k = 0 ; k < len ; k++)
+               fprintf (file, "% d\n", b [k]) ;
+
+       fclose (file) ;
+       return 0 ;
+} /* oct_save_short */
+
+/*
+** Do not edit or modify anything in this comment block.
+** The arch-tag line is a file identity tag for the GNU Arch 
+** revision control system.
+**
+** arch-tag: 0597b442-a5b0-4abf-92a4-92f6c24e85a6
+*/
+
diff --git a/libs/libsndfile/src/GSM610/COPYRIGHT b/libs/libsndfile/src/GSM610/COPYRIGHT
new file mode 100644 (file)
index 0000000..eba0e52
--- /dev/null
@@ -0,0 +1,16 @@
+Copyright 1992, 1993, 1994 by Jutta Degener and Carsten Bormann,
+Technische Universitaet Berlin
+
+Any use of this software is permitted provided that this notice is not
+removed and that neither the authors nor the Technische Universitaet Berlin
+are deemed to have made any representations as to the suitability of this
+software for any purpose nor are held responsible for any defects of
+this software.  THERE IS ABSOLUTELY NO WARRANTY FOR THIS SOFTWARE.
+
+As a matter of courtesy, the authors request to be informed about uses
+this software has found, about bugs in this software, and about any
+improvements that may be of general interest.
+
+Berlin, 28.11.1994
+Jutta Degener
+Carsten Bormann
diff --git a/libs/libsndfile/src/GSM610/ChangeLog b/libs/libsndfile/src/GSM610/ChangeLog
new file mode 100644 (file)
index 0000000..24f5248
--- /dev/null
@@ -0,0 +1,56 @@
+2004-05-12  Erik de Castro Lopo  <erikd AT mega-nerd DOT com>
+
+    * gsm610_priv.h
+    Replace ugly macros with inline functions.
+
+    * *.c
+    Remove temporary variables used by macros and other minor fixes required by
+    above change.
+
+2003-06-02  Erik de Castro Lopo  <erikd AT mega-nerd DOT com>
+
+    * rpe.c
+       Renamed variables "exp" to "expon" to avoid shadowed parameter warnigns.
+
+2002-06-08  Erik de Castro Lopo  <erikd AT mega-nerd DOT com>
+
+    * long_term.c
+       Changes tp removed compiler warnings about shadowed parameters.
+
+2002-06-08  Erik de Castro Lopo  <erikd AT mega-nerd DOT com>
+
+    * private.h
+       Made declarations of gsm_A, gsm_B, gsm_MIC etc extern. This fixed a compile
+       problem on MacOSX.
+
+2002-05-10  Erik de Castro Lopo  <erikd AT mega-nerd DOT com>
+
+       * *.[ch]
+       Removed all pre-ANSI prototype kludges. Removed proto.h and unproto.h. 
+       Started work on making GSM 6.10 files seekable. Currently they are not.
+
+    * code.c private.h
+       Function Gsm_Coder () used a statically defined array. This was obviously
+       not re-entrant so moved it to struct gsm_state.
+
+2001-09-16  Erik de Castro Lopo  <erikd AT mega-nerd DOT com>
+
+    * code.c
+    Added #includes for string.h and stdlib.h.
+
+2000-10-27  Erik de Castro Lopo  <erikd AT mega-nerd DOT com>
+
+    * config.h
+    Removed some commented out #defines (ie //*efine) which were causing problems on
+       the Sun cc compiler.
+
+2000-02-29  Erik de Castro Lopo  <erikd AT mega-nerd DOT com>
+
+    * private.h
+    Added #defines to emulate normal compile time options.
+
+2000-02-28  Erik de Castro Lopo  <erikd AT mega-nerd DOT com>
+
+    * everthing
+    Created this directory and copied files from libgsm.
+    http://kbs.cs.tu-berlin.de/~jutta/toast.html
diff --git a/libs/libsndfile/src/GSM610/README b/libs/libsndfile/src/GSM610/README
new file mode 100644 (file)
index 0000000..b57132b
--- /dev/null
@@ -0,0 +1,36 @@
+GSM 06.10 13 kbit/s RPE/LTP speech codec
+----------------------------------------
+
+All the file in this directory were written by Jutta Degener
+and Carsten Borman for The Communications and Operating Systems 
+Research Group (KBS) at the Technische Universitaet Berlin.
+
+Their work was released under the following license which is 
+assumed to be compatible with The GNU Lesser General Public License.
+
+----------------------------------------------------------------------------
+
+Copyright 1992, 1993, 1994 by Jutta Degener and Carsten Bormann,
+Technische Universitaet Berlin
+
+Any use of this software is permitted provided that this notice is not
+removed and that neither the authors nor the Technische Universitaet Berlin
+are deemed to have made any representations as to the suitability of this
+software for any purpose nor are held responsible for any defects of
+this software.  THERE IS ABSOLUTELY NO WARRANTY FOR THIS SOFTWARE.
+
+As a matter of courtesy, the authors request to be informed about uses
+this software has found, about bugs in this software, and about any
+improvements that may be of general interest.
+
+Berlin, 28.11.1994
+Jutta Degener (jutta@cs.tu-berlin.de)
+Carsten Bormann (cabo@cs.tu-berlin.de)
+
+----------------------------------------------------------------------------
+
+Jutta Degener and Carsten Bormann's work can be found on their homepage
+at:
+
+    http://kbs.cs.tu-berlin.de/~jutta/toast.html
+       
diff --git a/libs/libsndfile/src/GSM610/add.c b/libs/libsndfile/src/GSM610/add.c
new file mode 100644 (file)
index 0000000..fbf7cf1
--- /dev/null
@@ -0,0 +1,248 @@
+/*
+ * Copyright 1992 by Jutta Degener and Carsten Bormann, Technische
+ * Universitaet Berlin.  See the accompanying file "COPYRIGHT" for
+ * details.  THERE IS ABSOLUTELY NO WARRANTY FOR THIS SOFTWARE.
+ */
+
+/*
+ *  See private.h for the more commonly used macro versions.
+ */
+
+#include       <stdio.h>
+#include       <assert.h>
+
+#include       "gsm610_priv.h"
+#include       "gsm.h"
+
+#define        saturate(x)     \
+       ((x) < MIN_WORD ? MIN_WORD : (x) > MAX_WORD ? MAX_WORD: (x))
+
+word gsm_add ( word a, word b)
+{
+       longword sum = (longword)a + (longword)b;
+       return saturate(sum);
+}
+
+word gsm_sub ( word a, word b)
+{
+       longword diff = (longword)a - (longword)b;
+       return saturate(diff);
+}
+
+word gsm_mult ( word a, word b)
+{
+       if (a == MIN_WORD && b == MIN_WORD)
+               return MAX_WORD;
+       
+       return SASR_L( (longword)a * (longword)b, 15 );
+}
+
+word gsm_mult_r ( word a, word b)
+{
+       if (b == MIN_WORD && a == MIN_WORD) return MAX_WORD;
+       else {
+               longword prod = (longword)a * (longword)b + 16384;
+               prod >>= 15;
+               return prod & 0xFFFF;
+       }
+}
+
+word gsm_abs (word a)
+{
+       return a < 0 ? (a == MIN_WORD ? MAX_WORD : -a) : a;
+}
+
+longword gsm_L_mult (word a, word b)
+{
+       assert( a != MIN_WORD || b != MIN_WORD );
+       return ((longword)a * (longword)b) << 1;
+}
+
+longword gsm_L_add ( longword a, longword b)
+{
+       if (a < 0) {
+               if (b >= 0) return a + b;
+               else {
+                       ulongword A = (ulongword)-(a + 1) + (ulongword)-(b + 1);
+                       return A >= MAX_LONGWORD ? MIN_LONGWORD :-(longword)A-2;
+               }
+       }
+       else if (b <= 0) return a + b;
+       else {
+               ulongword A = (ulongword)a + (ulongword)b;
+               return A > MAX_LONGWORD ? MAX_LONGWORD : A;
+       }
+}
+
+longword gsm_L_sub ( longword a, longword b)
+{
+       if (a >= 0) {
+               if (b >= 0) return a - b;
+               else {
+                       /* a>=0, b<0 */
+
+                       ulongword A = (ulongword)a + -(b + 1);
+                       return A >= MAX_LONGWORD ? MAX_LONGWORD : (A + 1);
+               }
+       }
+       else if (b <= 0) return a - b;
+       else {
+               /* a<0, b>0 */  
+
+               ulongword A = (ulongword)-(a + 1) + b;
+               return A >= MAX_LONGWORD ? MIN_LONGWORD : -(longword)A - 1;
+       }
+}
+
+static unsigned char const bitoff[ 256 ] = {
+        8, 7, 6, 6, 5, 5, 5, 5, 4, 4, 4, 4, 4, 4, 4, 4,
+        3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3,
+        2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2,
+        2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2,
+        1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1,
+        1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1,
+        1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1,
+        1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1,
+        0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
+        0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
+        0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
+        0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
+        0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
+        0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
+        0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
+        0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0
+};
+
+word gsm_norm (longword a )
+/*
+ * the number of left shifts needed to normalize the 32 bit
+ * variable L_var1 for positive values on the interval
+ *
+ * with minimum of
+ * minimum of 1073741824  (01000000000000000000000000000000) and 
+ * maximum of 2147483647  (01111111111111111111111111111111)
+ *
+ *
+ * and for negative values on the interval with
+ * minimum of -2147483648 (-10000000000000000000000000000000) and
+ * maximum of -1073741824 ( -1000000000000000000000000000000).
+ *
+ * in order to normalize the result, the following
+ * operation must be done: L_norm_var1 = L_var1 << norm( L_var1 );
+ *
+ * (That's 'ffs', only from the left, not the right..)
+ */
+{
+       assert(a != 0);
+
+       if (a < 0) {
+               if (a <= -1073741824) return 0;
+               a = ~a;
+       }
+
+       return    a & 0xffff0000 
+               ? ( a & 0xff000000
+                 ?  -1 + bitoff[ 0xFF & (a >> 24) ]
+                 :   7 + bitoff[ 0xFF & (a >> 16) ] )
+               : ( a & 0xff00
+                 ?  15 + bitoff[ 0xFF & (a >> 8) ]
+                 :  23 + bitoff[ 0xFF & a ] );
+}
+
+longword gsm_L_asl (longword a, int n)
+{
+       if (n >= 32) return 0;
+       if (n <= -32) return -(a < 0);
+       if (n < 0) return gsm_L_asr(a, -n);
+       return a << n;
+}
+
+word gsm_asr (word a, int n)
+{
+       if (n >= 16) return -(a < 0);
+       if (n <= -16) return 0;
+       if (n < 0) return a << -n;
+
+       return SASR_W (a, (word) n);
+}
+
+word gsm_asl (word a, int n)
+{
+       if (n >= 16) return 0;
+       if (n <= -16) return -(a < 0);
+       if (n < 0) return gsm_asr(a, -n);
+       return a << n;
+}
+
+longword gsm_L_asr (longword a, int n)
+{
+       if (n >= 32) return -(a < 0);
+       if (n <= -32) return 0;
+       if (n < 0) return a << -n;
+
+       return SASR_L (a, (word) n);
+}
+
+/*
+**     word gsm_asr (word a, int n)
+**     {
+**             if (n >= 16) return -(a < 0);
+**             if (n <= -16) return 0;
+**             if (n < 0) return a << -n;
+**     
+**     #       ifdef   SASR_W
+**                     return a >> n;
+**     #       else
+**                     if (a >= 0) return a >> n;
+**                     else return -(word)( -(uword)a >> n );
+**     #       endif
+**     }
+**     
+*/
+/* 
+ *  (From p. 46, end of section 4.2.5)
+ *
+ *  NOTE: The following lines gives [sic] one correct implementation
+ *       of the div(num, denum) arithmetic operation.  Compute div
+ *        which is the integer division of num by denum: with denum
+ *       >= num > 0
+ */
+
+word gsm_div (word num, word denum)
+{
+       longword        L_num   = num;
+       longword        L_denum = denum;
+       word            div     = 0;
+       int             k       = 15;
+
+       /* The parameter num sometimes becomes zero.
+        * Although this is explicitly guarded against in 4.2.5,
+        * we assume that the result should then be zero as well.
+        */
+
+       /* assert(num != 0); */
+
+       assert(num >= 0 && denum >= num);
+       if (num == 0)
+           return 0;
+
+       while (k--) {
+               div   <<= 1;
+               L_num <<= 1;
+
+               if (L_num >= L_denum) {
+                       L_num -= L_denum;
+                       div++;
+               }
+       }
+
+       return div;
+}
+/*
+** Do not edit or modify anything in this comment block.
+** The arch-tag line is a file identity tag for the GNU Arch 
+** revision control system.
+**
+** arch-tag: a7398579-e2e1-4733-aa2d-4c6efc0c58ff
+*/
+
diff --git a/libs/libsndfile/src/GSM610/code.c b/libs/libsndfile/src/GSM610/code.c
new file mode 100644 (file)
index 0000000..02ec75b
--- /dev/null
@@ -0,0 +1,97 @@
+/*
+ * Copyright 1992 by Jutta Degener and Carsten Bormann, Technische
+ * Universitaet Berlin.  See the accompanying file "COPYRIGHT" for
+ * details.  THERE IS ABSOLUTELY NO WARRANTY FOR THIS SOFTWARE.
+ */
+
+
+#include       <stdlib.h>
+#include       <string.h>
+
+#include       "config.h"
+
+#include       "gsm610_priv.h"
+#include       "gsm.h"
+
+/* 
+ *  4.2 FIXED POINT IMPLEMENTATION OF THE RPE-LTP CODER 
+ */
+
+void Gsm_Coder (
+
+       struct gsm_state        * State,
+
+       word    * s,    /* [0..159] samples                     IN      */
+
+/*
+ * The RPE-LTD coder works on a frame by frame basis.  The length of
+ * the frame is equal to 160 samples.  Some computations are done
+ * once per frame to produce at the output of the coder the
+ * LARc[1..8] parameters which are the coded LAR coefficients and 
+ * also to realize the inverse filtering operation for the entire
+ * frame (160 samples of signal d[0..159]).  These parts produce at
+ * the output of the coder:
+ */
+
+       word    * LARc, /* [0..7] LAR coefficients              OUT     */
+
+/*
+ * Procedure 4.2.11 to 4.2.18 are to be executed four times per
+ * frame.  That means once for each sub-segment RPE-LTP analysis of
+ * 40 samples.  These parts produce at the output of the coder:
+ */
+
+       word    * Nc,   /* [0..3] LTP lag                       OUT     */
+       word    * bc,   /* [0..3] coded LTP gain                OUT     */
+       word    * Mc,   /* [0..3] RPE grid selection            OUT     */
+       word    * xmaxc,/* [0..3] Coded maximum amplitude       OUT     */
+       word    * xMc   /* [13*4] normalized RPE samples        OUT     */
+)
+{
+       int     k;
+       word    * dp  = State->dp0 + 120;       /* [ -120...-1 ] */
+       word    * dpp = dp;             /* [ 0...39 ]    */
+
+       word    so[160];
+
+       Gsm_Preprocess                  (State, s, so);
+       Gsm_LPC_Analysis                (State, so, LARc);
+       Gsm_Short_Term_Analysis_Filter  (State, LARc, so);
+
+       for (k = 0; k <= 3; k++, xMc += 13) {
+
+               Gsm_Long_Term_Predictor ( State,
+                                        so+k*40, /* d      [0..39] IN  */
+                                        dp,      /* dp  [-120..-1] IN  */
+                                       State->e + 5,     /* e      [0..39] OUT */
+                                       dpp,      /* dpp    [0..39] OUT */
+                                        Nc++,
+                                        bc++);
+
+               Gsm_RPE_Encoding        ( /*-S,-*/
+                                       State->e + 5,   /* e      ][0..39][ IN/OUT */
+                                         xmaxc++, Mc++, xMc );
+               /*
+                * Gsm_Update_of_reconstructed_short_time_residual_signal
+                *                      ( dpp, e + 5, dp );
+                */
+
+               { register int i;
+                 for (i = 0; i <= 39; i++)
+                       dp[ i ] = GSM_ADD( State->e[5 + i], dpp[i] );
+               }
+               dp  += 40;
+               dpp += 40;
+
+       }
+       (void)memcpy( (char *)State->dp0, (char *)(State->dp0 + 160),
+               120 * sizeof(*State->dp0) );
+}
+/*
+** Do not edit or modify anything in this comment block.
+** The arch-tag line is a file identity tag for the GNU Arch 
+** revision control system.
+**
+** arch-tag: ae8ef1b2-5a1e-4263-94cd-42b15dca81a3
+*/
+
diff --git a/libs/libsndfile/src/GSM610/config.h b/libs/libsndfile/src/GSM610/config.h
new file mode 100644 (file)
index 0000000..23ac5ad
--- /dev/null
@@ -0,0 +1,33 @@
+/*
+ * Copyright 1992 by Jutta Degener and Carsten Bormann, Technische
+ * Universitaet Berlin.  See the accompanying file "COPYRIGHT" for
+ * details.  THERE IS ABSOLUTELY NO WARRANTY FOR THIS SOFTWARE.
+ */
+
+#ifndef        CONFIG_H
+#define        CONFIG_H
+
+#define        HAS_STDLIB_H    1               /* /usr/include/stdlib.h        */
+#define        HAS_FCNTL_H     1               /* /usr/include/fcntl.h         */
+
+#define        HAS_FSTAT       1               /* fstat syscall                */
+#define        HAS_FCHMOD      1               /* fchmod syscall               */
+#define        HAS_CHMOD       1               /* chmod syscall                */
+#define        HAS_FCHOWN      1               /* fchown syscall               */
+#define        HAS_CHOWN       1               /* chown syscall                */
+
+#define        HAS_STRING_H    1               /* /usr/include/string.h        */
+
+#define        HAS_UNISTD_H    1               /* /usr/include/unistd.h        */
+#define        HAS_UTIME       1               /* POSIX utime(path, times)     */
+#define        HAS_UTIME_H     1               /* UTIME header file            */
+
+#endif /* CONFIG_H */
+/*
+** Do not edit or modify anything in this comment block.
+** The arch-tag line is a file identity tag for the GNU Arch 
+** revision control system.
+**
+** arch-tag: 5338dfef-8e59-4f51-af47-627c9ea85353
+*/
+
diff --git a/libs/libsndfile/src/GSM610/decode.c b/libs/libsndfile/src/GSM610/decode.c
new file mode 100644 (file)
index 0000000..46db318
--- /dev/null
@@ -0,0 +1,67 @@
+/*
+ * Copyright 1992 by Jutta Degener and Carsten Bormann, Technische
+ * Universitaet Berlin.  See the accompanying file "COPYRIGHT" for
+ * details.  THERE IS ABSOLUTELY NO WARRANTY FOR THIS SOFTWARE.
+ */
+
+#include <stdio.h>
+
+#include       "gsm610_priv.h"
+#include       "gsm.h"
+
+/*
+ *  4.3 FIXED POINT IMPLEMENTATION OF THE RPE-LTP DECODER
+ */
+
+static void Postprocessing (
+       struct gsm_state        * S,
+       register word           * s)
+{
+       register int            k;
+       register word           msr = S->msr;
+       register word           tmp;
+
+       for (k = 160; k--; s++) {
+               tmp = GSM_MULT_R( msr, 28180 );
+               msr = GSM_ADD(*s, tmp);            /* Deemphasis             */
+               *s  = GSM_ADD(msr, msr) & 0xFFF8;  /* Truncation & Upscaling */
+       }
+       S->msr = msr;
+}
+
+void Gsm_Decoder (
+       struct gsm_state        * S,
+
+       word            * LARcr,        /* [0..7]               IN      */
+
+       word            * Ncr,          /* [0..3]               IN      */
+       word            * bcr,          /* [0..3]               IN      */
+       word            * Mcr,          /* [0..3]               IN      */
+       word            * xmaxcr,       /* [0..3]               IN      */
+       word            * xMcr,         /* [0..13*4]            IN      */
+
+       word            * s)            /* [0..159]             OUT     */
+{
+       int             j, k;
+       word            erp[40], wt[160];
+       word            * drp = S->dp0 + 120;
+
+       for (j=0; j <= 3; j++, xmaxcr++, bcr++, Ncr++, Mcr++, xMcr += 13) {
+
+               Gsm_RPE_Decoding( /*-S,-*/ *xmaxcr, *Mcr, xMcr, erp );
+               Gsm_Long_Term_Synthesis_Filtering( S, *Ncr, *bcr, erp, drp );
+
+               for (k = 0; k <= 39; k++) wt[ j * 40 + k ] =  drp[ k ];
+       }
+
+       Gsm_Short_Term_Synthesis_Filter( S, LARcr, wt, s );
+       Postprocessing(S, s);
+}
+/*
+** Do not edit or modify anything in this comment block.
+** The arch-tag line is a file identity tag for the GNU Arch 
+** revision control system.
+**
+** arch-tag: 11ae5b90-2e8b-400b-ac64-a69a1fc6cc41
+*/
+
diff --git a/libs/libsndfile/src/GSM610/gsm.h b/libs/libsndfile/src/GSM610/gsm.h
new file mode 100644 (file)
index 0000000..a13a606
--- /dev/null
@@ -0,0 +1,58 @@
+/*
+ * Copyright 1992 by Jutta Degener and Carsten Bormann, Technische
+ * Universitaet Berlin.  See the accompanying file "COPYRIGHT" for
+ * details.  THERE IS ABSOLUTELY NO WARRANTY FOR THIS SOFTWARE.
+ */
+
+#ifndef        GSM_H
+#define        GSM_H
+
+#include       <stdio.h>               /* for FILE *   */
+
+/*
+ *     Interface
+ */
+
+typedef struct gsm_state *     gsm;
+typedef short                          gsm_signal;             /* signed 16 bit */
+typedef unsigned char          gsm_byte;
+typedef gsm_byte                       gsm_frame[33];          /* 33 * 8 bits   */
+
+#define        GSM_MAGIC               0xD                     /* 13 kbit/s RPE-LTP */
+
+#define        GSM_PATCHLEVEL          10
+#define        GSM_MINOR                       0
+#define        GSM_MAJOR                       1
+
+#define        GSM_OPT_VERBOSE         1
+#define        GSM_OPT_FAST            2
+#define        GSM_OPT_LTP_CUT         3
+#define        GSM_OPT_WAV49           4
+#define        GSM_OPT_FRAME_INDEX     5
+#define        GSM_OPT_FRAME_CHAIN     6
+
+gsm  gsm_create        (void);
+
+/* Added for libsndfile : May 6, 2002 */
+void gsm_init (gsm);   
+
+void gsm_destroy (gsm);        
+
+int  gsm_print   (FILE *, gsm, gsm_byte  *);
+int  gsm_option  (gsm, int, int *);
+
+void gsm_encode  (gsm, gsm_signal *, gsm_byte  *);
+int  gsm_decode  (gsm, gsm_byte   *, gsm_signal *);
+
+int  gsm_explode (gsm, gsm_byte   *, gsm_signal *);
+void gsm_implode (gsm, gsm_signal *, gsm_byte   *);
+
+#endif /* GSM_H */
+/*
+** Do not edit or modify anything in this comment block.
+** The arch-tag line is a file identity tag for the GNU Arch 
+** revision control system.
+**
+** arch-tag: 8cfc7698-5433-4b6f-aeca-967c6fda4dec
+*/
+
diff --git a/libs/libsndfile/src/GSM610/gsm610_priv.h b/libs/libsndfile/src/GSM610/gsm610_priv.h
new file mode 100644 (file)
index 0000000..c9ab3f2
--- /dev/null
@@ -0,0 +1,308 @@
+/*
+ * Copyright 1992 by Jutta Degener and Carsten Bormann, Technische
+ * Universitaet Berlin.  See the accompanying file "COPYRIGHT" for
+ * details.  THERE IS ABSOLUTELY NO WARRANTY FOR THIS SOFTWARE.
+ */
+
+#ifndef        PRIVATE_H
+#define        PRIVATE_H
+
+/* Added by Erik de Castro Lopo */
+#define        USE_FLOAT_MUL
+#define        FAST
+#define        WAV49
+
+#ifdef __cplusplus
+#error "This code is not designed to be compiled with a C++ compiler."
+#endif
+/* Added by Erik de Castro Lopo */
+
+
+
+typedef short                          word;           /* 16 bit signed int    */
+typedef int                                    longword;       /* 32 bit signed int    */
+
+typedef unsigned short         uword;          /* unsigned word        */
+typedef unsigned int           ulongword;      /* unsigned longword    */
+
+struct gsm_state
+{      word                    dp0[ 280 ] ;
+
+       word                    z1;                     /* preprocessing.c, Offset_com. */
+       longword                L_z2;           /*                  Offset_com. */
+       int                             mp;                     /*                  Preemphasis */
+
+       word                    u[8] ;                  /* short_term_aly_filter.c      */
+       word                    LARpp[2][8] ;   /*                              */
+       word                    j;                              /*                              */
+
+       word            ltp_cut;        /* long_term.c, LTP crosscorr.  */
+       word                    nrp;                    /* 40 */        /* long_term.c, synthesis       */
+       word                    v[9] ;                  /* short_term.c, synthesis      */
+       word                    msr;                    /* decoder.c,   Postprocessing  */
+
+       char                    verbose;                /* only used if !NDEBUG         */
+       char                    fast;                   /* only used if FAST            */
+
+       char                    wav_fmt;                /* only used if WAV49 defined   */
+       unsigned char   frame_index;    /*            odd/even chaining */
+       unsigned char   frame_chain;    /*   half-byte to carry forward */
+
+       /* Moved here from code.c where it was defined as static */
+       word e[50] ;
+} ;
+
+typedef struct gsm_state GSM_STATE ;
+
+#define        MIN_WORD        (-32767 - 1)
+#define        MAX_WORD          32767
+
+#define        MIN_LONGWORD    (-2147483647 - 1)
+#define        MAX_LONGWORD      2147483647
+
+/* Signed arithmetic shift right. */
+static inline word
+SASR_W (word x, word by)
+{      return (x >> by) ;
+} /* SASR */
+
+static inline longword
+SASR_L (longword x, word by)
+{      return (x >> by) ;
+} /* SASR */
+
+/*
+ *     Prototypes from add.c
+ */
+word   gsm_mult                (word a, word b) ;
+longword gsm_L_mult    (word a, word b) ;
+word   gsm_mult_r              (word a, word b) ;
+
+word   gsm_div                 (word num, word denum) ;
+
+word   gsm_add                 (word a, word b ) ;
+longword gsm_L_add     (longword a, longword b ) ;
+
+word   gsm_sub                 (word a, word b) ;
+longword gsm_L_sub     (longword a, longword b) ;
+
+word   gsm_abs                 (word a) ;
+
+word   gsm_norm                (longword a ) ;
+
+longword gsm_L_asl     (longword a, int n) ;
+word   gsm_asl                 (word a, int n) ;
+
+longword gsm_L_asr     (longword a, int n) ;
+word   gsm_asr                 (word a, int n) ;
+
+/*
+ *  Inlined functions from add.h
+ */
+
+static inline longword
+GSM_MULT_R (word a, word b)
+{      return (((longword) (a)) * ((longword) (b)) + 16384) >> 15 ;
+} /* GSM_MULT_R */
+
+static inline longword
+GSM_MULT (word a, word b)
+{      return (((longword) (a)) * ((longword) (b))) >> 15 ;
+} /* GSM_MULT */
+
+static inline longword
+GSM_L_MULT (word a, word b)
+{      return ((longword) (a)) * ((longword) (b)) << 1 ;
+} /* GSM_L_MULT */
+
+static inline longword
+GSM_L_ADD (longword a, longword b)
+{      ulongword utmp ;
+
+       if (a < 0 && b < 0)
+       {       utmp = (ulongword)-((a) + 1) + (ulongword)-((b) + 1) ;
+               return (utmp >= (ulongword) MAX_LONGWORD) ? MIN_LONGWORD : -(longword)utmp-2 ;
+               } ;
+
+       if (a > 0 && b > 0)
+       {       utmp = (ulongword) a + (ulongword) b ;
+               return (utmp >= (ulongword) MAX_LONGWORD) ? MAX_LONGWORD : utmp ;
+               } ;
+
+       return a + b ;
+} /* GSM_L_ADD */
+
+static inline longword
+GSM_ADD (word a, word b)
+{      longword ltmp ;
+
+       ltmp = ((longword) a) + ((longword) b) ;
+
+       if (ltmp >= MAX_WORD)
+               return MAX_WORD ;
+       if (ltmp <= MIN_WORD)
+               return MIN_WORD ;
+
+       return ltmp ;
+} /* GSM_ADD */
+
+static inline longword
+GSM_SUB (word a, word b)
+{      longword ltmp ;
+
+       ltmp = ((longword) a) - ((longword) b) ;
+
+       if (ltmp >= MAX_WORD)
+               ltmp = MAX_WORD ;
+       else if (ltmp <= MIN_WORD)
+               ltmp = MIN_WORD ;
+
+       return ltmp ;
+} /* GSM_SUB */
+
+static inline word
+GSM_ABS (word a)
+{
+       if (a > 0)
+               return a ;
+       if (a == MIN_WORD)
+               return MAX_WORD ;
+       return -a ;
+} /* GSM_ADD */
+
+
+/*
+ *  More prototypes from implementations..
+ */
+void Gsm_Coder (
+               struct gsm_state        * S,
+               word    * s,    /* [0..159] samples             IN      */
+               word    * LARc, /* [0..7] LAR coefficients      OUT     */
+               word    * Nc,   /* [0..3] LTP lag               OUT     */
+               word    * bc,   /* [0..3] coded LTP gain        OUT     */
+               word    * Mc,   /* [0..3] RPE grid selection    OUT     */
+               word    * xmaxc,/* [0..3] Coded maximum amplitude OUT   */
+               word    * xMc) ;/* [13*4] normalized RPE samples OUT    */
+
+void Gsm_Long_Term_Predictor (         /* 4x for 160 samples */
+               struct gsm_state * S,
+               word    * d,    /* [0..39]   residual signal    IN      */
+               word    * dp,   /* [-120..-1] d'                IN      */
+               word    * e,    /* [0..40]                      OUT     */
+               word    * dpp,  /* [0..40]                      OUT     */
+               word    * Nc,   /* correlation lag              OUT     */
+               word    * bc) ; /* gain factor                  OUT     */
+
+void Gsm_LPC_Analysis (
+               struct gsm_state * S,
+               word * s,               /* 0..159 signals       IN/OUT  */
+               word * LARc) ;   /* 0..7   LARc's       OUT     */
+
+void Gsm_Preprocess (
+               struct gsm_state * S,
+               word * s, word * so) ;
+
+void Gsm_Encoding (
+               struct gsm_state * S,
+               word    * e,
+               word    * ep,
+               word    * xmaxc,
+               word    * Mc,
+               word    * xMc) ;
+
+void Gsm_Short_Term_Analysis_Filter (
+               struct gsm_state * S,
+               word    * LARc, /* coded log area ratio [0..7]  IN      */
+               word    * d) ;  /* st res. signal [0..159]      IN/OUT  */
+
+void Gsm_Decoder (
+               struct gsm_state * S,
+               word    * LARcr,        /* [0..7]               IN      */
+               word    * Ncr,          /* [0..3]               IN      */
+               word    * bcr,          /* [0..3]               IN      */
+               word    * Mcr,          /* [0..3]               IN      */
+               word    * xmaxcr,       /* [0..3]               IN      */
+               word    * xMcr,         /* [0..13*4]            IN      */
+               word    * s) ;          /* [0..159]             OUT     */
+
+void Gsm_Decoding (
+               struct gsm_state * S,
+               word    xmaxcr,
+               word    Mcr,
+               word    * xMcr,         /* [0..12]              IN      */
+               word    * erp) ;        /* [0..39]              OUT     */
+
+void Gsm_Long_Term_Synthesis_Filtering (
+               struct gsm_state* S,
+               word    Ncr,
+               word    bcr,
+               word    * erp,          /* [0..39]                IN    */
+               word    * drp) ;        /* [-120..-1] IN, [0..40] OUT   */
+
+void Gsm_RPE_Decoding (
+       /*-struct gsm_state *S,-*/
+               word xmaxcr,
+               word Mcr,
+               word * xMcr,  /* [0..12], 3 bits             IN      */
+               word * erp) ; /* [0..39]                     OUT     */
+
+void Gsm_RPE_Encoding (
+               /*-struct gsm_state * S,-*/
+               word    * e,            /* -5..-1][0..39][40..44     IN/OUT  */
+               word    * xmaxc,        /*                              OUT */
+               word    * Mc,           /*                              OUT */
+               word    * xMc) ;        /* [0..12]                      OUT */
+
+void Gsm_Short_Term_Synthesis_Filter (
+               struct gsm_state * S,
+               word    * LARcr,        /* log area ratios [0..7]  IN   */
+               word    * drp,          /* received d [0...39]     IN   */
+               word    * s) ;          /* signal   s [0..159]    OUT   */
+
+void Gsm_Update_of_reconstructed_short_time_residual_signal (
+               word    * dpp,          /* [0...39]     IN      */
+               word    * ep,           /* [0...39]     IN      */
+               word    * dp) ;         /* [-120...-1]  IN/OUT  */
+
+/*
+ *  Tables from table.c
+ */
+#ifndef        GSM_TABLE_C
+
+extern word gsm_A [8], gsm_B [8], gsm_MIC [8], gsm_MAC [8] ;
+extern word gsm_INVA [8] ;
+extern word gsm_DLB [4], gsm_QLB [4] ;
+extern word gsm_H [11] ;
+extern word gsm_NRFAC [8] ;
+extern word gsm_FAC [8] ;
+
+#endif /* GSM_TABLE_C */
+
+/*
+ *  Debugging
+ */
+#ifdef NDEBUG
+
+#      define  gsm_debug_words(a, b, c, d)             /* nil */
+#      define  gsm_debug_longwords(a, b, c, d)         /* nil */
+#      define  gsm_debug_word(a, b)                    /* nil */
+#      define  gsm_debug_longword(a, b)                /* nil */
+
+#else  /* !NDEBUG => DEBUG */
+
+       void  gsm_debug_words     (char * name, int, int, word *) ;
+       void  gsm_debug_longwords (char * name, int, int, longword *) ;
+       void  gsm_debug_longword  (char * name, longword) ;
+       void  gsm_debug_word      (char * name, word) ;
+
+#endif /* !NDEBUG */
+
+#endif /* PRIVATE_H */
+/*
+** Do not edit or modify anything in this comment block.
+** The arch-tag line is a file identity tag for the GNU Arch
+** revision control system.
+**
+** arch-tag: 8bc5fdf2-e8c8-4686-9bd7-a30b512bef0c
+*/
+
diff --git a/libs/libsndfile/src/GSM610/gsm_create.c b/libs/libsndfile/src/GSM610/gsm_create.c
new file mode 100644 (file)
index 0000000..94e8d7d
--- /dev/null
@@ -0,0 +1,44 @@
+/*
+ * Copyright 1992 by Jutta Degener and Carsten Bormann, Technische
+ * Universitaet Berlin.  See the accompanying file "COPYRIGHT" for
+ * details.  THERE IS ABSOLUTELY NO WARRANTY FOR THIS SOFTWARE.
+ */
+
+#include       "config.h"
+
+#include       <stdio.h>
+#include       <stdlib.h>
+#include       <string.h>
+
+
+
+#include "gsm.h"
+#include "gsm610_priv.h"
+
+gsm gsm_create (void)
+{
+       gsm  r;
+
+       r = malloc (sizeof(struct gsm_state));
+       if (!r) return r;
+       
+       memset((char *)r, 0, sizeof (struct gsm_state));
+       r->nrp = 40;
+
+       return r;
+}
+
+/* Added for libsndfile : May 6, 2002. Not sure if it works. */
+void gsm_init (gsm state)
+{
+       memset (state, 0, sizeof (struct gsm_state)) ;
+       state->nrp = 40 ;
+} 
+/*
+** Do not edit or modify anything in this comment block.
+** The arch-tag line is a file identity tag for the GNU Arch 
+** revision control system.
+**
+** arch-tag: 9fedb6b3-ed99-40c2-aac1-484c536261fe
+*/
+
diff --git a/libs/libsndfile/src/GSM610/gsm_decode.c b/libs/libsndfile/src/GSM610/gsm_decode.c
new file mode 100644 (file)
index 0000000..e642558
--- /dev/null
@@ -0,0 +1,366 @@
+/*
+ * Copyright 1992 by Jutta Degener and Carsten Bormann, Technische
+ * Universitaet Berlin.  See the accompanying file "COPYRIGHT" for
+ * details.  THERE IS ABSOLUTELY NO WARRANTY FOR THIS SOFTWARE.
+ */
+
+#include "gsm610_priv.h"
+
+#include "gsm.h"
+
+int gsm_decode (gsm s, gsm_byte * c, gsm_signal * target)
+{
+       word    LARc[8], Nc[4], Mc[4], bc[4], xmaxc[4], xmc[13*4];
+
+#ifdef WAV49
+       if (s->wav_fmt) {
+
+               uword sr = 0;
+
+               s->frame_index = !s->frame_index;
+               if (s->frame_index) {
+
+                       sr = *c++;
+                       LARc[0] = sr & 0x3f;  sr >>= 6;
+                       sr |= (uword)*c++ << 2;
+                       LARc[1] = sr & 0x3f;  sr >>= 6;
+                       sr |= (uword)*c++ << 4;
+                       LARc[2] = sr & 0x1f;  sr >>= 5;
+                       LARc[3] = sr & 0x1f;  sr >>= 5;
+                       sr |= (uword)*c++ << 2;
+                       LARc[4] = sr & 0xf;  sr >>= 4;
+                       LARc[5] = sr & 0xf;  sr >>= 4;
+                       sr |= (uword)*c++ << 2;                 /* 5 */
+                       LARc[6] = sr & 0x7;  sr >>= 3;
+                       LARc[7] = sr & 0x7;  sr >>= 3;
+                       sr |= (uword)*c++ << 4;
+                       Nc[0] = sr & 0x7f;  sr >>= 7;
+                       bc[0] = sr & 0x3;  sr >>= 2;
+                       Mc[0] = sr & 0x3;  sr >>= 2;
+                       sr |= (uword)*c++ << 1;
+                       xmaxc[0] = sr & 0x3f;  sr >>= 6;
+                       xmc[0] = sr & 0x7;  sr >>= 3;
+                       sr = *c++;
+                       xmc[1] = sr & 0x7;  sr >>= 3;
+                       xmc[2] = sr & 0x7;  sr >>= 3;
+                       sr |= (uword)*c++ << 2;
+                       xmc[3] = sr & 0x7;  sr >>= 3;
+                       xmc[4] = sr & 0x7;  sr >>= 3;
+                       xmc[5] = sr & 0x7;  sr >>= 3;
+                       sr |= (uword)*c++ << 1;                 /* 10 */
+                       xmc[6] = sr & 0x7;  sr >>= 3;
+                       xmc[7] = sr & 0x7;  sr >>= 3;
+                       xmc[8] = sr & 0x7;  sr >>= 3;
+                       sr = *c++;
+                       xmc[9] = sr & 0x7;  sr >>= 3;
+                       xmc[10] = sr & 0x7;  sr >>= 3;
+                       sr |= (uword)*c++ << 2;
+                       xmc[11] = sr & 0x7;  sr >>= 3;
+                       xmc[12] = sr & 0x7;  sr >>= 3;
+                       sr |= (uword)*c++ << 4;
+                       Nc[1] = sr & 0x7f;  sr >>= 7;
+                       bc[1] = sr & 0x3;  sr >>= 2;
+                       Mc[1] = sr & 0x3;  sr >>= 2;
+                       sr |= (uword)*c++ << 1;
+                       xmaxc[1] = sr & 0x3f;  sr >>= 6;
+                       xmc[13] = sr & 0x7;  sr >>= 3;
+                       sr = *c++;                              /* 15 */
+                       xmc[14] = sr & 0x7;  sr >>= 3;
+                       xmc[15] = sr & 0x7;  sr >>= 3;
+                       sr |= (uword)*c++ << 2;
+                       xmc[16] = sr & 0x7;  sr >>= 3;
+                       xmc[17] = sr & 0x7;  sr >>= 3;
+                       xmc[18] = sr & 0x7;  sr >>= 3;
+                       sr |= (uword)*c++ << 1;
+                       xmc[19] = sr & 0x7;  sr >>= 3;
+                       xmc[20] = sr & 0x7;  sr >>= 3;
+                       xmc[21] = sr & 0x7;  sr >>= 3;
+                       sr = *c++;
+                       xmc[22] = sr & 0x7;  sr >>= 3;
+                       xmc[23] = sr & 0x7;  sr >>= 3;
+                       sr |= (uword)*c++ << 2;
+                       xmc[24] = sr & 0x7;  sr >>= 3;
+                       xmc[25] = sr & 0x7;  sr >>= 3;
+                       sr |= (uword)*c++ << 4;                 /* 20 */
+                       Nc[2] = sr & 0x7f;  sr >>= 7;
+                       bc[2] = sr & 0x3;  sr >>= 2;
+                       Mc[2] = sr & 0x3;  sr >>= 2;
+                       sr |= (uword)*c++ << 1;
+                       xmaxc[2] = sr & 0x3f;  sr >>= 6;
+                       xmc[26] = sr & 0x7;  sr >>= 3;
+                       sr = *c++;
+                       xmc[27] = sr & 0x7;  sr >>= 3;
+                       xmc[28] = sr & 0x7;  sr >>= 3;
+                       sr |= (uword)*c++ << 2;
+                       xmc[29] = sr & 0x7;  sr >>= 3;
+                       xmc[30] = sr & 0x7;  sr >>= 3;
+                       xmc[31] = sr & 0x7;  sr >>= 3;
+                       sr |= (uword)*c++ << 1;
+                       xmc[32] = sr & 0x7;  sr >>= 3;
+                       xmc[33] = sr & 0x7;  sr >>= 3;
+                       xmc[34] = sr & 0x7;  sr >>= 3;
+                       sr = *c++;                              /* 25 */
+                       xmc[35] = sr & 0x7;  sr >>= 3;
+                       xmc[36] = sr & 0x7;  sr >>= 3;
+                       sr |= (uword)*c++ << 2;
+                       xmc[37] = sr & 0x7;  sr >>= 3;
+                       xmc[38] = sr & 0x7;  sr >>= 3;
+                       sr |= (uword)*c++ << 4;
+                       Nc[3] = sr & 0x7f;  sr >>= 7;
+                       bc[3] = sr & 0x3;  sr >>= 2;
+                       Mc[3] = sr & 0x3;  sr >>= 2;
+                       sr |= (uword)*c++ << 1;
+                       xmaxc[3] = sr & 0x3f;  sr >>= 6;
+                       xmc[39] = sr & 0x7;  sr >>= 3;
+                       sr = *c++;
+                       xmc[40] = sr & 0x7;  sr >>= 3;
+                       xmc[41] = sr & 0x7;  sr >>= 3;
+                       sr |= (uword)*c++ << 2;                 /* 30 */
+                       xmc[42] = sr & 0x7;  sr >>= 3;
+                       xmc[43] = sr & 0x7;  sr >>= 3;
+                       xmc[44] = sr & 0x7;  sr >>= 3;
+                       sr |= (uword)*c++ << 1;
+                       xmc[45] = sr & 0x7;  sr >>= 3;
+                       xmc[46] = sr & 0x7;  sr >>= 3;
+                       xmc[47] = sr & 0x7;  sr >>= 3;
+                       sr = *c++;
+                       xmc[48] = sr & 0x7;  sr >>= 3;
+                       xmc[49] = sr & 0x7;  sr >>= 3;
+                       sr |= (uword)*c++ << 2;
+                       xmc[50] = sr & 0x7;  sr >>= 3;
+                       xmc[51] = sr & 0x7;  sr >>= 3;
+
+                       s->frame_chain = sr & 0xf;
+               }
+               else {
+                       sr = s->frame_chain;
+                       sr |= (uword)*c++ << 4;                 /* 1 */
+                       LARc[0] = sr & 0x3f;  sr >>= 6;
+                       LARc[1] = sr & 0x3f;  sr >>= 6;
+                       sr = *c++;
+                       LARc[2] = sr & 0x1f;  sr >>= 5;
+                       sr |= (uword)*c++ << 3;
+                       LARc[3] = sr & 0x1f;  sr >>= 5;
+                       LARc[4] = sr & 0xf;  sr >>= 4;
+                       sr |= (uword)*c++ << 2;
+                       LARc[5] = sr & 0xf;  sr >>= 4;
+                       LARc[6] = sr & 0x7;  sr >>= 3;
+                       LARc[7] = sr & 0x7;  sr >>= 3;
+                       sr = *c++;                              /* 5 */
+                       Nc[0] = sr & 0x7f;  sr >>= 7;
+                       sr |= (uword)*c++ << 1;
+                       bc[0] = sr & 0x3;  sr >>= 2;
+                       Mc[0] = sr & 0x3;  sr >>= 2;
+                       sr |= (uword)*c++ << 5;
+                       xmaxc[0] = sr & 0x3f;  sr >>= 6;
+                       xmc[0] = sr & 0x7;  sr >>= 3;
+                       xmc[1] = sr & 0x7;  sr >>= 3;
+                       sr |= (uword)*c++ << 1;
+                       xmc[2] = sr & 0x7;  sr >>= 3;
+                       xmc[3] = sr & 0x7;  sr >>= 3;
+                       xmc[4] = sr & 0x7;  sr >>= 3;
+                       sr = *c++;
+                       xmc[5] = sr & 0x7;  sr >>= 3;
+                       xmc[6] = sr & 0x7;  sr >>= 3;
+                       sr |= (uword)*c++ << 2;                 /* 10 */
+                       xmc[7] = sr & 0x7;  sr >>= 3;
+                       xmc[8] = sr & 0x7;  sr >>= 3;
+                       xmc[9] = sr & 0x7;  sr >>= 3;
+                       sr |= (uword)*c++ << 1;
+                       xmc[10] = sr & 0x7;  sr >>= 3;
+                       xmc[11] = sr & 0x7;  sr >>= 3;
+                       xmc[12] = sr & 0x7;  sr >>= 3;
+                       sr = *c++;
+                       Nc[1] = sr & 0x7f;  sr >>= 7;
+                       sr |= (uword)*c++ << 1;
+                       bc[1] = sr & 0x3;  sr >>= 2;
+                       Mc[1] = sr & 0x3;  sr >>= 2;
+                       sr |= (uword)*c++ << 5;
+                       xmaxc[1] = sr & 0x3f;  sr >>= 6;
+                       xmc[13] = sr & 0x7;  sr >>= 3;
+                       xmc[14] = sr & 0x7;  sr >>= 3;
+                       sr |= (uword)*c++ << 1;                 /* 15 */
+                       xmc[15] = sr & 0x7;  sr >>= 3;
+                       xmc[16] = sr & 0x7;  sr >>= 3;
+                       xmc[17] = sr & 0x7;  sr >>= 3;
+                       sr = *c++;
+                       xmc[18] = sr & 0x7;  sr >>= 3;
+                       xmc[19] = sr & 0x7;  sr >>= 3;
+                       sr |= (uword)*c++ << 2;
+                       xmc[20] = sr & 0x7;  sr >>= 3;
+                       xmc[21] = sr & 0x7;  sr >>= 3;
+                       xmc[22] = sr & 0x7;  sr >>= 3;
+                       sr |= (uword)*c++ << 1;
+                       xmc[23] = sr & 0x7;  sr >>= 3;
+                       xmc[24] = sr & 0x7;  sr >>= 3;
+                       xmc[25] = sr & 0x7;  sr >>= 3;
+                       sr = *c++;
+                       Nc[2] = sr & 0x7f;  sr >>= 7;
+                       sr |= (uword)*c++ << 1;                 /* 20 */
+                       bc[2] = sr & 0x3;  sr >>= 2;
+                       Mc[2] = sr & 0x3;  sr >>= 2;
+                       sr |= (uword)*c++ << 5;
+                       xmaxc[2] = sr & 0x3f;  sr >>= 6;
+                       xmc[26] = sr & 0x7;  sr >>= 3;
+                       xmc[27] = sr & 0x7;  sr >>= 3;
+                       sr |= (uword)*c++ << 1; 
+                       xmc[28] = sr & 0x7;  sr >>= 3;
+                       xmc[29] = sr & 0x7;  sr >>= 3;
+                       xmc[30] = sr & 0x7;  sr >>= 3;
+                       sr = *c++;
+                       xmc[31] = sr & 0x7;  sr >>= 3;
+                       xmc[32] = sr & 0x7;  sr >>= 3;
+                       sr |= (uword)*c++ << 2;
+                       xmc[33] = sr & 0x7;  sr >>= 3;
+                       xmc[34] = sr & 0x7;  sr >>= 3;
+                       xmc[35] = sr & 0x7;  sr >>= 3;
+                       sr |= (uword)*c++ << 1;                 /* 25 */
+                       xmc[36] = sr & 0x7;  sr >>= 3;
+                       xmc[37] = sr & 0x7;  sr >>= 3;
+                       xmc[38] = sr & 0x7;  sr >>= 3;
+                       sr = *c++;
+                       Nc[3] = sr & 0x7f;  sr >>= 7;
+                       sr |= (uword)*c++ << 1;         
+                       bc[3] = sr & 0x3;  sr >>= 2;
+                       Mc[3] = sr & 0x3;  sr >>= 2;
+                       sr |= (uword)*c++ << 5;
+                       xmaxc[3] = sr & 0x3f;  sr >>= 6;
+                       xmc[39] = sr & 0x7;  sr >>= 3;
+                       xmc[40] = sr & 0x7;  sr >>= 3;
+                       sr |= (uword)*c++ << 1;
+                       xmc[41] = sr & 0x7;  sr >>= 3;
+                       xmc[42] = sr & 0x7;  sr >>= 3;
+                       xmc[43] = sr & 0x7;  sr >>= 3;
+                       sr = *c++;                              /* 30 */
+                       xmc[44] = sr & 0x7;  sr >>= 3;
+                       xmc[45] = sr & 0x7;  sr >>= 3;
+                       sr |= (uword)*c++ << 2;
+                       xmc[46] = sr & 0x7;  sr >>= 3;
+                       xmc[47] = sr & 0x7;  sr >>= 3;
+                       xmc[48] = sr & 0x7;  sr >>= 3;
+                       sr |= (uword)*c++ << 1;
+                       xmc[49] = sr & 0x7;  sr >>= 3;
+                       xmc[50] = sr & 0x7;  sr >>= 3;
+                       xmc[51] = sr & 0x7;  sr >>= 3;
+               }
+       }
+       else
+#endif
+       {
+               /* GSM_MAGIC  = (*c >> 4) & 0xF; */
+
+               if (((*c >> 4) & 0x0F) != GSM_MAGIC) return -1;
+
+               LARc[0]  = (*c++ & 0xF) << 2;           /* 1 */
+               LARc[0] |= (*c >> 6) & 0x3;
+               LARc[1]  = *c++ & 0x3F;
+               LARc[2]  = (*c >> 3) & 0x1F;
+               LARc[3]  = (*c++ & 0x7) << 2;
+               LARc[3] |= (*c >> 6) & 0x3;
+               LARc[4]  = (*c >> 2) & 0xF;
+               LARc[5]  = (*c++ & 0x3) << 2;
+               LARc[5] |= (*c >> 6) & 0x3;
+               LARc[6]  = (*c >> 3) & 0x7;
+               LARc[7]  = *c++ & 0x7;
+               Nc[0]  = (*c >> 1) & 0x7F;
+               bc[0]  = (*c++ & 0x1) << 1;
+               bc[0] |= (*c >> 7) & 0x1;
+               Mc[0]  = (*c >> 5) & 0x3;
+               xmaxc[0]  = (*c++ & 0x1F) << 1;
+               xmaxc[0] |= (*c >> 7) & 0x1;
+               xmc[0]  = (*c >> 4) & 0x7;
+               xmc[1]  = (*c >> 1) & 0x7;
+               xmc[2]  = (*c++ & 0x1) << 2;
+               xmc[2] |= (*c >> 6) & 0x3;
+               xmc[3]  = (*c >> 3) & 0x7;
+               xmc[4]  = *c++ & 0x7;
+               xmc[5]  = (*c >> 5) & 0x7;
+               xmc[6]  = (*c >> 2) & 0x7;
+               xmc[7]  = (*c++ & 0x3) << 1;            /* 10 */
+               xmc[7] |= (*c >> 7) & 0x1;
+               xmc[8]  = (*c >> 4) & 0x7;
+               xmc[9]  = (*c >> 1) & 0x7;
+               xmc[10]  = (*c++ & 0x1) << 2;
+               xmc[10] |= (*c >> 6) & 0x3;
+               xmc[11]  = (*c >> 3) & 0x7;
+               xmc[12]  = *c++ & 0x7;
+               Nc[1]  = (*c >> 1) & 0x7F;
+               bc[1]  = (*c++ & 0x1) << 1;
+               bc[1] |= (*c >> 7) & 0x1;
+               Mc[1]  = (*c >> 5) & 0x3;
+               xmaxc[1]  = (*c++ & 0x1F) << 1;
+               xmaxc[1] |= (*c >> 7) & 0x1;
+               xmc[13]  = (*c >> 4) & 0x7;
+               xmc[14]  = (*c >> 1) & 0x7;
+               xmc[15]  = (*c++ & 0x1) << 2;
+               xmc[15] |= (*c >> 6) & 0x3;
+               xmc[16]  = (*c >> 3) & 0x7;
+               xmc[17]  = *c++ & 0x7;
+               xmc[18]  = (*c >> 5) & 0x7;
+               xmc[19]  = (*c >> 2) & 0x7;
+               xmc[20]  = (*c++ & 0x3) << 1;
+               xmc[20] |= (*c >> 7) & 0x1;
+               xmc[21]  = (*c >> 4) & 0x7;
+               xmc[22]  = (*c >> 1) & 0x7;
+               xmc[23]  = (*c++ & 0x1) << 2;
+               xmc[23] |= (*c >> 6) & 0x3;
+               xmc[24]  = (*c >> 3) & 0x7;
+               xmc[25]  = *c++ & 0x7;
+               Nc[2]  = (*c >> 1) & 0x7F;
+               bc[2]  = (*c++ & 0x1) << 1;             /* 20 */
+               bc[2] |= (*c >> 7) & 0x1;
+               Mc[2]  = (*c >> 5) & 0x3;
+               xmaxc[2]  = (*c++ & 0x1F) << 1;
+               xmaxc[2] |= (*c >> 7) & 0x1;
+               xmc[26]  = (*c >> 4) & 0x7;
+               xmc[27]  = (*c >> 1) & 0x7;
+               xmc[28]  = (*c++ & 0x1) << 2;
+               xmc[28] |= (*c >> 6) & 0x3;
+               xmc[29]  = (*c >> 3) & 0x7;
+               xmc[30]  = *c++ & 0x7;
+               xmc[31]  = (*c >> 5) & 0x7;
+               xmc[32]  = (*c >> 2) & 0x7;
+               xmc[33]  = (*c++ & 0x3) << 1;
+               xmc[33] |= (*c >> 7) & 0x1;
+               xmc[34]  = (*c >> 4) & 0x7;
+               xmc[35]  = (*c >> 1) & 0x7;
+               xmc[36]  = (*c++ & 0x1) << 2;
+               xmc[36] |= (*c >> 6) & 0x3;
+               xmc[37]  = (*c >> 3) & 0x7;
+               xmc[38]  = *c++ & 0x7;
+               Nc[3]  = (*c >> 1) & 0x7F;
+               bc[3]  = (*c++ & 0x1) << 1;
+               bc[3] |= (*c >> 7) & 0x1;
+               Mc[3]  = (*c >> 5) & 0x3;
+               xmaxc[3]  = (*c++ & 0x1F) << 1;
+               xmaxc[3] |= (*c >> 7) & 0x1;
+               xmc[39]  = (*c >> 4) & 0x7;
+               xmc[40]  = (*c >> 1) & 0x7;
+               xmc[41]  = (*c++ & 0x1) << 2;
+               xmc[41] |= (*c >> 6) & 0x3;
+               xmc[42]  = (*c >> 3) & 0x7;
+               xmc[43]  = *c++ & 0x7;                  /* 30  */
+               xmc[44]  = (*c >> 5) & 0x7;
+               xmc[45]  = (*c >> 2) & 0x7;
+               xmc[46]  = (*c++ & 0x3) << 1;
+               xmc[46] |= (*c >> 7) & 0x1;
+               xmc[47]  = (*c >> 4) & 0x7;
+               xmc[48]  = (*c >> 1) & 0x7;
+               xmc[49]  = (*c++ & 0x1) << 2;
+               xmc[49] |= (*c >> 6) & 0x3;
+               xmc[50]  = (*c >> 3) & 0x7;
+               xmc[51]  = *c & 0x7;                    /* 33 */
+       }
+
+       Gsm_Decoder(s, LARc, Nc, bc, Mc, xmaxc, xmc, target);
+
+       return 0;
+}
+/*
+** Do not edit or modify anything in this comment block.
+** The arch-tag line is a file identity tag for the GNU Arch 
+** revision control system.
+**
+** arch-tag: 6a9b6628-821c-4a96-84c1-485ebd35f170
+*/
+
diff --git a/libs/libsndfile/src/GSM610/gsm_destroy.c b/libs/libsndfile/src/GSM610/gsm_destroy.c
new file mode 100644 (file)
index 0000000..9e2d6a4
--- /dev/null
@@ -0,0 +1,31 @@
+/*
+ * Copyright 1992 by Jutta Degener and Carsten Bormann, Technische
+ * Universitaet Berlin.  See the accompanying file "COPYRIGHT" for
+ * details.  THERE IS ABSOLUTELY NO WARRANTY FOR THIS SOFTWARE.
+ */
+
+#include "gsm.h"
+#include "config.h"
+
+#ifdef HAS_STDLIB_H
+#      include <stdlib.h>
+#else
+#      ifdef   HAS_MALLOC_H
+#              include         <malloc.h>
+#      else
+               extern void free();
+#      endif
+#endif
+
+void gsm_destroy (gsm S)
+{
+       if (S) free((char *)S);
+}
+/*
+** Do not edit or modify anything in this comment block.
+** The arch-tag line is a file identity tag for the GNU Arch 
+** revision control system.
+**
+** arch-tag: f423d09b-6ccc-47e0-9b18-ee1cf7a8e473
+*/
+
diff --git a/libs/libsndfile/src/GSM610/gsm_encode.c b/libs/libsndfile/src/GSM610/gsm_encode.c
new file mode 100644 (file)
index 0000000..02af4ba
--- /dev/null
@@ -0,0 +1,456 @@
+/*
+ * Copyright 1992 by Jutta Degener and Carsten Bormann, Technische
+ * Universitaet Berlin.  See the accompanying file "COPYRIGHT" for
+ * details.  THERE IS ABSOLUTELY NO WARRANTY FOR THIS SOFTWARE.
+ */
+
+#include "gsm610_priv.h"
+#include "gsm.h"
+
+void gsm_encode (gsm s, gsm_signal * source, gsm_byte * c)
+{
+       word            LARc[8], Nc[4], Mc[4], bc[4], xmaxc[4], xmc[13*4];
+
+       Gsm_Coder(s, source, LARc, Nc, bc, Mc, xmaxc, xmc);
+
+
+       /*      variable        size
+
+               GSM_MAGIC       4
+
+               LARc[0]         6
+               LARc[1]         6
+               LARc[2]         5
+               LARc[3]         5
+               LARc[4]         4
+               LARc[5]         4
+               LARc[6]         3
+               LARc[7]         3
+
+               Nc[0]           7
+               bc[0]           2
+               Mc[0]           2
+               xmaxc[0]        6
+               xmc[0]          3
+               xmc[1]          3
+               xmc[2]          3
+               xmc[3]          3
+               xmc[4]          3
+               xmc[5]          3
+               xmc[6]          3
+               xmc[7]          3
+               xmc[8]          3
+               xmc[9]          3
+               xmc[10]         3
+               xmc[11]         3
+               xmc[12]         3
+
+               Nc[1]           7
+               bc[1]           2
+               Mc[1]           2
+               xmaxc[1]        6
+               xmc[13]         3
+               xmc[14]         3
+               xmc[15]         3
+               xmc[16]         3
+               xmc[17]         3
+               xmc[18]         3
+               xmc[19]         3
+               xmc[20]         3
+               xmc[21]         3
+               xmc[22]         3
+               xmc[23]         3
+               xmc[24]         3
+               xmc[25]         3
+
+               Nc[2]           7
+               bc[2]           2
+               Mc[2]           2
+               xmaxc[2]        6
+               xmc[26]         3
+               xmc[27]         3
+               xmc[28]         3
+               xmc[29]         3
+               xmc[30]         3
+               xmc[31]         3
+               xmc[32]         3
+               xmc[33]         3
+               xmc[34]         3
+               xmc[35]         3
+               xmc[36]         3
+               xmc[37]         3
+               xmc[38]         3
+
+               Nc[3]           7
+               bc[3]           2
+               Mc[3]           2
+               xmaxc[3]        6
+               xmc[39]         3
+               xmc[40]         3
+               xmc[41]         3
+               xmc[42]         3
+               xmc[43]         3
+               xmc[44]         3
+               xmc[45]         3
+               xmc[46]         3
+               xmc[47]         3
+               xmc[48]         3
+               xmc[49]         3
+               xmc[50]         3
+               xmc[51]         3
+       */
+
+#ifdef WAV49
+
+       if (s->wav_fmt) {
+               s->frame_index = !s->frame_index;
+               if (s->frame_index) {
+
+                       uword sr;
+
+                       sr = 0;
+                       sr = sr >> 6 | LARc[0] << 10;
+                       sr = sr >> 6 | LARc[1] << 10;
+                       *c++ = sr >> 4;
+                       sr = sr >> 5 | LARc[2] << 11;
+                       *c++ = sr >> 7;
+                       sr = sr >> 5 | LARc[3] << 11;
+                       sr = sr >> 4 | LARc[4] << 12;
+                       *c++ = sr >> 6;
+                       sr = sr >> 4 | LARc[5] << 12;
+                       sr = sr >> 3 | LARc[6] << 13;
+                       *c++ = sr >> 7;
+                       sr = sr >> 3 | LARc[7] << 13;
+                       sr = sr >> 7 | Nc[0] << 9;
+                       *c++ = sr >> 5;
+                       sr = sr >> 2 | bc[0] << 14;
+                       sr = sr >> 2 | Mc[0] << 14;
+                       sr = sr >> 6 | xmaxc[0] << 10;
+                       *c++ = sr >> 3;
+                       sr = sr >> 3 | xmc[0] << 13;
+                       *c++ = sr >> 8;
+                       sr = sr >> 3 | xmc[1] << 13;
+                       sr = sr >> 3 | xmc[2] << 13;
+                       sr = sr >> 3 | xmc[3] << 13;
+                       *c++ = sr >> 7;
+                       sr = sr >> 3 | xmc[4] << 13;
+                       sr = sr >> 3 | xmc[5] << 13;
+                       sr = sr >> 3 | xmc[6] << 13;
+                       *c++ = sr >> 6;
+                       sr = sr >> 3 | xmc[7] << 13;
+                       sr = sr >> 3 | xmc[8] << 13;
+                       *c++ = sr >> 8;
+                       sr = sr >> 3 | xmc[9] << 13;
+                       sr = sr >> 3 | xmc[10] << 13;
+                       sr = sr >> 3 | xmc[11] << 13;
+                       *c++ = sr >> 7;
+                       sr = sr >> 3 | xmc[12] << 13;
+                       sr = sr >> 7 | Nc[1] << 9;
+                       *c++ = sr >> 5;
+                       sr = sr >> 2 | bc[1] << 14;
+                       sr = sr >> 2 | Mc[1] << 14;
+                       sr = sr >> 6 | xmaxc[1] << 10;
+                       *c++ = sr >> 3;
+                       sr = sr >> 3 | xmc[13] << 13;
+                       *c++ = sr >> 8;
+                       sr = sr >> 3 | xmc[14] << 13;
+                       sr = sr >> 3 | xmc[15] << 13;
+                       sr = sr >> 3 | xmc[16] << 13;
+                       *c++ = sr >> 7;
+                       sr = sr >> 3 | xmc[17] << 13;
+                       sr = sr >> 3 | xmc[18] << 13;
+                       sr = sr >> 3 | xmc[19] << 13;
+                       *c++ = sr >> 6;
+                       sr = sr >> 3 | xmc[20] << 13;
+                       sr = sr >> 3 | xmc[21] << 13;
+                       *c++ = sr >> 8;
+                       sr = sr >> 3 | xmc[22] << 13;
+                       sr = sr >> 3 | xmc[23] << 13;
+                       sr = sr >> 3 | xmc[24] << 13;
+                       *c++ = sr >> 7;
+                       sr = sr >> 3 | xmc[25] << 13;
+                       sr = sr >> 7 | Nc[2] << 9;
+                       *c++ = sr >> 5;
+                       sr = sr >> 2 | bc[2] << 14;
+                       sr = sr >> 2 | Mc[2] << 14;
+                       sr = sr >> 6 | xmaxc[2] << 10;
+                       *c++ = sr >> 3;
+                       sr = sr >> 3 | xmc[26] << 13;
+                       *c++ = sr >> 8;
+                       sr = sr >> 3 | xmc[27] << 13;
+                       sr = sr >> 3 | xmc[28] << 13;
+                       sr = sr >> 3 | xmc[29] << 13;
+                       *c++ = sr >> 7;
+                       sr = sr >> 3 | xmc[30] << 13;
+                       sr = sr >> 3 | xmc[31] << 13;
+                       sr = sr >> 3 | xmc[32] << 13;
+                       *c++ = sr >> 6;
+                       sr = sr >> 3 | xmc[33] << 13;
+                       sr = sr >> 3 | xmc[34] << 13;
+                       *c++ = sr >> 8;
+                       sr = sr >> 3 | xmc[35] << 13;
+                       sr = sr >> 3 | xmc[36] << 13;
+                       sr = sr >> 3 | xmc[37] << 13;
+                       *c++ = sr >> 7;
+                       sr = sr >> 3 | xmc[38] << 13;
+                       sr = sr >> 7 | Nc[3] << 9;
+                       *c++ = sr >> 5;
+                       sr = sr >> 2 | bc[3] << 14;
+                       sr = sr >> 2 | Mc[3] << 14;
+                       sr = sr >> 6 | xmaxc[3] << 10;
+                       *c++ = sr >> 3;
+                       sr = sr >> 3 | xmc[39] << 13;
+                       *c++ = sr >> 8;
+                       sr = sr >> 3 | xmc[40] << 13;
+                       sr = sr >> 3 | xmc[41] << 13;
+                       sr = sr >> 3 | xmc[42] << 13;
+                       *c++ = sr >> 7;
+                       sr = sr >> 3 | xmc[43] << 13;
+                       sr = sr >> 3 | xmc[44] << 13;
+                       sr = sr >> 3 | xmc[45] << 13;
+                       *c++ = sr >> 6;
+                       sr = sr >> 3 | xmc[46] << 13;
+                       sr = sr >> 3 | xmc[47] << 13;
+                       *c++ = sr >> 8;
+                       sr = sr >> 3 | xmc[48] << 13;
+                       sr = sr >> 3 | xmc[49] << 13;
+                       sr = sr >> 3 | xmc[50] << 13;
+                       *c++ = sr >> 7;
+                       sr = sr >> 3 | xmc[51] << 13;
+                       sr = sr >> 4;
+                       *c = sr >> 8;
+                       s->frame_chain = *c;
+               }
+               else {
+                       uword sr;
+
+                       sr = 0;
+                       sr = sr >> 4 | s->frame_chain << 12;
+                       sr = sr >> 6 | LARc[0] << 10;
+                       *c++ = sr >> 6;
+                       sr = sr >> 6 | LARc[1] << 10;
+                       *c++ = sr >> 8;
+                       sr = sr >> 5 | LARc[2] << 11;
+                       sr = sr >> 5 | LARc[3] << 11;
+                       *c++ = sr >> 6;
+                       sr = sr >> 4 | LARc[4] << 12;
+                       sr = sr >> 4 | LARc[5] << 12;
+                       *c++ = sr >> 6;
+                       sr = sr >> 3 | LARc[6] << 13;
+                       sr = sr >> 3 | LARc[7] << 13;
+                       *c++ = sr >> 8;
+                       sr = sr >> 7 | Nc[0] << 9;
+                       sr = sr >> 2 | bc[0] << 14;
+                       *c++ = sr >> 7;
+                       sr = sr >> 2 | Mc[0] << 14;
+                       sr = sr >> 6 | xmaxc[0] << 10;
+                       *c++ = sr >> 7;
+                       sr = sr >> 3 | xmc[0] << 13;
+                       sr = sr >> 3 | xmc[1] << 13;
+                       sr = sr >> 3 | xmc[2] << 13;
+                       *c++ = sr >> 6;
+                       sr = sr >> 3 | xmc[3] << 13;
+                       sr = sr >> 3 | xmc[4] << 13;
+                       *c++ = sr >> 8;
+                       sr = sr >> 3 | xmc[5] << 13;
+                       sr = sr >> 3 | xmc[6] << 13;
+                       sr = sr >> 3 | xmc[7] << 13;
+                       *c++ = sr >> 7;
+                       sr = sr >> 3 | xmc[8] << 13;
+                       sr = sr >> 3 | xmc[9] << 13;
+                       sr = sr >> 3 | xmc[10] << 13;
+                       *c++ = sr >> 6;
+                       sr = sr >> 3 | xmc[11] << 13;
+                       sr = sr >> 3 | xmc[12] << 13;
+                       *c++ = sr >> 8;
+                       sr = sr >> 7 | Nc[1] << 9;
+                       sr = sr >> 2 | bc[1] << 14;
+                       *c++ = sr >> 7;
+                       sr = sr >> 2 | Mc[1] << 14;
+                       sr = sr >> 6 | xmaxc[1] << 10;
+                       *c++ = sr >> 7;
+                       sr = sr >> 3 | xmc[13] << 13;
+                       sr = sr >> 3 | xmc[14] << 13;
+                       sr = sr >> 3 | xmc[15] << 13;
+                       *c++ = sr >> 6;
+                       sr = sr >> 3 | xmc[16] << 13;
+                       sr = sr >> 3 | xmc[17] << 13;
+                       *c++ = sr >> 8;
+                       sr = sr >> 3 | xmc[18] << 13;
+                       sr = sr >> 3 | xmc[19] << 13;
+                       sr = sr >> 3 | xmc[20] << 13;
+                       *c++ = sr >> 7;
+                       sr = sr >> 3 | xmc[21] << 13;
+                       sr = sr >> 3 | xmc[22] << 13;
+                       sr = sr >> 3 | xmc[23] << 13;
+                       *c++ = sr >> 6;
+                       sr = sr >> 3 | xmc[24] << 13;
+                       sr = sr >> 3 | xmc[25] << 13;
+                       *c++ = sr >> 8;
+                       sr = sr >> 7 | Nc[2] << 9;
+                       sr = sr >> 2 | bc[2] << 14;
+                       *c++ = sr >> 7;
+                       sr = sr >> 2 | Mc[2] << 14;
+                       sr = sr >> 6 | xmaxc[2] << 10;
+                       *c++ = sr >> 7;
+                       sr = sr >> 3 | xmc[26] << 13;
+                       sr = sr >> 3 | xmc[27] << 13;
+                       sr = sr >> 3 | xmc[28] << 13;
+                       *c++ = sr >> 6;
+                       sr = sr >> 3 | xmc[29] << 13;
+                       sr = sr >> 3 | xmc[30] << 13;
+                       *c++ = sr >> 8;
+                       sr = sr >> 3 | xmc[31] << 13;
+                       sr = sr >> 3 | xmc[32] << 13;
+                       sr = sr >> 3 | xmc[33] << 13;
+                       *c++ = sr >> 7;
+                       sr = sr >> 3 | xmc[34] << 13;
+                       sr = sr >> 3 | xmc[35] << 13;
+                       sr = sr >> 3 | xmc[36] << 13;
+                       *c++ = sr >> 6;
+                       sr = sr >> 3 | xmc[37] << 13;
+                       sr = sr >> 3 | xmc[38] << 13;
+                       *c++ = sr >> 8;
+                       sr = sr >> 7 | Nc[3] << 9;
+                       sr = sr >> 2 | bc[3] << 14;
+                       *c++ = sr >> 7;
+                       sr = sr >> 2 | Mc[3] << 14;
+                       sr = sr >> 6 | xmaxc[3] << 10;
+                       *c++ = sr >> 7;
+                       sr = sr >> 3 | xmc[39] << 13;
+                       sr = sr >> 3 | xmc[40] << 13;
+                       sr = sr >> 3 | xmc[41] << 13;
+                       *c++ = sr >> 6;
+                       sr = sr >> 3 | xmc[42] << 13;
+                       sr = sr >> 3 | xmc[43] << 13;
+                       *c++ = sr >> 8;
+                       sr = sr >> 3 | xmc[44] << 13;
+                       sr = sr >> 3 | xmc[45] << 13;
+                       sr = sr >> 3 | xmc[46] << 13;
+                       *c++ = sr >> 7;
+                       sr = sr >> 3 | xmc[47] << 13;
+                       sr = sr >> 3 | xmc[48] << 13;
+                       sr = sr >> 3 | xmc[49] << 13;
+                       *c++ = sr >> 6;
+                       sr = sr >> 3 | xmc[50] << 13;
+                       sr = sr >> 3 | xmc[51] << 13;
+                       *c++ = sr >> 8;
+               }
+       }
+
+       else
+
+#endif /* WAV49 */
+       {
+
+               *c++ =   ((GSM_MAGIC & 0xF) << 4)               /* 1 */
+                      | ((LARc[0] >> 2) & 0xF);
+               *c++ =   ((LARc[0] & 0x3) << 6)
+                      | (LARc[1] & 0x3F);
+               *c++ =   ((LARc[2] & 0x1F) << 3)
+                      | ((LARc[3] >> 2) & 0x7);
+               *c++ =   ((LARc[3] & 0x3) << 6)
+                      | ((LARc[4] & 0xF) << 2)
+                      | ((LARc[5] >> 2) & 0x3);
+               *c++ =   ((LARc[5] & 0x3) << 6)
+                      | ((LARc[6] & 0x7) << 3)
+                      | (LARc[7] & 0x7);
+               *c++ =   ((Nc[0] & 0x7F) << 1)
+                      | ((bc[0] >> 1) & 0x1);
+               *c++ =   ((bc[0] & 0x1) << 7)
+                      | ((Mc[0] & 0x3) << 5)
+                      | ((xmaxc[0] >> 1) & 0x1F);
+               *c++ =   ((xmaxc[0] & 0x1) << 7)
+                      | ((xmc[0] & 0x7) << 4)
+                      | ((xmc[1] & 0x7) << 1)
+                      | ((xmc[2] >> 2) & 0x1);
+               *c++ =   ((xmc[2] & 0x3) << 6)
+                      | ((xmc[3] & 0x7) << 3)
+                      | (xmc[4] & 0x7);
+               *c++ =   ((xmc[5] & 0x7) << 5)                  /* 10 */
+                      | ((xmc[6] & 0x7) << 2)
+                      | ((xmc[7] >> 1) & 0x3);
+               *c++ =   ((xmc[7] & 0x1) << 7)
+                      | ((xmc[8] & 0x7) << 4)
+                      | ((xmc[9] & 0x7) << 1)
+                      | ((xmc[10] >> 2) & 0x1);
+               *c++ =   ((xmc[10] & 0x3) << 6)
+                      | ((xmc[11] & 0x7) << 3)
+                      | (xmc[12] & 0x7);
+               *c++ =   ((Nc[1] & 0x7F) << 1)
+                      | ((bc[1] >> 1) & 0x1);
+               *c++ =   ((bc[1] & 0x1) << 7)
+                      | ((Mc[1] & 0x3) << 5)
+                      | ((xmaxc[1] >> 1) & 0x1F);
+               *c++ =   ((xmaxc[1] & 0x1) << 7)
+                      | ((xmc[13] & 0x7) << 4)
+                      | ((xmc[14] & 0x7) << 1)
+                      | ((xmc[15] >> 2) & 0x1);
+               *c++ =   ((xmc[15] & 0x3) << 6)
+                      | ((xmc[16] & 0x7) << 3)
+                      | (xmc[17] & 0x7);
+               *c++ =   ((xmc[18] & 0x7) << 5)
+                      | ((xmc[19] & 0x7) << 2)
+                      | ((xmc[20] >> 1) & 0x3);
+               *c++ =   ((xmc[20] & 0x1) << 7)
+                      | ((xmc[21] & 0x7) << 4)
+                      | ((xmc[22] & 0x7) << 1)
+                      | ((xmc[23] >> 2) & 0x1);
+               *c++ =   ((xmc[23] & 0x3) << 6)
+                      | ((xmc[24] & 0x7) << 3)
+                      | (xmc[25] & 0x7);
+               *c++ =   ((Nc[2] & 0x7F) << 1)                  /* 20 */
+                      | ((bc[2] >> 1) & 0x1);
+               *c++ =   ((bc[2] & 0x1) << 7)
+                      | ((Mc[2] & 0x3) << 5)
+                      | ((xmaxc[2] >> 1) & 0x1F);
+               *c++ =   ((xmaxc[2] & 0x1) << 7)
+                      | ((xmc[26] & 0x7) << 4)
+                      | ((xmc[27] & 0x7) << 1)
+                      | ((xmc[28] >> 2) & 0x1);
+               *c++ =   ((xmc[28] & 0x3) << 6)
+                      | ((xmc[29] & 0x7) << 3)
+                      | (xmc[30] & 0x7);
+               *c++ =   ((xmc[31] & 0x7) << 5)
+                      | ((xmc[32] & 0x7) << 2)
+                      | ((xmc[33] >> 1) & 0x3);
+               *c++ =   ((xmc[33] & 0x1) << 7)
+                      | ((xmc[34] & 0x7) << 4)
+                      | ((xmc[35] & 0x7) << 1)
+                      | ((xmc[36] >> 2) & 0x1);
+               *c++ =   ((xmc[36] & 0x3) << 6)
+                      | ((xmc[37] & 0x7) << 3)
+                      | (xmc[38] & 0x7);
+               *c++ =   ((Nc[3] & 0x7F) << 1)
+                      | ((bc[3] >> 1) & 0x1);
+               *c++ =   ((bc[3] & 0x1) << 7)
+                      | ((Mc[3] & 0x3) << 5)
+                      | ((xmaxc[3] >> 1) & 0x1F);
+               *c++ =   ((xmaxc[3] & 0x1) << 7)
+                      | ((xmc[39] & 0x7) << 4)
+                      | ((xmc[40] & 0x7) << 1)
+                      | ((xmc[41] >> 2) & 0x1);
+               *c++ =   ((xmc[41] & 0x3) << 6)                 /* 30 */
+                      | ((xmc[42] & 0x7) << 3)
+                      | (xmc[43] & 0x7);
+               *c++ =   ((xmc[44] & 0x7) << 5)
+                      | ((xmc[45] & 0x7) << 2)
+                      | ((xmc[46] >> 1) & 0x3);
+               *c++ =   ((xmc[46] & 0x1) << 7)
+                      | ((xmc[47] & 0x7) << 4)
+                      | ((xmc[48] & 0x7) << 1)
+                      | ((xmc[49] >> 2) & 0x1);
+               *c++ =   ((xmc[49] & 0x3) << 6)
+                      | ((xmc[50] & 0x7) << 3)
+                      | (xmc[51] & 0x7);
+
+       }
+}
+/*
+** Do not edit or modify anything in this comment block.
+** The arch-tag line is a file identity tag for the GNU Arch 
+** revision control system.
+**
+** arch-tag: cfe9c43d-d97c-4216-b5e5-ccd6a25b582b
+*/
+
diff --git a/libs/libsndfile/src/GSM610/gsm_option.c b/libs/libsndfile/src/GSM610/gsm_option.c
new file mode 100644 (file)
index 0000000..5c56d78
--- /dev/null
@@ -0,0 +1,74 @@
+/*
+ * Copyright 1992 by Jutta Degener and Carsten Bormann, Technische
+ * Universitaet Berlin.  See the accompanying file "COPYRIGHT" for
+ * details.  THERE IS ABSOLUTELY NO WARRANTY FOR THIS SOFTWARE.
+ */
+
+#include "gsm610_priv.h"
+
+#include "gsm.h"
+
+int gsm_option (gsm r, int opt, int * val)
+{
+       int     result = -1;
+
+       switch (opt) {
+       case GSM_OPT_LTP_CUT:
+#ifdef         LTP_CUT
+               result = r->ltp_cut;
+               if (val) r->ltp_cut = *val;
+#endif
+               break;
+
+       case GSM_OPT_VERBOSE:
+#ifndef        NDEBUG
+               result = r->verbose;
+               if (val) r->verbose = *val;
+#endif
+               break;
+
+       case GSM_OPT_FAST:
+
+#if    defined(FAST) && defined(USE_FLOAT_MUL)
+               result = r->fast;
+               if (val) r->fast = !!*val;
+#endif
+               break;
+
+       case GSM_OPT_FRAME_CHAIN:
+
+#ifdef WAV49
+               result = r->frame_chain;
+               if (val) r->frame_chain = *val;
+#endif
+               break;
+
+       case GSM_OPT_FRAME_INDEX:
+
+#ifdef WAV49
+               result = r->frame_index;
+               if (val) r->frame_index = *val;
+#endif
+               break;
+
+       case GSM_OPT_WAV49:
+
+#ifdef WAV49 
+               result = r->wav_fmt;
+               if (val) r->wav_fmt = !!*val;
+#endif
+               break;
+
+       default:
+               break;
+       }
+       return result;
+}
+/*
+** Do not edit or modify anything in this comment block.
+** The arch-tag line is a file identity tag for the GNU Arch 
+** revision control system.
+**
+** arch-tag: 963ff156-506f-4359-9145-371e9060b030
+*/
+
diff --git a/libs/libsndfile/src/GSM610/long_term.c b/libs/libsndfile/src/GSM610/long_term.c
new file mode 100644 (file)
index 0000000..5179d1d
--- /dev/null
@@ -0,0 +1,951 @@
+/*
+ * Copyright 1992 by Jutta Degener and Carsten Bormann, Technische
+ * Universitaet Berlin.  See the accompanying file "COPYRIGHT" for
+ * details.  THERE IS ABSOLUTELY NO WARRANTY FOR THIS SOFTWARE.
+ */
+
+#include <stdio.h>
+#include <assert.h>
+
+#include "gsm610_priv.h"
+
+#include "gsm.h"
+
+/*
+ *  4.2.11 .. 4.2.12 LONG TERM PREDICTOR (LTP) SECTION
+ */
+
+
+/*
+ * This module computes the LTP gain (bc) and the LTP lag (Nc)
+ * for the long term analysis filter.   This is done by calculating a
+ * maximum of the cross-correlation function between the current
+ * sub-segment short term residual signal d[0..39] (output of
+ * the short term analysis filter; for simplification the index
+ * of this array begins at 0 and ends at 39 for each sub-segment of the
+ * RPE-LTP analysis) and the previous reconstructed short term
+ * residual signal dp[ -120 .. -1 ].  A dynamic scaling must be
+ * performed to avoid overflow.
+ */
+
+ /* The next procedure exists in six versions.  First two integer
+  * version (if USE_FLOAT_MUL is not defined); then four floating
+  * point versions, twice with proper scaling (USE_FLOAT_MUL defined),
+  * once without (USE_FLOAT_MUL and FAST defined, and fast run-time
+  * option used).  Every pair has first a Cut version (see the -C
+  * option to toast or the LTP_CUT option to gsm_option()), then the
+  * uncut one.  (For a detailed explanation of why this is altogether
+  * a bad idea, see Henry Spencer and Geoff Collyer, ``#ifdef Considered
+  * Harmful''.)
+  */
+
+#ifndef  USE_FLOAT_MUL
+
+#ifdef LTP_CUT
+
+static void Cut_Calculation_of_the_LTP_parameters (
+
+       struct gsm_state * st,
+
+       register word   * d,            /* [0..39]      IN      */
+       register word   * dp,           /* [-120..-1]   IN      */
+       word            * bc_out,       /*              OUT     */
+       word            * Nc_out        /*              OUT     */
+)
+{
+       register int    k, lambda;
+       word            Nc, bc;
+       word            wt[40];
+
+       longword        L_result;
+       longword        L_max, L_power;
+       word            R, S, dmax, scal, best_k;
+       word            ltp_cut;
+
+       register word   temp, wt_k;
+
+       /*  Search of the optimum scaling of d[0..39].
+        */
+       dmax = 0;
+       for (k = 0; k <= 39; k++) {
+               temp = d[k];
+               temp = GSM_ABS( temp );
+               if (temp > dmax) {
+                       dmax = temp;
+                       best_k = k;
+               }
+       }
+       temp = 0;
+       if (dmax == 0) scal = 0;
+       else {
+               assert(dmax > 0);
+               temp = gsm_norm( (longword)dmax << 16 );
+       }
+       if (temp > 6) scal = 0;
+       else scal = 6 - temp;
+       assert(scal >= 0);
+
+       /* Search for the maximum cross-correlation and coding of the LTP lag
+        */
+       L_max = 0;
+       Nc    = 40;     /* index for the maximum cross-correlation */
+       wt_k  = SASR_W(d[best_k], scal);
+
+       for (lambda = 40; lambda <= 120; lambda++) {
+               L_result = (longword)wt_k * dp[best_k - lambda];
+               if (L_result > L_max) {
+                       Nc    = lambda;
+                       L_max = L_result;
+               }
+       }
+       *Nc_out = Nc;
+       L_max <<= 1;
+
+       /*  Rescaling of L_max
+        */
+       assert(scal <= 100 && scal >= -100);
+       L_max = L_max >> (6 - scal);    /* sub(6, scal) */
+
+       assert( Nc <= 120 && Nc >= 40);
+
+       /*   Compute the power of the reconstructed short term residual
+        *   signal dp[..]
+        */
+       L_power = 0;
+       for (k = 0; k <= 39; k++) {
+
+               register longword L_temp;
+
+               L_temp   = SASR_W( dp[k - Nc], 3 );
+               L_power += L_temp * L_temp;
+       }
+       L_power <<= 1;  /* from L_MULT */
+
+       /*  Normalization of L_max and L_power
+        */
+
+       if (L_max <= 0)  {
+               *bc_out = 0;
+               return;
+       }
+       if (L_max >= L_power) {
+               *bc_out = 3;
+               return;
+       }
+
+       temp = gsm_norm( L_power );
+
+       R = SASR( L_max   << temp, 16 );
+       S = SASR( L_power << temp, 16 );
+
+       /*  Coding of the LTP gain
+        */
+
+       /*  Table 4.3a must be used to obtain the level DLB[i] for the
+        *  quantization of the LTP gain b to get the coded version bc.
+        */
+       for (bc = 0; bc <= 2; bc++) if (R <= gsm_mult(S, gsm_DLB[bc])) break;
+       *bc_out = bc;
+}
+
+#endif         /* LTP_CUT */
+
+static void Calculation_of_the_LTP_parameters (
+       register word   * d,            /* [0..39]      IN      */
+       register word   * dp,           /* [-120..-1]   IN      */
+       word            * bc_out,       /*              OUT     */
+       word            * Nc_out        /*              OUT     */
+)
+{
+       register int    k, lambda;
+       word            Nc, bc;
+       word            wt[40];
+
+       longword        L_max, L_power;
+       word            R, S, dmax, scal;
+       register word   temp;
+
+       /*  Search of the optimum scaling of d[0..39].
+        */
+       dmax = 0;
+
+       for (k = 0; k <= 39; k++) {
+               temp = d[k];
+               temp = GSM_ABS( temp );
+               if (temp > dmax) dmax = temp;
+       }
+
+       temp = 0;
+       if (dmax == 0) scal = 0;
+       else {
+               assert(dmax > 0);
+               temp = gsm_norm( (longword)dmax << 16 );
+       }
+
+       if (temp > 6) scal = 0;
+       else scal = 6 - temp;
+
+       assert(scal >= 0);
+
+       /*  Initialization of a working array wt
+        */
+
+       for (k = 0; k <= 39; k++) wt[k] = SASR_W( d[k], scal );
+
+       /* Search for the maximum cross-correlation and coding of the LTP lag
+        */
+       L_max = 0;
+       Nc    = 40;     /* index for the maximum cross-correlation */
+
+       for (lambda = 40; lambda <= 120; lambda++) {
+
+# undef STEP
+#              define STEP(k)  (longword)wt[k] * dp[k - lambda]
+
+               register longword L_result;
+
+               L_result  = STEP(0)  ; L_result += STEP(1) ;
+               L_result += STEP(2)  ; L_result += STEP(3) ;
+               L_result += STEP(4)  ; L_result += STEP(5)  ;
+               L_result += STEP(6)  ; L_result += STEP(7)  ;
+               L_result += STEP(8)  ; L_result += STEP(9)  ;
+               L_result += STEP(10) ; L_result += STEP(11) ;
+               L_result += STEP(12) ; L_result += STEP(13) ;
+               L_result += STEP(14) ; L_result += STEP(15) ;
+               L_result += STEP(16) ; L_result += STEP(17) ;
+               L_result += STEP(18) ; L_result += STEP(19) ;
+               L_result += STEP(20) ; L_result += STEP(21) ;
+               L_result += STEP(22) ; L_result += STEP(23) ;
+               L_result += STEP(24) ; L_result += STEP(25) ;
+               L_result += STEP(26) ; L_result += STEP(27) ;
+               L_result += STEP(28) ; L_result += STEP(29) ;
+               L_result += STEP(30) ; L_result += STEP(31) ;
+               L_result += STEP(32) ; L_result += STEP(33) ;
+               L_result += STEP(34) ; L_result += STEP(35) ;
+               L_result += STEP(36) ; L_result += STEP(37) ;
+               L_result += STEP(38) ; L_result += STEP(39) ;
+
+               if (L_result > L_max) {
+
+                       Nc    = lambda;
+                       L_max = L_result;
+               }
+       }
+
+       *Nc_out = Nc;
+
+       L_max <<= 1;
+
+       /*  Rescaling of L_max
+        */
+       assert(scal <= 100 && scal >=  -100);
+       L_max = L_max >> (6 - scal);    /* sub(6, scal) */
+
+       assert( Nc <= 120 && Nc >= 40);
+
+       /*   Compute the power of the reconstructed short term residual
+        *   signal dp[..]
+        */
+       L_power = 0;
+       for (k = 0; k <= 39; k++) {
+
+               register longword L_temp;
+
+               L_temp   = SASR_W( dp[k - Nc], 3 );
+               L_power += L_temp * L_temp;
+       }
+       L_power <<= 1;  /* from L_MULT */
+
+       /*  Normalization of L_max and L_power
+        */
+
+       if (L_max <= 0)  {
+               *bc_out = 0;
+               return;
+       }
+       if (L_max >= L_power) {
+               *bc_out = 3;
+               return;
+       }
+
+       temp = gsm_norm( L_power );
+
+       R = SASR_L( L_max   << temp, 16 );
+       S = SASR_L( L_power << temp, 16 );
+
+       /*  Coding of the LTP gain
+        */
+
+       /*  Table 4.3a must be used to obtain the level DLB[i] for the
+        *  quantization of the LTP gain b to get the coded version bc.
+        */
+       for (bc = 0; bc <= 2; bc++) if (R <= gsm_mult(S, gsm_DLB[bc])) break;
+       *bc_out = bc;
+}
+
+#else  /* USE_FLOAT_MUL */
+
+#ifdef LTP_CUT
+
+static void Cut_Calculation_of_the_LTP_parameters (
+       struct gsm_state * st,          /*              IN      */
+       register word   * d,            /* [0..39]      IN      */
+       register word   * dp,           /* [-120..-1]   IN      */
+       word            * bc_out,       /*              OUT     */
+       word            * Nc_out        /*              OUT     */
+)
+{
+       register int    k, lambda;
+       word            Nc, bc;
+       word            ltp_cut;
+
+       float           wt_float[40];
+       float           dp_float_base[120], * dp_float = dp_float_base + 120;
+
+       longword        L_max, L_power;
+       word            R, S, dmax, scal;
+       register word   temp;
+
+       /*  Search of the optimum scaling of d[0..39].
+        */
+       dmax = 0;
+
+       for (k = 0; k <= 39; k++) {
+               temp = d[k];
+               temp = GSM_ABS( temp );
+               if (temp > dmax) dmax = temp;
+       }
+
+       temp = 0;
+       if (dmax == 0) scal = 0;
+       else {
+               assert(dmax > 0);
+               temp = gsm_norm( (longword)dmax << 16 );
+       }
+
+       if (temp > 6) scal = 0;
+       else scal = 6 - temp;
+
+       assert(scal >= 0);
+       ltp_cut = (longword)SASR_W(dmax, scal) * st->ltp_cut / 100; 
+
+
+       /*  Initialization of a working array wt
+        */
+
+       for (k = 0; k < 40; k++) {
+               register word w = SASR_W( d[k], scal );
+               if (w < 0 ? w > -ltp_cut : w < ltp_cut) {
+                       wt_float[k] = 0.0;
+               }
+               else {
+                       wt_float[k] =  w;
+               }
+       }
+       for (k = -120; k <  0; k++) dp_float[k] =  dp[k];
+
+       /* Search for the maximum cross-correlation and coding of the LTP lag
+        */
+       L_max = 0;
+       Nc    = 40;     /* index for the maximum cross-correlation */
+
+       for (lambda = 40; lambda <= 120; lambda += 9) {
+
+               /*  Calculate L_result for l = lambda .. lambda + 9.
+                */
+               register float *lp = dp_float - lambda;
+
+               register float  W;
+               register float  a = lp[-8], b = lp[-7], c = lp[-6],
+                               d = lp[-5], e = lp[-4], f = lp[-3],
+                               g = lp[-2], h = lp[-1];
+               register float  E; 
+               register float  S0 = 0, S1 = 0, S2 = 0, S3 = 0, S4 = 0,
+                               S5 = 0, S6 = 0, S7 = 0, S8 = 0;
+
+#              undef STEP
+#              define  STEP(K, a, b, c, d, e, f, g, h) \
+                       if ((W = wt_float[K]) != 0.0) { \
+                       E = W * a; S8 += E;             \
+                       E = W * b; S7 += E;             \
+                       E = W * c; S6 += E;             \
+                       E = W * d; S5 += E;             \
+                       E = W * e; S4 += E;             \
+                       E = W * f; S3 += E;             \
+                       E = W * g; S2 += E;             \
+                       E = W * h; S1 += E;             \
+                       a  = lp[K];                     \
+                       E = W * a; S0 += E; } else (a = lp[K])
+
+#              define  STEP_A(K)       STEP(K, a, b, c, d, e, f, g, h)
+#              define  STEP_B(K)       STEP(K, b, c, d, e, f, g, h, a)
+#              define  STEP_C(K)       STEP(K, c, d, e, f, g, h, a, b)
+#              define  STEP_D(K)       STEP(K, d, e, f, g, h, a, b, c)
+#              define  STEP_E(K)       STEP(K, e, f, g, h, a, b, c, d)
+#              define  STEP_F(K)       STEP(K, f, g, h, a, b, c, d, e)
+#              define  STEP_G(K)       STEP(K, g, h, a, b, c, d, e, f)
+#              define  STEP_H(K)       STEP(K, h, a, b, c, d, e, f, g)
+
+               STEP_A( 0); STEP_B( 1); STEP_C( 2); STEP_D( 3);
+               STEP_E( 4); STEP_F( 5); STEP_G( 6); STEP_H( 7);
+
+               STEP_A( 8); STEP_B( 9); STEP_C(10); STEP_D(11);
+               STEP_E(12); STEP_F(13); STEP_G(14); STEP_H(15);
+
+               STEP_A(16); STEP_B(17); STEP_C(18); STEP_D(19);
+               STEP_E(20); STEP_F(21); STEP_G(22); STEP_H(23);
+
+               STEP_A(24); STEP_B(25); STEP_C(26); STEP_D(27);
+               STEP_E(28); STEP_F(29); STEP_G(30); STEP_H(31);
+
+               STEP_A(32); STEP_B(33); STEP_C(34); STEP_D(35);
+               STEP_E(36); STEP_F(37); STEP_G(38); STEP_H(39);
+
+               if (S0 > L_max) { L_max = S0; Nc = lambda;     }
+               if (S1 > L_max) { L_max = S1; Nc = lambda + 1; }
+               if (S2 > L_max) { L_max = S2; Nc = lambda + 2; }
+               if (S3 > L_max) { L_max = S3; Nc = lambda + 3; }
+               if (S4 > L_max) { L_max = S4; Nc = lambda + 4; }
+               if (S5 > L_max) { L_max = S5; Nc = lambda + 5; }
+               if (S6 > L_max) { L_max = S6; Nc = lambda + 6; }
+               if (S7 > L_max) { L_max = S7; Nc = lambda + 7; }
+               if (S8 > L_max) { L_max = S8; Nc = lambda + 8; }
+
+       }
+       *Nc_out = Nc;
+
+       L_max <<= 1;
+
+       /*  Rescaling of L_max
+        */
+       assert(scal <= 100 && scal >=  -100);
+       L_max = L_max >> (6 - scal);    /* sub(6, scal) */
+
+       assert( Nc <= 120 && Nc >= 40);
+
+       /*   Compute the power of the reconstructed short term residual
+        *   signal dp[..]
+        */
+       L_power = 0;
+       for (k = 0; k <= 39; k++) {
+
+               register longword L_temp;
+
+               L_temp   = SASR_W( dp[k - Nc], 3 );
+               L_power += L_temp * L_temp;
+       }
+       L_power <<= 1;  /* from L_MULT */
+
+       /*  Normalization of L_max and L_power
+        */
+
+       if (L_max <= 0)  {
+               *bc_out = 0;
+               return;
+       }
+       if (L_max >= L_power) {
+               *bc_out = 3;
+               return;
+       }
+
+       temp = gsm_norm( L_power );
+
+       R = SASR( L_max   << temp, 16 );
+       S = SASR( L_power << temp, 16 );
+
+       /*  Coding of the LTP gain
+        */
+
+       /*  Table 4.3a must be used to obtain the level DLB[i] for the
+        *  quantization of the LTP gain b to get the coded version bc.
+        */
+       for (bc = 0; bc <= 2; bc++) if (R <= gsm_mult(S, gsm_DLB[bc])) break;
+       *bc_out = bc;
+}
+
+#endif /* LTP_CUT */
+
+static void Calculation_of_the_LTP_parameters (
+       register word   * din,          /* [0..39]      IN      */
+       register word   * dp,           /* [-120..-1]   IN      */
+       word            * bc_out,       /*              OUT     */
+       word            * Nc_out        /*              OUT     */
+)
+{
+       register int    k, lambda;
+       word            Nc, bc;
+
+       float           wt_float[40];
+       float           dp_float_base[120], * dp_float = dp_float_base + 120;
+
+       longword        L_max, L_power;
+       word            R, S, dmax, scal;
+       register word   temp;
+
+       /*  Search of the optimum scaling of d[0..39].
+        */
+       dmax = 0;
+
+       for (k = 0; k <= 39; k++) {
+               temp = din [k] ;
+               temp = GSM_ABS (temp) ;
+               if (temp > dmax) dmax = temp;
+       }
+
+       temp = 0;
+       if (dmax == 0) scal = 0;
+       else {
+               assert(dmax > 0);
+               temp = gsm_norm( (longword)dmax << 16 );
+       }
+
+       if (temp > 6) scal = 0;
+       else scal = 6 - temp;
+
+       assert(scal >= 0);
+
+       /*  Initialization of a working array wt
+        */
+
+       for (k =    0; k < 40; k++) wt_float[k] =  SASR_W (din [k], scal) ;
+       for (k = -120; k <  0; k++) dp_float[k] =  dp[k];
+
+       /* Search for the maximum cross-correlation and coding of the LTP lag
+        */
+       L_max = 0;
+       Nc    = 40;     /* index for the maximum cross-correlation */
+
+       for (lambda = 40; lambda <= 120; lambda += 9) {
+
+               /*  Calculate L_result for l = lambda .. lambda + 9.
+                */
+               register float *lp = dp_float - lambda;
+
+               register float  W;
+               register float  a = lp[-8], b = lp[-7], c = lp[-6],
+                               d = lp[-5], e = lp[-4], f = lp[-3],
+                               g = lp[-2], h = lp[-1];
+               register float  E; 
+               register float  S0 = 0, S1 = 0, S2 = 0, S3 = 0, S4 = 0,
+                               S5 = 0, S6 = 0, S7 = 0, S8 = 0;
+
+#              undef STEP
+#              define  STEP(K, a, b, c, d, e, f, g, h) \
+                       W = wt_float[K];                \
+                       E = W * a; S8 += E;             \
+                       E = W * b; S7 += E;             \
+                       E = W * c; S6 += E;             \
+                       E = W * d; S5 += E;             \
+                       E = W * e; S4 += E;             \
+                       E = W * f; S3 += E;             \
+                       E = W * g; S2 += E;             \
+                       E = W * h; S1 += E;             \
+                       a  = lp[K];                     \
+                       E = W * a; S0 += E
+
+#              define  STEP_A(K)       STEP(K, a, b, c, d, e, f, g, h)
+#              define  STEP_B(K)       STEP(K, b, c, d, e, f, g, h, a)
+#              define  STEP_C(K)       STEP(K, c, d, e, f, g, h, a, b)
+#              define  STEP_D(K)       STEP(K, d, e, f, g, h, a, b, c)
+#              define  STEP_E(K)       STEP(K, e, f, g, h, a, b, c, d)
+#              define  STEP_F(K)       STEP(K, f, g, h, a, b, c, d, e)
+#              define  STEP_G(K)       STEP(K, g, h, a, b, c, d, e, f)
+#              define  STEP_H(K)       STEP(K, h, a, b, c, d, e, f, g)
+
+               STEP_A( 0); STEP_B( 1); STEP_C( 2); STEP_D( 3);
+               STEP_E( 4); STEP_F( 5); STEP_G( 6); STEP_H( 7);
+
+               STEP_A( 8); STEP_B( 9); STEP_C(10); STEP_D(11);
+               STEP_E(12); STEP_F(13); STEP_G(14); STEP_H(15);
+
+               STEP_A(16); STEP_B(17); STEP_C(18); STEP_D(19);
+               STEP_E(20); STEP_F(21); STEP_G(22); STEP_H(23);
+
+               STEP_A(24); STEP_B(25); STEP_C(26); STEP_D(27);
+               STEP_E(28); STEP_F(29); STEP_G(30); STEP_H(31);
+
+               STEP_A(32); STEP_B(33); STEP_C(34); STEP_D(35);
+               STEP_E(36); STEP_F(37); STEP_G(38); STEP_H(39);
+
+               if (S0 > L_max) { L_max = S0; Nc = lambda;     }
+               if (S1 > L_max) { L_max = S1; Nc = lambda + 1; }
+               if (S2 > L_max) { L_max = S2; Nc = lambda + 2; }
+               if (S3 > L_max) { L_max = S3; Nc = lambda + 3; }
+               if (S4 > L_max) { L_max = S4; Nc = lambda + 4; }
+               if (S5 > L_max) { L_max = S5; Nc = lambda + 5; }
+               if (S6 > L_max) { L_max = S6; Nc = lambda + 6; }
+               if (S7 > L_max) { L_max = S7; Nc = lambda + 7; }
+               if (S8 > L_max) { L_max = S8; Nc = lambda + 8; }
+       }
+       *Nc_out = Nc;
+
+       L_max <<= 1;
+
+       /*  Rescaling of L_max
+        */
+       assert(scal <= 100 && scal >=  -100);
+       L_max = L_max >> (6 - scal);    /* sub(6, scal) */
+
+       assert( Nc <= 120 && Nc >= 40);
+
+       /*   Compute the power of the reconstructed short term residual
+        *   signal dp[..]
+        */
+       L_power = 0;
+       for (k = 0; k <= 39; k++) {
+
+               register longword L_temp;
+
+               L_temp   = SASR_W( dp[k - Nc], 3 );
+               L_power += L_temp * L_temp;
+       }
+       L_power <<= 1;  /* from L_MULT */
+
+       /*  Normalization of L_max and L_power
+        */
+
+       if (L_max <= 0)  {
+               *bc_out = 0;
+               return;
+       }
+       if (L_max >= L_power) {
+               *bc_out = 3;
+               return;
+       }
+
+       temp = gsm_norm( L_power );
+
+       R = SASR_L ( L_max   << temp, 16 );
+       S = SASR_L ( L_power << temp, 16 );
+
+       /*  Coding of the LTP gain
+        */
+
+       /*  Table 4.3a must be used to obtain the level DLB[i] for the
+        *  quantization of the LTP gain b to get the coded version bc.
+        */
+       for (bc = 0; bc <= 2; bc++) if (R <= gsm_mult(S, gsm_DLB[bc])) break;
+       *bc_out = bc;
+}
+
+#ifdef FAST
+#ifdef LTP_CUT
+
+static void Cut_Fast_Calculation_of_the_LTP_parameters (
+       struct gsm_state * st,          /*              IN      */
+       register word   * d,            /* [0..39]      IN      */
+       register word   * dp,           /* [-120..-1]   IN      */
+       word            * bc_out,       /*              OUT     */
+       word            * Nc_out        /*              OUT     */
+)
+{
+       register int    k, lambda;
+       register float  wt_float;
+       word            Nc, bc;
+       word            wt_max, best_k, ltp_cut;
+
+       float           dp_float_base[120], * dp_float = dp_float_base + 120;
+
+       register float  L_result, L_max, L_power;
+
+       wt_max = 0;
+
+       for (k = 0; k < 40; ++k) {
+               if      ( d[k] > wt_max) wt_max =  d[best_k = k];
+               else if (-d[k] > wt_max) wt_max = -d[best_k = k];
+       }
+
+       assert(wt_max >= 0);
+       wt_float = (float)wt_max;
+
+       for (k = -120; k < 0; ++k) dp_float[k] = (float)dp[k];
+
+       /* Search for the maximum cross-correlation and coding of the LTP lag
+        */
+       L_max = 0;
+       Nc    = 40;     /* index for the maximum cross-correlation */
+
+       for (lambda = 40; lambda <= 120; lambda++) {
+               L_result = wt_float * dp_float[best_k - lambda];
+               if (L_result > L_max) {
+                       Nc    = lambda;
+                       L_max = L_result;
+               }
+       }
+
+       *Nc_out = Nc;
+       if (L_max <= 0.)  {
+               *bc_out = 0;
+               return;
+       }
+
+       /*  Compute the power of the reconstructed short term residual
+        *  signal dp[..]
+        */
+       dp_float -= Nc;
+       L_power = 0;
+       for (k = 0; k < 40; ++k) {
+               register float f = dp_float[k];
+               L_power += f * f;
+       }
+
+       if (L_max >= L_power) {
+               *bc_out = 3;
+               return;
+       }
+
+       /*  Coding of the LTP gain
+        *  Table 4.3a must be used to obtain the level DLB[i] for the
+        *  quantization of the LTP gain b to get the coded version bc.
+        */
+       lambda = L_max / L_power * 32768.;
+       for (bc = 0; bc <= 2; ++bc) if (lambda <= gsm_DLB[bc]) break;
+       *bc_out = bc;
+}
+
+#endif /* LTP_CUT */
+
+static void Fast_Calculation_of_the_LTP_parameters (
+       register word   * din,          /* [0..39]      IN      */
+       register word   * dp,           /* [-120..-1]   IN      */
+       word            * bc_out,       /*              OUT     */
+       word            * Nc_out        /*              OUT     */
+)
+{
+       register int    k, lambda;
+       word            Nc, bc;
+
+       float           wt_float[40];
+       float           dp_float_base[120], * dp_float = dp_float_base + 120;
+
+       register float  L_max, L_power;
+
+       for (k = 0; k < 40; ++k) wt_float[k] = (float) din [k] ;
+       for (k = -120; k < 0; ++k) dp_float[k] = (float) dp [k] ;
+
+       /* Search for the maximum cross-correlation and coding of the LTP lag
+        */
+       L_max = 0;
+       Nc    = 40;     /* index for the maximum cross-correlation */
+
+       for (lambda = 40; lambda <= 120; lambda += 9) {
+
+               /*  Calculate L_result for l = lambda .. lambda + 9.
+                */
+               register float *lp = dp_float - lambda;
+
+               register float  W;
+               register float  a = lp[-8], b = lp[-7], c = lp[-6],
+                               d = lp[-5], e = lp[-4], f = lp[-3],
+                               g = lp[-2], h = lp[-1];
+               register float  E; 
+               register float  S0 = 0, S1 = 0, S2 = 0, S3 = 0, S4 = 0,
+                               S5 = 0, S6 = 0, S7 = 0, S8 = 0;
+
+#              undef STEP
+#              define  STEP(K, a, b, c, d, e, f, g, h) \
+                       W = wt_float[K];                \
+                       E = W * a; S8 += E;             \
+                       E = W * b; S7 += E;             \
+                       E = W * c; S6 += E;             \
+                       E = W * d; S5 += E;             \
+                       E = W * e; S4 += E;             \
+                       E = W * f; S3 += E;             \
+                       E = W * g; S2 += E;             \
+                       E = W * h; S1 += E;             \
+                       a  = lp[K];                     \
+                       E = W * a; S0 += E
+
+#              define  STEP_A(K)       STEP(K, a, b, c, d, e, f, g, h)
+#              define  STEP_B(K)       STEP(K, b, c, d, e, f, g, h, a)
+#              define  STEP_C(K)       STEP(K, c, d, e, f, g, h, a, b)
+#              define  STEP_D(K)       STEP(K, d, e, f, g, h, a, b, c)
+#              define  STEP_E(K)       STEP(K, e, f, g, h, a, b, c, d)
+#              define  STEP_F(K)       STEP(K, f, g, h, a, b, c, d, e)
+#              define  STEP_G(K)       STEP(K, g, h, a, b, c, d, e, f)
+#              define  STEP_H(K)       STEP(K, h, a, b, c, d, e, f, g)
+
+               STEP_A( 0); STEP_B( 1); STEP_C( 2); STEP_D( 3);
+               STEP_E( 4); STEP_F( 5); STEP_G( 6); STEP_H( 7);
+
+               STEP_A( 8); STEP_B( 9); STEP_C(10); STEP_D(11);
+               STEP_E(12); STEP_F(13); STEP_G(14); STEP_H(15);
+
+               STEP_A(16); STEP_B(17); STEP_C(18); STEP_D(19);
+               STEP_E(20); STEP_F(21); STEP_G(22); STEP_H(23);
+
+               STEP_A(24); STEP_B(25); STEP_C(26); STEP_D(27);
+               STEP_E(28); STEP_F(29); STEP_G(30); STEP_H(31);
+
+               STEP_A(32); STEP_B(33); STEP_C(34); STEP_D(35);
+               STEP_E(36); STEP_F(37); STEP_G(38); STEP_H(39);
+
+               if (S0 > L_max) { L_max = S0; Nc = lambda;     }
+               if (S1 > L_max) { L_max = S1; Nc = lambda + 1; }
+               if (S2 > L_max) { L_max = S2; Nc = lambda + 2; }
+               if (S3 > L_max) { L_max = S3; Nc = lambda + 3; }
+               if (S4 > L_max) { L_max = S4; Nc = lambda + 4; }
+               if (S5 > L_max) { L_max = S5; Nc = lambda + 5; }
+               if (S6 > L_max) { L_max = S6; Nc = lambda + 6; }
+               if (S7 > L_max) { L_max = S7; Nc = lambda + 7; }
+               if (S8 > L_max) { L_max = S8; Nc = lambda + 8; }
+       }
+       *Nc_out = Nc;
+
+       if (L_max <= 0.)  {
+               *bc_out = 0;
+               return;
+       }
+
+       /*  Compute the power of the reconstructed short term residual
+        *  signal dp[..]
+        */
+       dp_float -= Nc;
+       L_power = 0;
+       for (k = 0; k < 40; ++k) {
+               register float f = dp_float[k];
+               L_power += f * f;
+       }
+
+       if (L_max >= L_power) {
+               *bc_out = 3;
+               return;
+       }
+
+       /*  Coding of the LTP gain
+        *  Table 4.3a must be used to obtain the level DLB[i] for the
+        *  quantization of the LTP gain b to get the coded version bc.
+        */
+       lambda = L_max / L_power * 32768.;
+       for (bc = 0; bc <= 2; ++bc) if (lambda <= gsm_DLB[bc]) break;
+       *bc_out = bc;
+}
+
+#endif /* FAST          */
+#endif /* USE_FLOAT_MUL */
+
+
+/* 4.2.12 */
+
+static void Long_term_analysis_filtering (
+       word            bc,     /*                                      IN  */
+       word            Nc,     /*                                      IN  */
+       register word   * dp,   /* previous d   [-120..-1]              IN  */
+       register word   * d,    /* d            [0..39]                 IN  */
+       register word   * dpp,  /* estimate     [0..39]                 OUT */
+       register word   * e     /* long term res. signal [0..39]        OUT */
+)
+/*
+ *  In this part, we have to decode the bc parameter to compute
+ *  the samples of the estimate dpp[0..39].  The decoding of bc needs the
+ *  use of table 4.3b.  The long term residual signal e[0..39]
+ *  is then calculated to be fed to the RPE encoding section.
+ */
+{
+       register int      k;
+
+#      undef STEP
+#      define STEP(BP)                                 \
+       for (k = 0; k <= 39; k++) {                     \
+               dpp[k]  = GSM_MULT_R( BP, dp[k - Nc]);  \
+               e[k]    = GSM_SUB( d[k], dpp[k] );      \
+       }
+
+       switch (bc) {
+       case 0: STEP(  3277 ); break;
+       case 1: STEP( 11469 ); break;
+       case 2: STEP( 21299 ); break;
+       case 3: STEP( 32767 ); break; 
+       }
+}
+
+void Gsm_Long_Term_Predictor ( /* 4x for 160 samples */
+
+       struct gsm_state        * S,
+
+       word    * d,    /* [0..39]   residual signal    IN      */
+       word    * dp,   /* [-120..-1] d'                IN      */
+
+       word    * e,    /* [0..39]                      OUT     */
+       word    * dpp,  /* [0..39]                      OUT     */
+       word    * Nc,   /* correlation lag              OUT     */
+       word    * bc    /* gain factor                  OUT     */
+)
+{
+       assert( d  ); assert( dp ); assert( e  );
+       assert( dpp); assert( Nc ); assert( bc );
+
+#if defined(FAST) && defined(USE_FLOAT_MUL)
+       if (S->fast) 
+#if   defined (LTP_CUT)
+               if (S->ltp_cut)
+                       Cut_Fast_Calculation_of_the_LTP_parameters(S,
+                               d, dp, bc, Nc);
+               else
+#endif /* LTP_CUT */
+                       Fast_Calculation_of_the_LTP_parameters(d, dp, bc, Nc );
+       else 
+#endif /* FAST & USE_FLOAT_MUL */
+#ifdef LTP_CUT
+               if (S->ltp_cut)
+                       Cut_Calculation_of_the_LTP_parameters(S, d, dp, bc, Nc);
+               else
+#endif
+                       Calculation_of_the_LTP_parameters(d, dp, bc, Nc);
+
+       Long_term_analysis_filtering( *bc, *Nc, dp, d, dpp, e );
+}
+
+/* 4.3.2 */
+void Gsm_Long_Term_Synthesis_Filtering (
+       struct gsm_state        * S,
+
+       word                    Ncr,
+       word                    bcr,
+       register word           * erp,     /* [0..39]                    IN */
+       register word           * drp      /* [-120..-1] IN, [-120..40] OUT */
+)
+/*
+ *  This procedure uses the bcr and Ncr parameter to realize the
+ *  long term synthesis filtering.  The decoding of bcr needs
+ *  table 4.3b.
+ */
+{
+       register int            k;
+       word                    brp, drpp, Nr;
+
+       /*  Check the limits of Nr.
+        */
+       Nr = Ncr < 40 || Ncr > 120 ? S->nrp : Ncr;
+       S->nrp = Nr;
+       assert(Nr >= 40 && Nr <= 120);
+
+       /*  Decoding of the LTP gain bcr
+        */
+       brp = gsm_QLB[ bcr ];
+
+       /*  Computation of the reconstructed short term residual 
+        *  signal drp[0..39]
+        */
+       assert(brp != MIN_WORD);
+
+       for (k = 0; k <= 39; k++) {
+               drpp   = GSM_MULT_R( brp, drp[ k - Nr ] );
+               drp[k] = GSM_ADD( erp[k], drpp );
+       }
+
+       /*
+        *  Update of the reconstructed short term residual signal
+        *  drp[ -1..-120 ]
+        */
+
+       for (k = 0; k <= 119; k++) drp[ -120 + k ] = drp[ -80 + k ];
+}
+/*
+** Do not edit or modify anything in this comment block.
+** The arch-tag line is a file identity tag for the GNU Arch 
+** revision control system.
+**
+** arch-tag: b369b90d-0284-42a0-87b0-99a25bbd93ac
+*/
+
diff --git a/libs/libsndfile/src/GSM610/lpc.c b/libs/libsndfile/src/GSM610/lpc.c
new file mode 100644 (file)
index 0000000..0a879f3
--- /dev/null
@@ -0,0 +1,341 @@
+/*
+ * Copyright 1992 by Jutta Degener and Carsten Bormann, Technische
+ * Universitaet Berlin.  See the accompanying file "COPYRIGHT" for
+ * details.  THERE IS ABSOLUTELY NO WARRANTY FOR THIS SOFTWARE.
+ */
+
+#include <stdio.h>
+#include <assert.h>
+
+#include "gsm610_priv.h"
+
+#include "gsm.h"
+
+/*
+ *  4.2.4 .. 4.2.7 LPC ANALYSIS SECTION
+ */
+
+/* 4.2.4 */
+
+
+static void Autocorrelation (
+       word     * s,           /* [0..159]     IN/OUT  */
+       longword * L_ACF)       /* [0..8]       OUT     */
+/*
+ *  The goal is to compute the array L_ACF[k].  The signal s[i] must
+ *  be scaled in order to avoid an overflow situation.
+ */
+{
+       register int    k, i;
+
+       word            temp, smax, scalauto;
+
+#ifdef USE_FLOAT_MUL
+       float           float_s[160];
+#endif
+
+       /*  Dynamic scaling of the array  s[0..159]
+        */
+
+       /*  Search for the maximum.
+        */
+       smax = 0;
+       for (k = 0; k <= 159; k++) {
+               temp = GSM_ABS( s[k] );
+               if (temp > smax) smax = temp;
+       }
+
+       /*  Computation of the scaling factor.
+        */
+       if (smax == 0) scalauto = 0;
+       else {
+               assert(smax > 0);
+               scalauto = 4 - gsm_norm( (longword)smax << 16 );/* sub(4,..) */
+       }
+
+       /*  Scaling of the array s[0...159]
+        */
+
+       if (scalauto > 0) {
+
+# ifdef USE_FLOAT_MUL
+#   define SCALE(n)    \
+       case n: for (k = 0; k <= 159; k++) \
+                       float_s[k] = (float)    \
+                               (s[k] = GSM_MULT_R(s[k], 16384 >> (n-1)));\
+               break;
+# else 
+#   define SCALE(n)    \
+       case n: for (k = 0; k <= 159; k++) \
+                       s[k] = GSM_MULT_R( s[k], 16384 >> (n-1) );\
+               break;
+# endif /* USE_FLOAT_MUL */
+
+               switch (scalauto) {
+               SCALE(1)
+               SCALE(2)
+               SCALE(3)
+               SCALE(4)
+               }
+# undef        SCALE
+       }
+# ifdef        USE_FLOAT_MUL
+       else for (k = 0; k <= 159; k++) float_s[k] = (float) s[k];
+# endif
+
+       /*  Compute the L_ACF[..].
+        */
+       {
+# ifdef        USE_FLOAT_MUL
+               register float * sp = float_s;
+               register float   sl = *sp;
+
+#              define STEP(k)   L_ACF[k] += (longword)(sl * sp[ -(k) ]);
+# else
+               word  * sp = s;
+               word    sl = *sp;
+
+#              define STEP(k)   L_ACF[k] += ((longword)sl * sp[ -(k) ]);
+# endif
+
+#      define NEXTI     sl = *++sp
+
+
+       for (k = 9; k--; L_ACF[k] = 0) ;
+
+       STEP (0);
+       NEXTI;
+       STEP(0); STEP(1);
+       NEXTI;
+       STEP(0); STEP(1); STEP(2);
+       NEXTI;
+       STEP(0); STEP(1); STEP(2); STEP(3);
+       NEXTI;
+       STEP(0); STEP(1); STEP(2); STEP(3); STEP(4);
+       NEXTI;
+       STEP(0); STEP(1); STEP(2); STEP(3); STEP(4); STEP(5);
+       NEXTI;
+       STEP(0); STEP(1); STEP(2); STEP(3); STEP(4); STEP(5); STEP(6);
+       NEXTI;
+       STEP(0); STEP(1); STEP(2); STEP(3); STEP(4); STEP(5); STEP(6); STEP(7);
+
+       for (i = 8; i <= 159; i++) {
+
+               NEXTI;
+
+               STEP(0);
+               STEP(1); STEP(2); STEP(3); STEP(4);
+               STEP(5); STEP(6); STEP(7); STEP(8);
+       }
+
+       for (k = 9; k--; L_ACF[k] <<= 1) ; 
+
+       }
+       /*   Rescaling of the array s[0..159]
+        */
+       if (scalauto > 0) {
+               assert(scalauto <= 4); 
+               for (k = 160; k--; *s++ <<= scalauto) ;
+       }
+}
+
+#if defined(USE_FLOAT_MUL) && defined(FAST)
+
+static void Fast_Autocorrelation (
+       word * s,               /* [0..159]     IN/OUT  */
+       longword * L_ACF)       /* [0..8]       OUT     */
+{
+       register int    k, i;
+       float f_L_ACF[9];
+       float scale;
+
+       float          s_f[160];
+       register float *sf = s_f;
+
+       for (i = 0; i < 160; ++i) sf[i] = s[i];
+       for (k = 0; k <= 8; k++) {
+               register float L_temp2 = 0;
+               register float *sfl = sf - k;
+               for (i = k; i < 160; ++i) L_temp2 += sf[i] * sfl[i];
+               f_L_ACF[k] = L_temp2;
+       }
+       scale = MAX_LONGWORD / f_L_ACF[0];
+
+       for (k = 0; k <= 8; k++) {
+               L_ACF[k] = f_L_ACF[k] * scale;
+       }
+}
+#endif /* defined (USE_FLOAT_MUL) && defined (FAST) */
+
+/* 4.2.5 */
+
+static void Reflection_coefficients (
+       longword        * L_ACF,                /* 0...8        IN      */
+       register word   * r                     /* 0...7        OUT     */
+)
+{
+       register int    i, m, n;
+       register word   temp;
+       word            ACF[9]; /* 0..8 */
+       word            P[  9]; /* 0..8 */
+       word            K[  9]; /* 2..8 */
+
+       /*  Schur recursion with 16 bits arithmetic.
+        */
+
+       if (L_ACF[0] == 0) {
+               for (i = 8; i--; *r++ = 0) ;
+               return;
+       }
+
+       assert( L_ACF[0] != 0 );
+       temp = gsm_norm( L_ACF[0] );
+
+       assert(temp >= 0 && temp < 32);
+
+       /* ? overflow ? */
+       for (i = 0; i <= 8; i++) ACF[i] = SASR_L( L_ACF[i] << temp, 16 );
+
+       /*   Initialize array P[..] and K[..] for the recursion.
+        */
+
+       for (i = 1; i <= 7; i++) K[ i ] = ACF[ i ];
+       for (i = 0; i <= 8; i++) P[ i ] = ACF[ i ];
+
+       /*   Compute reflection coefficients
+        */
+       for (n = 1; n <= 8; n++, r++) {
+
+               temp = P[1];
+               temp = GSM_ABS(temp);
+               if (P[0] < temp) {
+                       for (i = n; i <= 8; i++) *r++ = 0;
+                       return;
+               }
+
+               *r = gsm_div( temp, P[0] );
+
+               assert(*r >= 0);
+               if (P[1] > 0) *r = -*r;         /* r[n] = sub(0, r[n]) */
+               assert (*r != MIN_WORD);
+               if (n == 8) return; 
+
+               /*  Schur recursion
+                */
+               temp = GSM_MULT_R( P[1], *r );
+               P[0] = GSM_ADD( P[0], temp );
+
+               for (m = 1; m <= 8 - n; m++) {
+                       temp     = GSM_MULT_R( K[ m   ],    *r );
+                       P[m]     = GSM_ADD(    P[ m+1 ],  temp );
+
+                       temp     = GSM_MULT_R( P[ m+1 ],    *r );
+                       K[m]     = GSM_ADD(    K[ m   ],  temp );
+               }
+       }
+}
+
+/* 4.2.6 */
+
+static void Transformation_to_Log_Area_Ratios (
+       register word   * r                     /* 0..7    IN/OUT */
+)
+/*
+ *  The following scaling for r[..] and LAR[..] has been used:
+ *
+ *  r[..]   = integer( real_r[..]*32768. ); -1 <= real_r < 1.
+ *  LAR[..] = integer( real_LAR[..] * 16384 );
+ *  with -1.625 <= real_LAR <= 1.625
+ */
+{
+       register word   temp;
+       register int    i;
+
+
+       /* Computation of the LAR[0..7] from the r[0..7]
+        */
+       for (i = 1; i <= 8; i++, r++) {
+
+               temp = *r;
+               temp = GSM_ABS(temp);
+               assert(temp >= 0);
+
+               if (temp < 22118) {
+                       temp >>= 1;
+               } else if (temp < 31130) {
+                       assert( temp >= 11059 );
+                       temp -= 11059;
+               } else {
+                       assert( temp >= 26112 );
+                       temp -= 26112;
+                       temp <<= 2;
+               }
+
+               *r = *r < 0 ? -temp : temp;
+               assert( *r != MIN_WORD );
+       }
+}
+
+/* 4.2.7 */
+
+static void Quantization_and_coding (
+       register word * LAR     /* [0..7]       IN/OUT  */
+)
+{
+       register word   temp;
+
+       /*  This procedure needs four tables; the following equations
+        *  give the optimum scaling for the constants:
+        *  
+        *  A[0..7] = integer( real_A[0..7] * 1024 )
+        *  B[0..7] = integer( real_B[0..7] *  512 )
+        *  MAC[0..7] = maximum of the LARc[0..7]
+        *  MIC[0..7] = minimum of the LARc[0..7]
+        */
+
+#      undef STEP
+#      define  STEP( A, B, MAC, MIC )          \
+               temp = GSM_MULT( A,   *LAR );   \
+               temp = GSM_ADD(  temp,   B );   \
+               temp = GSM_ADD(  temp, 256 );   \
+               temp = SASR_W(     temp,   9 ); \
+               *LAR  =  temp>MAC ? MAC - MIC : (temp<MIC ? 0 : temp - MIC); \
+               LAR++;
+
+       STEP(  20480,     0,  31, -32 );
+       STEP(  20480,     0,  31, -32 );
+       STEP(  20480,  2048,  15, -16 );
+       STEP(  20480, -2560,  15, -16 );
+
+       STEP(  13964,    94,   7,  -8 );
+       STEP(  15360, -1792,   7,  -8 );
+       STEP(   8534,  -341,   3,  -4 );
+       STEP(   9036, -1144,   3,  -4 );
+
+#      undef   STEP
+}
+
+void Gsm_LPC_Analysis (
+       struct gsm_state *S,
+       word             * s,           /* 0..159 signals       IN/OUT  */
+        word            * LARc)        /* 0..7   LARc's        OUT     */
+{
+       longword        L_ACF[9];
+
+#if defined(USE_FLOAT_MUL) && defined(FAST)
+       if (S->fast) Fast_Autocorrelation (s,     L_ACF );
+       else
+#endif
+       Autocorrelation                   (s,     L_ACF );
+       Reflection_coefficients           (L_ACF, LARc  );
+       Transformation_to_Log_Area_Ratios (LARc);
+       Quantization_and_coding           (LARc);
+}
+/*
+** Do not edit or modify anything in this comment block.
+** The arch-tag line is a file identity tag for the GNU Arch 
+** revision control system.
+**
+** arch-tag: 63146664-a002-4e1e-8b7b-f0cc8a6a53da
+*/
+
diff --git a/libs/libsndfile/src/GSM610/preprocess.c b/libs/libsndfile/src/GSM610/preprocess.c
new file mode 100644 (file)
index 0000000..d1b473d
--- /dev/null
@@ -0,0 +1,115 @@
+/*
+ * Copyright 1992 by Jutta Degener and Carsten Bormann, Technische
+ * Universitaet Berlin.  See the accompanying file "COPYRIGHT" for
+ * details.  THERE IS ABSOLUTELY NO WARRANTY FOR THIS SOFTWARE.
+ */
+
+#include       <stdio.h>
+#include       <assert.h>
+
+#include "gsm610_priv.h"
+
+#include       "gsm.h"
+
+/*     4.2.0 .. 4.2.3  PREPROCESSING SECTION
+ *  
+ *     After A-law to linear conversion (or directly from the
+ *     Ato D converter) the following scaling is assumed for
+ *     input to the RPE-LTP algorithm:
+ *
+ *      in:  0.1.....................12
+ *          S.v.v.v.v.v.v.v.v.v.v.v.v.*.*.*
+ *
+ *     Where S is the sign bit, v a valid bit, and * a "don't care" bit.
+ *     The original signal is called sop[..]
+ *
+ *      out:   0.1................... 12 
+ *          S.S.v.v.v.v.v.v.v.v.v.v.v.v.0.0
+ */
+
+
+void Gsm_Preprocess (
+       struct gsm_state * S,
+       word             * s,
+       word             * so )         /* [0..159]     IN/OUT  */
+{
+
+       word       z1 = S->z1;
+       longword L_z2 = S->L_z2;
+       word       mp = S->mp;
+
+       word            s1;
+       longword      L_s2;
+
+       longword      L_temp;
+
+       word            msp, lsp;
+       word            SO;
+
+       register int            k = 160;
+
+       while (k--) {
+
+       /*  4.2.1   Downscaling of the input signal
+        */
+               SO = SASR_W( *s, 3 ) << 2;
+               s++;
+
+               assert (SO >= -0x4000); /* downscaled by     */
+               assert (SO <=  0x3FFC); /* previous routine. */
+
+
+       /*  4.2.2   Offset compensation
+        * 
+        *  This part implements a high-pass filter and requires extended
+        *  arithmetic precision for the recursive part of this filter.
+        *  The input of this procedure is the array so[0...159] and the
+        *  output the array sof[ 0...159 ].
+        */
+               /*   Compute the non-recursive part
+                */
+
+               s1 = SO - z1;                   /* s1 = gsm_sub( *so, z1 ); */
+               z1 = SO;
+
+               assert(s1 != MIN_WORD);
+
+               /*   Compute the recursive part
+                */
+               L_s2 = s1;
+               L_s2 <<= 15;
+
+               /*   Execution of a 31 bv 16 bits multiplication
+                */
+
+               msp = SASR_L( L_z2, 15 );
+               lsp = L_z2-((longword)msp<<15); /* gsm_L_sub(L_z2,(msp<<15)); */
+
+               L_s2  += GSM_MULT_R( lsp, 32735 );
+               L_temp = (longword)msp * 32735; /* GSM_L_MULT(msp,32735) >> 1;*/
+               L_z2   = GSM_L_ADD( L_temp, L_s2 );
+
+               /*    Compute sof[k] with rounding
+                */
+               L_temp = GSM_L_ADD( L_z2, 16384 );
+
+       /*   4.2.3  Preemphasis
+        */
+
+               msp   = GSM_MULT_R( mp, -28180 );
+               mp    = SASR_L( L_temp, 15 );
+               *so++ = GSM_ADD( mp, msp );
+       }
+
+       S->z1   = z1;
+       S->L_z2 = L_z2;
+       S->mp   = mp;
+}
+/*
+** Do not edit or modify anything in this comment block.
+** The arch-tag line is a file identity tag for the GNU Arch 
+** revision control system.
+**
+** arch-tag: b760b0d9-3a05-4da3-9dc9-441ffb905d87
+*/
+
diff --git a/libs/libsndfile/src/GSM610/rpe.c b/libs/libsndfile/src/GSM610/rpe.c
new file mode 100644 (file)
index 0000000..1d91f38
--- /dev/null
@@ -0,0 +1,490 @@
+/*
+ * Copyright 1992 by Jutta Degener and Carsten Bormann, Technische
+ * Universitaet Berlin.  See the accompanying file "COPYRIGHT" for
+ * details.  THERE IS ABSOLUTELY NO WARRANTY FOR THIS SOFTWARE.
+ */
+
+#include <stdio.h>
+#include <assert.h>
+
+#include "gsm610_priv.h"
+
+#include "gsm.h"
+
+/*  4.2.13 .. 4.2.17  RPE ENCODING SECTION
+ */
+
+/* 4.2.13 */
+
+static void Weighting_filter (
+       register word   * e,            /* signal [-5..0.39.44] IN  */
+       word            * x             /* signal [0..39]       OUT */
+)
+/*
+ *  The coefficients of the weighting filter are stored in a table
+ *  (see table 4.4).  The following scaling is used:
+ *
+ *     H[0..10] = integer( real_H[ 0..10] * 8192 ); 
+ */
+{
+       /* word                 wt[ 50 ]; */
+
+       register longword       L_result;
+       register int            k /* , i */ ;
+
+       /*  Initialization of a temporary working array wt[0...49]
+        */
+
+       /* for (k =  0; k <=  4; k++) wt[k] = 0;
+        * for (k =  5; k <= 44; k++) wt[k] = *e++;
+        * for (k = 45; k <= 49; k++) wt[k] = 0;
+        *
+        *  (e[-5..-1] and e[40..44] are allocated by the caller,
+        *  are initially zero and are not written anywhere.)
+        */
+       e -= 5;
+
+       /*  Compute the signal x[0..39]
+        */ 
+       for (k = 0; k <= 39; k++) {
+
+               L_result = 8192 >> 1;
+
+               /* for (i = 0; i <= 10; i++) {
+                *      L_temp   = GSM_L_MULT( wt[k+i], gsm_H[i] );
+                *      L_result = GSM_L_ADD( L_result, L_temp );
+                * }
+                */
+
+#undef STEP
+#define        STEP( i, H )    (e[ k + i ] * (longword)H)
+
+               /*  Every one of these multiplications is done twice --
+                *  but I don't see an elegant way to optimize this. 
+                *  Do you?
+                */
+
+#ifdef STUPID_COMPILER
+               L_result += STEP(       0,      -134 ) ;
+               L_result += STEP(       1,      -374 )  ;
+                      /* + STEP(       2,      0    )  */
+               L_result += STEP(       3,      2054 ) ;
+               L_result += STEP(       4,      5741 ) ;
+               L_result += STEP(       5,      8192 ) ;
+               L_result += STEP(       6,      5741 ) ;
+               L_result += STEP(       7,      2054 ) ;
+                      /* + STEP(       8,      0    )  */
+               L_result += STEP(       9,      -374 ) ;
+               L_result += STEP(       10,     -134 ) ;
+#else
+               L_result +=
+                 STEP( 0,      -134 ) 
+               + STEP( 1,      -374 ) 
+            /* + STEP( 2,      0    )  */
+               + STEP( 3,      2054 ) 
+               + STEP( 4,      5741 ) 
+               + STEP( 5,      8192 ) 
+               + STEP( 6,      5741 ) 
+               + STEP( 7,      2054 ) 
+            /* + STEP( 8,      0    )  */
+               + STEP( 9,      -374 ) 
+               + STEP(10,      -134 )
+               ;
+#endif
+
+               /* L_result = GSM_L_ADD( L_result, L_result ); (* scaling(x2) *)
+                * L_result = GSM_L_ADD( L_result, L_result ); (* scaling(x4) *)
+                *
+                * x[k] = SASR( L_result, 16 );
+                */
+
+               /* 2 adds vs. >>16 => 14, minus one shift to compensate for
+                * those we lost when replacing L_MULT by '*'.
+                */
+
+               L_result = SASR_L( L_result, 13 );
+               x[k] =  (  L_result < MIN_WORD ? MIN_WORD
+                       : (L_result > MAX_WORD ? MAX_WORD : L_result ));
+       }
+}
+
+/* 4.2.14 */
+
+static void RPE_grid_selection (
+       word            * x,            /* [0..39]              IN  */ 
+       word            * xM,           /* [0..12]              OUT */
+       word            * Mc_out        /*                      OUT */
+)
+/*
+ *  The signal x[0..39] is used to select the RPE grid which is
+ *  represented by Mc.
+ */
+{
+       /* register word        temp1;  */
+       register int            /* m, */  i;
+       register longword       L_result, L_temp;
+       longword                EM;     /* xxx should be L_EM? */
+       word                    Mc;
+
+       longword                L_common_0_3;
+
+       EM = 0;
+       Mc = 0;
+
+       /* for (m = 0; m <= 3; m++) {
+        *      L_result = 0;
+        *
+        *
+        *      for (i = 0; i <= 12; i++) {
+        *
+        *              temp1    = SASR_W( x[m + 3*i], 2 );
+        *
+        *              assert(temp1 != MIN_WORD);
+        *
+        *              L_temp   = GSM_L_MULT( temp1, temp1 );
+        *              L_result = GSM_L_ADD( L_temp, L_result );
+        *      }
+        * 
+        *      if (L_result > EM) {
+        *              Mc = m;
+        *              EM = L_result;
+        *      }
+        * }
+        */
+
+#undef STEP
+#define        STEP( m, i )            L_temp = SASR_W( x[m + 3 * i], 2 );     \
+                               L_result += L_temp * L_temp;
+
+       /* common part of 0 and 3 */
+
+       L_result = 0;
+       STEP( 0, 1 ); STEP( 0, 2 ); STEP( 0, 3 ); STEP( 0, 4 );
+       STEP( 0, 5 ); STEP( 0, 6 ); STEP( 0, 7 ); STEP( 0, 8 );
+       STEP( 0, 9 ); STEP( 0, 10); STEP( 0, 11); STEP( 0, 12);
+       L_common_0_3 = L_result;
+
+       /* i = 0 */
+
+       STEP( 0, 0 );
+       L_result <<= 1; /* implicit in L_MULT */
+       EM = L_result;
+
+       /* i = 1 */
+
+       L_result = 0;
+       STEP( 1, 0 );
+       STEP( 1, 1 ); STEP( 1, 2 ); STEP( 1, 3 ); STEP( 1, 4 );
+       STEP( 1, 5 ); STEP( 1, 6 ); STEP( 1, 7 ); STEP( 1, 8 );
+       STEP( 1, 9 ); STEP( 1, 10); STEP( 1, 11); STEP( 1, 12);
+       L_result <<= 1;
+       if (L_result > EM) {
+               Mc = 1;
+               EM = L_result;
+       }
+
+       /* i = 2 */
+
+       L_result = 0;
+       STEP( 2, 0 );
+       STEP( 2, 1 ); STEP( 2, 2 ); STEP( 2, 3 ); STEP( 2, 4 );
+       STEP( 2, 5 ); STEP( 2, 6 ); STEP( 2, 7 ); STEP( 2, 8 );
+       STEP( 2, 9 ); STEP( 2, 10); STEP( 2, 11); STEP( 2, 12);
+       L_result <<= 1;
+       if (L_result > EM) {
+               Mc = 2;
+               EM = L_result;
+       }
+
+       /* i = 3 */
+
+       L_result = L_common_0_3;
+       STEP( 3, 12 );
+       L_result <<= 1;
+       if (L_result > EM) {
+               Mc = 3;
+               EM = L_result;
+       }
+
+       /**/
+
+       /*  Down-sampling by a factor 3 to get the selected xM[0..12]
+        *  RPE sequence.
+        */
+       for (i = 0; i <= 12; i ++) xM[i] = x[Mc + 3*i];
+       *Mc_out = Mc;
+}
+
+/* 4.12.15 */
+
+static void APCM_quantization_xmaxc_to_exp_mant (
+       word            xmaxc,          /* IN   */
+       word            * expon_out,    /* OUT  */
+       word            * mant_out )    /* OUT  */
+{
+       word    expon, mant;
+
+       /* Compute expononent and mantissa of the decoded version of xmaxc
+        */
+
+       expon = 0;
+       if (xmaxc > 15) expon = SASR_W(xmaxc, 3) - 1;
+       mant = xmaxc - (expon << 3);
+
+       if (mant == 0) {
+               expon  = -4;
+               mant = 7;
+       }
+       else {
+               while (mant <= 7) {
+                       mant = mant << 1 | 1;
+                       expon--;
+               }
+               mant -= 8;
+       }
+
+       assert( expon  >= -4 && expon <= 6 );
+       assert( mant >= 0 && mant <= 7 );
+
+       *expon_out  = expon;
+       *mant_out = mant;
+}
+
+static void APCM_quantization (
+       word            * xM,           /* [0..12]              IN      */
+       word            * xMc,          /* [0..12]              OUT     */
+       word            * mant_out,     /*                      OUT     */
+       word            * expon_out,    /*                      OUT     */
+       word            * xmaxc_out     /*                      OUT     */
+)
+{
+       int     i, itest;
+
+       word    xmax, xmaxc, temp, temp1, temp2;
+       word    expon, mant;
+
+
+       /*  Find the maximum absolute value xmax of xM[0..12].
+        */
+
+       xmax = 0;
+       for (i = 0; i <= 12; i++) {
+               temp = xM[i];
+               temp = GSM_ABS(temp);
+               if (temp > xmax) xmax = temp;
+       }
+
+       /*  Qantizing and coding of xmax to get xmaxc.
+        */
+
+       expon   = 0;
+       temp  = SASR_W( xmax, 9 );
+       itest = 0;
+
+       for (i = 0; i <= 5; i++) {
+
+               itest |= (temp <= 0);
+               temp = SASR_W( temp, 1 );
+
+               assert(expon <= 5);
+               if (itest == 0) expon++;                /* expon = add (expon, 1) */
+       }
+
+       assert(expon <= 6 && expon >= 0);
+       temp = expon + 5;
+
+       assert(temp <= 11 && temp >= 0);
+       xmaxc = gsm_add( SASR_W(xmax, temp), (word) (expon << 3) );
+
+       /*   Quantizing and coding of the xM[0..12] RPE sequence
+        *   to get the xMc[0..12]
+        */
+
+       APCM_quantization_xmaxc_to_exp_mant( xmaxc, &expon, &mant );
+
+       /*  This computation uses the fact that the decoded version of xmaxc
+        *  can be calculated by using the expononent and the mantissa part of
+        *  xmaxc (logarithmic table).
+        *  So, this method avoids any division and uses only a scaling
+        *  of the RPE samples by a function of the expononent.  A direct 
+        *  multiplication by the inverse of the mantissa (NRFAC[0..7]
+        *  found in table 4.5) gives the 3 bit coded version xMc[0..12]
+        *  of the RPE samples.
+        */
+
+
+       /* Direct computation of xMc[0..12] using table 4.5
+        */
+
+       assert( expon <= 4096 && expon >= -4096);
+       assert( mant >= 0 && mant <= 7 ); 
+
+       temp1 = 6 - expon;              /* normalization by the expononent */
+       temp2 = gsm_NRFAC[ mant ];      /* inverse mantissa              */
+
+       for (i = 0; i <= 12; i++) {
+
+               assert(temp1 >= 0 && temp1 < 16);
+
+               temp = xM[i] << temp1;
+               temp = GSM_MULT( temp, temp2 );
+               temp = SASR_W(temp, 12);
+               xMc[i] = temp + 4;              /* see note below */
+       }
+
+       /*  NOTE: This equation is used to make all the xMc[i] positive.
+        */
+
+       *mant_out  = mant;
+       *expon_out   = expon;
+       *xmaxc_out = xmaxc;
+}
+
+/* 4.2.16 */
+
+static void APCM_inverse_quantization (
+       register word   * xMc,  /* [0..12]                      IN      */
+       word            mant,
+       word            expon,
+       register word   * xMp)  /* [0..12]                      OUT     */
+/* 
+ *  This part is for decoding the RPE sequence of coded xMc[0..12]
+ *  samples to obtain the xMp[0..12] array.  Table 4.6 is used to get
+ *  the mantissa of xmaxc (FAC[0..7]).
+ */
+{
+       int     i;
+       word    temp, temp1, temp2, temp3;
+
+       assert( mant >= 0 && mant <= 7 ); 
+
+       temp1 = gsm_FAC[ mant ];        /* see 4.2-15 for mant */
+       temp2 = gsm_sub( 6, expon );    /* see 4.2-15 for exp  */
+       temp3 = gsm_asl( 1, gsm_sub( temp2, 1 ));
+
+       for (i = 13; i--;) {
+
+               assert( *xMc <= 7 && *xMc >= 0 );       /* 3 bit unsigned */
+
+               /* temp = gsm_sub( *xMc++ << 1, 7 ); */
+               temp = (*xMc++ << 1) - 7;               /* restore sign   */
+               assert( temp <= 7 && temp >= -7 );      /* 4 bit signed   */
+
+               temp <<= 12;                            /* 16 bit signed  */
+               temp = GSM_MULT_R( temp1, temp );
+               temp = GSM_ADD( temp, temp3 );
+               *xMp++ = gsm_asr( temp, temp2 );
+       }
+}
+
+/* 4.2.17 */
+
+static void RPE_grid_positioning (
+       word            Mc,             /* grid position        IN      */
+       register word   * xMp,          /* [0..12]              IN      */
+       register word   * ep            /* [0..39]              OUT     */
+)
+/*
+ *  This procedure computes the reconstructed long term residual signal
+ *  ep[0..39] for the LTP analysis filter.  The inputs are the Mc
+ *  which is the grid position selection and the xMp[0..12] decoded
+ *  RPE samples which are upsampled by a factor of 3 by inserting zero
+ *  values.
+ */
+{
+       int     i = 13;
+
+       assert(0 <= Mc && Mc <= 3);
+
+        switch (Mc) {
+                case 3: *ep++ = 0;
+                case 2:  do {
+                                *ep++ = 0;
+                case 1:         *ep++ = 0;
+                case 0:         *ep++ = *xMp++;
+                         } while (--i);
+        }
+        while (++Mc < 4) *ep++ = 0;
+
+       /*
+
+       int i, k;
+       for (k = 0; k <= 39; k++) ep[k] = 0;
+       for (i = 0; i <= 12; i++) {
+               ep[ Mc + (3*i) ] = xMp[i];
+       }
+       */
+}
+
+/* 4.2.18 */
+
+/*  This procedure adds the reconstructed long term residual signal
+ *  ep[0..39] to the estimated signal dpp[0..39] from the long term
+ *  analysis filter to compute the reconstructed short term residual
+ *  signal dp[-40..-1]; also the reconstructed short term residual
+ *  array dp[-120..-41] is updated.
+ */
+
+#if 0  /* Has been inlined in code.c */
+void Gsm_Update_of_reconstructed_short_time_residual_signal (
+       word    * dpp,          /* [0...39]     IN      */
+       word    * ep,           /* [0...39]     IN      */
+       word    * dp)           /* [-120...-1]  IN/OUT  */
+{
+       int             k;
+
+       for (k = 0; k <= 79; k++) 
+               dp[ -120 + k ] = dp[ -80 + k ];
+
+       for (k = 0; k <= 39; k++)
+               dp[ -40 + k ] = gsm_add( ep[k], dpp[k] );
+}
+#endif /* Has been inlined in code.c */
+
+void Gsm_RPE_Encoding (
+       /*-struct gsm_state * S,-*/
+
+       word    * e,            /* -5..-1][0..39][40..44        IN/OUT  */
+       word    * xmaxc,        /*                              OUT */
+       word    * Mc,           /*                              OUT */
+       word    * xMc)          /* [0..12]                      OUT */
+{
+       word    x[40];
+       word    xM[13], xMp[13];
+       word    mant, expon;
+
+       Weighting_filter(e, x);
+       RPE_grid_selection(x, xM, Mc);
+
+       APCM_quantization(      xM, xMc, &mant, &expon, xmaxc);
+       APCM_inverse_quantization(  xMc,  mant,  expon, xMp);
+
+       RPE_grid_positioning( *Mc, xMp, e );
+
+}
+
+void Gsm_RPE_Decoding (
+       /*-struct gsm_state     * S,-*/
+
+       word            xmaxcr,
+       word            Mcr,
+       word            * xMcr,  /* [0..12], 3 bits             IN      */
+       word            * erp    /* [0..39]                     OUT     */
+)
+{
+       word    expon, mant;
+       word    xMp[ 13 ];
+
+       APCM_quantization_xmaxc_to_exp_mant( xmaxcr, &expon, &mant );
+       APCM_inverse_quantization( xMcr, mant, expon, xMp );
+       RPE_grid_positioning( Mcr, xMp, erp );
+
+}
+/*
+** Do not edit or modify anything in this comment block.
+** The arch-tag line is a file identity tag for the GNU Arch 
+** revision control system.
+**
+** arch-tag: 82005b9e-1560-4e94-9ddb-00cb14867295
+*/
+
diff --git a/libs/libsndfile/src/GSM610/short_term.c b/libs/libsndfile/src/GSM610/short_term.c
new file mode 100644 (file)
index 0000000..0174b05
--- /dev/null
@@ -0,0 +1,427 @@
+/*
+ * Copyright 1992 by Jutta Degener and Carsten Bormann, Technische
+ * Universitaet Berlin.  See the accompanying file "COPYRIGHT" for
+ * details.  THERE IS ABSOLUTELY NO WARRANTY FOR THIS SOFTWARE.
+ */
+
+#include <stdio.h>
+#include <assert.h>
+
+#include "gsm610_priv.h"
+
+#include "gsm.h"
+
+/*
+ *  SHORT TERM ANALYSIS FILTERING SECTION
+ */
+
+/* 4.2.8 */
+
+static void Decoding_of_the_coded_Log_Area_Ratios (
+       word    * LARc,         /* coded log area ratio [0..7]  IN      */
+       word    * LARpp)        /* out: decoded ..                      */
+{
+       register word   temp1 /* , temp2 */;
+
+       /*  This procedure requires for efficient implementation
+        *  two tables.
+        *
+        *  INVA[1..8] = integer( (32768 * 8) / real_A[1..8])
+        *  MIC[1..8]  = minimum value of the LARc[1..8]
+        */
+
+       /*  Compute the LARpp[1..8]
+        */
+
+       /*      for (i = 1; i <= 8; i++, B++, MIC++, INVA++, LARc++, LARpp++) {
+        *
+        *              temp1  = GSM_ADD( *LARc, *MIC ) << 10;
+        *              temp2  = *B << 1;
+        *              temp1  = GSM_SUB( temp1, temp2 );
+        *
+        *              assert(*INVA != MIN_WORD);
+        *
+        *              temp1  = GSM_MULT_R( *INVA, temp1 );
+        *              *LARpp = GSM_ADD( temp1, temp1 );
+        *      }
+        */
+
+#undef STEP
+#define        STEP( B, MIC, INVA )    \
+               temp1    = GSM_ADD( *LARc++, MIC ) << 10;       \
+               temp1    = GSM_SUB( temp1, B << 1 );            \
+               temp1    = GSM_MULT_R( INVA, temp1 );           \
+               *LARpp++ = GSM_ADD( temp1, temp1 );
+
+       STEP(      0,  -32,  13107 );
+       STEP(      0,  -32,  13107 );
+       STEP(   2048,  -16,  13107 );
+       STEP(  -2560,  -16,  13107 );
+
+       STEP(     94,   -8,  19223 );
+       STEP(  -1792,   -8,  17476 );
+       STEP(   -341,   -4,  31454 );
+       STEP(  -1144,   -4,  29708 );
+
+       /* NOTE: the addition of *MIC is used to restore
+        *       the sign of *LARc.
+        */
+}
+
+/* 4.2.9 */
+/* Computation of the quantized reflection coefficients 
+ */
+
+/* 4.2.9.1  Interpolation of the LARpp[1..8] to get the LARp[1..8]
+ */
+
+/*
+ *  Within each frame of 160 analyzed speech samples the short term
+ *  analysis and synthesis filters operate with four different sets of
+ *  coefficients, derived from the previous set of decoded LARs(LARpp(j-1))
+ *  and the actual set of decoded LARs (LARpp(j))
+ *
+ * (Initial value: LARpp(j-1)[1..8] = 0.)
+ */
+
+static void Coefficients_0_12 (
+       register word * LARpp_j_1,
+       register word * LARpp_j,
+       register word * LARp)
+{
+       register int    i;
+
+       for (i = 1; i <= 8; i++, LARp++, LARpp_j_1++, LARpp_j++) {
+               *LARp = GSM_ADD( SASR_W( *LARpp_j_1, 2 ), SASR_W( *LARpp_j, 2 ));
+               *LARp = GSM_ADD( *LARp,  SASR_W( *LARpp_j_1, 1));
+       }
+}
+
+static void Coefficients_13_26 (
+       register word * LARpp_j_1,
+       register word * LARpp_j,
+       register word * LARp)
+{
+       register int i;
+       for (i = 1; i <= 8; i++, LARpp_j_1++, LARpp_j++, LARp++) {
+               *LARp = GSM_ADD( SASR_W( *LARpp_j_1, 1), SASR_W( *LARpp_j, 1 ));
+       }
+}
+
+static void Coefficients_27_39 (
+       register word * LARpp_j_1,
+       register word * LARpp_j,
+       register word * LARp)
+{
+       register int i;
+
+       for (i = 1; i <= 8; i++, LARpp_j_1++, LARpp_j++, LARp++) {
+               *LARp = GSM_ADD( SASR_W( *LARpp_j_1, 2 ), SASR_W( *LARpp_j, 2 ));
+               *LARp = GSM_ADD( *LARp, SASR_W( *LARpp_j, 1 ));
+       }
+}
+
+
+static void Coefficients_40_159 (
+       register word * LARpp_j,
+       register word * LARp)
+{
+       register int i;
+
+       for (i = 1; i <= 8; i++, LARp++, LARpp_j++)
+               *LARp = *LARpp_j;
+}
+
+/* 4.2.9.2 */
+
+static void LARp_to_rp (
+       register word * LARp)   /* [0..7] IN/OUT  */
+/*
+ *  The input of this procedure is the interpolated LARp[0..7] array.
+ *  The reflection coefficients, rp[i], are used in the analysis
+ *  filter and in the synthesis filter.
+ */
+{
+       register int            i;
+       register word           temp;
+
+       for (i = 1; i <= 8; i++, LARp++) {
+
+               /* temp = GSM_ABS( *LARp );
+                *
+                * if (temp < 11059) temp <<= 1;
+                * else if (temp < 20070) temp += 11059;
+                * else temp = GSM_ADD( temp >> 2, 26112 );
+                *
+                * *LARp = *LARp < 0 ? -temp : temp;
+                */
+
+               if (*LARp < 0) {
+                       temp = *LARp == MIN_WORD ? MAX_WORD : -(*LARp);
+                       *LARp = - ((temp < 11059) ? temp << 1
+                               : ((temp < 20070) ? temp + 11059
+                               :  GSM_ADD( (word) (temp >> 2), (word) 26112 )));
+               } else {
+                       temp  = *LARp;
+                       *LARp =    (temp < 11059) ? temp << 1
+                               : ((temp < 20070) ? temp + 11059
+                               :  GSM_ADD( (word) (temp >> 2), (word) 26112 ));
+               }
+       }
+}
+
+
+/* 4.2.10 */
+static void Short_term_analysis_filtering (
+       struct gsm_state * S,
+       register word   * rp,   /* [0..7]       IN      */
+       register int    k_n,    /*   k_end - k_start    */
+       register word   * s     /* [0..n-1]     IN/OUT  */
+)
+/*
+ *  This procedure computes the short term residual signal d[..] to be fed
+ *  to the RPE-LTP loop from the s[..] signal and from the local rp[..]
+ *  array (quantized reflection coefficients).  As the call of this
+ *  procedure can be done in many ways (see the interpolation of the LAR
+ *  coefficient), it is assumed that the computation begins with index
+ *  k_start (for arrays d[..] and s[..]) and stops with index k_end
+ *  (k_start and k_end are defined in 4.2.9.1).  This procedure also
+ *  needs to keep the array u[0..7] in memory for each call.
+ */
+{
+       register word           * u = S->u;
+       register int            i;
+       register word           di, zzz, ui, sav, rpi;
+
+       for (; k_n--; s++) {
+
+               di = sav = *s;
+
+               for (i = 0; i < 8; i++) {               /* YYY */
+
+                       ui    = u[i];
+                       rpi   = rp[i];
+                       u[i]  = sav;
+
+                       zzz   = GSM_MULT_R(rpi, di);
+                       sav   = GSM_ADD(   ui,  zzz);
+
+                       zzz   = GSM_MULT_R(rpi, ui);
+                       di    = GSM_ADD(   di,  zzz );
+               }
+
+               *s = di;
+       }
+}
+
+#if defined(USE_FLOAT_MUL) && defined(FAST)
+
+static void Fast_Short_term_analysis_filtering (
+       struct gsm_state * S,
+       register word   * rp,   /* [0..7]       IN      */
+       register int    k_n,    /*   k_end - k_start    */
+       register word   * s     /* [0..n-1]     IN/OUT  */
+)
+{
+       register word           * u = S->u;
+       register int            i;
+
+       float     uf[8],
+                rpf[8];
+
+       register float scalef = 3.0517578125e-5;
+       register float          sav, di, temp;
+
+       for (i = 0; i < 8; ++i) {
+               uf[i]  = u[i];
+               rpf[i] = rp[i] * scalef;
+       }
+       for (; k_n--; s++) {
+               sav = di = *s;
+               for (i = 0; i < 8; ++i) {
+                       register float rpfi = rpf[i];
+                       register float ufi  = uf[i];
+
+                       uf[i] = sav;
+                       temp  = rpfi * di + ufi;
+                       di   += rpfi * ufi;
+                       sav   = temp;
+               }
+               *s = di;
+       }
+       for (i = 0; i < 8; ++i) u[i] = uf[i];
+}
+#endif /* ! (defined (USE_FLOAT_MUL) && defined (FAST)) */
+
+static void Short_term_synthesis_filtering (
+       struct gsm_state * S,
+       register word   * rrp,  /* [0..7]       IN      */
+       register int    k,      /* k_end - k_start      */
+       register word   * wt,   /* [0..k-1]     IN      */
+       register word   * sr    /* [0..k-1]     OUT     */
+)
+{
+       register word           * v = S->v;
+       register int            i;
+       register word           sri, tmp1, tmp2;
+
+       while (k--) {
+               sri = *wt++;
+               for (i = 8; i--;) {
+
+                       /* sri = GSM_SUB( sri, gsm_mult_r( rrp[i], v[i] ) );
+                        */
+                       tmp1 = rrp[i];
+                       tmp2 = v[i];
+                       tmp2 =  ( tmp1 == MIN_WORD && tmp2 == MIN_WORD
+                               ? MAX_WORD
+                               : 0x0FFFF & (( (longword)tmp1 * (longword)tmp2
+                                            + 16384) >> 15)) ;
+
+                       sri  = GSM_SUB( sri, tmp2 );
+
+                       /* v[i+1] = GSM_ADD( v[i], gsm_mult_r( rrp[i], sri ) );
+                        */
+                       tmp1  = ( tmp1 == MIN_WORD && sri == MIN_WORD
+                               ? MAX_WORD
+                               : 0x0FFFF & (( (longword)tmp1 * (longword)sri
+                                            + 16384) >> 15)) ;
+
+                       v[i+1] = GSM_ADD( v[i], tmp1);
+               }
+               *sr++ = v[0] = sri;
+       }
+}
+
+
+#if defined(FAST) && defined(USE_FLOAT_MUL)
+
+static void Fast_Short_term_synthesis_filtering (
+       struct gsm_state * S,
+       register word   * rrp,  /* [0..7]       IN      */
+       register int    k,      /* k_end - k_start      */
+       register word   * wt,   /* [0..k-1]     IN      */
+       register word   * sr    /* [0..k-1]     OUT     */
+)
+{
+       register word           * v = S->v;
+       register int            i;
+
+       float va[9], rrpa[8];
+       register float scalef = 3.0517578125e-5, temp;
+
+       for (i = 0; i < 8; ++i) {
+               va[i]   = v[i];
+               rrpa[i] = (float)rrp[i] * scalef;
+       }
+       while (k--) {
+               register float sri = *wt++;
+               for (i = 8; i--;) {
+                       sri -= rrpa[i] * va[i];
+                       if     (sri < -32768.) sri = -32768.;
+                       else if (sri > 32767.) sri =  32767.;
+
+                       temp = va[i] + rrpa[i] * sri;
+                       if     (temp < -32768.) temp = -32768.;
+                       else if (temp > 32767.) temp =  32767.;
+                       va[i+1] = temp;
+               }
+               *sr++ = va[0] = sri;
+       }
+       for (i = 0; i < 9; ++i) v[i] = va[i];
+}
+
+#endif /* defined(FAST) && defined(USE_FLOAT_MUL) */
+
+void Gsm_Short_Term_Analysis_Filter (
+
+       struct gsm_state * S,
+
+       word    * LARc,         /* coded log area ratio [0..7]  IN      */
+       word    * s             /* signal [0..159]              IN/OUT  */
+)
+{
+       word            * LARpp_j       = S->LARpp[ S->j      ];
+       word            * LARpp_j_1     = S->LARpp[ S->j ^= 1 ];
+
+       word            LARp[8];
+
+#undef FILTER
+#if    defined(FAST) && defined(USE_FLOAT_MUL)
+#      define  FILTER  (* (S->fast                     \
+                          ? Fast_Short_term_analysis_filtering \
+                          : Short_term_analysis_filtering      ))
+
+#else
+#      define  FILTER  Short_term_analysis_filtering
+#endif
+
+       Decoding_of_the_coded_Log_Area_Ratios( LARc, LARpp_j );
+
+       Coefficients_0_12(  LARpp_j_1, LARpp_j, LARp );
+       LARp_to_rp( LARp );
+       FILTER( S, LARp, 13, s);
+
+       Coefficients_13_26( LARpp_j_1, LARpp_j, LARp);
+       LARp_to_rp( LARp );
+       FILTER( S, LARp, 14, s + 13);
+
+       Coefficients_27_39( LARpp_j_1, LARpp_j, LARp);
+       LARp_to_rp( LARp );
+       FILTER( S, LARp, 13, s + 27);
+
+       Coefficients_40_159( LARpp_j, LARp);
+       LARp_to_rp( LARp );
+       FILTER( S, LARp, 120, s + 40);
+}
+
+void Gsm_Short_Term_Synthesis_Filter (
+       struct gsm_state * S,
+
+       word    * LARcr,        /* received log area ratios [0..7] IN  */
+       word    * wt,           /* received d [0..159]             IN  */
+
+       word    * s             /* signal   s [0..159]            OUT  */
+)
+{
+       word            * LARpp_j       = S->LARpp[ S->j     ];
+       word            * LARpp_j_1     = S->LARpp[ S->j ^=1 ];
+
+       word            LARp[8];
+
+#undef FILTER
+#if    defined(FAST) && defined(USE_FLOAT_MUL)
+
+#      define  FILTER  (* (S->fast                     \
+                          ? Fast_Short_term_synthesis_filtering        \
+                          : Short_term_synthesis_filtering     ))
+#else
+#      define  FILTER  Short_term_synthesis_filtering
+#endif
+
+       Decoding_of_the_coded_Log_Area_Ratios( LARcr, LARpp_j );
+
+       Coefficients_0_12( LARpp_j_1, LARpp_j, LARp );
+       LARp_to_rp( LARp );
+       FILTER( S, LARp, 13, wt, s );
+
+       Coefficients_13_26( LARpp_j_1, LARpp_j, LARp);
+       LARp_to_rp( LARp );
+       FILTER( S, LARp, 14, wt + 13, s + 13 );
+
+       Coefficients_27_39( LARpp_j_1, LARpp_j, LARp);
+       LARp_to_rp( LARp );
+       FILTER( S, LARp, 13, wt + 27, s + 27 );
+
+       Coefficients_40_159( LARpp_j, LARp );
+       LARp_to_rp( LARp );
+       FILTER(S, LARp, 120, wt + 40, s + 40);
+}
+/*
+** Do not edit or modify anything in this comment block.
+** The arch-tag line is a file identity tag for the GNU Arch 
+** revision control system.
+**
+** arch-tag: 019ac7ba-c6dd-4540-abf0-8644b6c4a633
+*/
+
diff --git a/libs/libsndfile/src/GSM610/table.c b/libs/libsndfile/src/GSM610/table.c
new file mode 100644 (file)
index 0000000..b5aa881
--- /dev/null
@@ -0,0 +1,69 @@
+/*
+ * Copyright 1992 by Jutta Degener and Carsten Bormann, Technische
+ * Universitaet Berlin.  See the accompanying file "COPYRIGHT" for
+ * details.  THERE IS ABSOLUTELY NO WARRANTY FOR THIS SOFTWARE.
+ */
+
+/*  Most of these tables are inlined at their point of use.
+ */
+
+/*  4.4 TABLES USED IN THE FIXED POINT IMPLEMENTATION OF THE RPE-LTP
+ *      CODER AND DECODER
+ *
+ *     (Most of them inlined, so watch out.)
+ */
+
+#define        GSM_TABLE_C
+#include "gsm610_priv.h"
+#include       "gsm.h"
+
+/*  Table 4.1  Quantization of the Log.-Area Ratios
+ */
+/* i                1      2      3        4      5      6        7       8 */
+word gsm_A[8]   = {20480, 20480, 20480,  20480,  13964,  15360,   8534,  9036};
+word gsm_B[8]   = {    0,     0,  2048,  -2560,     94,  -1792,   -341, -1144};
+word gsm_MIC[8] = { -32,   -32,   -16,    -16,     -8,     -8,     -4,    -4 };
+word gsm_MAC[8] = {  31,    31,    15,     15,      7,      7,      3,     3 };
+
+
+/*  Table 4.2  Tabulation  of 1/A[1..8]
+ */
+word gsm_INVA[8]={ 13107, 13107,  13107, 13107,  19223, 17476,  31454, 29708 };
+
+
+/*   Table 4.3a  Decision level of the LTP gain quantizer
+ */
+/*  bc               0         1         2          3                  */
+word gsm_DLB[4] = {  6554,    16384,   26214,     32767        };
+
+
+/*   Table 4.3b   Quantization levels of the LTP gain quantizer
+ */
+/* bc                0          1        2          3                  */
+word gsm_QLB[4] = {  3277,    11469,   21299,     32767        };
+
+
+/*   Table 4.4  Coefficients of the weighting filter
+ */
+/* i               0      1   2    3   4      5      6     7   8   9    10  */
+word gsm_H[11] = {-134, -374, 0, 2054, 5741, 8192, 5741, 2054, 0, -374, -134 };
+
+
+/*   Table 4.5          Normalized inverse mantissa used to compute xM/xmax 
+ */
+/* i                   0        1    2      3      4      5     6      7   */
+word gsm_NRFAC[8] = { 29128, 26215, 23832, 21846, 20165, 18725, 17476, 16384 };
+
+
+/*   Table 4.6  Normalized direct mantissa used to compute xM/xmax
+ */
+/* i                  0      1       2      3      4      5      6      7   */
+word gsm_FAC[8]        = { 18431, 20479, 22527, 24575, 26623, 28671, 30719, 32767 };
+/*
+** Do not edit or modify anything in this comment block.
+** The arch-tag line is a file identity tag for the GNU Arch 
+** revision control system.
+**
+** arch-tag: 8957c531-e6b0-4097-9202-da7ca42729ca
+*/
+
diff --git a/libs/libsndfile/src/Symbols.darwin b/libs/libsndfile/src/Symbols.darwin
new file mode 100644 (file)
index 0000000..271e0b0
--- /dev/null
@@ -0,0 +1,36 @@
+# Auto-generated by create_symbols_file.py
+
+_sf_command
+_sf_open
+_sf_close
+_sf_seek
+_sf_error
+_sf_perror
+_sf_error_str
+_sf_error_number
+_sf_format_check
+_sf_read_raw
+_sf_readf_short
+_sf_readf_int
+_sf_readf_float
+_sf_readf_double
+_sf_read_short
+_sf_read_int
+_sf_read_float
+_sf_read_double
+_sf_write_raw
+_sf_writef_short
+_sf_writef_int
+_sf_writef_float
+_sf_writef_double
+_sf_write_short
+_sf_write_int
+_sf_write_float
+_sf_write_double
+_sf_strerror
+_sf_get_string
+_sf_set_string
+_sf_open_fd
+_sf_open_virtual
+_sf_write_sync
+
diff --git a/libs/libsndfile/src/Symbols.linux b/libs/libsndfile/src/Symbols.linux
new file mode 100644 (file)
index 0000000..163346f
--- /dev/null
@@ -0,0 +1,42 @@
+# Auto-generated by create_symbols_file.py
+
+libsndfile.so.1.0
+{
+  global:
+    sf_command ;
+    sf_open ;
+    sf_close ;
+    sf_seek ;
+    sf_error ;
+    sf_perror ;
+    sf_error_str ;
+    sf_error_number ;
+    sf_format_check ;
+    sf_read_raw ;
+    sf_readf_short ;
+    sf_readf_int ;
+    sf_readf_float ;
+    sf_readf_double ;
+    sf_read_short ;
+    sf_read_int ;
+    sf_read_float ;
+    sf_read_double ;
+    sf_write_raw ;
+    sf_writef_short ;
+    sf_writef_int ;
+    sf_writef_float ;
+    sf_writef_double ;
+    sf_write_short ;
+    sf_write_int ;
+    sf_write_float ;
+    sf_write_double ;
+    sf_strerror ;
+    sf_get_string ;
+    sf_set_string ;
+    sf_open_fd ;
+    sf_open_virtual ;
+    sf_write_sync ;
+  local:
+    * ;
+} ;
+
diff --git a/libs/libsndfile/src/aiff.c b/libs/libsndfile/src/aiff.c
new file mode 100644 (file)
index 0000000..129d79c
--- /dev/null
@@ -0,0 +1,1482 @@
+/*
+** Copyright (C) 1999-2006 Erik de Castro Lopo <erikd@mega-nerd.com>
+** Copyright (C) 2005 David Viens <davidv@plogue.com>
+**
+** This program is free software; you can redistribute it and/or modify
+** it under the terms of the GNU Lesser General Public License as published by
+** the Free Software Foundation; either version 2.1 of the License, or
+** (at your option) any later version.
+**
+** This program is distributed in the hope that it will be useful,
+** but WITHOUT ANY WARRANTY; without even the implied warranty of
+** MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+** GNU Lesser General Public License for more details.
+**
+** You should have received a copy of the GNU Lesser General Public License
+** along with this program; if not, write to the Free Software
+** Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA.
+*/
+
+#include "sfconfig.h"
+
+#include <stdio.h>
+#include <stdlib.h>
+#include <string.h>
+#include <time.h>
+#include <ctype.h>
+
+#include "sndfile.h"
+#include "sfendian.h"
+#include "common.h"
+
+/*------------------------------------------------------------------------------
+ * Macros to handle big/little endian issues.
+ */
+
+#define FORM_MARKER            (MAKE_MARKER ('F', 'O', 'R', 'M'))
+#define AIFF_MARKER            (MAKE_MARKER ('A', 'I', 'F', 'F'))
+#define AIFC_MARKER            (MAKE_MARKER ('A', 'I', 'F', 'C'))
+#define COMM_MARKER            (MAKE_MARKER ('C', 'O', 'M', 'M'))
+#define SSND_MARKER            (MAKE_MARKER ('S', 'S', 'N', 'D'))
+#define MARK_MARKER            (MAKE_MARKER ('M', 'A', 'R', 'K'))
+#define INST_MARKER            (MAKE_MARKER ('I', 'N', 'S', 'T'))
+#define APPL_MARKER            (MAKE_MARKER ('A', 'P', 'P', 'L'))
+
+#define c_MARKER               (MAKE_MARKER ('(', 'c', ')', ' '))
+#define NAME_MARKER            (MAKE_MARKER ('N', 'A', 'M', 'E'))
+#define AUTH_MARKER            (MAKE_MARKER ('A', 'U', 'T', 'H'))
+#define ANNO_MARKER            (MAKE_MARKER ('A', 'N', 'N', 'O'))
+#define COMT_MARKER            (MAKE_MARKER ('C', 'O', 'M', 'T'))
+#define FVER_MARKER            (MAKE_MARKER ('F', 'V', 'E', 'R'))
+#define SFX_MARKER             (MAKE_MARKER ('S', 'F', 'X', '!'))
+
+#define PEAK_MARKER            (MAKE_MARKER ('P', 'E', 'A', 'K'))
+#define basc_MARKER            (MAKE_MARKER ('b', 'a', 's', 'c'))
+
+/* Supported AIFC encodings.*/
+#define NONE_MARKER            (MAKE_MARKER ('N', 'O', 'N', 'E'))
+#define sowt_MARKER            (MAKE_MARKER ('s', 'o', 'w', 't'))
+#define twos_MARKER            (MAKE_MARKER ('t', 'w', 'o', 's'))
+#define raw_MARKER             (MAKE_MARKER ('r', 'a', 'w', ' '))
+#define in32_MARKER            (MAKE_MARKER ('i', 'n', '3', '2'))
+#define ni32_MARKER            (MAKE_MARKER ('2', '3', 'n', 'i'))
+
+#define fl32_MARKER            (MAKE_MARKER ('f', 'l', '3', '2'))
+#define FL32_MARKER            (MAKE_MARKER ('F', 'L', '3', '2'))
+#define fl64_MARKER            (MAKE_MARKER ('f', 'l', '6', '4'))
+#define FL64_MARKER            (MAKE_MARKER ('F', 'L', '6', '4'))
+
+#define ulaw_MARKER            (MAKE_MARKER ('u', 'l', 'a', 'w'))
+#define ULAW_MARKER            (MAKE_MARKER ('U', 'L', 'A', 'W'))
+#define alaw_MARKER            (MAKE_MARKER ('a', 'l', 'a', 'w'))
+#define ALAW_MARKER            (MAKE_MARKER ('A', 'L', 'A', 'W'))
+
+#define DWVW_MARKER            (MAKE_MARKER ('D', 'W', 'V', 'W'))
+#define GSM_MARKER             (MAKE_MARKER ('G', 'S', 'M', ' '))
+#define ima4_MARKER            (MAKE_MARKER ('i', 'm', 'a', '4'))
+
+/* Unsupported AIFC encodings.*/
+
+#define MAC3_MARKER            (MAKE_MARKER ('M', 'A', 'C', '3'))
+#define MAC6_MARKER            (MAKE_MARKER ('M', 'A', 'C', '6'))
+#define ADP4_MARKER            (MAKE_MARKER ('A', 'D', 'P', '4'))
+
+/* Predfined chunk sizes. */
+#define SIZEOF_AIFF_COMM               18
+#define SIZEOF_AIFC_COMM_MIN   22
+#define SIZEOF_AIFC_COMM               24
+#define SIZEOF_SSND_CHUNK              8
+#define SIZEOF_INST_CHUNK              20
+
+/* Is it constant? */
+
+/* AIFC/IMA4 defines. */
+#define AIFC_IMA4_BLOCK_LEN                            34
+#define AIFC_IMA4_SAMPLES_PER_BLOCK            64
+
+#define AIFF_PEAK_CHUNK_SIZE(ch)       (2 * sizeof (int) + ch * (sizeof (float) + sizeof (int)))
+
+/*------------------------------------------------------------------------------
+ * Typedefs for file chunks.
+ */
+
+enum
+{      HAVE_FORM               = 0x01,
+       HAVE_AIFF               = 0x02,
+       HAVE_COMM               = 0x04,
+       HAVE_SSND               = 0x08
+} ;
+
+typedef struct
+{      unsigned int    size ;
+       short                   numChannels ;
+       unsigned int    numSampleFrames ;
+       short                   sampleSize ;
+       unsigned char   sampleRate [10] ;
+       unsigned int    encoding ;
+       char                    zero_bytes [2] ;
+} COMM_CHUNK ;
+
+typedef struct
+{      unsigned int    offset ;
+       unsigned int    blocksize ;
+} SSND_CHUNK ;
+
+typedef struct
+{      short                   playMode ;
+       unsigned short  beginLoop ;
+       unsigned short  endLoop ;
+} INST_LOOP ;
+
+typedef struct
+{      char            baseNote ;              /* all notes are MIDI note numbers */
+       char            detune ;                /* cents off, only -50 to +50 are significant */
+       char            lowNote ;
+       char            highNote ;
+       char            lowVelocity ;   /* 1 to 127 */
+       char            highVelocity ;  /* 1 to 127 */
+       short           gain ;                  /* in dB, 0 is normal */
+       INST_LOOP       sustain_loop ;
+       INST_LOOP       release_loop ;
+} INST_CHUNK ;
+
+
+enum
+{      basc_SCALE_MINOR = 1,
+       basc_SCALE_MAJOR,
+       basc_SCALE_NEITHER,
+       basc_SCALE_BOTH
+} ;
+
+enum
+{      basc_TYPE_LOOP = 0,
+       basc_TYPE_ONE_SHOT
+} ;
+
+
+typedef struct
+{      unsigned int    version ;
+       unsigned int    numBeats ;
+       unsigned short  rootNote ;
+       unsigned short  scaleType ;
+       unsigned short  sigNumerator ;
+       unsigned short  sigDenominator ;
+       unsigned short  loopType ;
+} basc_CHUNK ;
+
+typedef struct
+{      unsigned short  markerID ;
+       unsigned int    position ;
+} MARK_ID_POS ;
+
+/*------------------------------------------------------------------------------
+ * Private static functions.
+ */
+
+static int     aiff_close (SF_PRIVATE *psf) ;
+
+static int     tenbytefloat2int (unsigned char *bytes) ;
+static void uint2tenbytefloat (unsigned int num, unsigned char *bytes) ;
+
+static int     aiff_read_comm_chunk (SF_PRIVATE *psf, COMM_CHUNK *comm_fmt) ;
+
+static int     aiff_read_header (SF_PRIVATE *psf, COMM_CHUNK *comm_fmt) ;
+
+static int     aiff_write_header (SF_PRIVATE *psf, int calc_length) ;
+static int     aiff_write_tailer (SF_PRIVATE *psf) ;
+static void    aiff_write_strings (SF_PRIVATE *psf, int location) ;
+
+static int     aiff_command (SF_PRIVATE *psf, int command, void *data, int datasize) ;
+
+static const char *get_loop_mode_str (short mode) ;
+
+static short get_loop_mode (short mode) ;
+
+static int aiff_read_basc_chunk (SF_PRIVATE * psf, int) ;
+
+static unsigned int marker_to_position (const MARK_ID_POS *m, unsigned short n, int marksize) ;
+
+/*------------------------------------------------------------------------------
+** Public function.
+*/
+
+int
+aiff_open (SF_PRIVATE *psf)
+{      COMM_CHUNK comm_fmt ;
+       int error, subformat ;
+
+       memset (&comm_fmt, 0, sizeof (comm_fmt)) ;
+
+       subformat = psf->sf.format & SF_FORMAT_SUBMASK ;
+
+       if (psf->mode == SFM_READ || (psf->mode == SFM_RDWR && psf->filelength > 0))
+       {       if ((error = aiff_read_header (psf, &comm_fmt)))
+                       return error ;
+
+               psf_fseek (psf, psf->dataoffset, SEEK_SET) ;
+               } ;
+
+       if (psf->mode == SFM_WRITE || psf->mode == SFM_RDWR)
+       {       if (psf->is_pipe)
+                       return SFE_NO_PIPE_WRITE ;
+
+               if ((psf->sf.format & SF_FORMAT_TYPEMASK) != SF_FORMAT_AIFF)
+                       return SFE_BAD_OPEN_FORMAT ;
+
+               if (psf->mode == SFM_WRITE && (subformat == SF_FORMAT_FLOAT || subformat == SF_FORMAT_DOUBLE))
+               {       if ((psf->peak_info = peak_info_calloc (psf->sf.channels)) == NULL)
+                               return SFE_MALLOC_FAILED ;
+                       psf->peak_info->peak_loc = SF_PEAK_START ;
+                       } ;
+
+               if (psf->mode != SFM_RDWR || psf->filelength < 40)
+               {       psf->filelength = 0 ;
+                       psf->datalength = 0 ;
+                       psf->dataoffset = 0 ;
+                       psf->sf.frames = 0 ;
+                       } ;
+
+               psf->str_flags = SF_STR_ALLOW_START | SF_STR_ALLOW_END ;
+
+               if ((error = aiff_write_header (psf, SF_FALSE)))
+                       return error ;
+
+               psf->write_header = aiff_write_header ;
+               } ;
+
+       psf->container_close = aiff_close ;
+       psf->command = aiff_command ;
+
+       switch (psf->sf.format & SF_FORMAT_SUBMASK)
+       {       case SF_FORMAT_PCM_U8 :
+                               error = pcm_init (psf) ;
+                               break ;
+
+               case SF_FORMAT_PCM_S8 :
+                               error = pcm_init (psf) ;
+                               break ;
+
+               case SF_FORMAT_PCM_16 :
+               case SF_FORMAT_PCM_24 :
+               case SF_FORMAT_PCM_32 :
+                               error = pcm_init (psf) ;
+                               break ;
+
+               case SF_FORMAT_ULAW :
+                               error = ulaw_init (psf) ;
+                               break ;
+
+               case SF_FORMAT_ALAW :
+                               error = alaw_init (psf) ;
+                               break ;
+
+               /* Lite remove start */
+               case SF_FORMAT_FLOAT :
+                               error = float32_init (psf) ;
+                               break ;
+
+               case SF_FORMAT_DOUBLE :
+                               error = double64_init (psf) ;
+                               break ;
+
+               case SF_FORMAT_DWVW_12 :
+                               error = dwvw_init (psf, 12) ;
+                               break ;
+
+               case SF_FORMAT_DWVW_16 :
+                               error = dwvw_init (psf, 16) ;
+                               break ;
+
+               case SF_FORMAT_DWVW_24 :
+                               error = dwvw_init (psf, 24) ;
+                               break ;
+
+               case SF_FORMAT_DWVW_N :
+                               if (psf->mode != SFM_READ)
+                               {       error = SFE_DWVW_BAD_BITWIDTH ;
+                                       break ;
+                                       } ;
+                               if (comm_fmt.sampleSize >= 8 && comm_fmt.sampleSize < 24)
+                               {       error = dwvw_init (psf, comm_fmt.sampleSize) ;
+                                       psf->sf.frames = comm_fmt.numSampleFrames ;
+                                       break ;
+                                       } ;
+                               psf_log_printf (psf, "AIFC/DWVW : Bad bitwidth %d\n", comm_fmt.sampleSize) ;
+                               error = SFE_DWVW_BAD_BITWIDTH ;
+                               break ;
+
+               case SF_FORMAT_IMA_ADPCM :
+                               /*
+                               **      IMA ADPCM encoded AIFF files always have a block length
+                               **      of 34 which decodes to 64 samples.
+                               */
+                               error = aiff_ima_init (psf, AIFC_IMA4_BLOCK_LEN, AIFC_IMA4_SAMPLES_PER_BLOCK) ;
+                               break ;
+               /* Lite remove end */
+
+               case SF_FORMAT_GSM610 :
+                               error = gsm610_init (psf) ;
+                               break ;
+
+               default : return SFE_UNIMPLEMENTED ;
+               } ;
+
+
+       return error ;
+} /* aiff_open */
+
+/*==========================================================================================
+** Private functions.
+*/
+
+/* This function ought to check size */
+static unsigned int
+marker_to_position (const MARK_ID_POS *m, unsigned short n, int marksize)
+{      int i ;
+
+    for (i = 0 ; i < marksize ; i++)
+               if (m [i].markerID == n)
+                       return m [i].position ;
+    return 0 ;
+} /* marker_to_position */
+
+static int
+aiff_read_header (SF_PRIVATE *psf, COMM_CHUNK *comm_fmt)
+{      SSND_CHUNK      ssnd_fmt ;
+       MARK_ID_POS *markstr = NULL ;
+       unsigned        marker, dword, FORMsize, SSNDsize, bytesread ;
+       int                     k, found_chunk = 0, done = 0, error = 0 ;
+       char            *cptr, byte ;
+       int                     instr_found = 0, mark_found = 0, mark_count = 0 ;
+
+       /* Set position to start of file to begin reading header. */
+       psf_binheader_readf (psf, "p", 0) ;
+
+       memset (comm_fmt, 0, sizeof (COMM_CHUNK)) ;
+
+       /* Until recently AIF* file were all BIG endian. */
+       psf->endian = SF_ENDIAN_BIG ;
+
+       /*      AIFF files can apparently have their chunks in any order. However, they
+       **      must have a FORM chunk. Approach here is to read all the chunks one by
+       **      one and then check for the mandatory chunks at the end.
+       */
+       while (! done)
+       {       psf_binheader_readf (psf, "m", &marker) ;
+
+               if (psf->mode == SFM_RDWR && (found_chunk & HAVE_SSND))
+                       return SFE_AIFF_RW_SSND_NOT_LAST ;
+
+               switch (marker)
+               {       case FORM_MARKER :
+                                       if (found_chunk)
+                                               return SFE_AIFF_NO_FORM ;
+
+                                       psf_binheader_readf (psf, "E4", &FORMsize) ;
+
+                                       if (psf->fileoffset > 0 && psf->filelength > FORMsize + 8)
+                                       {       /* Set file length. */
+                                               psf->filelength = FORMsize + 8 ;
+                                               psf_log_printf (psf, "FORM : %u\n", FORMsize) ;
+                                               }
+                                       else if (FORMsize != psf->filelength - 2 * SIGNED_SIZEOF (dword))
+                                       {       dword = psf->filelength - 2 * sizeof (dword) ;
+                                               psf_log_printf (psf, "FORM : %u (should be %u)\n", FORMsize, dword) ;
+                                               FORMsize = dword ;
+                                               }
+                                       else
+                                               psf_log_printf (psf, "FORM : %u\n", FORMsize) ;
+                                       found_chunk |= HAVE_FORM ;
+                                       break ;
+
+                       case AIFC_MARKER :
+                       case AIFF_MARKER :
+                                       if ((found_chunk & HAVE_FORM) == 0)
+                                               return SFE_AIFF_AIFF_NO_FORM ;
+                                       psf_log_printf (psf, " %M\n", marker) ;
+                                       found_chunk |= HAVE_AIFF ;
+                                       break ;
+
+                       case COMM_MARKER :
+                                       error = aiff_read_comm_chunk (psf, comm_fmt) ;
+
+                                       psf->sf.samplerate = tenbytefloat2int (comm_fmt->sampleRate) ;
+                                       psf->sf.frames = comm_fmt->numSampleFrames ;
+                                       psf->sf.channels = comm_fmt->numChannels ;
+                                       psf->bytewidth = BITWIDTH2BYTES (comm_fmt->sampleSize) ;
+
+                                       if (error)
+                                               return error ;
+
+                                       found_chunk |= HAVE_COMM ;
+                                       break ;
+
+                       case PEAK_MARKER :
+                                       /* Must have COMM chunk before PEAK chunk. */
+                                       if ((found_chunk & (HAVE_FORM | HAVE_AIFF | HAVE_COMM)) != (HAVE_FORM | HAVE_AIFF | HAVE_COMM))
+                                               return SFE_AIFF_PEAK_B4_COMM ;
+
+                                       psf_binheader_readf (psf, "E4", &dword) ;
+
+                                       psf_log_printf (psf, "%M : %d\n", marker, dword) ;
+                                       if (dword != AIFF_PEAK_CHUNK_SIZE (psf->sf.channels))
+                                       {       psf_binheader_readf (psf, "j", dword) ;
+                                               psf_log_printf (psf, "*** File PEAK chunk too big.\n") ;
+                                               return SFE_WAV_BAD_PEAK ;
+                                               } ;
+
+                                       if ((psf->peak_info = peak_info_calloc (psf->sf.channels)) == NULL)
+                                               return SFE_MALLOC_FAILED ;
+
+                                       /* read in rest of PEAK chunk. */
+                                       psf_binheader_readf (psf, "E44", &(psf->peak_info->version), &(psf->peak_info->timestamp)) ;
+
+                                       if (psf->peak_info->version != 1)
+                                               psf_log_printf (psf, "  version    : %d *** (should be version 1)\n", psf->peak_info->version) ;
+                                       else
+                                               psf_log_printf (psf, "  version    : %d\n", psf->peak_info->version) ;
+
+                                       psf_log_printf (psf, "  time stamp : %d\n", psf->peak_info->timestamp) ;
+                                       psf_log_printf (psf, "    Ch   Position       Value\n") ;
+
+                                       cptr = psf->u.cbuf ;
+                                       for (dword = 0 ; dword < (unsigned) psf->sf.channels ; dword++)
+                                       {       float value ;
+                                               unsigned int position ;
+
+                                               psf_binheader_readf (psf, "Ef4", &value, &position) ;
+                                               psf->peak_info->peaks [dword].value = value ;
+                                               psf->peak_info->peaks [dword].position = position ;
+
+                                               LSF_SNPRINTF (cptr, sizeof (psf->u.scbuf), "    %2d   %-12ld   %g\n",
+                                                               dword, (long) psf->peak_info->peaks [dword].position, psf->peak_info->peaks [dword].value) ;
+                                               cptr [sizeof (psf->u.scbuf) - 1] = 0 ;
+                                               psf_log_printf (psf, cptr) ;
+                                               } ;
+
+                                       break ;
+
+                       case SSND_MARKER :
+                                       psf_binheader_readf (psf, "E444", &SSNDsize, &(ssnd_fmt.offset), &(ssnd_fmt.blocksize)) ;
+
+                                       psf->datalength = SSNDsize - sizeof (ssnd_fmt) ;
+                                       psf->dataoffset = psf_ftell (psf) ;
+
+                                       if (psf->datalength > psf->filelength - psf->dataoffset || psf->datalength < 0)
+                                       {       psf_log_printf (psf, " SSND : %u (should be %D)\n", SSNDsize, psf->filelength - psf->dataoffset + sizeof (SSND_CHUNK)) ;
+                                               psf->datalength = psf->filelength - psf->dataoffset ;
+                                               }
+                                       else
+                                               psf_log_printf (psf, " SSND : %u\n", SSNDsize) ;
+
+                                       /* Only set dataend if there really is data at the end. */
+                                       if (psf->datalength + psf->dataoffset < psf->filelength)
+                                               psf->dataend = psf->datalength + psf->dataoffset ;
+
+                                       psf_log_printf (psf, "  Offset     : %u\n", ssnd_fmt.offset) ;
+                                       psf_log_printf (psf, "  Block Size : %u\n", ssnd_fmt.blocksize) ;
+
+                                       found_chunk |= HAVE_SSND ;
+
+                                       if (! psf->sf.seekable)
+                                               break ;
+
+                                       /*      Seek to end of SSND chunk. */
+                                       psf_fseek (psf, psf->dataoffset + psf->datalength + (SSNDsize & 1), SEEK_SET) ;
+                                       break ;
+
+                       case c_MARKER :
+                                       psf_binheader_readf (psf, "E4", &dword) ;
+                                       if (dword == 0)
+                                               break ;
+                                       if (dword > SIGNED_SIZEOF (psf->u.scbuf) - 1)
+                                       {       psf_log_printf (psf, " %M : %d (too big)\n", marker, dword) ;
+                                               return SFE_INTERNAL ;
+                                               } ;
+
+                                       cptr = psf->u.cbuf ;
+                                       psf_binheader_readf (psf, "b", cptr, dword + (dword & 1)) ;
+                                       cptr [dword] = 0 ;
+                                       psf_log_printf (psf, " %M : %s\n", marker, cptr) ;
+                                       psf_store_string (psf, SF_STR_COPYRIGHT, cptr) ;
+                                       break ;
+
+                       case AUTH_MARKER :
+                                       psf_binheader_readf (psf, "E4", &dword) ;
+                                       if (dword == 0)
+                                               break ;
+                                       if (dword > SIGNED_SIZEOF (psf->u.scbuf) - 1)
+                                       {       psf_log_printf (psf, " %M : %d (too big)\n", marker, dword) ;
+                                               return SFE_INTERNAL ;
+                                               } ;
+
+                                       cptr = psf->u.cbuf ;
+                                       psf_binheader_readf (psf, "b", cptr, dword + (dword & 1)) ;
+                                       cptr [dword] = 0 ;
+                                       psf_log_printf (psf, " %M : %s\n", marker, cptr) ;
+                                       psf_store_string (psf, SF_STR_ARTIST, cptr) ;
+                                       break ;
+
+                       case COMT_MARKER :
+                               {       unsigned short count, id, len ;
+                                       unsigned int timestamp ;
+
+                                       psf_binheader_readf (psf, "E42", &dword, &count) ;
+                                       psf_log_printf (psf, " %M : %d\n  count  : %d\n", marker, dword, count) ;
+                                       dword += (dword & 1) ;
+                                       if (dword == 0)
+                                               break ;
+                                       dword -= 2 ;
+
+                                       for (k = 0 ; k < count ; k++)
+                                       {       dword -= psf_binheader_readf (psf, "E422", &timestamp, &id, &len) ;
+                                               psf_log_printf (psf, "   time   : 0x%x\n   marker : %x\n   length : %d\n", timestamp, id, len) ;
+
+                                               if (len + 1 > SIGNED_SIZEOF (psf->u.scbuf))
+                                               {       psf_log_printf (psf, "\nError : string length (%d) too big.\n", len) ;
+                                                       return SFE_INTERNAL ;
+                                                       } ;
+
+                                               cptr = psf->u.cbuf ;
+                                               dword -= psf_binheader_readf (psf, "b", cptr, len) ;
+                                               cptr [len] = 0 ;
+                                               psf_log_printf (psf, "   string : %s\n", cptr) ;
+                                               } ;
+
+                                       if (dword > 0)
+                                               psf_binheader_readf (psf, "j", dword) ;
+                                       } ;
+                                       break ;
+
+                       case APPL_MARKER :
+                                       psf_binheader_readf (psf, "E4", &dword) ;
+                                       if (dword == 0)
+                                               break ;
+                                       if (dword >= SIGNED_SIZEOF (psf->u.scbuf) - 1)
+                                       {       psf_log_printf (psf, " %M : %d (too big, skipping)\n", marker, dword) ;
+                                               psf_binheader_readf (psf, "j", dword + (dword & 1)) ;
+                                               break ;
+                                               } ;
+
+                                       cptr = psf->u.cbuf ;
+                                       psf_binheader_readf (psf, "b", cptr, dword + (dword & 1)) ;
+                                       cptr [dword] = 0 ;
+
+                                       for (k = 0 ; k < (int) dword ; k++)
+                                               if (! isprint (cptr [k]))
+                                               {       cptr [k] = 0 ;
+                                                       break ;
+                                                       } ;
+
+                                       psf_log_printf (psf, " %M : %s\n", marker, cptr) ;
+                                       psf_store_string (psf, SF_STR_SOFTWARE, cptr) ;
+                                       break ;
+
+                       case NAME_MARKER :
+                                       psf_binheader_readf (psf, "E4", &dword) ;
+                                       if (dword == 0)
+                                               break ;
+                                       if (dword > SIGNED_SIZEOF (psf->u.scbuf) - 2)
+                                       {       psf_log_printf (psf, " %M : %d (too big)\n", marker, dword) ;
+                                               return SFE_INTERNAL ;
+                                               } ;
+
+                                       cptr = psf->u.cbuf ;
+                                       psf_binheader_readf (psf, "b", cptr, dword + (dword & 1)) ;
+                                       cptr [dword] = 0 ;
+                                       psf_log_printf (psf, " %M : %s\n", marker, cptr) ;
+                                       psf_store_string (psf, SF_STR_TITLE, cptr) ;
+                                       break ;
+
+                       case ANNO_MARKER :
+                                       psf_binheader_readf (psf, "E4", &dword) ;
+                                       if (dword == 0)
+                                               break ;
+                                       if (dword > SIGNED_SIZEOF (psf->u.scbuf) - 2)
+                                       {       psf_log_printf (psf, " %M : %d (too big)\n", marker, dword) ;
+                                               return SFE_INTERNAL ;
+                                               } ;
+
+                                       cptr = psf->u.cbuf ;
+                                       psf_binheader_readf (psf, "b", cptr, dword + (dword & 1)) ;
+                                       cptr [dword] = 0 ;
+                                       psf_log_printf (psf, " %M : %s\n", marker, cptr) ;
+                                       psf_store_string (psf, SF_STR_COMMENT, cptr) ;
+                                       break ;
+
+                       case INST_MARKER :
+                                       psf_binheader_readf (psf, "E4", &dword) ;
+                                       if (dword != SIZEOF_INST_CHUNK)
+                                       {       psf_log_printf (psf, " %M : %d (should be %d)\n", marker, dword, SIZEOF_INST_CHUNK) ;
+                                               psf_binheader_readf (psf, "j", dword) ;
+                                               break ;
+                                               } ;
+                                       psf_log_printf (psf, " %M : %d\n", marker, dword) ;
+                                       {       unsigned char bytes [6] ;
+                                               short gain ;
+
+                                               if (psf->instrument == NULL && (psf->instrument = psf_instrument_alloc ()) == NULL)
+                                                       return SFE_MALLOC_FAILED ;
+
+                                               psf_binheader_readf (psf, "b", bytes, 6) ;
+                                               psf_log_printf (psf, "  Base Note : %u\n  Detune    : %u\n"
+                                                                                       "  Low  Note : %u\n  High Note : %u\n"
+                                                                                       "  Low  Vel. : %u\n  High Vel. : %u\n",
+                                                                                       bytes [0], bytes [1], bytes [2], bytes [3], bytes [4], bytes [5]) ;
+                                               psf->instrument->basenote = bytes [0] ;
+                                               psf->instrument->detune = bytes [1] ;
+                                               psf->instrument->key_lo = bytes [2] ;
+                                               psf->instrument->key_hi = bytes [3] ;
+                                               psf->instrument->velocity_lo = bytes [4] ;
+                                               psf->instrument->velocity_hi = bytes [5] ;
+                                               psf_binheader_readf (psf, "E2", &gain) ;
+                                               psf->instrument->gain = gain ;
+                                               psf_log_printf (psf, "  Gain (dB) : %d\n", gain) ;
+                                               } ;
+                                       {       short   mode ; /* 0 - no loop, 1 - forward looping, 2 - backward looping */
+                                               const char      *loop_mode ;
+                                               unsigned short begin, end ;
+
+                                               psf_binheader_readf (psf, "E222", &mode, &begin, &end) ;
+                                               loop_mode = get_loop_mode_str (mode) ;
+                                               mode = get_loop_mode (mode) ;
+                                               if (mode == SF_LOOP_NONE)
+                                               {       psf->instrument->loop_count = 0 ;
+                                                       psf->instrument->loops [0].mode = SF_LOOP_NONE ;
+                                                       }
+                                               else
+                                               {       psf->instrument->loop_count = 1 ;
+                                                       psf->instrument->loops [0].mode = SF_LOOP_FORWARD ;
+                                                       psf->instrument->loops [0].start = begin ;
+                                                       psf->instrument->loops [0].end = end ;
+                                                       psf->instrument->loops [0].count = 0 ;
+                                                       } ;
+                                               psf_log_printf (psf, "  Sustain\n   mode  : %d => %s\n   begin : %u\n   end   : %u\n",
+                                                                                       mode, loop_mode, begin, end) ;
+                                               psf_binheader_readf (psf, "E222", &mode, &begin, &end) ;
+                                               loop_mode = get_loop_mode_str (mode) ;
+                                               mode = get_loop_mode (mode) ;
+                                               if (mode == SF_LOOP_NONE)
+                                                       psf->instrument->loops [0].mode = SF_LOOP_NONE ;
+                                               else
+                                               {       psf->instrument->loop_count += 1 ;
+                                                       psf->instrument->loops [1].mode = SF_LOOP_FORWARD ;
+                                                       psf->instrument->loops [1].start = begin ;
+                                                       psf->instrument->loops [1].end = end ;
+                                                       psf->instrument->loops [1].count = 0 ;
+                                                       } ;
+                                               psf_log_printf (psf, "  Release\n   mode  : %d => %s\n   begin : %u\n   end   : %u\n",
+                                                                               mode, loop_mode, begin, end) ;
+                                               } ;
+                                       instr_found++ ;
+                                       break ;
+
+                       case basc_MARKER :
+                                       psf_binheader_readf (psf, "E4", &dword) ;
+                                       psf_log_printf (psf, " basc : %u\n", dword) ;
+
+                                       if ((error = aiff_read_basc_chunk (psf, dword)))
+                                               return error ;
+                                       break ;
+
+                       case MARK_MARKER :
+                                       psf_binheader_readf (psf, "E4", &dword) ;
+                                       psf_log_printf (psf, " %M : %d\n", marker, dword) ;
+                                       {       unsigned short mark_id, n = 0 ;
+                                               unsigned char pstr_len ;
+                                               unsigned int position ;
+
+                                               bytesread = psf_binheader_readf (psf, "E2", &n) ;
+                                               mark_count = n ;
+                                               markstr = calloc (mark_count, sizeof (MARK_ID_POS)) ;
+                                               psf_log_printf (psf, "  Count : %d\n", mark_count) ;
+
+                                               for (n = 0 ; n < mark_count && bytesread < dword ; n++)
+                                               {       bytesread += psf_binheader_readf (psf, "E241", &mark_id, &position, &pstr_len) ;
+                                                       psf_log_printf (psf, "   Mark ID  : %u\n   Position : %u\n", mark_id, position) ;
+
+                                                       pstr_len += (pstr_len & 1) + 1 ; /* fudgy, fudgy, hack, hack */
+
+                                                       bytesread += psf_binheader_readf (psf, "b", psf->u.scbuf, pstr_len) ;
+                                                       psf_log_printf (psf, "   Name     : %s\n", psf->u.scbuf) ;
+
+                                                       markstr [n].markerID = mark_id ;
+                                                       markstr [n].position = position ;
+                                                       /*
+                                                       **      TODO if psf->u.scbuf is equal to
+                                                       **      either Beg_loop, Beg loop or beg loop and spam
+                                                       **      if (psf->instrument == NULL && (psf->instrument = psf_instrument_alloc ()) == NULL)
+                                                       **              return SFE_MALLOC_FAILED ;
+                                                       */
+                                                       } ;
+                                               } ;
+                                       mark_found++ ;
+                                       psf_binheader_readf (psf, "j", dword - bytesread) ;
+                                       break ;
+
+                       case FVER_MARKER :
+                       case SFX_MARKER :
+                                       psf_binheader_readf (psf, "E4", &dword) ;
+                                       psf_log_printf (psf, " %M : %d\n", marker, dword) ;
+
+                                       psf_binheader_readf (psf, "j", dword) ;
+                                       break ;
+
+                       case NONE_MARKER :
+                                       /* Fix for broken AIFC files with incorrect COMM chunk length. */
+                                       psf_binheader_readf (psf, "1", &byte) ;
+                                       dword = byte ;
+                                       psf_binheader_readf (psf, "j", dword) ;
+                                       break ;
+
+                       default :
+                                       if (isprint ((marker >> 24) & 0xFF) && isprint ((marker >> 16) & 0xFF)
+                                               && isprint ((marker >> 8) & 0xFF) && isprint (marker & 0xFF))
+                                       {       psf_binheader_readf (psf, "E4", &dword) ;
+                                               psf_log_printf (psf, " %M : %d (unknown marker)\n", marker, dword) ;
+
+                                               psf_binheader_readf (psf, "j", dword) ;
+                                               break ;
+                                               } ;
+                                       if ((dword = psf_ftell (psf)) & 0x03)
+                                       {       psf_log_printf (psf, "  Unknown chunk marker %X at position %d. Resyncing.\n", marker, dword - 4) ;
+
+                                               psf_binheader_readf (psf, "j", -3) ;
+                                               break ;
+                                               } ;
+                                       psf_log_printf (psf, "*** Unknown chunk marker %X at position %D. Exiting parser.\n", marker, psf_ftell (psf)) ;
+                                       done = 1 ;
+                                       break ;
+                       } ;     /* switch (marker) */
+
+               if ((! psf->sf.seekable) && (found_chunk & HAVE_SSND))
+                       break ;
+
+               if (psf_ftell (psf) >= psf->filelength - (2 * SIGNED_SIZEOF (dword)))
+                       break ;
+               } ; /* while (1) */
+
+       if (instr_found && mark_found)
+       {       int j ;
+
+               for (j = 0 ; j<psf->instrument->loop_count ; j ++)
+               {       if (j < ARRAY_LEN (psf->instrument->loops))
+                       {       psf->instrument->loops [j].start = marker_to_position (markstr, psf->instrument->loops [j].start, mark_count) ;
+                               psf->instrument->loops [j].end = marker_to_position (markstr, psf->instrument->loops [j].end, mark_count) ;
+                               psf->instrument->loops [j].mode = SF_LOOP_FORWARD ;
+                               } ;
+                       } ;
+               } ;
+
+       if (markstr)
+               free (markstr) ;
+
+       if (! (found_chunk & HAVE_FORM))
+               return SFE_AIFF_NO_FORM ;
+
+       if (! (found_chunk & HAVE_AIFF))
+               return SFE_AIFF_COMM_NO_FORM ;
+
+       if (! (found_chunk & HAVE_COMM))
+               return SFE_AIFF_SSND_NO_COMM ;
+
+       if (! psf->dataoffset)
+               return SFE_AIFF_NO_DATA ;
+
+       return 0 ;
+} /* aiff_read_header */
+
+static int
+aiff_close (SF_PRIVATE *psf)
+{
+       if (psf->mode == SFM_WRITE || psf->mode == SFM_RDWR)
+       {       aiff_write_tailer (psf) ;
+
+               aiff_write_header (psf, SF_TRUE) ;
+               } ;
+
+       return 0 ;
+} /* aiff_close */
+
+static int
+aiff_read_comm_chunk (SF_PRIVATE *psf, COMM_CHUNK *comm_fmt)
+{      int error = 0, bytesread, subformat ;
+
+       psf->u.scbuf [0] = 0 ;
+
+       bytesread = psf_binheader_readf (psf, "E4", &(comm_fmt->size)) ;
+
+       /* The COMM chunk has an int aligned to an odd word boundary. Some
+       ** procesors are not able to deal with this (ie bus fault) so we have
+       ** to take special care.
+       */
+       comm_fmt->size += comm_fmt->size & 1 ;
+
+       bytesread +=
+       psf_binheader_readf (psf, "E242b", &(comm_fmt->numChannels), &(comm_fmt->numSampleFrames),
+                       &(comm_fmt->sampleSize), &(comm_fmt->sampleRate), SIGNED_SIZEOF (comm_fmt->sampleRate)) ;
+
+       if (comm_fmt->size == SIZEOF_AIFF_COMM)
+               comm_fmt->encoding = NONE_MARKER ;
+       else if (comm_fmt->size == SIZEOF_AIFC_COMM_MIN)
+               bytesread += psf_binheader_readf (psf, "Em", &(comm_fmt->encoding)) ;
+       else if (comm_fmt->size >= SIZEOF_AIFC_COMM)
+       {       unsigned char encoding_len ;
+
+               bytesread += psf_binheader_readf (psf, "Em1", &(comm_fmt->encoding), &encoding_len) ;
+
+               memset (psf->u.scbuf, 0, comm_fmt->size) ;
+
+               bytesread += psf_binheader_readf (psf, "b", psf->u.scbuf,
+                                                       comm_fmt->size - SIZEOF_AIFC_COMM + 1) ;
+               psf->u.scbuf [encoding_len] = 0 ;
+               } ;
+
+       psf_log_printf (psf, " COMM : %d\n", comm_fmt->size) ;
+       psf_log_printf (psf, "  Sample Rate : %d\n", tenbytefloat2int (comm_fmt->sampleRate)) ;
+       psf_log_printf (psf, "  Frames      : %u%s\n", comm_fmt->numSampleFrames, (comm_fmt->numSampleFrames == 0 && psf->filelength > 100) ? " (Should not be 0)" : "") ;
+       psf_log_printf (psf, "  Channels    : %d\n", comm_fmt->numChannels) ;
+
+       /*      Found some broken 'fl32' files with comm.samplesize == 16. Fix it here. */
+
+       if ((comm_fmt->encoding == fl32_MARKER || comm_fmt->encoding == FL32_MARKER) && comm_fmt->sampleSize != 32)
+       {       psf_log_printf (psf, "  Sample Size : %d (should be 32)\n", comm_fmt->sampleSize) ;
+               comm_fmt->sampleSize = 32 ;
+               }
+       else if ((comm_fmt->encoding == fl64_MARKER || comm_fmt->encoding == FL64_MARKER) && comm_fmt->sampleSize != 64)
+       {       psf_log_printf (psf, "  Sample Size : %d (should be 64)\n", comm_fmt->sampleSize) ;
+               comm_fmt->sampleSize = 64 ;
+               }
+       else
+               psf_log_printf (psf, "  Sample Size : %d\n", comm_fmt->sampleSize) ;
+
+       subformat = s_bitwidth_to_subformat (comm_fmt->sampleSize) ;
+
+       psf->endian = SF_ENDIAN_BIG ;
+
+       switch (comm_fmt->encoding)
+       {       case NONE_MARKER :
+                               psf->sf.format = (SF_FORMAT_AIFF | subformat) ;
+                               break ;
+
+               case twos_MARKER :
+               case in32_MARKER :
+                               psf->sf.format = (SF_ENDIAN_BIG | SF_FORMAT_AIFF | subformat) ;
+                               break ;
+
+               case sowt_MARKER :
+               case ni32_MARKER :
+                               psf->endian = SF_ENDIAN_LITTLE ;
+                               psf->sf.format = (SF_ENDIAN_LITTLE | SF_FORMAT_AIFF | subformat) ;
+                               break ;
+
+               case fl32_MARKER :
+               case FL32_MARKER :
+                               psf->sf.format = (SF_FORMAT_AIFF | SF_FORMAT_FLOAT) ;
+                               break ;
+
+               case ulaw_MARKER :
+               case ULAW_MARKER :
+                               psf->sf.format = (SF_FORMAT_AIFF | SF_FORMAT_ULAW) ;
+                               break ;
+
+               case alaw_MARKER :
+               case ALAW_MARKER :
+                               psf->sf.format = (SF_FORMAT_AIFF | SF_FORMAT_ALAW) ;
+                               break ;
+
+               case fl64_MARKER :
+               case FL64_MARKER :
+                               psf->sf.format = (SF_FORMAT_AIFF | SF_FORMAT_DOUBLE) ;
+                               break ;
+
+               case raw_MARKER :
+                               psf->sf.format = (SF_FORMAT_AIFF | SF_FORMAT_PCM_U8) ;
+                               break ;
+
+               case DWVW_MARKER :
+                               psf->sf.format = SF_FORMAT_AIFF ;
+                               switch (comm_fmt->sampleSize)
+                               {       case 12 :
+                                               psf->sf.format |= SF_FORMAT_DWVW_12 ;
+                                               break ;
+                                       case 16 :
+                                               psf->sf.format |= SF_FORMAT_DWVW_16 ;
+                                               break ;
+                                       case 24 :
+                                               psf->sf.format |= SF_FORMAT_DWVW_24 ;
+                                               break ;
+
+                                       default :
+                                               psf->sf.format |= SF_FORMAT_DWVW_N ;
+                                               break ;
+                                       } ;
+                               break ;
+
+               case GSM_MARKER :
+                               psf->sf.format = SF_FORMAT_AIFF ;
+                               psf->sf.format = (SF_FORMAT_AIFF | SF_FORMAT_GSM610) ;
+                               break ;
+
+
+               case ima4_MARKER :
+                               psf->endian = SF_ENDIAN_BIG ;
+                               psf->sf.format = (SF_FORMAT_AIFF | SF_FORMAT_IMA_ADPCM) ;
+                               break ;
+
+               default :
+                       psf_log_printf (psf, "AIFC : Unimplemented format : %M\n", comm_fmt->encoding) ;
+                       error = SFE_UNIMPLEMENTED ;
+               } ;
+
+       if (! psf->u.scbuf [0])
+               psf_log_printf (psf, "  Encoding    : %M\n", comm_fmt->encoding) ;
+       else
+               psf_log_printf (psf, "  Encoding    : %M => %s\n", comm_fmt->encoding, psf->u.scbuf) ;
+
+       return error ;
+} /* aiff_read_comm_chunk */
+
+
+static int
+aiff_write_header (SF_PRIVATE *psf, int calc_length)
+{      sf_count_t              current ;
+       unsigned char   comm_sample_rate [10], comm_zero_bytes [2] = { 0, 0 } ;
+       unsigned int    comm_type, comm_size, comm_encoding, comm_frames ;
+       int                             k, endian ;
+       short                   bit_width ;
+
+       current = psf_ftell (psf) ;
+
+       if (calc_length)
+       {       psf->filelength = psf_get_filelen (psf) ;
+
+               psf->datalength = psf->filelength - psf->dataoffset ;
+               if (psf->dataend)
+                       psf->datalength -= psf->filelength - psf->dataend ;
+
+               if (psf->bytewidth > 0)
+                       psf->sf.frames = psf->datalength / (psf->bytewidth * psf->sf.channels) ;
+               } ;
+
+       if (psf->mode == SFM_RDWR && psf->dataoffset > 0)
+       {       /* Assuming here that the header has already been written and just
+               ** needs to be corrected for new data length. That means that we
+               ** only change the length fields of the FORM and SSND chunks ;
+               ** everything else can be skipped over.
+               */
+
+               /* First write new FORM chunk. */
+               psf->headindex = 0 ;
+               psf_fseek (psf, 0, SEEK_SET) ;
+
+               psf_binheader_writef (psf, "Etm8", FORM_MARKER, psf->filelength - 8) ;
+               psf_fwrite (psf->header, psf->headindex, 1, psf) ;
+
+               /* Now write frame count field of COMM chunk header. */
+               psf->headindex = 0 ;
+               psf_fseek (psf, 22, SEEK_SET) ;
+
+               psf_binheader_writef (psf, "Et8", psf->sf.frames) ;
+               psf_fwrite (psf->header, psf->headindex, 1, psf) ;
+
+               /* Now write new SSND chunk header. */
+               psf->headindex = 0 ;
+               psf_fseek (psf, psf->dataoffset - 16, SEEK_SET) ;
+
+               psf_binheader_writef (psf, "Etm8", SSND_MARKER, psf->datalength + SIZEOF_SSND_CHUNK) ;
+               psf_fwrite (psf->header, psf->headindex, 1, psf) ;
+
+               if (current < psf->dataoffset)
+                       psf_fseek (psf, psf->dataoffset, SEEK_SET) ;
+               else if (current > 0)
+                       psf_fseek (psf, current, SEEK_SET) ;
+
+               return 0 ;
+               } ;
+
+       endian = psf->sf.format & SF_FORMAT_ENDMASK ;
+       if (CPU_IS_LITTLE_ENDIAN && endian == SF_ENDIAN_CPU)
+               endian = SF_ENDIAN_LITTLE ;
+
+       /* Standard value here. */
+       bit_width = psf->bytewidth * 8 ;
+       comm_frames = (psf->sf.frames > 0xFFFFFFFF) ? 0xFFFFFFFF : psf->sf.frames ;
+
+       switch (psf->sf.format & SF_FORMAT_SUBMASK)
+       {       case SF_FORMAT_PCM_S8 :
+               case SF_FORMAT_PCM_16 :
+               case SF_FORMAT_PCM_24 :
+               case SF_FORMAT_PCM_32 :
+                               switch (endian)
+                               {       case SF_ENDIAN_BIG :
+                                                       psf->endian = SF_ENDIAN_BIG ;
+                                                       comm_type = AIFC_MARKER ;
+                                                       comm_size = SIZEOF_AIFC_COMM ;
+                                                       comm_encoding = twos_MARKER ;
+                                                       break ;
+
+                                       case SF_ENDIAN_LITTLE :
+                                                       psf->endian = SF_ENDIAN_LITTLE ;
+                                                       comm_type = AIFC_MARKER ;
+                                                       comm_size = SIZEOF_AIFC_COMM ;
+                                                       comm_encoding = sowt_MARKER ;
+                                                       break ;
+
+                                       default : /* SF_ENDIAN_FILE */
+                                                       psf->endian = SF_ENDIAN_BIG ;
+                                                       comm_type = AIFF_MARKER ;
+                                                       comm_size = SIZEOF_AIFF_COMM ;
+                                                       comm_encoding = 0 ;
+                                                       break ;
+                                       } ;
+                               break ;
+
+               case SF_FORMAT_FLOAT :                                  /* Big endian floating point. */
+                               psf->endian = SF_ENDIAN_BIG ;
+                               comm_type = AIFC_MARKER ;
+                               comm_size = SIZEOF_AIFC_COMM ;
+                               comm_encoding = FL32_MARKER ;   /* Use 'FL32' because its easier to read. */
+                               break ;
+
+               case SF_FORMAT_DOUBLE :                                 /* Big endian double precision floating point. */
+                               psf->endian = SF_ENDIAN_BIG ;
+                               comm_type = AIFC_MARKER ;
+                               comm_size = SIZEOF_AIFC_COMM ;
+                               comm_encoding = FL64_MARKER ;   /* Use 'FL64' because its easier to read. */
+                               break ;
+
+               case SF_FORMAT_ULAW :
+                               psf->endian = SF_ENDIAN_BIG ;
+                               comm_type = AIFC_MARKER ;
+                               comm_size = SIZEOF_AIFC_COMM ;
+                               comm_encoding = ulaw_MARKER ;
+                               break ;
+
+               case SF_FORMAT_ALAW :
+                               psf->endian = SF_ENDIAN_BIG ;
+                               comm_type = AIFC_MARKER ;
+                               comm_size = SIZEOF_AIFC_COMM ;
+                               comm_encoding = alaw_MARKER ;
+                               break ;
+
+               case SF_FORMAT_PCM_U8 :
+                               psf->endian = SF_ENDIAN_BIG ;
+                               comm_type = AIFC_MARKER ;
+                               comm_size = SIZEOF_AIFC_COMM ;
+                               comm_encoding = raw_MARKER ;
+                               break ;
+
+               case SF_FORMAT_DWVW_12 :
+                               psf->endian = SF_ENDIAN_BIG ;
+                               comm_type = AIFC_MARKER ;
+                               comm_size = SIZEOF_AIFC_COMM ;
+                               comm_encoding = DWVW_MARKER ;
+
+                               /* Override standard value here.*/
+                               bit_width = 12 ;
+                               break ;
+
+               case SF_FORMAT_DWVW_16 :
+                               psf->endian = SF_ENDIAN_BIG ;
+                               comm_type = AIFC_MARKER ;
+                               comm_size = SIZEOF_AIFC_COMM ;
+                               comm_encoding = DWVW_MARKER ;
+
+                               /* Override standard value here.*/
+                               bit_width = 16 ;
+                               break ;
+
+               case SF_FORMAT_DWVW_24 :
+                               psf->endian = SF_ENDIAN_BIG ;
+                               comm_type = AIFC_MARKER ;
+                               comm_size = SIZEOF_AIFC_COMM ;
+                               comm_encoding = DWVW_MARKER ;
+
+                               /* Override standard value here.*/
+                               bit_width = 24 ;
+                               break ;
+
+               case SF_FORMAT_GSM610 :
+                               psf->endian = SF_ENDIAN_BIG ;
+                               comm_type = AIFC_MARKER ;
+                               comm_size = SIZEOF_AIFC_COMM ;
+                               comm_encoding = GSM_MARKER ;
+
+                               /* Override standard value here.*/
+                               bit_width = 16 ;
+                               break ;
+
+               case SF_FORMAT_IMA_ADPCM :
+                               psf->endian = SF_ENDIAN_BIG ;
+                               comm_type = AIFC_MARKER ;
+                               comm_size = SIZEOF_AIFC_COMM ;
+                               comm_encoding = ima4_MARKER ;
+
+                               /* Override standard value here.*/
+                               bit_width = 16 ;
+                               comm_frames = psf->sf.frames / AIFC_IMA4_SAMPLES_PER_BLOCK ;
+                               break ;
+
+               default : return SFE_BAD_OPEN_FORMAT ;
+               } ;
+
+       /* Reset the current header length to zero. */
+       psf->header [0] = 0 ;
+       psf->headindex = 0 ;
+       psf_fseek (psf, 0, SEEK_SET) ;
+
+       psf_binheader_writef (psf, "Etm8", FORM_MARKER, psf->filelength - 8) ;
+
+       /* Write COMM chunk. */
+       psf_binheader_writef (psf, "Emm4", comm_type, COMM_MARKER, comm_size) ;
+
+       memset (comm_sample_rate, 0, sizeof (comm_sample_rate)) ;
+       uint2tenbytefloat (psf->sf.samplerate, comm_sample_rate) ;
+
+       psf_binheader_writef (psf, "Et242", psf->sf.channels, comm_frames, bit_width) ;
+       psf_binheader_writef (psf, "b", comm_sample_rate, sizeof (comm_sample_rate)) ;
+
+       /* AIFC chunks have some extra data. */
+       if (comm_type == AIFC_MARKER)
+               psf_binheader_writef (psf, "mb", comm_encoding, comm_zero_bytes, sizeof (comm_zero_bytes)) ;
+
+       if (psf->instrument != NULL)
+       {       MARK_ID_POS     m [4] ;
+               INST_CHUNK ch ;
+               unsigned short ct = 0 ;
+
+               memset (m, 0, sizeof (m)) ;
+               memset (&ch, 0, sizeof (ch)) ;
+
+               ch.baseNote = psf->instrument->basenote ;
+               ch.detune = psf->instrument->detune ;
+               ch.lowNote = psf->instrument->key_lo ;
+               ch.highNote = psf->instrument->key_hi ;
+               ch.lowVelocity = psf->instrument->velocity_lo ;
+               ch.highVelocity = psf->instrument->velocity_hi ;
+               ch.gain = psf->instrument->gain ;
+               if (psf->instrument->loops [0].mode != SF_LOOP_NONE)
+               {       ch.sustain_loop.playMode = 1 ;
+                       ch.sustain_loop.beginLoop = ct ;
+                       m [0].markerID = ct++ ;
+                       m [0].position = psf->instrument->loops [0].start ;
+                       ch.sustain_loop.endLoop = ct ;
+                       m [1].markerID = ct++ ;
+                       m [1].position = psf->instrument->loops [0].end ;
+                       } ;
+               if (psf->instrument->loops [1].mode != SF_LOOP_NONE)
+               {       ch.release_loop.playMode = 1 ;
+                       ch.release_loop.beginLoop = ct ;
+                       m [2].markerID = ct++ ;
+                       m [2].position = psf->instrument->loops [1].start ;
+                       ch.release_loop.endLoop = ct ;
+                       m [3].markerID = ct++ ;
+                       m [3].position = psf->instrument->loops [1].end ;
+                       }
+               else
+               {       ch.release_loop.playMode = 0 ;
+                       ch.release_loop.beginLoop = 0 ;
+                       ch.release_loop.endLoop = 0 ;
+                       } ;
+
+               psf_binheader_writef (psf, "Em4111111", INST_MARKER, SIZEOF_INST_CHUNK, ch.baseNote, ch.detune,
+                                               ch.lowNote, ch.highNote, ch.lowVelocity, ch.highVelocity) ;
+               psf_binheader_writef (psf, "2222222", ch.gain, ch.sustain_loop.playMode,
+                                               ch.sustain_loop.beginLoop, ch.sustain_loop.endLoop, ch.release_loop.playMode,
+                                               ch.release_loop.beginLoop, ch.release_loop.endLoop) ;
+
+               if (ct == 2)
+                       psf_binheader_writef (psf, "Em42241b241b",
+                                       MARK_MARKER, 2 + 2 * (2 + 4 + 1 + 9), 2,
+                                       m [0].markerID, m [0].position, 8, "beg loop", make_size_t (9),
+                                       m [1].markerID, m [1].position, 8, "end loop", make_size_t (9)) ;
+               else if (ct == 4)
+                       psf_binheader_writef (psf, "Em42 241b 241b 241b 241b",
+                                       MARK_MARKER, 2 + 4 * (2 + 4 + 1 + 9), 4,
+                                       m [0].markerID, m [0].position, 8, "beg loop", make_size_t (9),
+                                       m [1].markerID, m [1].position, 8, "end loop", make_size_t (9),
+                                       m [2].markerID, m [2].position, 8, "beg loop", make_size_t (9),
+                                       m [3].markerID, m [3].position, 8, "end loop", make_size_t (9)) ;
+               } ;
+
+       if (psf->str_flags & SF_STR_LOCATE_START)
+               aiff_write_strings (psf, SF_STR_LOCATE_START) ;
+
+       if (psf->peak_info != NULL && psf->peak_info->peak_loc == SF_PEAK_START)
+       {       psf_binheader_writef (psf, "Em4", PEAK_MARKER, AIFF_PEAK_CHUNK_SIZE (psf->sf.channels)) ;
+               psf_binheader_writef (psf, "E44", 1, time (NULL)) ;
+               for (k = 0 ; k < psf->sf.channels ; k++)
+                       psf_binheader_writef (psf, "Eft8", (float) psf->peak_info->peaks [k].value, psf->peak_info->peaks [k].position) ;
+               } ;
+
+       /* Write SSND chunk. */
+       psf_binheader_writef (psf, "Etm844", SSND_MARKER, psf->datalength + SIZEOF_SSND_CHUNK, 0, 0) ;
+
+       /* Header construction complete so write it out. */
+       psf_fwrite (psf->header, psf->headindex, 1, psf) ;
+
+       if (psf->error)
+               return psf->error ;
+
+       psf->dataoffset = psf->headindex ;
+
+       if (current < psf->dataoffset)
+               psf_fseek (psf, psf->dataoffset, SEEK_SET) ;
+       else if (current > 0)
+               psf_fseek (psf, current, SEEK_SET) ;
+
+       return psf->error ;
+} /* aiff_write_header */
+
+static int
+aiff_write_tailer (SF_PRIVATE *psf)
+{      int             k ;
+
+       /* Reset the current header length to zero. */
+       psf->header [0] = 0 ;
+       psf->headindex = 0 ;
+
+       psf->dataend = psf_fseek (psf, 0, SEEK_END) ;
+
+       /* Make sure tailer data starts at even byte offset. Pad if necessary. */
+       if (psf->dataend % 2 == 1)
+       {       psf_fwrite (psf->header, 1, 1, psf) ;
+               psf->dataend ++ ;
+               } ;
+
+       if (psf->peak_info != NULL && psf->peak_info->peak_loc == SF_PEAK_END)
+       {       psf_binheader_writef (psf, "Em4", PEAK_MARKER, AIFF_PEAK_CHUNK_SIZE (psf->sf.channels)) ;
+               psf_binheader_writef (psf, "E44", 1, time (NULL)) ;
+               for (k = 0 ; k < psf->sf.channels ; k++)
+                       psf_binheader_writef (psf, "Eft8", (float) psf->peak_info->peaks [k].value, psf->peak_info->peaks [k].position) ;
+               } ;
+
+       if (psf->str_flags & SF_STR_LOCATE_END)
+               aiff_write_strings (psf, SF_STR_LOCATE_END) ;
+
+       /* Write the tailer. */
+       if (psf->headindex > 0)
+               psf_fwrite (psf->header, psf->headindex, 1, psf) ;
+
+       return 0 ;
+} /* aiff_write_tailer */
+
+static void
+aiff_write_strings (SF_PRIVATE *psf, int location)
+{      int     k ;
+
+       for (k = 0 ; k < SF_MAX_STRINGS ; k++)
+       {       if (psf->strings [k].type == 0)
+                       break ;
+
+               if (psf->strings [k].flags != location)
+                       continue ;
+
+               switch (psf->strings [k].type)
+               {       case SF_STR_SOFTWARE :
+                               psf_binheader_writef (psf, "EmS", APPL_MARKER, psf->strings [k].str) ;
+                               break ;
+
+                       case SF_STR_TITLE :
+                               psf_binheader_writef (psf, "EmS", NAME_MARKER, psf->strings [k].str) ;
+                               break ;
+
+                       case SF_STR_COPYRIGHT :
+                               psf_binheader_writef (psf, "EmS", c_MARKER, psf->strings [k].str) ;
+                               break ;
+
+                       case SF_STR_ARTIST :
+                               psf_binheader_writef (psf, "EmS", AUTH_MARKER, psf->strings [k].str) ;
+                               break ;
+
+                       case SF_STR_COMMENT :
+                               psf_binheader_writef (psf, "EmS", ANNO_MARKER, psf->strings [k].str) ;
+                               break ;
+
+                       /*
+                       case SF_STR_DATE :
+                               psf_binheader_writef (psf, "Ems", ICRD_MARKER, psf->strings [k].str) ;
+                               break ;
+                       */
+                       } ;
+               } ;
+
+       return ;
+} /* aiff_write_strings */
+
+static int
+aiff_command (SF_PRIVATE *psf, int command, void *data, int datasize)
+{
+       /* Avoid compiler warnings. */
+       psf = psf ;
+       data = data ;
+       datasize = datasize ;
+
+       switch (command)
+       {       default : break ;
+               } ;
+
+       return 0 ;
+} /* aiff_command */
+
+static const char*
+get_loop_mode_str (short mode)
+{      switch (mode)
+       {       case 0 : return "none" ;
+               case 1 : return "forward" ;
+               case 2 : return "backward" ;
+               } ;
+
+       return "*** unknown" ;
+} /* get_loop_mode_str */
+
+static short
+get_loop_mode (short mode)
+{      switch (mode)
+       {       case 0 : return SF_LOOP_NONE ;
+               case 1 : return SF_LOOP_FORWARD ;
+               case 2 : return SF_LOOP_BACKWARD ;
+               } ;
+
+       return SF_LOOP_NONE ;
+} /* get_loop_mode */
+
+/*==========================================================================================
+**     Rough hack at converting from 80 bit IEEE float in AIFF header to an int and
+**     back again. It assumes that all sample rates are between 1 and 800MHz, which
+**     should be OK as other sound file formats use a 32 bit integer to store sample
+**     rate.
+**     There is another (probably better) version in the source code to the SoX but it
+**     has a copyright which probably prevents it from being allowable as GPL/LGPL.
+*/
+
+static int
+tenbytefloat2int (unsigned char *bytes)
+{      int val = 3 ;
+
+       if (bytes [0] & 0x80)   /* Negative number. */
+               return 0 ;
+
+       if (bytes [0] <= 0x3F)  /* Less than 1. */
+               return 1 ;
+
+       if (bytes [0] > 0x40)   /* Way too big. */
+               return 0x4000000 ;
+
+       if (bytes [0] == 0x40 && bytes [1] > 0x1C) /* Too big. */
+               return 800000000 ;
+
+       /* Ok, can handle it. */
+
+       val = (bytes [2] << 23) | (bytes [3] << 15) | (bytes [4] << 7) | (bytes [5] >> 1) ;
+
+       val >>= (29 - bytes [1]) ;
+
+       return val ;
+} /* tenbytefloat2int */
+
+static void
+uint2tenbytefloat (unsigned int num, unsigned char *bytes)
+{      unsigned int mask = 0x40000000 ;
+       int     count ;
+
+       if (num <= 1)
+       {       bytes [0] = 0x3F ;
+               bytes [1] = 0xFF ;
+               bytes [2] = 0x80 ;
+               return ;
+               } ;
+
+       bytes [0] = 0x40 ;
+
+       if (num >= mask)
+       {       bytes [1] = 0x1D ;
+               return ;
+               } ;
+
+       for (count = 0 ; count <= 32 ; count ++)
+       {       if (num & mask)
+                       break ;
+               mask >>= 1 ;
+               } ;
+
+       num <<= count + 1 ;
+       bytes [1] = 29 - count ;
+       bytes [2] = (num >> 24) & 0xFF ;
+       bytes [3] = (num >> 16) & 0xFF ;
+       bytes [4] = (num >> 8) & 0xFF ;
+       bytes [5] = num & 0xFF ;
+
+} /* uint2tenbytefloat */
+
+static int
+aiff_read_basc_chunk (SF_PRIVATE * psf, int datasize)
+{      const char * type_str ;
+       basc_CHUNK bc ;
+
+       psf_binheader_readf (psf, "E442", &bc.version, &bc.numBeats, &bc.rootNote) ;
+       psf_binheader_readf (psf, "E222", &bc.scaleType, &bc.sigNumerator, &bc.sigDenominator) ;
+       psf_binheader_readf (psf, "E2j", &bc.loopType, datasize - sizeof (bc)) ;
+
+       psf_log_printf (psf, "  Version ? : %u\n  Num Beats : %u\n  Root Note : 0x%x\n",
+                                               bc.version, bc.numBeats, bc.rootNote) ;
+
+       switch (bc.scaleType)
+       {       case basc_SCALE_MINOR :
+                               type_str = "MINOR" ;
+                               break ;
+               case basc_SCALE_MAJOR :
+                               type_str = "MAJOR" ;
+                               break ;
+               case basc_SCALE_NEITHER :
+                               type_str = "NEITHER" ;
+                               break ;
+               case basc_SCALE_BOTH :
+                               type_str = "BOTH" ;
+                               break ;
+               default :
+                               type_str = "!!WRONG!!" ;
+                               break ;
+               } ;
+
+       psf_log_printf (psf, "  ScaleType : 0x%x (%s)\n", bc.scaleType, type_str) ;
+       psf_log_printf (psf, "  Time Sig  : %d/%d\n", bc.sigNumerator, bc.sigDenominator) ;
+
+       switch (bc.loopType)
+       {       case basc_TYPE_ONE_SHOT :
+                               type_str = "One Shot" ;
+                               break ;
+               case basc_TYPE_LOOP :
+                               type_str = "Loop" ;
+                               break ;
+               default:
+                               type_str = "!!WRONG!!" ;
+                               break ;
+               } ;
+
+       psf_log_printf (psf, "  Loop Type : 0x%x (%s)\n", bc.loopType, type_str) ;
+
+       if ((psf->loop_info = calloc (1, sizeof (SF_LOOP_INFO))) == NULL)
+               return SFE_MALLOC_FAILED ;
+
+       psf->loop_info->time_sig_num    = bc.sigNumerator ;
+       psf->loop_info->time_sig_den    = bc.sigDenominator ;
+       psf->loop_info->loop_mode               = (bc.loopType == basc_TYPE_ONE_SHOT) ? SF_LOOP_NONE : SF_LOOP_FORWARD ;
+       psf->loop_info->num_beats               = bc.numBeats ;
+
+       /* Can always be recalculated from other known fields. */
+       psf->loop_info->bpm = (1.0 / psf->sf.frames) * psf->sf.samplerate
+                                                       * ((bc.numBeats * 4.0) / bc.sigDenominator) * 60.0 ;
+       psf->loop_info->root_key = bc.rootNote ;
+
+       return 0 ;
+} /* aiff_read_basc_chunk */
+
+/*
+** Do not edit or modify anything in this comment block.
+** The arch-tag line is a file identity tag for the GNU Arch
+** revision control system.
+**
+** arch-tag: 7dec56ca-d6f2-48cf-863b-a72e7e17a5d9
+*/
diff --git a/libs/libsndfile/src/alaw.c b/libs/libsndfile/src/alaw.c
new file mode 100644 (file)
index 0000000..a2d27cb
--- /dev/null
@@ -0,0 +1,544 @@
+/*
+** Copyright (C) 1999-2005 Erik de Castro Lopo <erikd@mega-nerd.com>
+**
+** This program is free software; you can redistribute it and/or modify
+** it under the terms of the GNU Lesser General Public License as published by
+** the Free Software Foundation; either version 2.1 of the License, or
+** (at your option) any later version.
+**
+** This program is distributed in the hope that it will be useful,
+** but WITHOUT ANY WARRANTY; without even the implied warranty of
+** MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+** GNU Lesser General Public License for more details.
+**
+** You should have received a copy of the GNU Lesser General Public License
+** along with this program; if not, write to the Free Software
+** Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA.
+*/
+
+#include       "sndfile.h"
+#include       "float_cast.h"
+#include       "common.h"
+
+static sf_count_t alaw_read_alaw2s (SF_PRIVATE *psf, short *ptr, sf_count_t len) ;
+static sf_count_t alaw_read_alaw2i (SF_PRIVATE *psf, int *ptr, sf_count_t len) ;
+static sf_count_t alaw_read_alaw2f (SF_PRIVATE *psf, float *ptr, sf_count_t len) ;
+static sf_count_t alaw_read_alaw2d (SF_PRIVATE *psf, double *ptr, sf_count_t len) ;
+
+static sf_count_t alaw_write_s2alaw (SF_PRIVATE *psf, const short *ptr, sf_count_t len) ;
+static sf_count_t alaw_write_i2alaw (SF_PRIVATE *psf, const int *ptr, sf_count_t len) ;
+static sf_count_t alaw_write_f2alaw (SF_PRIVATE *psf, const float *ptr, sf_count_t len) ;
+static sf_count_t alaw_write_d2alaw (SF_PRIVATE *psf, const double *ptr, sf_count_t len) ;
+
+static void alaw2s_array (unsigned char *buffer, int count, short *ptr) ;
+static void alaw2i_array (unsigned char *buffer, int count, int *ptr) ;
+static void alaw2f_array (unsigned char *buffer, int count, float *ptr, float normfact) ;
+static void alaw2d_array (unsigned char *buffer, int count, double *ptr, double normfact) ;
+
+static void s2alaw_array (const short *buffer, int count, unsigned char *ptr) ;
+static void i2alaw_array (const int *buffer, int count, unsigned char *ptr) ;
+static void f2alaw_array (const float *buffer, int count, unsigned char *ptr, float normfact) ;
+static void d2alaw_array (const double *buffer, int count, unsigned char *ptr, double normfact) ;
+
+
+int
+alaw_init (SF_PRIVATE *psf)
+{
+       if (psf->mode == SFM_READ || psf->mode == SFM_RDWR)
+       {       psf->read_short         = alaw_read_alaw2s ;
+               psf->read_int           = alaw_read_alaw2i ;
+               psf->read_float         = alaw_read_alaw2f ;
+               psf->read_double        = alaw_read_alaw2d ;
+               } ;
+
+       if (psf->mode == SFM_WRITE || psf->mode == SFM_RDWR)
+       {       psf->write_short        = alaw_write_s2alaw ;
+               psf->write_int          = alaw_write_i2alaw ;
+               psf->write_float        = alaw_write_f2alaw ;
+               psf->write_double       = alaw_write_d2alaw ;
+               } ;
+
+       psf->bytewidth = 1 ;
+       psf->blockwidth = psf->sf.channels ;
+
+       if (psf->filelength > psf->dataoffset)
+               psf->datalength = (psf->dataend) ? psf->dataend - psf->dataoffset : psf->filelength - psf->dataoffset ;
+       else
+               psf->datalength = 0 ;
+
+       psf->sf.frames = psf->datalength / psf->blockwidth ;
+
+       return 0 ;
+} /* alaw_init */
+
+/*==============================================================================
+ *     Private static functions and data.
+ */
+
+static
+short alaw_decode [256] =
+{      -5504,  -5248,  -6016,  -5760,  -4480,  -4224,  -4992,  -4736,
+       -7552,  -7296,  -8064,  -7808,  -6528,  -6272,  -7040,  -6784,
+       -2752,  -2624,  -3008,  -2880,  -2240,  -2112,  -2496,  -2368,
+       -3776,  -3648,  -4032,  -3904,  -3264,  -3136,  -3520,  -3392,
+       -22016, -20992, -24064, -23040, -17920, -16896, -19968, -18944,
+       -30208, -29184, -32256, -31232, -26112, -25088, -28160, -27136,
+       -11008, -10496, -12032, -11520, -8960,  -8448,  -9984,  -9472,
+       -15104, -14592, -16128, -15616, -13056, -12544, -14080, -13568,
+       -344,   -328,   -376,   -360,   -280,   -264,   -312,   -296,
+       -472,   -456,   -504,   -488,   -408,   -392,   -440,   -424,
+       -88,    -72,    -120,   -104,   -24,    -8,             -56,    -40,
+       -216,   -200,   -248,   -232,   -152,   -136,   -184,   -168,
+       -1376,  -1312,  -1504,  -1440,  -1120,  -1056,  -1248,  -1184,
+       -1888,  -1824,  -2016,  -1952,  -1632,  -1568,  -1760,  -1696,
+       -688,   -656,   -752,   -720,   -560,   -528,   -624,   -592,
+       -944,   -912,   -1008,  -976,   -816,   -784,   -880,   -848,
+       5504,   5248,   6016,   5760,   4480,   4224,   4992,   4736,
+       7552,   7296,   8064,   7808,   6528,   6272,   7040,   6784,
+       2752,   2624,   3008,   2880,   2240,   2112,   2496,   2368,
+       3776,   3648,   4032,   3904,   3264,   3136,   3520,   3392,
+       22016,  20992,  24064,  23040,  17920,  16896,  19968,  18944,
+       30208,  29184,  32256,  31232,  26112,  25088,  28160,  27136,
+       11008,  10496,  12032,  11520,  8960,   8448,   9984,   9472,
+       15104,  14592,  16128,  15616,  13056,  12544,  14080,  13568,
+       344,    328,    376,    360,    280,    264,    312,    296,
+       472,    456,    504,    488,    408,    392,    440,    424,
+       88,             72,             120,    104,    24,             8,              56,             40,
+       216,    200,    248,    232,    152,    136,    184,    168,
+       1376,   1312,   1504,   1440,   1120,   1056,   1248,   1184,
+       1888,   1824,   2016,   1952,   1632,   1568,   1760,   1696,
+       688,    656,    752,    720,    560,    528,    624,    592,
+       944,    912,    1008,   976,    816,    784,    880,    848
+} ; /* alaw_decode */
+
+static
+unsigned char alaw_encode [2048 + 1] =
+{      0xd5, 0xd4, 0xd7, 0xd6, 0xd1, 0xd0, 0xd3, 0xd2, 0xdd, 0xdc, 0xdf, 0xde,
+       0xd9, 0xd8, 0xdb, 0xda, 0xc5, 0xc4, 0xc7, 0xc6, 0xc1, 0xc0, 0xc3, 0xc2,
+       0xcd, 0xcc, 0xcf, 0xce, 0xc9, 0xc8, 0xcb, 0xca, 0xf5, 0xf5, 0xf4, 0xf4,
+       0xf7, 0xf7, 0xf6, 0xf6, 0xf1, 0xf1, 0xf0, 0xf0, 0xf3, 0xf3, 0xf2, 0xf2,
+       0xfd, 0xfd, 0xfc, 0xfc, 0xff, 0xff, 0xfe, 0xfe, 0xf9, 0xf9, 0xf8, 0xf8,
+       0xfb, 0xfb, 0xfa, 0xfa, 0xe5, 0xe5, 0xe5, 0xe5, 0xe4, 0xe4, 0xe4, 0xe4,
+       0xe7, 0xe7, 0xe7, 0xe7, 0xe6, 0xe6, 0xe6, 0xe6, 0xe1, 0xe1, 0xe1, 0xe1,
+       0xe0, 0xe0, 0xe0, 0xe0, 0xe3, 0xe3, 0xe3, 0xe3, 0xe2, 0xe2, 0xe2, 0xe2,
+       0xed, 0xed, 0xed, 0xed, 0xec, 0xec, 0xec, 0xec, 0xef, 0xef, 0xef, 0xef,
+       0xee, 0xee, 0xee, 0xee, 0xe9, 0xe9, 0xe9, 0xe9, 0xe8, 0xe8, 0xe8, 0xe8,
+       0xeb, 0xeb, 0xeb, 0xeb, 0xea, 0xea, 0xea, 0xea, 0x95, 0x95, 0x95, 0x95,
+       0x95, 0x95, 0x95, 0x95, 0x94, 0x94, 0x94, 0x94, 0x94, 0x94, 0x94, 0x94,
+       0x97, 0x97, 0x97, 0x97, 0x97, 0x97, 0x97, 0x97, 0x96, 0x96, 0x96, 0x96,
+       0x96, 0x96, 0x96, 0x96, 0x91, 0x91, 0x91, 0x91, 0x91, 0x91, 0x91, 0x91,
+       0x90, 0x90, 0x90, 0x90, 0x90, 0x90, 0x90, 0x90, 0x93, 0x93, 0x93, 0x93,
+       0x93, 0x93, 0x93, 0x93, 0x92, 0x92, 0x92, 0x92, 0x92, 0x92, 0x92, 0x92,
+       0x9d, 0x9d, 0x9d, 0x9d, 0x9d, 0x9d, 0x9d, 0x9d, 0x9c, 0x9c, 0x9c, 0x9c,
+       0x9c, 0x9c, 0x9c, 0x9c, 0x9f, 0x9f, 0x9f, 0x9f, 0x9f, 0x9f, 0x9f, 0x9f,
+       0x9e, 0x9e, 0x9e, 0x9e, 0x9e, 0x9e, 0x9e, 0x9e, 0x99, 0x99, 0x99, 0x99,
+       0x99, 0x99, 0x99, 0x99, 0x98, 0x98, 0x98, 0x98, 0x98, 0x98, 0x98, 0x98,
+       0x9b, 0x9b, 0x9b, 0x9b, 0x9b, 0x9b, 0x9b, 0x9b, 0x9a, 0x9a, 0x9a, 0x9a,
+       0x9a, 0x9a, 0x9a, 0x9a, 0x85, 0x85, 0x85, 0x85, 0x85, 0x85, 0x85, 0x85,
+       0x85, 0x85, 0x85, 0x85, 0x85, 0x85, 0x85, 0x85, 0x84, 0x84, 0x84, 0x84,
+       0x84, 0x84, 0x84, 0x84, 0x84, 0x84, 0x84, 0x84, 0x84, 0x84, 0x84, 0x84,
+       0x87, 0x87, 0x87, 0x87, 0x87, 0x87, 0x87, 0x87, 0x87, 0x87, 0x87, 0x87,
+       0x87, 0x87, 0x87, 0x87, 0x86, 0x86, 0x86, 0x86, 0x86, 0x86, 0x86, 0x86,
+       0x86, 0x86, 0x86, 0x86, 0x86, 0x86, 0x86, 0x86, 0x81, 0x81, 0x81, 0x81,
+       0x81, 0x81, 0x81, 0x81, 0x81, 0x81, 0x81, 0x81, 0x81, 0x81, 0x81, 0x81,
+       0x80, 0x80, 0x80, 0x80, 0x80, 0x80, 0x80, 0x80, 0x80, 0x80, 0x80, 0x80,
+       0x80, 0x80, 0x80, 0x80, 0x83, 0x83, 0x83, 0x83, 0x83, 0x83, 0x83, 0x83,
+       0x83, 0x83, 0x83, 0x83, 0x83, 0x83, 0x83, 0x83, 0x82, 0x82, 0x82, 0x82,
+       0x82, 0x82, 0x82, 0x82, 0x82, 0x82, 0x82, 0x82, 0x82, 0x82, 0x82, 0x82,
+       0x8d, 0x8d, 0x8d, 0x8d, 0x8d, 0x8d, 0x8d, 0x8d, 0x8d, 0x8d, 0x8d, 0x8d,
+       0x8d, 0x8d, 0x8d, 0x8d, 0x8c, 0x8c, 0x8c, 0x8c, 0x8c, 0x8c, 0x8c, 0x8c,
+       0x8c, 0x8c, 0x8c, 0x8c, 0x8c, 0x8c, 0x8c, 0x8c, 0x8f, 0x8f, 0x8f, 0x8f,
+       0x8f, 0x8f, 0x8f, 0x8f, 0x8f, 0x8f, 0x8f, 0x8f, 0x8f, 0x8f, 0x8f, 0x8f,
+       0x8e, 0x8e, 0x8e, 0x8e, 0x8e, 0x8e, 0x8e, 0x8e, 0x8e, 0x8e, 0x8e, 0x8e,
+       0x8e, 0x8e, 0x8e, 0x8e, 0x89, 0x89, 0x89, 0x89, 0x89, 0x89, 0x89, 0x89,
+       0x89, 0x89, 0x89, 0x89, 0x89, 0x89, 0x89, 0x89, 0x88, 0x88, 0x88, 0x88,
+       0x88, 0x88, 0x88, 0x88, 0x88, 0x88, 0x88, 0x88, 0x88, 0x88, 0x88, 0x88,
+       0x8b, 0x8b, 0x8b, 0x8b, 0x8b, 0x8b, 0x8b, 0x8b, 0x8b, 0x8b, 0x8b, 0x8b,
+       0x8b, 0x8b, 0x8b, 0x8b, 0x8a, 0x8a, 0x8a, 0x8a, 0x8a, 0x8a, 0x8a, 0x8a,
+       0x8a, 0x8a, 0x8a, 0x8a, 0x8a, 0x8a, 0x8a, 0x8a, 0xb5, 0xb5, 0xb5, 0xb5,
+       0xb5, 0xb5, 0xb5, 0xb5, 0xb5, 0xb5, 0xb5, 0xb5, 0xb5, 0xb5, 0xb5, 0xb5,
+       0xb5, 0xb5, 0xb5, 0xb5, 0xb5, 0xb5, 0xb5, 0xb5, 0xb5, 0xb5, 0xb5, 0xb5,
+       0xb5, 0xb5, 0xb5, 0xb5, 0xb4, 0xb4, 0xb4, 0xb4, 0xb4, 0xb4, 0xb4, 0xb4,
+       0xb4, 0xb4, 0xb4, 0xb4, 0xb4, 0xb4, 0xb4, 0xb4, 0xb4, 0xb4, 0xb4, 0xb4,
+       0xb4, 0xb4, 0xb4, 0xb4, 0xb4, 0xb4, 0xb4, 0xb4, 0xb4, 0xb4, 0xb4, 0xb4,
+       0xb7, 0xb7, 0xb7, 0xb7, 0xb7, 0xb7, 0xb7, 0xb7, 0xb7, 0xb7, 0xb7, 0xb7,
+       0xb7, 0xb7, 0xb7, 0xb7, 0xb7, 0xb7, 0xb7, 0xb7, 0xb7, 0xb7, 0xb7, 0xb7,
+       0xb7, 0xb7, 0xb7, 0xb7, 0xb7, 0xb7, 0xb7, 0xb7, 0xb6, 0xb6, 0xb6, 0xb6,
+       0xb6, 0xb6, 0xb6, 0xb6, 0xb6, 0xb6, 0xb6, 0xb6, 0xb6, 0xb6, 0xb6, 0xb6,
+       0xb6, 0xb6, 0xb6, 0xb6, 0xb6, 0xb6, 0xb6, 0xb6, 0xb6, 0xb6, 0xb6, 0xb6,
+       0xb6, 0xb6, 0xb6, 0xb6, 0xb1, 0xb1, 0xb1, 0xb1, 0xb1, 0xb1, 0xb1, 0xb1,
+       0xb1, 0xb1, 0xb1, 0xb1, 0xb1, 0xb1, 0xb1, 0xb1, 0xb1, 0xb1, 0xb1, 0xb1,
+       0xb1, 0xb1, 0xb1, 0xb1, 0xb1, 0xb1, 0xb1, 0xb1, 0xb1, 0xb1, 0xb1, 0xb1,
+       0xb0, 0xb0, 0xb0, 0xb0, 0xb0, 0xb0, 0xb0, 0xb0, 0xb0, 0xb0, 0xb0, 0xb0,
+       0xb0, 0xb0, 0xb0, 0xb0, 0xb0, 0xb0, 0xb0, 0xb0, 0xb0, 0xb0, 0xb0, 0xb0,
+       0xb0, 0xb0, 0xb0, 0xb0, 0xb0, 0xb0, 0xb0, 0xb0, 0xb3, 0xb3, 0xb3, 0xb3,
+       0xb3, 0xb3, 0xb3, 0xb3, 0xb3, 0xb3, 0xb3, 0xb3, 0xb3, 0xb3, 0xb3, 0xb3,
+       0xb3, 0xb3, 0xb3, 0xb3, 0xb3, 0xb3, 0xb3, 0xb3, 0xb3, 0xb3, 0xb3, 0xb3,
+       0xb3, 0xb3, 0xb3, 0xb3, 0xb2, 0xb2, 0xb2, 0xb2, 0xb2, 0xb2, 0xb2, 0xb2,
+       0xb2, 0xb2, 0xb2, 0xb2, 0xb2, 0xb2, 0xb2, 0xb2, 0xb2, 0xb2, 0xb2, 0xb2,
+       0xb2, 0xb2, 0xb2, 0xb2, 0xb2, 0xb2, 0xb2, 0xb2, 0xb2, 0xb2, 0xb2, 0xb2,
+       0xbd, 0xbd, 0xbd, 0xbd, 0xbd, 0xbd, 0xbd, 0xbd, 0xbd, 0xbd, 0xbd, 0xbd,
+       0xbd, 0xbd, 0xbd, 0xbd, 0xbd, 0xbd, 0xbd, 0xbd, 0xbd, 0xbd, 0xbd, 0xbd,
+       0xbd, 0xbd, 0xbd, 0xbd, 0xbd, 0xbd, 0xbd, 0xbd, 0xbc, 0xbc, 0xbc, 0xbc,
+       0xbc, 0xbc, 0xbc, 0xbc, 0xbc, 0xbc, 0xbc, 0xbc, 0xbc, 0xbc, 0xbc, 0xbc,
+       0xbc, 0xbc, 0xbc, 0xbc, 0xbc, 0xbc, 0xbc, 0xbc, 0xbc, 0xbc, 0xbc, 0xbc,
+       0xbc, 0xbc, 0xbc, 0xbc, 0xbf, 0xbf, 0xbf, 0xbf, 0xbf, 0xbf, 0xbf, 0xbf,
+       0xbf, 0xbf, 0xbf, 0xbf, 0xbf, 0xbf, 0xbf, 0xbf, 0xbf, 0xbf, 0xbf, 0xbf,
+       0xbf, 0xbf, 0xbf, 0xbf, 0xbf, 0xbf, 0xbf, 0xbf, 0xbf, 0xbf, 0xbf, 0xbf,
+       0xbe, 0xbe, 0xbe, 0xbe, 0xbe, 0xbe, 0xbe, 0xbe, 0xbe, 0xbe, 0xbe, 0xbe,
+       0xbe, 0xbe, 0xbe, 0xbe, 0xbe, 0xbe, 0xbe, 0xbe, 0xbe, 0xbe, 0xbe, 0xbe,
+       0xbe, 0xbe, 0xbe, 0xbe, 0xbe, 0xbe, 0xbe, 0xbe, 0xb9, 0xb9, 0xb9, 0xb9,
+       0xb9, 0xb9, 0xb9, 0xb9, 0xb9, 0xb9, 0xb9, 0xb9, 0xb9, 0xb9, 0xb9, 0xb9,
+       0xb9, 0xb9, 0xb9, 0xb9, 0xb9, 0xb9, 0xb9, 0xb9, 0xb9, 0xb9, 0xb9, 0xb9,
+       0xb9, 0xb9, 0xb9, 0xb9, 0xb8, 0xb8, 0xb8, 0xb8, 0xb8, 0xb8, 0xb8, 0xb8,
+       0xb8, 0xb8, 0xb8, 0xb8, 0xb8, 0xb8, 0xb8, 0xb8, 0xb8, 0xb8, 0xb8, 0xb8,
+       0xb8, 0xb8, 0xb8, 0xb8, 0xb8, 0xb8, 0xb8, 0xb8, 0xb8, 0xb8, 0xb8, 0xb8,
+       0xbb, 0xbb, 0xbb, 0xbb, 0xbb, 0xbb, 0xbb, 0xbb, 0xbb, 0xbb, 0xbb, 0xbb,
+       0xbb, 0xbb, 0xbb, 0xbb, 0xbb, 0xbb, 0xbb, 0xbb, 0xbb, 0xbb, 0xbb, 0xbb,
+       0xbb, 0xbb, 0xbb, 0xbb, 0xbb, 0xbb, 0xbb, 0xbb, 0xba, 0xba, 0xba, 0xba,
+       0xba, 0xba, 0xba, 0xba, 0xba, 0xba, 0xba, 0xba, 0xba, 0xba, 0xba, 0xba,
+       0xba, 0xba, 0xba, 0xba, 0xba, 0xba, 0xba, 0xba, 0xba, 0xba, 0xba, 0xba,
+       0xba, 0xba, 0xba, 0xba, 0xa5, 0xa5, 0xa5, 0xa5, 0xa5, 0xa5, 0xa5, 0xa5,
+       0xa5, 0xa5, 0xa5, 0xa5, 0xa5, 0xa5, 0xa5, 0xa5, 0xa5, 0xa5, 0xa5, 0xa5,
+       0xa5, 0xa5, 0xa5, 0xa5, 0xa5, 0xa5, 0xa5, 0xa5, 0xa5, 0xa5, 0xa5, 0xa5,
+       0xa5, 0xa5, 0xa5, 0xa5, 0xa5, 0xa5, 0xa5, 0xa5, 0xa5, 0xa5, 0xa5, 0xa5,
+       0xa5, 0xa5, 0xa5, 0xa5, 0xa5, 0xa5, 0xa5, 0xa5, 0xa5, 0xa5, 0xa5, 0xa5,
+       0xa5, 0xa5, 0xa5, 0xa5, 0xa5, 0xa5, 0xa5, 0xa5, 0xa4, 0xa4, 0xa4, 0xa4,
+       0xa4, 0xa4, 0xa4, 0xa4, 0xa4, 0xa4, 0xa4, 0xa4, 0xa4, 0xa4, 0xa4, 0xa4,
+       0xa4, 0xa4, 0xa4, 0xa4, 0xa4, 0xa4, 0xa4, 0xa4, 0xa4, 0xa4, 0xa4, 0xa4,
+       0xa4, 0xa4, 0xa4, 0xa4, 0xa4, 0xa4, 0xa4, 0xa4, 0xa4, 0xa4, 0xa4, 0xa4,
+       0xa4, 0xa4, 0xa4, 0xa4, 0xa4, 0xa4, 0xa4, 0xa4, 0xa4, 0xa4, 0xa4, 0xa4,
+       0xa4, 0xa4, 0xa4, 0xa4, 0xa4, 0xa4, 0xa4, 0xa4, 0xa4, 0xa4, 0xa4, 0xa4,
+       0xa7, 0xa7, 0xa7, 0xa7, 0xa7, 0xa7, 0xa7, 0xa7, 0xa7, 0xa7, 0xa7, 0xa7,
+       0xa7, 0xa7, 0xa7, 0xa7, 0xa7, 0xa7, 0xa7, 0xa7, 0xa7, 0xa7, 0xa7, 0xa7,
+       0xa7, 0xa7, 0xa7, 0xa7, 0xa7, 0xa7, 0xa7, 0xa7, 0xa7, 0xa7, 0xa7, 0xa7,
+       0xa7, 0xa7, 0xa7, 0xa7, 0xa7, 0xa7, 0xa7, 0xa7, 0xa7, 0xa7, 0xa7, 0xa7,
+       0xa7, 0xa7, 0xa7, 0xa7, 0xa7, 0xa7, 0xa7, 0xa7, 0xa7, 0xa7, 0xa7, 0xa7,
+       0xa7, 0xa7, 0xa7, 0xa7, 0xa6, 0xa6, 0xa6, 0xa6, 0xa6, 0xa6, 0xa6, 0xa6,
+       0xa6, 0xa6, 0xa6, 0xa6, 0xa6, 0xa6, 0xa6, 0xa6, 0xa6, 0xa6, 0xa6, 0xa6,
+       0xa6, 0xa6, 0xa6, 0xa6, 0xa6, 0xa6, 0xa6, 0xa6, 0xa6, 0xa6, 0xa6, 0xa6,
+       0xa6, 0xa6, 0xa6, 0xa6, 0xa6, 0xa6, 0xa6, 0xa6, 0xa6, 0xa6, 0xa6, 0xa6,
+       0xa6, 0xa6, 0xa6, 0xa6, 0xa6, 0xa6, 0xa6, 0xa6, 0xa6, 0xa6, 0xa6, 0xa6,
+       0xa6, 0xa6, 0xa6, 0xa6, 0xa6, 0xa6, 0xa6, 0xa6, 0xa1, 0xa1, 0xa1, 0xa1,
+       0xa1, 0xa1, 0xa1, 0xa1, 0xa1, 0xa1, 0xa1, 0xa1, 0xa1, 0xa1, 0xa1, 0xa1,
+       0xa1, 0xa1, 0xa1, 0xa1, 0xa1, 0xa1, 0xa1, 0xa1, 0xa1, 0xa1, 0xa1, 0xa1,
+       0xa1, 0xa1, 0xa1, 0xa1, 0xa1, 0xa1, 0xa1, 0xa1, 0xa1, 0xa1, 0xa1, 0xa1,
+       0xa1, 0xa1, 0xa1, 0xa1, 0xa1, 0xa1, 0xa1, 0xa1, 0xa1, 0xa1, 0xa1, 0xa1,
+       0xa1, 0xa1, 0xa1, 0xa1, 0xa1, 0xa1, 0xa1, 0xa1, 0xa1, 0xa1, 0xa1, 0xa1,
+       0xa0, 0xa0, 0xa0, 0xa0, 0xa0, 0xa0, 0xa0, 0xa0, 0xa0, 0xa0, 0xa0, 0xa0,
+       0xa0, 0xa0, 0xa0, 0xa0, 0xa0, 0xa0, 0xa0, 0xa0, 0xa0, 0xa0, 0xa0, 0xa0,
+       0xa0, 0xa0, 0xa0, 0xa0, 0xa0, 0xa0, 0xa0, 0xa0, 0xa0, 0xa0, 0xa0, 0xa0,
+       0xa0, 0xa0, 0xa0, 0xa0, 0xa0, 0xa0, 0xa0, 0xa0, 0xa0, 0xa0, 0xa0, 0xa0,
+       0xa0, 0xa0, 0xa0, 0xa0, 0xa0, 0xa0, 0xa0, 0xa0, 0xa0, 0xa0, 0xa0, 0xa0,
+       0xa0, 0xa0, 0xa0, 0xa0, 0xa3, 0xa3, 0xa3, 0xa3, 0xa3, 0xa3, 0xa3, 0xa3,
+       0xa3, 0xa3, 0xa3, 0xa3, 0xa3, 0xa3, 0xa3, 0xa3, 0xa3, 0xa3, 0xa3, 0xa3,
+       0xa3, 0xa3, 0xa3, 0xa3, 0xa3, 0xa3, 0xa3, 0xa3, 0xa3, 0xa3, 0xa3, 0xa3,
+       0xa3, 0xa3, 0xa3, 0xa3, 0xa3, 0xa3, 0xa3, 0xa3, 0xa3, 0xa3, 0xa3, 0xa3,
+       0xa3, 0xa3, 0xa3, 0xa3, 0xa3, 0xa3, 0xa3, 0xa3, 0xa3, 0xa3, 0xa3, 0xa3,
+       0xa3, 0xa3, 0xa3, 0xa3, 0xa3, 0xa3, 0xa3, 0xa3, 0xa2, 0xa2, 0xa2, 0xa2,
+       0xa2, 0xa2, 0xa2, 0xa2, 0xa2, 0xa2, 0xa2, 0xa2, 0xa2, 0xa2, 0xa2, 0xa2,
+       0xa2, 0xa2, 0xa2, 0xa2, 0xa2, 0xa2, 0xa2, 0xa2, 0xa2, 0xa2, 0xa2, 0xa2,
+       0xa2, 0xa2, 0xa2, 0xa2, 0xa2, 0xa2, 0xa2, 0xa2, 0xa2, 0xa2, 0xa2, 0xa2,
+       0xa2, 0xa2, 0xa2, 0xa2, 0xa2, 0xa2, 0xa2, 0xa2, 0xa2, 0xa2, 0xa2, 0xa2,
+       0xa2, 0xa2, 0xa2, 0xa2, 0xa2, 0xa2, 0xa2, 0xa2, 0xa2, 0xa2, 0xa2, 0xa2,
+       0xad, 0xad, 0xad, 0xad, 0xad, 0xad, 0xad, 0xad, 0xad, 0xad, 0xad, 0xad,
+       0xad, 0xad, 0xad, 0xad, 0xad, 0xad, 0xad, 0xad, 0xad, 0xad, 0xad, 0xad,
+       0xad, 0xad, 0xad, 0xad, 0xad, 0xad, 0xad, 0xad, 0xad, 0xad, 0xad, 0xad,
+       0xad, 0xad, 0xad, 0xad, 0xad, 0xad, 0xad, 0xad, 0xad, 0xad, 0xad, 0xad,
+       0xad, 0xad, 0xad, 0xad, 0xad, 0xad, 0xad, 0xad, 0xad, 0xad, 0xad, 0xad,
+       0xad, 0xad, 0xad, 0xad, 0xac, 0xac, 0xac, 0xac, 0xac, 0xac, 0xac, 0xac,
+       0xac, 0xac, 0xac, 0xac, 0xac, 0xac, 0xac, 0xac, 0xac, 0xac, 0xac, 0xac,
+       0xac, 0xac, 0xac, 0xac, 0xac, 0xac, 0xac, 0xac, 0xac, 0xac, 0xac, 0xac,
+       0xac, 0xac, 0xac, 0xac, 0xac, 0xac, 0xac, 0xac, 0xac, 0xac, 0xac, 0xac,
+       0xac, 0xac, 0xac, 0xac, 0xac, 0xac, 0xac, 0xac, 0xac, 0xac, 0xac, 0xac,
+       0xac, 0xac, 0xac, 0xac, 0xac, 0xac, 0xac, 0xac, 0xaf, 0xaf, 0xaf, 0xaf,
+       0xaf, 0xaf, 0xaf, 0xaf, 0xaf, 0xaf, 0xaf, 0xaf, 0xaf, 0xaf, 0xaf, 0xaf,
+       0xaf, 0xaf, 0xaf, 0xaf, 0xaf, 0xaf, 0xaf, 0xaf, 0xaf, 0xaf, 0xaf, 0xaf,
+       0xaf, 0xaf, 0xaf, 0xaf, 0xaf, 0xaf, 0xaf, 0xaf, 0xaf, 0xaf, 0xaf, 0xaf,
+       0xaf, 0xaf, 0xaf, 0xaf, 0xaf, 0xaf, 0xaf, 0xaf, 0xaf, 0xaf, 0xaf, 0xaf,
+       0xaf, 0xaf, 0xaf, 0xaf, 0xaf, 0xaf, 0xaf, 0xaf, 0xaf, 0xaf, 0xaf, 0xaf,
+       0xae, 0xae, 0xae, 0xae, 0xae, 0xae, 0xae, 0xae, 0xae, 0xae, 0xae, 0xae,
+       0xae, 0xae, 0xae, 0xae, 0xae, 0xae, 0xae, 0xae, 0xae, 0xae, 0xae, 0xae,
+       0xae, 0xae, 0xae, 0xae, 0xae, 0xae, 0xae, 0xae, 0xae, 0xae, 0xae, 0xae,
+       0xae, 0xae, 0xae, 0xae, 0xae, 0xae, 0xae, 0xae, 0xae, 0xae, 0xae, 0xae,
+       0xae, 0xae, 0xae, 0xae, 0xae, 0xae, 0xae, 0xae, 0xae, 0xae, 0xae, 0xae,
+       0xae, 0xae, 0xae, 0xae, 0xa9, 0xa9, 0xa9, 0xa9, 0xa9, 0xa9, 0xa9, 0xa9,
+       0xa9, 0xa9, 0xa9, 0xa9, 0xa9, 0xa9, 0xa9, 0xa9, 0xa9, 0xa9, 0xa9, 0xa9,
+       0xa9, 0xa9, 0xa9, 0xa9, 0xa9, 0xa9, 0xa9, 0xa9, 0xa9, 0xa9, 0xa9, 0xa9,
+       0xa9, 0xa9, 0xa9, 0xa9, 0xa9, 0xa9, 0xa9, 0xa9, 0xa9, 0xa9, 0xa9, 0xa9,
+       0xa9, 0xa9, 0xa9, 0xa9, 0xa9, 0xa9, 0xa9, 0xa9, 0xa9, 0xa9, 0xa9, 0xa9,
+       0xa9, 0xa9, 0xa9, 0xa9, 0xa9, 0xa9, 0xa9, 0xa9, 0xa8, 0xa8, 0xa8, 0xa8,
+       0xa8, 0xa8, 0xa8, 0xa8, 0xa8, 0xa8, 0xa8, 0xa8, 0xa8, 0xa8, 0xa8, 0xa8,
+       0xa8, 0xa8, 0xa8, 0xa8, 0xa8, 0xa8, 0xa8, 0xa8, 0xa8, 0xa8, 0xa8, 0xa8,
+       0xa8, 0xa8, 0xa8, 0xa8, 0xa8, 0xa8, 0xa8, 0xa8, 0xa8, 0xa8, 0xa8, 0xa8,
+       0xa8, 0xa8, 0xa8, 0xa8, 0xa8, 0xa8, 0xa8, 0xa8, 0xa8, 0xa8, 0xa8, 0xa8,
+       0xa8, 0xa8, 0xa8, 0xa8, 0xa8, 0xa8, 0xa8, 0xa8, 0xa8, 0xa8, 0xa8, 0xa8,
+       0xab, 0xab, 0xab, 0xab, 0xab, 0xab, 0xab, 0xab, 0xab, 0xab, 0xab, 0xab,
+       0xab, 0xab, 0xab, 0xab, 0xab, 0xab, 0xab, 0xab, 0xab, 0xab, 0xab, 0xab,
+       0xab, 0xab, 0xab, 0xab, 0xab, 0xab, 0xab, 0xab, 0xab, 0xab, 0xab, 0xab,
+       0xab, 0xab, 0xab, 0xab, 0xab, 0xab, 0xab, 0xab, 0xab, 0xab, 0xab, 0xab,
+       0xab, 0xab, 0xab, 0xab, 0xab, 0xab, 0xab, 0xab, 0xab, 0xab, 0xab, 0xab,
+       0xab, 0xab, 0xab, 0xab, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa,
+       0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa,
+       0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa,
+       0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa,
+       0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa,
+       0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0x2a
+} ; /* alaw_encode */
+
+static inline void
+alaw2s_array (unsigned char *buffer, int count, short *ptr)
+{      while (--count >= 0)
+               ptr [count] = alaw_decode [(int) buffer [count]] ;
+} /* alaw2s_array */
+
+static inline void
+alaw2i_array (unsigned char *buffer, int count, int *ptr)
+{      while (--count >= 0)
+               ptr [count] = alaw_decode [(int) buffer [count]] << 16 ;
+} /* alaw2i_array */
+
+static inline void
+alaw2f_array (unsigned char *buffer, int count, float *ptr, float normfact)
+{      while (--count >= 0)
+               ptr [count] = normfact * alaw_decode [(int) buffer [count]] ;
+} /* alaw2f_array */
+
+static inline void
+alaw2d_array (unsigned char *buffer, int count, double *ptr, double normfact)
+{      while (--count >= 0)
+               ptr [count] = normfact * alaw_decode [(int) buffer [count]] ;
+} /* alaw2d_array */
+
+static inline void
+s2alaw_array (const short *ptr, int count, unsigned char *buffer)
+{      while (--count >= 0)
+       {       if (ptr [count] >= 0)
+                       buffer [count] = alaw_encode [ptr [count] / 16] ;
+               else
+                       buffer [count] = 0x7F & alaw_encode [ptr [count] / -16] ;
+               } ;
+} /* s2alaw_array */
+
+static inline void
+i2alaw_array (const int *ptr, int count, unsigned char *buffer)
+{      while (--count >= 0)
+       {       if (ptr [count] >= 0)
+                       buffer [count] = alaw_encode [ptr [count] >> (16 + 4)] ;
+               else
+                       buffer [count] = 0x7F & alaw_encode [- ptr [count] >> (16 + 4)] ;
+               } ;
+} /* i2alaw_array */
+
+static inline void
+f2alaw_array (const float *ptr, int count, unsigned char *buffer, float normfact)
+{      while (--count >= 0)
+       {       if (ptr [count] >= 0)
+                       buffer [count] = alaw_encode [lrintf (normfact * ptr [count])] ;
+               else
+                       buffer [count] = 0x7F & alaw_encode [- lrintf (normfact * ptr [count])] ;
+               } ;
+} /* f2alaw_array */
+
+static inline void
+d2alaw_array (const double *ptr, int count, unsigned char *buffer, double normfact)
+{      while (--count >= 0)
+       {       if (ptr [count] >= 0)
+                       buffer [count] = alaw_encode [lrint (normfact * ptr [count])] ;
+               else
+                       buffer [count] = 0x7F & alaw_encode [- lrint (normfact * ptr [count])] ;
+               } ;
+} /* d2alaw_array */
+
+/*==============================================================================
+*/
+
+static sf_count_t
+alaw_read_alaw2s (SF_PRIVATE *psf, short *ptr, sf_count_t len)
+{      int                     bufferlen, readcount ;
+       sf_count_t      total = 0 ;
+
+       bufferlen = ARRAY_LEN (psf->u.ucbuf) ;
+
+       while (len > 0)
+       {       if (len < bufferlen)
+                       bufferlen = (int) len ;
+               readcount = psf_fread (psf->u.ucbuf, 1, bufferlen, psf) ;
+               alaw2s_array (psf->u.ucbuf, readcount, ptr + total) ;
+               total += readcount ;
+               if (readcount < bufferlen)
+                       break ;
+               len -= readcount ;
+               } ;
+
+       return total ;
+} /* alaw_read_alaw2s */
+
+static sf_count_t
+alaw_read_alaw2i (SF_PRIVATE *psf, int *ptr, sf_count_t len)
+{      int                     bufferlen, readcount ;
+       sf_count_t      total = 0 ;
+
+       bufferlen = ARRAY_LEN (psf->u.ucbuf) ;
+
+       while (len > 0)
+       {       if (len < bufferlen)
+                       bufferlen = (int) len ;
+               readcount = psf_fread (psf->u.ucbuf, 1, bufferlen, psf) ;
+               alaw2i_array (psf->u.ucbuf, readcount, ptr + total) ;
+               total += readcount ;
+               if (readcount < bufferlen)
+                       break ;
+               len -= readcount ;
+               } ;
+
+       return total ;
+} /* alaw_read_alaw2i */
+
+static sf_count_t
+alaw_read_alaw2f (SF_PRIVATE *psf, float *ptr, sf_count_t len)
+{      int                     bufferlen, readcount ;
+       sf_count_t      total = 0 ;
+       float   normfact ;
+
+       normfact = (psf->norm_float == SF_TRUE) ? 1.0 / ((float) 0x8000) : 1.0 ;
+
+       bufferlen = ARRAY_LEN (psf->u.ucbuf) ;
+
+       while (len > 0)
+       {       if (len < bufferlen)
+                       bufferlen = (int) len ;
+               readcount = psf_fread (psf->u.ucbuf, 1, bufferlen, psf) ;
+               alaw2f_array (psf->u.ucbuf, readcount, ptr + total, normfact) ;
+               total += readcount ;
+               if (readcount < bufferlen)
+                       break ;
+               len -= readcount ;
+               } ;
+
+       return total ;
+} /* alaw_read_alaw2f */
+
+static sf_count_t
+alaw_read_alaw2d (SF_PRIVATE *psf, double *ptr, sf_count_t len)
+{      int                     bufferlen, readcount ;
+       sf_count_t      total = 0 ;
+       double  normfact ;
+
+       normfact = (psf->norm_double) ? 1.0 / ((double) 0x8000) : 1.0 ;
+       bufferlen = ARRAY_LEN (psf->u.ucbuf) ;
+
+       while (len > 0)
+       {       if (len < bufferlen)
+                       bufferlen = (int) len ;
+               readcount = psf_fread (psf->u.ucbuf, 1, bufferlen, psf) ;
+               alaw2d_array (psf->u.ucbuf, readcount, ptr + total, normfact) ;
+               total += readcount ;
+               if (readcount < bufferlen)
+                       break ;
+               len -= readcount ;
+               } ;
+
+       return total ;
+} /* alaw_read_alaw2d */
+
+/*=============================================================================================
+*/
+
+static sf_count_t
+alaw_write_s2alaw      (SF_PRIVATE *psf, const short *ptr, sf_count_t len)
+{      int                     bufferlen, writecount ;
+       sf_count_t      total = 0 ;
+
+       bufferlen = ARRAY_LEN (psf->u.ucbuf) ;
+
+       while (len > 0)
+       {       if (len < bufferlen)
+                       bufferlen = (int) len ;
+               s2alaw_array (ptr + total, bufferlen, psf->u.ucbuf) ;
+               writecount = psf_fwrite (psf->u.ucbuf, 1, bufferlen, psf) ;
+               total += writecount ;
+               if (writecount < bufferlen)
+                       break ;
+               len -= writecount ;
+               } ;
+
+       return total ;
+} /* alaw_write_s2alaw */
+
+static sf_count_t
+alaw_write_i2alaw      (SF_PRIVATE *psf, const int *ptr, sf_count_t len)
+{      int                     bufferlen, writecount ;
+       sf_count_t      total = 0 ;
+
+       bufferlen = ARRAY_LEN (psf->u.ucbuf) ;
+
+       while (len > 0)
+       {       if (len < bufferlen)
+                       bufferlen = (int) len ;
+               i2alaw_array (ptr + total, bufferlen, psf->u.ucbuf) ;
+               writecount = psf_fwrite (psf->u.ucbuf, 1, bufferlen, psf) ;
+               total += writecount ;
+               if (writecount < bufferlen)
+                       break ;
+               len -= writecount ;
+               } ;
+
+       return total ;
+} /* alaw_write_i2alaw */
+
+static sf_count_t
+alaw_write_f2alaw      (SF_PRIVATE *psf, const float *ptr, sf_count_t len)
+{      int                     bufferlen, writecount ;
+       sf_count_t      total = 0 ;
+       float   normfact ;
+
+       normfact = (psf->norm_float == SF_TRUE) ? (1.0 * 0x7FFF) / 16.0 : 1.0 / 16 ;
+
+       bufferlen = ARRAY_LEN (psf->u.ucbuf) ;
+
+       while (len > 0)
+       {       if (len < bufferlen)
+                       bufferlen = (int) len ;
+               f2alaw_array (ptr + total, bufferlen, psf->u.ucbuf, normfact) ;
+               writecount = psf_fwrite (psf->u.ucbuf, 1, bufferlen, psf) ;
+               total += writecount ;
+               if (writecount < bufferlen)
+                       break ;
+               len -= writecount ;
+               } ;
+
+       return total ;
+} /* alaw_write_f2alaw */
+
+static sf_count_t
+alaw_write_d2alaw      (SF_PRIVATE *psf, const double *ptr, sf_count_t len)
+{      int                     bufferlen, writecount ;
+       sf_count_t      total = 0 ;
+       double  normfact ;
+
+       normfact = (psf->norm_double) ? (1.0 * 0x7FFF) / 16.0 : 1.0 / 16.0 ;
+
+       bufferlen = ARRAY_LEN (psf->u.ucbuf) ;
+
+       while (len > 0)
+       {       if (len < bufferlen)
+                       bufferlen = (int) len ;
+               d2alaw_array (ptr + total, bufferlen, psf->u.ucbuf, normfact) ;
+               writecount = psf_fwrite (psf->u.ucbuf, 1, bufferlen, psf) ;
+               total += writecount ;
+               if (writecount < bufferlen)
+                       break ;
+               len -= writecount ;
+               } ;
+
+       return total ;
+} /* alaw_write_d2alaw */
+
+/*
+** Do not edit or modify anything in this comment block.
+** The arch-tag line is a file identity tag for the GNU Arch 
+** revision control system.
+**
+** arch-tag: 289ccfc2-42a6-4f1f-a29f-4dcc9bfa8752
+*/
diff --git a/libs/libsndfile/src/au.c b/libs/libsndfile/src/au.c
new file mode 100644 (file)
index 0000000..3a5f93b
--- /dev/null
@@ -0,0 +1,453 @@
+/*
+** Copyright (C) 1999-2004 Erik de Castro Lopo <erikd@mega-nerd.com>
+**
+** This program is free software; you can redistribute it and/or modify
+** it under the terms of the GNU Lesser General Public License as published by
+** the Free Software Foundation; either version 2.1 of the License, or
+** (at your option) any later version.
+**
+** This program is distributed in the hope that it will be useful,
+** but WITHOUT ANY WARRANTY; without even the implied warranty of
+** MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+** GNU Lesser General Public License for more details.
+**
+** You should have received a copy of the GNU Lesser General Public License
+** along with this program; if not, write to the Free Software
+** Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA.
+*/
+
+#include       "sfconfig.h"
+
+#include       <stdio.h>
+#include       <fcntl.h>
+#include       <string.h>
+#include       <ctype.h>
+
+#include       "sndfile.h"
+#include       "sfendian.h"
+#include       "common.h"
+
+/*------------------------------------------------------------------------------
+** Macros to handle big/little endian issues.
+*/
+
+#define DOTSND_MARKER  (MAKE_MARKER ('.', 's', 'n', 'd'))
+#define DNSDOT_MARKER  (MAKE_MARKER ('d', 'n', 's', '.'))
+
+#define AU_DATA_OFFSET 24
+
+/*------------------------------------------------------------------------------
+** Known AU file encoding types.
+*/
+
+enum
+{      AU_ENCODING_ULAW_8                                      = 1,    /* 8-bit u-law samples */
+       AU_ENCODING_PCM_8                                       = 2,    /* 8-bit linear samples */
+       AU_ENCODING_PCM_16                                      = 3,    /* 16-bit linear samples */
+       AU_ENCODING_PCM_24                                      = 4,    /* 24-bit linear samples */
+       AU_ENCODING_PCM_32                                      = 5,    /* 32-bit linear samples */
+
+       AU_ENCODING_FLOAT                                       = 6,    /* floating-point samples */
+       AU_ENCODING_DOUBLE                                      = 7,    /* double-precision float samples */
+       AU_ENCODING_INDIRECT                            = 8,    /* fragmented sampled data */
+       AU_ENCODING_NESTED                                      = 9,    /* ? */
+       AU_ENCODING_DSP_CORE                            = 10,   /* DSP program */
+       AU_ENCODING_DSP_DATA_8                          = 11,   /* 8-bit fixed-point samples */
+       AU_ENCODING_DSP_DATA_16                         = 12,   /* 16-bit fixed-point samples */
+       AU_ENCODING_DSP_DATA_24                         = 13,   /* 24-bit fixed-point samples */
+       AU_ENCODING_DSP_DATA_32                         = 14,   /* 32-bit fixed-point samples */
+
+       AU_ENCODING_DISPLAY                                     = 16,   /* non-audio display data */
+       AU_ENCODING_MULAW_SQUELCH                       = 17,   /* ? */
+       AU_ENCODING_EMPHASIZED                          = 18,   /* 16-bit linear with emphasis */
+       AU_ENCODING_NEXT                                        = 19,   /* 16-bit linear with compression (NEXT) */
+       AU_ENCODING_COMPRESSED_EMPHASIZED       = 20,   /* A combination of the two above */
+       AU_ENCODING_DSP_COMMANDS                        = 21,   /* Music Kit DSP commands */
+       AU_ENCODING_DSP_COMMANDS_SAMPLES        = 22,   /* ? */
+
+       AU_ENCODING_ADPCM_G721_32                       = 23,   /* G721 32 kbs ADPCM - 4 bits per sample. */
+       AU_ENCODING_ADPCM_G722                          = 24,   /* G722 64 kbs ADPCM */
+       AU_ENCODING_ADPCM_G723_24                       = 25,   /* G723 24 kbs ADPCM - 3 bits per sample. */
+       AU_ENCODING_ADPCM_G723_40                       = 26,   /* G723 40 kbs ADPCM - 5 bits per sample. */
+
+       AU_ENCODING_ALAW_8                                      = 27
+} ;
+
+/*------------------------------------------------------------------------------
+** Typedefs.
+*/
+
+typedef        struct
+{      int             dataoffset ;
+       int             datasize ;
+       int             encoding ;
+    int                samplerate ;
+    int                channels ;
+} AU_FMT ;
+
+
+/*------------------------------------------------------------------------------
+** Private static functions.
+*/
+
+static int             au_close                (SF_PRIVATE *psf) ;
+
+static int     au_format_to_encoding   (int format) ;
+
+static int             au_write_header (SF_PRIVATE *psf, int calc_length) ;
+static int             au_read_header (SF_PRIVATE *psf) ;
+
+/*------------------------------------------------------------------------------
+** Public function.
+*/
+
+int
+au_open        (SF_PRIVATE *psf)
+{      int             subformat ;
+       int             error = 0 ;
+
+       if (psf->mode == SFM_READ || (psf->mode == SFM_RDWR && psf->filelength > 0))
+       {       if ((error = au_read_header (psf)))
+                       return error ;
+               } ;
+
+       if ((psf->sf.format & SF_FORMAT_TYPEMASK) != SF_FORMAT_AU)
+               return  SFE_BAD_OPEN_FORMAT ;
+
+       subformat = psf->sf.format & SF_FORMAT_SUBMASK ;
+
+       if (psf->mode == SFM_WRITE || psf->mode == SFM_RDWR)
+       {       psf->endian = psf->sf.format & SF_FORMAT_ENDMASK ;
+               if (CPU_IS_LITTLE_ENDIAN && psf->endian == SF_ENDIAN_CPU)
+                       psf->endian = SF_ENDIAN_LITTLE ;
+               else if (psf->endian != SF_ENDIAN_LITTLE)
+                       psf->endian = SF_ENDIAN_BIG ;
+
+               if (au_write_header (psf, SF_FALSE))
+                       return psf->error ;
+
+               psf->write_header = au_write_header ;
+               } ;
+
+       psf->container_close = au_close ;
+
+       psf->blockwidth = psf->bytewidth * psf->sf.channels ;
+
+       switch (subformat)
+       {       case SF_FORMAT_ULAW :   /* 8-bit Ulaw encoding. */
+                               ulaw_init (psf) ;
+                               break ;
+
+               case SF_FORMAT_PCM_S8 : /* 8-bit linear PCM. */
+                               error = pcm_init (psf) ;
+                               break ;
+
+               case SF_FORMAT_PCM_16 : /* 16-bit linear PCM. */
+               case SF_FORMAT_PCM_24 : /* 24-bit linear PCM */
+               case SF_FORMAT_PCM_32 : /* 32-bit linear PCM. */
+                               error = pcm_init (psf) ;
+                               break ;
+
+               case SF_FORMAT_ALAW :   /* 8-bit Alaw encoding. */
+                               alaw_init (psf) ;
+                               break ;
+
+               /* Lite remove start */
+               case SF_FORMAT_FLOAT :  /* 32-bit floats. */
+                               error = float32_init (psf) ;
+                               break ;
+
+               case SF_FORMAT_DOUBLE : /* 64-bit double precision floats. */
+                               error = double64_init (psf) ;
+                               break ;
+
+               case SF_FORMAT_G721_32 :
+                               error = g72x_init (psf) ;
+                               psf->sf.seekable = SF_FALSE ;
+                               break ;
+
+               case SF_FORMAT_G723_24 :
+                               error = g72x_init (psf) ;
+                               psf->sf.seekable = SF_FALSE ;
+                               break ;
+
+               case SF_FORMAT_G723_40 :
+                               error = g72x_init (psf) ;
+                               psf->sf.seekable = SF_FALSE ;
+                               break ;
+               /* Lite remove end */
+
+               default :       break ;
+               } ;
+
+       return error ;
+} /* au_open */
+
+/*------------------------------------------------------------------------------
+*/
+
+static int
+au_close       (SF_PRIVATE *psf)
+{
+       if (psf->mode == SFM_WRITE || psf->mode == SFM_RDWR)
+               au_write_header (psf, SF_TRUE) ;
+
+       return 0 ;
+} /* au_close */
+
+static int
+au_write_header (SF_PRIVATE *psf, int calc_length)
+{      sf_count_t      current ;
+       int                     encoding, datalength ;
+
+       if (psf->pipeoffset > 0)
+               return 0 ;
+
+       current = psf_ftell (psf) ;
+
+       if (calc_length)
+       {       psf->filelength = psf_get_filelen (psf) ;
+
+               psf->datalength = psf->filelength - psf->dataoffset ;
+               if (psf->dataend)
+                       psf->datalength -= psf->filelength - psf->dataend ;
+
+               psf->sf.frames = psf->datalength / (psf->bytewidth * psf->sf.channels) ;
+               } ;
+
+       encoding = au_format_to_encoding (psf->sf.format & SF_FORMAT_SUBMASK) ;
+       if (! encoding)
+               return (psf->error = SFE_BAD_OPEN_FORMAT) ;
+
+       /* Reset the current header length to zero. */
+       psf->header [0] = 0 ;
+       psf->headindex = 0 ;
+
+       /*
+       ** Only attempt to seek if we are not writng to a pipe. If we are
+       ** writing to a pipe we shouldn't be here anyway.
+       */
+       if (psf->is_pipe == SF_FALSE)
+               psf_fseek (psf, 0, SEEK_SET) ;
+
+       /*
+       **      AU format files allow a datalength value of -1 if the datalength
+       **      is not know at the time the header is written.
+       **      Also use this value of -1 if the datalength > 2 gigabytes.
+       */
+       if (psf->datalength     < 0 || psf->datalength > 0x7FFFFFFF)
+               datalength = -1 ;
+       else
+               datalength = (int) (psf->datalength & 0x7FFFFFFF) ;
+
+       if (psf->endian == SF_ENDIAN_BIG)
+       {       psf_binheader_writef (psf, "Em4", DOTSND_MARKER, AU_DATA_OFFSET) ;
+               psf_binheader_writef (psf, "E4444", datalength, encoding, psf->sf.samplerate, psf->sf.channels) ;
+               }
+       else if (psf->endian == SF_ENDIAN_LITTLE)
+       {       psf_binheader_writef (psf, "em4", DNSDOT_MARKER, AU_DATA_OFFSET) ;
+               psf_binheader_writef (psf, "e4444", datalength, encoding, psf->sf.samplerate, psf->sf.channels) ;
+               }
+       else
+               return (psf->error = SFE_BAD_OPEN_FORMAT) ;
+
+       /* Header construction complete so write it out. */
+       psf_fwrite (psf->header, psf->headindex, 1, psf) ;
+
+       if (psf->error)
+               return psf->error ;
+
+       psf->dataoffset = psf->headindex ;
+
+       if (current > 0)
+               psf_fseek (psf, current, SEEK_SET) ;
+
+       return psf->error ;
+} /* au_write_header */
+
+static int
+au_format_to_encoding (int format)
+{
+       switch (format)
+       {       case SF_FORMAT_PCM_S8 :         return AU_ENCODING_PCM_8 ;
+               case SF_FORMAT_PCM_16 :         return AU_ENCODING_PCM_16 ;
+               case SF_FORMAT_PCM_24 :         return AU_ENCODING_PCM_24 ;
+               case SF_FORMAT_PCM_32 :         return AU_ENCODING_PCM_32 ;
+
+               case SF_FORMAT_FLOAT :          return AU_ENCODING_FLOAT ;
+               case SF_FORMAT_DOUBLE :         return AU_ENCODING_DOUBLE ;
+
+               case SF_FORMAT_ULAW :           return AU_ENCODING_ULAW_8 ;
+               case SF_FORMAT_ALAW :           return AU_ENCODING_ALAW_8 ;
+
+               case SF_FORMAT_G721_32 :        return AU_ENCODING_ADPCM_G721_32 ;
+               case SF_FORMAT_G723_24 :        return AU_ENCODING_ADPCM_G723_24 ;
+               case SF_FORMAT_G723_40 :        return AU_ENCODING_ADPCM_G723_40 ;
+
+               default : break ;
+               } ;
+       return 0 ;
+} /* au_format_to_encoding */
+
+static int
+au_read_header (SF_PRIVATE *psf)
+{      AU_FMT  au_fmt ;
+       int             marker, dword ;
+
+       memset (&au_fmt, 0, sizeof (au_fmt)) ;
+       psf_binheader_readf (psf, "pm", 0, &marker) ;
+       psf_log_printf (psf, "%M\n", marker) ;
+
+       if (marker == DOTSND_MARKER)
+       {       psf->endian = SF_ENDIAN_BIG ;
+
+               psf_binheader_readf (psf, "E44444", &(au_fmt.dataoffset), &(au_fmt.datasize),
+                                       &(au_fmt.encoding), &(au_fmt.samplerate), &(au_fmt.channels)) ;
+               }
+       else if (marker == DNSDOT_MARKER)
+       {       psf->endian = SF_ENDIAN_LITTLE ;
+               psf_binheader_readf (psf, "e44444", &(au_fmt.dataoffset), &(au_fmt.datasize),
+                                       &(au_fmt.encoding), &(au_fmt.samplerate), &(au_fmt.channels)) ;
+               }
+       else
+               return SFE_AU_NO_DOTSND ;
+
+       psf_log_printf (psf, "  Data Offset : %d\n", au_fmt.dataoffset) ;
+
+       if (psf->fileoffset > 0 && au_fmt.datasize == -1)
+       {       psf_log_printf (psf, "  Data Size   : -1\n") ;
+               return SFE_AU_EMBED_BAD_LEN ;
+               } ;
+
+       if (psf->fileoffset > 0)
+       {       psf->filelength = au_fmt.dataoffset + au_fmt.datasize ;
+               psf_log_printf (psf, "  Data Size   : %d\n", au_fmt.datasize) ;
+               }
+       else if (au_fmt.datasize == -1 || au_fmt.dataoffset + au_fmt.datasize == psf->filelength)
+               psf_log_printf (psf, "  Data Size   : %d\n", au_fmt.datasize) ;
+       else if (au_fmt.dataoffset + au_fmt.datasize < psf->filelength)
+       {       psf->filelength = au_fmt.dataoffset + au_fmt.datasize ;
+               psf_log_printf (psf, "  Data Size   : %d\n", au_fmt.datasize) ;
+               }
+       else
+       {       dword = psf->filelength - au_fmt.dataoffset ;
+               psf_log_printf (psf, "  Data Size   : %d (should be %d)\n", au_fmt.datasize, dword) ;
+               au_fmt.datasize = dword ;
+               } ;
+
+       psf->dataoffset = au_fmt.dataoffset ;
+       psf->datalength = psf->filelength - psf->dataoffset ;
+
+       if (psf_ftell (psf) < psf->dataoffset)
+               psf_binheader_readf (psf, "j", psf->dataoffset - psf_ftell (psf)) ;
+
+       psf->sf.samplerate      = au_fmt.samplerate ;
+       psf->sf.channels        = au_fmt.channels ;
+
+       /* Only fill in type major. */
+       if (psf->endian == SF_ENDIAN_BIG)
+               psf->sf.format = SF_FORMAT_AU ;
+       else if (psf->endian == SF_ENDIAN_LITTLE)
+               psf->sf.format = SF_ENDIAN_LITTLE | SF_FORMAT_AU ;
+
+       psf_log_printf (psf, "  Encoding    : %d => ", au_fmt.encoding) ;
+
+       psf->sf.format = psf->sf.format & SF_FORMAT_ENDMASK ;
+
+       switch (au_fmt.encoding)
+       {       case AU_ENCODING_ULAW_8 :
+                               psf->sf.format |= SF_FORMAT_AU | SF_FORMAT_ULAW ;
+                               psf->bytewidth = 1 ;    /* Before decoding */
+                               psf_log_printf (psf, "8-bit ISDN u-law\n") ;
+                               break ;
+
+               case AU_ENCODING_PCM_8 :
+                               psf->sf.format |= SF_FORMAT_AU | SF_FORMAT_PCM_S8 ;
+                               psf->bytewidth = 1 ;
+                               psf_log_printf (psf, "8-bit linear PCM\n") ;
+                               break ;
+
+               case AU_ENCODING_PCM_16 :
+                               psf->sf.format |= SF_FORMAT_AU | SF_FORMAT_PCM_16 ;
+                               psf->bytewidth = 2 ;
+                               psf_log_printf (psf, "16-bit linear PCM\n") ;
+                               break ;
+
+               case AU_ENCODING_PCM_24 :
+                               psf->sf.format |= SF_FORMAT_AU | SF_FORMAT_PCM_24 ;
+                               psf->bytewidth = 3 ;
+                               psf_log_printf (psf, "24-bit linear PCM\n") ;
+                               break ;
+
+               case AU_ENCODING_PCM_32 :
+                               psf->sf.format |= SF_FORMAT_AU | SF_FORMAT_PCM_32 ;
+                               psf->bytewidth = 4 ;
+                               psf_log_printf (psf, "32-bit linear PCM\n") ;
+                               break ;
+
+               case AU_ENCODING_FLOAT :
+                               psf->sf.format |= SF_FORMAT_AU | SF_FORMAT_FLOAT ;
+                               psf->bytewidth = 4 ;
+                               psf_log_printf (psf, "32-bit float\n") ;
+                               break ;
+
+               case AU_ENCODING_DOUBLE :
+                               psf->sf.format |= SF_FORMAT_AU | SF_FORMAT_DOUBLE ;
+                               psf->bytewidth = 8 ;
+                               psf_log_printf (psf, "64-bit double precision float\n") ;
+                               break ;
+
+               case AU_ENCODING_ALAW_8 :
+                               psf->sf.format |= SF_FORMAT_AU | SF_FORMAT_ALAW ;
+                               psf->bytewidth = 1 ;    /* Before decoding */
+                               psf_log_printf (psf, "8-bit ISDN A-law\n") ;
+                               break ;
+
+               case AU_ENCODING_ADPCM_G721_32 :
+                               psf->sf.format |= SF_FORMAT_AU | SF_FORMAT_G721_32 ;
+                               psf->bytewidth = 0 ;
+                               psf_log_printf (psf, "G721 32kbs ADPCM\n") ;
+                               break ;
+
+               case AU_ENCODING_ADPCM_G723_24 :
+                               psf->sf.format |= SF_FORMAT_AU | SF_FORMAT_G723_24 ;
+                               psf->bytewidth = 0 ;
+                               psf_log_printf (psf, "G723 24kbs ADPCM\n") ;
+                               break ;
+
+               case AU_ENCODING_ADPCM_G723_40 :
+                               psf->sf.format |= SF_FORMAT_AU | SF_FORMAT_G723_40 ;
+                               psf->bytewidth = 0 ;
+                               psf_log_printf (psf, "G723 40kbs ADPCM\n") ;
+                               break ;
+
+               case AU_ENCODING_ADPCM_G722 :
+                               psf_log_printf (psf, "G722 64 kbs ADPCM (unsupported)\n") ;
+                               break ;
+
+               case AU_ENCODING_NEXT :
+                               psf_log_printf (psf, "Weird NeXT encoding format (unsupported)\n") ;
+                               break ;
+
+               default :
+                               psf_log_printf (psf, "Unknown!!\n") ;
+                               break ;
+               } ;
+
+       psf_log_printf (psf, "  Sample Rate : %d\n", au_fmt.samplerate) ;
+       psf_log_printf (psf, "  Channels    : %d\n", au_fmt.channels) ;
+
+       psf->blockwidth = psf->sf.channels * psf->bytewidth ;
+
+       if (! psf->sf.frames && psf->blockwidth)
+               psf->sf.frames = (psf->filelength - psf->dataoffset) / psf->blockwidth ;
+
+       return 0 ;
+} /* au_read_header */
+/*
+** Do not edit or modify anything in this comment block.
+** The arch-tag line is a file identity tag for the GNU Arch 
+** revision control system.
+**
+** arch-tag: 31f691b1-cde9-4ed2-9469-6bca60fb9cd0
+*/
diff --git a/libs/libsndfile/src/avr.c b/libs/libsndfile/src/avr.c
new file mode 100644 (file)
index 0000000..ad02c04
--- /dev/null
@@ -0,0 +1,254 @@
+/*
+** Copyright (C) 2004-2006 Erik de Castro Lopo <erikd@mega-nerd.com>
+**
+** This program is free software; you can redistribute it and/or modify
+** it under the terms of the GNU Lesser General Public License as published by
+** the Free Software Foundation; either version 2.1 of the License, or
+** (at your option) any later version.
+**
+** This program is distributed in the hope that it will be useful,
+** but WITHOUT ANY WARRANTY; without even the implied warranty of
+** MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+** GNU Lesser General Public License for more details.
+**
+** You should have received a copy of the GNU Lesser General Public License
+** along with this program; if not, write to the Free Software
+** Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA.
+*/
+
+#include "sfconfig.h"
+
+#include <stdio.h>
+#include <string.h>
+
+#include "sndfile.h"
+#include "sfendian.h"
+#include "common.h"
+
+#define TWOBIT_MARKER  (MAKE_MARKER ('2', 'B', 'I', 'T'))
+#define        AVR_HDR_SIZE    128
+
+#define        SFE_AVR_X       666
+
+/*
+** From: hyc@hanauma.Jpl.Nasa.Gov (Howard Chu)
+**
+** A lot of PD software exists to play Mac .snd files on the ST. One other
+** format that seems pretty popular (used by a number of commercial packages)
+** is the AVR format (from Audio Visual Research). This format has a 128 byte
+** header that looks like this (its actually packed, but thats not portable):
+*/
+
+typedef struct
+{      int             marker ;        /* 2BIT */
+       char    name [8] ;      /* null-padded sample name */
+       short   mono ;          /* 0 = mono, 0xffff = stereo */
+       short   rez ;           /* 8 = 8 bit, 16 = 16 bit */
+       short   sign ;          /* 0 = unsigned, 0xffff = signed */
+
+       short   loop ;          /* 0 = no loop, 0xffff = looping sample */
+       short   midi ;          /* 0xffff = no MIDI note assigned,  */
+                                               /*      0xffXX = single key note assignment */
+                                               /*      0xLLHH = key split, low/hi note */
+       int             srate ;         /* sample frequency in hertz */
+       int             frames ;        /* sample length in bytes or words (see rez) */
+       int             lbeg ;          /* offset to start of loop in bytes or words. */
+                                               /* set to zero if unused */
+       int             lend ;          /* offset to end of loop in bytes or words. */
+                                               /* set to sample length if unused */
+       short   res1 ;          /* Reserved, MIDI keyboard split */
+       short   res2 ;          /* Reserved, sample compression */
+       short   res3 ;          /* Reserved */
+       char    ext [20] ;      /* Additional filename space, used if (name[7] != 0) */
+       char    user [64] ; /* User defined. Typically ASCII message */
+} AVR_HEADER ;
+
+/*------------------------------------------------------------------------------
+** Private static functions.
+*/
+
+static int             avr_close (SF_PRIVATE *psf) ;
+
+static int             avr_read_header (SF_PRIVATE *psf) ;
+static int             avr_write_header (SF_PRIVATE *psf, int calc_length) ;
+
+/*------------------------------------------------------------------------------
+** Public function.
+*/
+
+int
+avr_open       (SF_PRIVATE *psf)
+{      int             error = 0 ;
+
+       if (psf->mode == SFM_READ || (psf->mode == SFM_RDWR && psf->filelength > 0))
+       {       if ((error = avr_read_header (psf)))
+                       return error ;
+               } ;
+
+       if ((psf->sf.format & SF_FORMAT_TYPEMASK) != SF_FORMAT_AVR)
+               return  SFE_BAD_OPEN_FORMAT ;
+
+       if (psf->mode == SFM_WRITE || psf->mode == SFM_RDWR)
+       {       psf->endian = psf->sf.format & SF_FORMAT_ENDMASK ;
+               psf->endian = SF_ENDIAN_BIG ;
+
+               if (avr_write_header (psf, SF_FALSE))
+                       return psf->error ;
+
+               psf->write_header = avr_write_header ;
+               } ;
+
+       psf->container_close = avr_close ;
+
+       psf->blockwidth = psf->bytewidth * psf->sf.channels ;
+
+       error = pcm_init (psf) ;
+
+       return error ;
+} /* avr_open */
+
+static int
+avr_read_header (SF_PRIVATE *psf)
+{      AVR_HEADER      hdr ;
+
+       memset (&hdr, 0, sizeof (hdr)) ;
+
+       psf_binheader_readf (psf, "pmb", 0, &hdr.marker, &hdr.name, sizeof (hdr.name)) ;
+       psf_log_printf (psf, "%M\n", hdr.marker) ;
+
+       if (hdr.marker != TWOBIT_MARKER)
+               return SFE_AVR_X ;
+
+       psf_log_printf (psf, "  Name        : %s\n", hdr.name) ;
+
+       psf_binheader_readf (psf, "E22222", &hdr.mono, &hdr.rez, &hdr.sign, &hdr.loop, &hdr.midi) ;
+
+       psf->sf.channels = (hdr.mono & 1) + 1 ;
+
+       psf_log_printf (psf, "  Channels    : %d\n  Bit width   : %d\n  Signed      : %s\n",
+                       (hdr.mono & 1) + 1, hdr.rez, hdr.sign ? "yes" : "no") ;
+
+       switch ((hdr.rez << 16) + (hdr.sign & 1))
+       {       case ((8 << 16) + 0) :
+                       psf->sf.format = SF_FORMAT_AVR | SF_FORMAT_PCM_U8 ;
+                       psf->bytewidth = 1 ;
+                       break ;
+
+               case ((8 << 16) + 1) :
+                       psf->sf.format = SF_FORMAT_AVR | SF_FORMAT_PCM_S8 ;
+                       psf->bytewidth = 1 ;
+                       break ;
+
+               case ((16 << 16) + 1) :
+                       psf->sf.format = SF_FORMAT_AVR | SF_FORMAT_PCM_16 ;
+                       psf->bytewidth = 2 ;
+                       break ;
+
+               default :
+                       psf_log_printf (psf, "Error : bad rez/sign combination.\n") ;
+                       return SFE_AVR_X ;
+               } ;
+
+       psf_binheader_readf (psf, "E4444", &hdr.srate, &hdr.frames, &hdr.lbeg, &hdr.lend) ;
+
+       psf->sf.frames = hdr.frames ;
+       psf->sf.samplerate = hdr.srate ;
+
+       psf_log_printf (psf, "  Frames      : %D\n", psf->sf.frames) ;
+       psf_log_printf (psf, "  Sample rate : %d\n", psf->sf.samplerate) ;
+
+       psf_binheader_readf (psf, "E222", &hdr.res1, &hdr.res2, &hdr.res3) ;
+       psf_binheader_readf (psf, "bb", hdr.ext, sizeof (hdr.ext), hdr.user, sizeof (hdr.user)) ;
+
+       psf_log_printf (psf, "  Ext         : %s\n  User        : %s\n", hdr.ext, hdr.user) ;
+
+       psf->endian = SF_ENDIAN_BIG ;
+
+       psf->dataoffset = AVR_HDR_SIZE ;
+       psf->datalength = hdr.frames * (hdr.rez / 8) ;
+
+       if (psf->fileoffset > 0)
+               psf->filelength = AVR_HDR_SIZE + psf->datalength ;
+
+       if (psf_ftell (psf) != psf->dataoffset)
+               psf_binheader_readf (psf, "j", psf->dataoffset - psf_ftell (psf)) ;
+
+       psf->blockwidth = psf->sf.channels * psf->bytewidth ;
+
+       if (psf->sf.frames == 0 && psf->blockwidth)
+               psf->sf.frames = (psf->filelength - psf->dataoffset) / psf->blockwidth ;
+
+       return 0 ;
+} /* avr_read_header */
+
+static int
+avr_write_header (SF_PRIVATE *psf, int calc_length)
+{      sf_count_t      current ;
+       int                     sign ;
+
+       if (psf->pipeoffset > 0)
+               return 0 ;
+
+       current = psf_ftell (psf) ;
+
+       if (calc_length)
+       {       psf->filelength = psf_get_filelen (psf) ;
+
+               psf->datalength = psf->filelength - psf->dataoffset ;
+               if (psf->dataend)
+                       psf->datalength -= psf->filelength - psf->dataend ;
+
+               psf->sf.frames = psf->datalength / (psf->bytewidth * psf->sf.channels) ;
+               } ;
+
+       /* Reset the current header length to zero. */
+       psf->header [0] = 0 ;
+       psf->headindex = 0 ;
+
+       /*
+       ** Only attempt to seek if we are not writng to a pipe. If we are
+       ** writing to a pipe we shouldn't be here anyway.
+       */
+       if (psf->is_pipe == SF_FALSE)
+               psf_fseek (psf, 0, SEEK_SET) ;
+
+       psf_binheader_writef (psf, "Emz22", TWOBIT_MARKER, make_size_t (8),
+                       psf->sf.channels == 2 ? 0xFFFF : 0, psf->bytewidth * 8) ;
+
+       sign = ((psf->sf.format & SF_FORMAT_SUBMASK) == SF_FORMAT_PCM_U8) ? 0 : 0xFFFF ;
+
+       psf_binheader_writef (psf, "E222", sign, 0, 0xFFFF) ;
+       psf_binheader_writef (psf, "E4444", psf->sf.samplerate, psf->sf.frames, 0, 0) ;
+
+       psf_binheader_writef (psf, "E222zz", 0, 0, 0, make_size_t (20), make_size_t (64)) ;
+
+       /* Header construction complete so write it out. */
+       psf_fwrite (psf->header, psf->headindex, 1, psf) ;
+
+       if (psf->error)
+               return psf->error ;
+
+       psf->dataoffset = psf->headindex ;
+
+       if (current > 0)
+               psf_fseek (psf, current, SEEK_SET) ;
+
+       return psf->error ;
+} /* avr_write_header */
+
+static int
+avr_close (SF_PRIVATE *psf)
+{
+       if (psf->mode == SFM_WRITE || psf->mode == SFM_RDWR)
+               avr_write_header (psf, SF_TRUE) ;
+
+       return 0 ;
+} /* avr_close */
+
+/*
+** Do not edit or modify anything in this comment block.
+** The arch-tag line is a file identity tag for the GNU Arch
+** revision control system.
+**
+** arch-tag: 0823d454-f39a-4a28-a776-607f1ef33b52
+*/
diff --git a/libs/libsndfile/src/broadcast.c b/libs/libsndfile/src/broadcast.c
new file mode 100644 (file)
index 0000000..e332277
--- /dev/null
@@ -0,0 +1,89 @@
+/*
+** Copyright (C) 2006 Paul Davis <paul@linuxaudiosystems.com>
+** Copyright (C) 2006 Erik de Castro Lopo <erikd@mega-nerd.com>
+**
+** This program is free software; you can redistribute it and/or modify
+** it under the terms of the GNU Lesser General Public License as published by
+** the Free Software Foundation; either version 2.1 of the License, or
+** (at your option) any later version.
+**
+** This program is distributed in the hope that it will be useful,
+** but WITHOUT ANY WARRANTY; without even the implied warranty of
+** MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+** GNU Lesser General Public License for more details.
+**
+** You should have received a copy of the GNU Lesser General Public License
+** along with this program; if not, write to the Free Software
+** Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA.
+*/
+
+#include <stdio.h>
+#include <string.h>
+
+#include "common.h"
+
+/*
+** Allocate and initialize a broadcast info structure.
+*/
+
+SF_BROADCAST_INFO*
+broadcast_info_alloc (void)
+{      SF_BROADCAST_INFO* bext ;
+
+       if ((bext = calloc (1, sizeof (SF_BROADCAST_INFO))) == NULL)
+               return NULL ;
+
+       return bext ;
+} /* broadcast_info_alloc */
+
+int
+broadcast_info_copy (SF_BROADCAST_INFO* dst, SF_BROADCAST_INFO* src)
+{      memcpy (dst, src, sizeof (SF_BROADCAST_INFO)) ;
+
+       /* Currently writing this version. */
+       dst->version = 1 ;
+
+       return SF_TRUE ;
+} /* broadcast_info_copy */
+
+int
+broadcast_add_coding_history (SF_BROADCAST_INFO* bext, unsigned int channels, unsigned int samplerate)
+{      char chnstr [16] ;
+       int count ;
+
+       switch (channels)
+       {       case 0 :
+                       return SF_FALSE ;
+
+               case 1 :
+                       strncpy (chnstr, "mono", sizeof (chnstr)) ;
+                       break ;
+
+               case 2 :
+                       strncpy (chnstr, "stereo", sizeof (chnstr)) ;
+                       break ;
+
+       default :
+               LSF_SNPRINTF (chnstr, sizeof (chnstr), "%uchn", channels) ;
+               break ;
+       }
+
+       count = LSF_SNPRINTF (bext->coding_history, sizeof (bext->coding_history), "F=%u,A=PCM,M=%s,W=24,T=%s-%s", samplerate, chnstr, PACKAGE, VERSION) ;
+
+       if (count >= SIGNED_SIZEOF (bext->coding_history))
+               bext->coding_history_size = sizeof (bext->coding_history) ;
+       else
+       {       count += count & 1 ;
+               bext->coding_history_size = count ;
+               } ;
+
+       return SF_TRUE ;
+} /* broadcast_add_coding_history */
+
+/*
+** Do not edit or modify anything in this comment block.
+** The following line is a file identity tag for the GNU Arch
+** revision control system.
+**
+** arch-tag: 4b3b69c7-d710-4424-9da0-5048534a0beb
+*/
diff --git a/libs/libsndfile/src/caf.c b/libs/libsndfile/src/caf.c
new file mode 100644 (file)
index 0000000..01f3719
--- /dev/null
@@ -0,0 +1,538 @@
+/*
+** Copyright (C) 2005 Erik de Castro Lopo <erikd@mega-nerd.com>
+**
+** This program is free software; you can redistribute it and/or modify
+** it under the terms of the GNU Lesser General Public License as published by
+** the Free Software Foundation; either version 2.1 of the License, or
+** (at your option) any later version.
+**
+** This program is distributed in the hope that it will be useful,
+** but WITHOUT ANY WARRANTY; without even the implied warranty of
+** MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+** GNU Lesser General Public License for more details.
+**
+** You should have received a copy of the GNU Lesser General Public License
+** along with this program; if not, write to the Free Software
+** Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA.
+*/
+
+#include       "sfconfig.h"
+
+#include       <stdio.h>
+#include       <stdlib.h>
+#include       <string.h>
+#include       <ctype.h>
+
+#include       "sndfile.h"
+#include       "sfendian.h"
+#include       "float_cast.h"
+#include       "common.h"
+
+/*------------------------------------------------------------------------------
+** Macros to handle big/little endian issues.
+*/
+
+#define aac_MARKER             MAKE_MARKER ('a', 'a', 'c', ' ')
+#define alac_MARKER            MAKE_MARKER ('a', 'l', 'a', 'c')
+#define alaw_MARKER            MAKE_MARKER ('a', 'l', 'a', 'w')
+#define caff_MARKER            MAKE_MARKER ('c', 'a', 'f', 'f')
+#define chan_MARKER            MAKE_MARKER ('c', 'h', 'a', 'n')
+#define data_MARKER            MAKE_MARKER ('d', 'a', 't', 'a')
+#define desc_MARKER            MAKE_MARKER ('d', 'e', 's', 'c')
+#define edct_MARKER            MAKE_MARKER ('e', 'd', 'c', 't')
+#define free_MARKER            MAKE_MARKER ('f', 'r', 'e', 'e')
+#define ima4_MARKER            MAKE_MARKER ('i', 'm', 'a', '4')
+#define info_MARKER            MAKE_MARKER ('i', 'n', 'f', 'o')
+#define inst_MARKER            MAKE_MARKER ('i', 'n', 's', 't')
+#define kuki_MARKER            MAKE_MARKER ('k', 'u', 'k', 'i')
+#define lpcm_MARKER            MAKE_MARKER ('l', 'p', 'c', 'm')
+#define mark_MARKER            MAKE_MARKER ('m', 'a', 'r', 'k')
+#define midi_MARKER            MAKE_MARKER ('m', 'i', 'd', 'i')
+#define mp1_MARKER             MAKE_MARKER ('.', 'm', 'p', '1')
+#define mp2_MARKER             MAKE_MARKER ('.', 'm', 'p', '2')
+#define mp3_MARKER             MAKE_MARKER ('.', 'm', 'p', '3')
+#define ovvw_MARKER            MAKE_MARKER ('o', 'v', 'v', 'w')
+#define pakt_MARKER            MAKE_MARKER ('p', 'a', 'k', 't')
+#define peak_MARKER            MAKE_MARKER ('p', 'e', 'a', 'k')
+#define regn_MARKER            MAKE_MARKER ('r', 'e', 'g', 'n')
+#define strg_MARKER            MAKE_MARKER ('s', 't', 'r', 'g')
+#define umid_MARKER            MAKE_MARKER ('u', 'm', 'i', 'd')
+#define uuid_MARKER            MAKE_MARKER ('u', 'u', 'i', 'd')
+#define ulaw_MARKER            MAKE_MARKER ('u', 'l', 'a', 'w')
+#define MAC3_MARKER            MAKE_MARKER ('M', 'A', 'C', '3')
+#define MAC6_MARKER            MAKE_MARKER ('M', 'A', 'C', '6')
+
+#define CAF_PEAK_CHUNK_SIZE(ch)        (sizeof (int) + ch * (sizeof (float) + 8))
+
+#define SFE_CAF_NOT_CAF        666
+#define SFE_CAF_NO_DESC        667
+#define SFE_CAF_BAD_PEAK 668
+
+/*------------------------------------------------------------------------------
+** Typedefs.
+*/
+
+typedef struct
+{      unsigned char srate [8] ;
+       unsigned int fmt_id ;
+       unsigned int fmt_flags ;
+       unsigned int pkt_bytes ;
+       unsigned int pkt_frames ;
+       unsigned int channels_per_frame ;
+       unsigned int bits_per_chan ;
+} DESC_CHUNK ;
+
+/*------------------------------------------------------------------------------
+** Private static functions.
+*/
+
+static int     caf_close (SF_PRIVATE *psf) ;
+static int     caf_read_header (SF_PRIVATE *psf) ;
+static int     caf_write_header (SF_PRIVATE *psf, int calc_length) ;
+
+/*------------------------------------------------------------------------------
+** Public function.
+*/
+
+int
+caf_open (SF_PRIVATE *psf)
+{      int     subformat, format, error = 0 ;
+
+       if (psf->mode == SFM_READ || (psf->mode == SFM_RDWR && psf->filelength > 0))
+       {       if ((error = caf_read_header (psf)))
+                       return error ;
+               } ;
+
+       subformat = psf->sf.format & SF_FORMAT_SUBMASK ;
+
+       if (psf->mode == SFM_WRITE || psf->mode == SFM_RDWR)
+       {       if (psf->is_pipe)
+                       return SFE_NO_PIPE_WRITE ;
+
+               format = psf->sf.format & SF_FORMAT_TYPEMASK ;
+               if (format != SF_FORMAT_CAF)
+                       return  SFE_BAD_OPEN_FORMAT ;
+
+               psf->blockwidth = psf->bytewidth * psf->sf.channels ;
+
+               if (psf->mode != SFM_RDWR || psf->filelength < 44)
+               {       psf->filelength = 0 ;
+                       psf->datalength = 0 ;
+                       psf->dataoffset = 0 ;
+                       psf->sf.frames = 0 ;
+                       } ;
+
+               psf->str_flags = SF_STR_ALLOW_START ;
+
+               /*
+               **      By default, add the peak chunk to floating point files. Default behaviour
+               **      can be switched off using sf_command (SFC_SET_PEAK_CHUNK, SF_FALSE).
+               */
+               if (psf->mode == SFM_WRITE && (subformat == SF_FORMAT_FLOAT || subformat == SF_FORMAT_DOUBLE))
+               {       if ((psf->peak_info = peak_info_calloc (psf->sf.channels)) == NULL)
+                               return SFE_MALLOC_FAILED ;
+                       psf->peak_info->peak_loc = SF_PEAK_START ;
+                       } ;
+
+               if ((error = caf_write_header (psf, SF_FALSE)) != 0)
+                       return error ;
+
+               psf->write_header = caf_write_header ;
+               } ;
+
+       psf->container_close = caf_close ;
+       /*psf->command = caf_command ;*/
+
+       switch (subformat)
+       {       case SF_FORMAT_PCM_S8 :
+               case SF_FORMAT_PCM_16 :
+               case SF_FORMAT_PCM_24 :
+               case SF_FORMAT_PCM_32 :
+                                       error = pcm_init (psf) ;
+                                       break ;
+
+               case SF_FORMAT_ULAW :
+                                       error = ulaw_init (psf) ;
+                                       break ;
+
+               case SF_FORMAT_ALAW :
+                                       error = alaw_init (psf) ;
+                                       break ;
+
+               /* Lite remove start */
+               case SF_FORMAT_FLOAT :
+                                       error = float32_init (psf) ;
+                                       break ;
+
+               case SF_FORMAT_DOUBLE :
+                                       error = double64_init (psf) ;
+                                       break ;
+               /* Lite remove end */
+
+               default :
+                       return SFE_UNSUPPORTED_ENCODING ;
+               } ;
+
+       return error ;
+} /* caf_open */
+
+static int
+caf_close (SF_PRIVATE *psf)
+{
+       if (psf->mode == SFM_WRITE || psf->mode == SFM_RDWR)
+               caf_write_header (psf, SF_TRUE) ;
+
+       return 0 ;
+} /* caf_close */
+
+/*------------------------------------------------------------------------------
+*/
+
+static int
+decode_desc_chunk (SF_PRIVATE *psf, const DESC_CHUNK *desc)
+{      int format ;
+
+       psf->sf.channels = desc->channels_per_frame ;
+
+       format = SF_FORMAT_CAF | (psf->endian == SF_ENDIAN_LITTLE ? SF_ENDIAN_LITTLE : 0) ;
+
+       if (desc->fmt_id == lpcm_MARKER && desc->fmt_flags & 1)
+       {       /* Floating point data. */
+               if (desc->bits_per_chan == 32 && desc->pkt_bytes == 4 * desc->channels_per_frame)
+               {       psf->bytewidth = 4 ;
+                       return format | SF_FORMAT_FLOAT ;
+                       } ;
+               if (desc->bits_per_chan == 64 && desc->pkt_bytes == 8 * desc->channels_per_frame)
+               {       psf->bytewidth = 8 ;
+                       return format | SF_FORMAT_DOUBLE ;
+                       } ;
+               } ;
+
+       if ((desc->fmt_flags & 1) != 0)
+       {       psf_log_printf (psf, "**** Ooops, 'desc' chunk suggests float data, but other info invalid.\n") ;
+               return 0 ;
+               } ;
+
+       if (desc->fmt_id == lpcm_MARKER)
+       {       /* Integer data. */
+               if (desc->bits_per_chan == 32 && desc->pkt_bytes == 4 * desc->channels_per_frame)
+               {       psf->bytewidth = 4 ;
+                       return format | SF_FORMAT_PCM_32 ;
+                       } ;
+               if (desc->bits_per_chan == 24 && desc->pkt_bytes == 3 * desc->channels_per_frame)
+               {       psf->bytewidth = 3 ;
+                       return format | SF_FORMAT_PCM_24 ;
+                       } ;
+               if (desc->bits_per_chan == 16 && desc->pkt_bytes == 2 * desc->channels_per_frame)
+               {       psf->bytewidth = 2 ;
+                       return format | SF_FORMAT_PCM_16 ;
+                       } ;
+               if (desc->bits_per_chan == 8 && desc->pkt_bytes == 1 * desc->channels_per_frame)
+               {       psf->bytewidth = 1 ;
+                       return format | SF_FORMAT_PCM_S8 ;
+                       } ;
+               } ;
+
+       if (desc->fmt_id == alaw_MARKER && desc->bits_per_chan == 8)
+       {       psf->bytewidth = 1 ;
+               return format | SF_FORMAT_ALAW ;
+               } ;
+
+       if (desc->fmt_id == ulaw_MARKER && desc->bits_per_chan == 8)
+       {       psf->bytewidth = 1 ;
+               return format | SF_FORMAT_ULAW ;
+               } ;
+
+       return 0 ;
+} /* decode_desc_chunk */
+
+static int
+caf_read_header (SF_PRIVATE *psf)
+{      DESC_CHUNK desc ;
+       sf_count_t chunk_size ;
+       double srate ;
+       short version, flags ;
+       int marker, k, have_data = 0 ;
+
+       memset (&desc, 0, sizeof (desc)) ;
+
+       /* Set position to start of file to begin reading header. */
+       psf_binheader_readf (psf, "pmE2E2", 0, &marker, &version, &flags) ;
+       psf_log_printf (psf, "%M\n  Version : %d\n  Flags   : %x\n", marker, version, flags) ;
+       if (marker != caff_MARKER)
+               return SFE_CAF_NOT_CAF ;
+
+       psf_binheader_readf (psf, "mE8b", &marker, &chunk_size, psf->u.ucbuf, 8) ;
+       srate = double64_be_read (psf->u.ucbuf) ;
+       LSF_SNPRINTF (psf->u.cbuf, sizeof (psf->u.cbuf), "%5.3f", srate) ;
+       psf_log_printf (psf, "%M : %D\n  Sample rate  : %s\n", marker, chunk_size, psf->u.cbuf) ;
+       if (marker != desc_MARKER)
+               return SFE_CAF_NO_DESC ;
+
+       if (chunk_size < sizeof (DESC_CHUNK))
+       {       psf_log_printf (psf, "**** Chunk size too small. Should be > 32 bytes.\n") ;
+               return SFE_MALFORMED_FILE ;
+               } ;
+
+       psf->sf.samplerate = lrint (srate) ;
+
+       psf_binheader_readf (psf, "mE44444", &desc.fmt_id, &desc.fmt_flags, &desc.pkt_bytes, &desc.pkt_frames,
+                       &desc.channels_per_frame, &desc.bits_per_chan) ;
+       psf_log_printf (psf, "  Format id    : %M\n  Format flags : %x\n  Bytes / packet   : %u\n"
+                       "  Frames / packet  : %u\n  Channels / frame : %u\n  Bits / channel   : %u\n",
+                       desc.fmt_id, desc.fmt_flags, desc.pkt_bytes, desc.pkt_frames, desc.channels_per_frame, desc.bits_per_chan) ;
+
+       if (chunk_size > sizeof (DESC_CHUNK))
+               psf_binheader_readf (psf, "j", (int) (chunk_size - sizeof (DESC_CHUNK))) ;
+
+       psf->sf.channels = desc.channels_per_frame ;
+
+       while (have_data == 0 && psf_ftell (psf) < psf->filelength - SIGNED_SIZEOF (marker))
+       {       psf_binheader_readf (psf, "mE8", &marker, &chunk_size) ;
+
+               switch (marker)
+               {       case peak_MARKER :
+                               psf_log_printf (psf, "%M : %D\n", marker, chunk_size) ;
+                               if (chunk_size != CAF_PEAK_CHUNK_SIZE (psf->sf.channels))
+                               {       psf_binheader_readf (psf, "j", (int) chunk_size) ;
+                                       psf_log_printf (psf, "*** File PEAK chunk %D should be %d.\n", chunk_size, CAF_PEAK_CHUNK_SIZE (psf->sf.channels)) ;
+                                       return SFE_CAF_BAD_PEAK ;
+                                       } ;
+
+                               if ((psf->peak_info = peak_info_calloc (psf->sf.channels)) == NULL)
+                                       return SFE_MALLOC_FAILED ;
+
+                               /* read in rest of PEAK chunk. */
+                               psf_binheader_readf (psf, "E4", & (psf->peak_info->edit_number)) ;
+                               psf_log_printf (psf, "  edit count : %d\n", psf->peak_info->edit_number) ;
+
+                               psf_log_printf (psf, "     Ch   Position      Value\n") ;
+                               for (k = 0 ; k < psf->sf.channels ; k++)
+                               {       sf_count_t position ;
+                                       float value ;
+
+                                       psf_binheader_readf (psf, "Ef8", &value, &position) ;
+                                       psf->peak_info->peaks [k].value = value ;
+                                       psf->peak_info->peaks [k].position = position ;
+
+                                       LSF_SNPRINTF (psf->u.cbuf, sizeof (psf->u.cbuf), "    %2d   %-12ld   %g\n", k, (long) position, value) ;
+                                       psf_log_printf (psf, psf->u.cbuf) ;
+                                       } ;
+
+                               psf->peak_info->peak_loc = SF_PEAK_START ;
+                               break ;
+
+                       case free_MARKER :
+                               psf_log_printf (psf, "%M : %D\n", marker, chunk_size) ;
+                               psf_binheader_readf (psf, "j", (int) chunk_size) ;
+                               break ;
+
+                       case data_MARKER :
+                               psf_log_printf (psf, "%M : %D\n", marker, chunk_size) ;
+                               psf_binheader_readf (psf, "E4", &k) ;
+                               psf_log_printf (psf, "  edit : %u\n", k) ;
+                               have_data = 1 ;
+                               break ;
+
+                       default :
+                               psf_log_printf (psf, " %M : %D (skipped)\n", marker, chunk_size) ;
+                               psf_binheader_readf (psf, "j", (int) chunk_size) ;
+                               break ;
+                       } ;
+               } ;
+
+       if (have_data == 0)
+       {       psf_log_printf (psf, "**** Error, could not find 'data' chunk.\n") ;
+               return SFE_MALFORMED_FILE ;
+               } ;
+
+       psf_log_printf (psf, "End\n") ;
+
+       psf->dataoffset = psf_ftell (psf) ;
+       psf->datalength = psf->filelength - psf->dataoffset ;
+       psf->endian = (desc.fmt_flags & 2) ? SF_ENDIAN_LITTLE : SF_ENDIAN_BIG ;
+
+       if ((psf->sf.format = decode_desc_chunk (psf, &desc)) == 0)
+               return SFE_UNSUPPORTED_ENCODING ;
+
+       if (psf->bytewidth > 0)
+               psf->sf.frames = psf->datalength / psf->bytewidth ;
+
+       return 0 ;
+} /* caf_read_header */
+
+/*------------------------------------------------------------------------------
+*/
+
+static int
+caf_write_header (SF_PRIVATE *psf, int calc_length)
+{      DESC_CHUNK desc ;
+       sf_count_t current, free_len ;
+       int subformat ;
+
+       memset (&desc, 0, sizeof (desc)) ;
+
+       current = psf_ftell (psf) ;
+
+       if (calc_length)
+       {       psf->filelength = psf_get_filelen (psf) ;
+
+               psf->datalength = psf->filelength - psf->dataoffset ;
+
+               if (psf->dataend)
+                       psf->datalength -= psf->filelength - psf->dataend ;
+
+               if (psf->bytewidth > 0)
+                       psf->sf.frames = psf->datalength / (psf->bytewidth * psf->sf.channels) ;
+               } ;
+
+       /* Reset the current header length to zero. */
+       psf->header [0] = 0 ;
+       psf->headindex = 0 ;
+       psf_fseek (psf, 0, SEEK_SET) ;
+
+       /* 'caff' marker, version and flags. */
+       psf_binheader_writef (psf, "Em22", caff_MARKER, 1, 0) ;
+
+       /* 'desc' marker and chunk size. */
+       psf_binheader_writef (psf, "Em8", desc_MARKER, (sf_count_t) (sizeof (DESC_CHUNK))) ;
+
+       double64_be_write (1.0 * psf->sf.samplerate, psf->u.ucbuf) ;
+       psf_binheader_writef (psf, "b", psf->u.ucbuf, 8) ;
+
+       subformat = psf->sf.format & SF_FORMAT_SUBMASK ;
+
+       psf->endian = psf->sf.format & SF_FORMAT_ENDMASK ;
+
+       if (CPU_IS_BIG_ENDIAN && (psf->endian == 0 || psf->endian == SF_ENDIAN_CPU))
+               psf->endian = SF_ENDIAN_BIG ;
+       else if (CPU_IS_LITTLE_ENDIAN && (psf->endian == SF_ENDIAN_LITTLE || psf->endian == SF_ENDIAN_CPU))
+               psf->endian = SF_ENDIAN_LITTLE ;
+
+       if (psf->endian == SF_ENDIAN_LITTLE)
+               desc.fmt_flags = 2 ;
+       else
+               psf->endian = SF_ENDIAN_BIG ;
+
+       /* initial section (same for all, it appears) */
+       switch (subformat)
+       {       case SF_FORMAT_PCM_S8 :
+                       desc.fmt_id = lpcm_MARKER ;
+                       psf->bytewidth = 1 ;
+                       desc.pkt_bytes = psf->bytewidth * psf->sf.channels ;
+                       desc.pkt_frames = 1 ;
+                       desc.channels_per_frame = psf->sf.channels ;
+                       desc.bits_per_chan = 8 ;
+                       break ;
+
+               case SF_FORMAT_PCM_16 :
+                       desc.fmt_id = lpcm_MARKER ;
+                       psf->bytewidth = 2 ;
+                       desc.pkt_bytes = psf->bytewidth * psf->sf.channels ;
+                       desc.pkt_frames = 1 ;
+                       desc.channels_per_frame = psf->sf.channels ;
+                       desc.bits_per_chan = 16 ;
+                       break ;
+
+               case SF_FORMAT_PCM_24 :
+                       psf->bytewidth = 3 ;
+                       desc.pkt_bytes = psf->bytewidth * psf->sf.channels ;
+                       desc.pkt_frames = 1 ;
+                       desc.channels_per_frame = psf->sf.channels ;
+                       desc.bits_per_chan = 24 ;
+                       desc.fmt_id = lpcm_MARKER ;
+                       break ;
+
+               case SF_FORMAT_PCM_32 :
+                       desc.fmt_id = lpcm_MARKER ;
+                       psf->bytewidth = 4 ;
+                       desc.pkt_bytes = psf->bytewidth * psf->sf.channels ;
+                       desc.pkt_frames = 1 ;
+                       desc.channels_per_frame = psf->sf.channels ;
+                       desc.bits_per_chan = 32 ;
+                       break ;
+
+               case SF_FORMAT_FLOAT :
+                       desc.fmt_id = lpcm_MARKER ;
+                       desc.fmt_flags |= 1 ;
+                       psf->bytewidth = 4 ;
+                       desc.pkt_bytes = psf->bytewidth * psf->sf.channels ;
+                       desc.pkt_frames = 1 ;
+                       desc.channels_per_frame = psf->sf.channels ;
+                       desc.bits_per_chan = 32 ;
+                       break ;
+
+               case SF_FORMAT_DOUBLE :
+                       desc.fmt_id = lpcm_MARKER ;
+                       desc.fmt_flags |= 1 ;
+                       psf->bytewidth = 8 ;
+                       desc.pkt_bytes = psf->bytewidth * psf->sf.channels ;
+                       desc.pkt_frames = 1 ;
+                       desc.channels_per_frame = psf->sf.channels ;
+                       desc.bits_per_chan = 64 ;
+                       break ;
+
+               case SF_FORMAT_ALAW :
+                       desc.fmt_id = alaw_MARKER ;
+                       psf->bytewidth = 1 ;
+                       desc.pkt_bytes = psf->bytewidth * psf->sf.channels ;
+                       desc.pkt_frames = 1 ;
+                       desc.channels_per_frame = psf->sf.channels ;
+                       desc.bits_per_chan = 8 ;
+                       break ;
+
+               case SF_FORMAT_ULAW :
+                       desc.fmt_id = ulaw_MARKER ;
+                       psf->bytewidth = 1 ;
+                       desc.pkt_bytes = psf->bytewidth * psf->sf.channels ;
+                       desc.pkt_frames = 1 ;
+                       desc.channels_per_frame = psf->sf.channels ;
+                       desc.bits_per_chan = 8 ;
+                       break ;
+
+               default :
+                       return SFE_UNIMPLEMENTED ;
+               } ;
+
+       psf_binheader_writef (psf, "mE44444", desc.fmt_id, desc.fmt_flags, desc.pkt_bytes, desc.pkt_frames, desc.channels_per_frame, desc.bits_per_chan) ;
+
+#if 0
+       if (psf->str_flags & SF_STR_LOCATE_START)
+               caf_write_strings (psf, SF_STR_LOCATE_START) ;
+#endif
+
+       if (psf->peak_info != NULL)
+       {       int k ;
+               psf_binheader_writef (psf, "Em84", peak_MARKER, (sf_count_t) CAF_PEAK_CHUNK_SIZE (psf->sf.channels), psf->peak_info->edit_number) ;
+               for (k = 0 ; k < psf->sf.channels ; k++)
+                       psf_binheader_writef (psf, "Ef8", (float) psf->peak_info->peaks [k].value, psf->peak_info->peaks [k].position) ;
+               } ;
+
+       /* Add free chunk so that the actual audio data starts at a multiple 0x1000. */
+       free_len = 0x1000 - psf->headindex - 16 - 12 ;
+       while (free_len < 0)
+               free_len += 0x1000 ;
+       psf_binheader_writef (psf, "Em8z", free_MARKER, free_len, (int) free_len) ;
+
+       psf_binheader_writef (psf, "Em84", data_MARKER, psf->datalength, 0) ;
+
+       psf_fwrite (psf->header, psf->headindex, 1, psf) ;
+       if (psf->error)
+               return psf->error ;
+
+       psf->dataoffset = psf->headindex ;
+       if (current < psf->dataoffset)
+               psf_fseek (psf, psf->dataoffset, SEEK_SET) ;
+       else if (current > 0)
+               psf_fseek (psf, current, SEEK_SET) ;
+
+       return psf->error ;
+} /* caf_write_header */
+
+/*
+** Do not edit or modify anything in this comment block.
+** The arch-tag line is a file identity tag for the GNU Arch
+** revision control system.
+**
+** arch-tag: 65883e65-bd3c-4618-9241-d3c02fd630bd
+*/
diff --git a/libs/libsndfile/src/command.c b/libs/libsndfile/src/command.c
new file mode 100644 (file)
index 0000000..edb793f
--- /dev/null
@@ -0,0 +1,367 @@
+/*
+** Copyright (C) 2001-2004 Erik de Castro Lopo <erikd@mega-nerd.com>
+**
+** This program is free software; you can redistribute it and/or modify
+** it under the terms of the GNU Lesser General Public License as published by
+** the Free Software Foundation; either version 2.1 of the License, or
+** (at your option) any later version.
+**
+** This program is distributed in the hope that it will be useful,
+** but WITHOUT ANY WARRANTY; without even the implied warranty of
+** MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+** GNU Lesser General Public License for more details.
+**
+** You should have received a copy of the GNU Lesser General Public License
+** along with this program; if not, write to the Free Software
+** Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA.
+*/
+
+#include       "sfconfig.h"
+
+#include       <stdio.h>
+#include       <string.h>
+#include       <math.h>
+
+#include       "sndfile.h"
+#include       "common.h"
+
+static SF_FORMAT_INFO const simple_formats [] =
+{
+       {       SF_FORMAT_AIFF | SF_FORMAT_PCM_16,
+               "AIFF (Apple/SGI 16 bit PCM)", "aiff"
+               },
+
+       {       SF_FORMAT_AIFF | SF_FORMAT_FLOAT,
+               "AIFF (Apple/SGI 32 bit float)", "aifc"
+               },
+
+       {       SF_FORMAT_AIFF | SF_FORMAT_PCM_S8,
+               "AIFF (Apple/SGI 8 bit PCM)", "aiff"
+               },
+
+       {       SF_FORMAT_AU | SF_FORMAT_PCM_16,
+               "AU (Sun/Next 16 bit PCM)", "au"
+               },
+
+       {       SF_FORMAT_AU | SF_FORMAT_ULAW,
+               "AU (Sun/Next 8-bit u-law)", "au"
+               },
+
+       {       SF_FORMAT_CAF | SF_FORMAT_PCM_16,
+               "CAF (Apple 16 bit PCM)", "caf"
+               },
+
+#ifdef HAVE_FLAC_ALL_H
+       {       SF_FORMAT_FLAC | SF_FORMAT_PCM_16,
+               "FLAC 16 bit", "flac"
+               },
+#endif
+
+       {       SF_FORMAT_RAW | SF_FORMAT_VOX_ADPCM,
+               "OKI Dialogic VOX ADPCM", "vox"
+               },
+
+       {       SF_FORMAT_WAV | SF_FORMAT_PCM_16,
+               "WAV (Microsoft 16 bit PCM)", "wav"
+               },
+
+       {       SF_FORMAT_WAV | SF_FORMAT_FLOAT,
+               "WAV (Microsoft 32 bit float)", "wav"
+               },
+
+       {       SF_FORMAT_WAV | SF_FORMAT_IMA_ADPCM,
+               "WAV (Microsoft 4 bit IMA ADPCM)", "wav"
+               },
+
+       {       SF_FORMAT_WAV | SF_FORMAT_MS_ADPCM,
+               "WAV (Microsoft 4 bit MS ADPCM)", "wav"
+               },
+
+       {       SF_FORMAT_WAV | SF_FORMAT_PCM_U8,
+               "WAV (Microsoft 8 bit PCM)", "wav"
+               },
+
+} ; /* simple_formats */
+
+int
+psf_get_format_simple_count    (void)
+{      return (sizeof (simple_formats) / sizeof (SF_FORMAT_INFO)) ;
+} /* psf_get_format_simple_count */
+
+int
+psf_get_format_simple (SF_FORMAT_INFO *data)
+{      int indx ;
+
+       if (data->format < 0 || data->format >= (SIGNED_SIZEOF (simple_formats) / SIGNED_SIZEOF (SF_FORMAT_INFO)))
+               return SFE_BAD_CONTROL_CMD ;
+
+       indx = data->format ;
+       memcpy (data, &(simple_formats [indx]), SIGNED_SIZEOF (SF_FORMAT_INFO)) ;
+
+       return 0 ;
+} /* psf_get_format_simple */
+
+/*============================================================================
+** Major format info.
+*/
+
+static SF_FORMAT_INFO const major_formats [] =
+{
+       {       SF_FORMAT_AIFF,         "AIFF (Apple/SGI)",                                             "aiff"  },
+       {       SF_FORMAT_AU,           "AU (Sun/NeXT)",                                                "au"    },
+       {       SF_FORMAT_AVR,          "AVR (Audio Visual Research)",                  "avr"   },
+       {       SF_FORMAT_CAF,          "CAF (Apple Core Audio File)",                  "caf"   },
+#ifdef HAVE_FLAC_ALL_H
+       {       SF_FORMAT_FLAC,         "FLAC (FLAC Lossless Audio Codec)",             "flac"  },
+#endif
+       {       SF_FORMAT_HTK,          "HTK (HMM Tool Kit)",                                   "htk"   },
+       {       SF_FORMAT_SVX,          "IFF (Amiga IFF/SVX8/SV16)",                    "iff"   },
+       {       SF_FORMAT_MAT4,         "MAT4 (GNU Octave 2.0 / Matlab 4.2)",   "mat"   },
+       {       SF_FORMAT_MAT5,         "MAT5 (GNU Octave 2.1 / Matlab 5.0)",   "mat"   },
+       {       SF_FORMAT_PAF,          "PAF (Ensoniq PARIS)",                                  "paf"   },
+       {       SF_FORMAT_PVF,          "PVF (Portable Voice Format)",                  "pvf"   },
+       {       SF_FORMAT_RAW,          "RAW (header-less)",                                    "raw"   },
+       {       SF_FORMAT_SD2,          "SD2 (Sound Designer II)",                              "sd2"   },
+       {       SF_FORMAT_SDS,          "SDS (Midi Sample Dump Standard)",              "sds"   },
+       {       SF_FORMAT_IRCAM,        "SF (Berkeley/IRCAM/CARL)",                             "sf"    },
+       {       SF_FORMAT_VOC,          "VOC (Creative Labs)",                                  "voc"   },
+       {       SF_FORMAT_W64,          "W64 (SoundFoundry WAVE 64)",                   "w64"   },
+       {       SF_FORMAT_WAV,          "WAV (Microsoft)",                                              "wav"   },
+       {       SF_FORMAT_NIST,         "WAV (NIST Sphere)",                                    "wav"   },
+       {       SF_FORMAT_WAVEX,        "WAVEX (Microsoft)",                                    "wav"   },
+       {       SF_FORMAT_XI,           "XI (FastTracker 2)",                                   "xi"    },
+
+} ; /* major_formats */
+
+int
+psf_get_format_major_count     (void)
+{      return (sizeof (major_formats) / sizeof (SF_FORMAT_INFO)) ;
+} /* psf_get_format_major_count */
+
+int
+psf_get_format_major (SF_FORMAT_INFO *data)
+{      int indx ;
+
+       if (data->format < 0 || data->format >= (SIGNED_SIZEOF (major_formats) / SIGNED_SIZEOF (SF_FORMAT_INFO)))
+               return SFE_BAD_CONTROL_CMD ;
+
+       indx = data->format ;
+       memcpy (data, &(major_formats [indx]), SIGNED_SIZEOF (SF_FORMAT_INFO)) ;
+
+       return 0 ;
+} /* psf_get_format_major */
+
+/*============================================================================
+** Subtype format info.
+*/
+
+static SF_FORMAT_INFO subtype_formats [] =
+{
+       {       SF_FORMAT_PCM_S8,               "Signed 8 bit PCM",             NULL    },
+       {       SF_FORMAT_PCM_16,               "Signed 16 bit PCM",    NULL    },
+       {       SF_FORMAT_PCM_24,               "Signed 24 bit PCM",    NULL    },
+       {       SF_FORMAT_PCM_32,               "Signed 32 bit PCM",    NULL    },
+
+       {       SF_FORMAT_PCM_U8,               "Unsigned 8 bit PCM",   NULL    },
+
+       {       SF_FORMAT_FLOAT,                "32 bit float",                 NULL    },
+       {       SF_FORMAT_DOUBLE,               "64 bit float",                 NULL    },
+
+       {       SF_FORMAT_ULAW,                 "U-Law",                                NULL    },
+       {       SF_FORMAT_ALAW,                 "A-Law",                                NULL    },
+       {       SF_FORMAT_IMA_ADPCM,    "IMA ADPCM",                    NULL    },
+       {       SF_FORMAT_MS_ADPCM,             "Microsoft ADPCM",              NULL    },
+
+       {       SF_FORMAT_GSM610,               "GSM 6.10",                             NULL    },
+
+       {       SF_FORMAT_G721_32,              "32kbs G721 ADPCM",             NULL    },
+       {       SF_FORMAT_G723_24,              "24kbs G723 ADPCM",             NULL    },
+
+       {       SF_FORMAT_DWVW_12,              "12 bit DWVW",                  NULL    },
+       {       SF_FORMAT_DWVW_16,              "16 bit DWVW",                  NULL    },
+       {       SF_FORMAT_DWVW_24,              "24 bit DWVW",                  NULL    },
+       {       SF_FORMAT_VOX_ADPCM,    "VOX ADPCM",                    "vox"   },
+
+       {       SF_FORMAT_DPCM_16,              "16 bit DPCM",                  NULL    },
+       {       SF_FORMAT_DPCM_8,               "8 bit DPCM",                   NULL    }
+} ; /* subtype_formats */
+
+int
+psf_get_format_subtype_count   (void)
+{      return (sizeof (subtype_formats) / sizeof (SF_FORMAT_INFO)) ;
+} /* psf_get_format_subtype_count */
+
+int
+psf_get_format_subtype (SF_FORMAT_INFO *data)
+{      int indx ;
+
+       if (data->format < 0 || data->format >= (SIGNED_SIZEOF (subtype_formats) / SIGNED_SIZEOF (SF_FORMAT_INFO)))
+               return SFE_BAD_CONTROL_CMD ;
+
+       indx = data->format ;
+       memcpy (data, &(subtype_formats [indx]), sizeof (SF_FORMAT_INFO)) ;
+
+       return 0 ;
+} /* psf_get_format_subtype */
+
+/*==============================================================================
+*/
+
+int
+psf_get_format_info (SF_FORMAT_INFO *data)
+{      int k, format ;
+
+       if (data->format & SF_FORMAT_TYPEMASK)
+       {       format = data->format & SF_FORMAT_TYPEMASK ;
+
+               for (k = 0 ; k < (SIGNED_SIZEOF (major_formats) / SIGNED_SIZEOF (SF_FORMAT_INFO)) ; k++)
+               {       if (format == major_formats [k].format)
+                       {       memcpy (data, &(major_formats [k]), sizeof (SF_FORMAT_INFO)) ;
+                               return 0 ;
+                               } ;
+                       } ;
+               }
+       else if (data->format & SF_FORMAT_SUBMASK)
+       {       format = data->format & SF_FORMAT_SUBMASK ;
+
+               for (k = 0 ; k < (SIGNED_SIZEOF (subtype_formats) / SIGNED_SIZEOF (SF_FORMAT_INFO)) ; k++)
+               {       if (format == subtype_formats [k].format)
+                       {       memcpy (data, &(subtype_formats [k]), sizeof (SF_FORMAT_INFO)) ;
+                               return 0 ;
+                               } ;
+                       } ;
+               } ;
+
+       memset (data, 0, sizeof (SF_FORMAT_INFO)) ;
+
+       return SFE_BAD_CONTROL_CMD ;
+} /* psf_get_format_info */
+
+/*==============================================================================
+*/
+
+double
+psf_calc_signal_max (SF_PRIVATE *psf, int normalize)
+{      sf_count_t      position ;
+       double          max_val, temp, *data ;
+       int                     k, len, readcount, save_state ;
+
+       /* If the file is not seekable, there is nothing we can do. */
+       if (! psf->sf.seekable)
+       {       psf->error = SFE_NOT_SEEKABLE ;
+               return  0.0 ;
+               } ;
+
+       if (! psf->read_double)
+       {       psf->error = SFE_UNIMPLEMENTED ;
+               return  0.0 ;
+               } ;
+
+       save_state = sf_command ((SNDFILE*) psf, SFC_GET_NORM_DOUBLE, NULL, 0) ;
+       sf_command ((SNDFILE*) psf, SFC_SET_NORM_DOUBLE, NULL, normalize) ;
+
+       /* Brute force. Read the whole file and find the biggest sample. */
+       /* Get current position in file */
+       position = sf_seek ((SNDFILE*) psf, 0, SEEK_CUR) ;
+       /* Go to start of file. */
+       sf_seek ((SNDFILE*) psf, 0, SEEK_SET) ;
+
+       data = psf->u.dbuf ;
+       len = ARRAY_LEN (psf->u.dbuf) ;
+
+       for (readcount = 1, max_val = 0.0 ; readcount > 0 ; /* nothing */)
+       {       readcount = sf_read_double ((SNDFILE*) psf, data, len) ;
+               for (k = 0 ; k < readcount ; k++)
+               {       temp = fabs (data [k]) ;
+                       max_val = temp > max_val ? temp : max_val ;
+                       } ;
+               } ;
+
+       /* Return to SNDFILE to original state. */
+       sf_seek ((SNDFILE*) psf, position, SEEK_SET) ;
+       sf_command ((SNDFILE*) psf, SFC_SET_NORM_DOUBLE, NULL, save_state) ;
+
+       return  max_val ;
+} /* psf_calc_signal_max */
+
+int
+psf_calc_max_all_channels (SF_PRIVATE *psf, double *peaks, int normalize)
+{      sf_count_t      position ;
+       double          temp, *data ;
+       int                     k, len, readcount, save_state ;
+       int                     chan ;
+
+       /* If the file is not seekable, there is nothing we can do. */
+       if (! psf->sf.seekable)
+               return (psf->error = SFE_NOT_SEEKABLE) ;
+
+       if (! psf->read_double)
+               return (psf->error = SFE_UNIMPLEMENTED) ;
+
+       save_state = sf_command ((SNDFILE*) psf, SFC_GET_NORM_DOUBLE, NULL, 0) ;
+       sf_command ((SNDFILE*) psf, SFC_SET_NORM_DOUBLE, NULL, normalize) ;
+
+       memset (peaks, 0, sizeof (double) * psf->sf.channels) ;
+
+       /* Brute force. Read the whole file and find the biggest sample for each channel. */
+       position = sf_seek ((SNDFILE*) psf, 0, SEEK_CUR) ; /* Get current position in file */
+       sf_seek ((SNDFILE*) psf, 0, SEEK_SET) ;                 /* Go to start of file. */
+
+       len = ARRAY_LEN (psf->u.dbuf) ;
+
+       data = psf->u.dbuf ;
+
+       chan = 0 ;
+       readcount = len ;
+       while (readcount > 0)
+       {       readcount = sf_read_double ((SNDFILE*) psf, data, len) ;
+               for (k = 0 ; k < readcount ; k++)
+               {       temp = fabs (data [k]) ;
+                       peaks [chan] = temp > peaks [chan] ? temp : peaks [chan] ;
+                       chan = (chan + 1) % psf->sf.channels ;
+                       } ;
+               } ;
+
+       sf_seek ((SNDFILE*) psf, position, SEEK_SET) ;          /* Return to original position. */
+
+       sf_command ((SNDFILE*) psf, SFC_SET_NORM_DOUBLE, NULL, save_state) ;
+
+       return  0 ;
+} /* psf_calc_max_all_channels */
+
+int
+psf_get_signal_max (SF_PRIVATE *psf, double *peak)
+{      int k ;
+
+       if (psf->peak_info == NULL)
+               return SF_FALSE ;
+
+       peak [0] = psf->peak_info->peaks [0].value ;
+
+       for (k = 1 ; k < psf->sf.channels ; k++)
+               peak [0] = SF_MAX (peak [0], psf->peak_info->peaks [k].value) ;
+
+       return SF_TRUE ;
+} /* psf_get_signal_max */
+
+int
+psf_get_max_all_channels (SF_PRIVATE *psf, double *peaks)
+{      int k ;
+
+       if (psf->peak_info == NULL)
+               return SF_FALSE ;
+
+       for (k = 0 ; k < psf->sf.channels ; k++)
+               peaks [k] = psf->peak_info->peaks [k].value ;
+
+       return SF_TRUE ;
+}  /* psf_get_max_all_channels */
+
+
+/*
+** Do not edit or modify anything in this comment block.
+** The arch-tag line is a file identity tag for the GNU Arch 
+** revision control system.
+**
+** arch-tag: 0aae0d9d-ab2b-4d70-ade3-47a534666f8e
+*/
diff --git a/libs/libsndfile/src/common.c b/libs/libsndfile/src/common.c
new file mode 100644 (file)
index 0000000..fa0f4f7
--- /dev/null
@@ -0,0 +1,1290 @@
+/*
+** Copyright (C) 1999-2006 Erik de Castro Lopo <erikd@mega-nerd.com>
+**
+** This program is free software; you can redistribute it and/or modify
+** it under the terms of the GNU Lesser General Public License as published by
+** the Free Software Foundation; either version 2.1 of the License, or
+** (at your option) any later version.
+**
+** This program is distributed in the hope that it will be useful,
+** but WITHOUT ANY WARRANTY; without even the implied warranty of
+** MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+** GNU Lesser General Public License for more details.
+**
+** You should have received a copy of the GNU Lesser General Public License
+** along with this program; if not, write to the Free Software
+** Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA.
+*/
+
+#include       <stdarg.h>
+#include       <string.h>
+#include       <ctype.h>
+#include       <math.h>
+#include       <time.h>
+
+#include       "sndfile.h"
+#include       "sfendian.h"
+#include       "common.h"
+
+/*-----------------------------------------------------------------------------------------------
+** psf_log_printf allows libsndfile internal functions to print to an internal logbuffer which
+** can later be displayed.
+** The format specifiers are as for printf but without the field width and other modifiers.
+** Printing is performed to the logbuffer char array of the SF_PRIVATE struct.
+** Printing is done in such a way as to guarantee that the log never overflows the end of the
+** logbuffer array.
+*/
+
+static inline void
+log_putchar (SF_PRIVATE *psf, char ch)
+{      if (psf->logindex < SIGNED_SIZEOF (psf->logbuffer) - 1)
+       {       psf->logbuffer [psf->logindex++] = ch ;
+               psf->logbuffer [psf->logindex] = 0 ;
+               } ;
+       return ;
+} /* log_putchar */
+
+void
+psf_log_printf (SF_PRIVATE *psf, const char *format, ...)
+{      va_list                 ap ;
+       unsigned int    u ;
+       int                             d, tens, shift, width, width_specifier, left_align ;
+       char                    c, *strptr, istr [5], lead_char, sign_char ;
+
+       va_start (ap, format) ;
+
+       while ((c = *format++))
+       {       if (c != '%')
+               {       log_putchar (psf, c) ;
+                       continue ;
+                       } ;
+
+               if (format [0] == '%') /* Handle %% */
+               {       log_putchar (psf, '%') ;
+                       format ++ ;
+                       continue ;
+                       } ;
+
+               sign_char = 0 ;
+               left_align = SF_FALSE ;
+               while (1)
+               {       switch (format [0])
+                       {       case ' ' :
+                               case '+' :
+                                       sign_char = format [0] ;
+                                       format ++ ;
+                                       continue ;
+
+                               case '-' :
+                                       left_align = SF_TRUE ;
+                                       format ++ ;
+                                       continue ;
+
+                               default : break ;
+                               } ;
+
+                       break ;
+                       } ;
+
+               if (format [0] == 0)
+                       break ;
+
+               lead_char = ' ' ;
+               if (format [0] == '0')
+                       lead_char = '0' ;
+
+               width_specifier = 0 ;
+               while ((c = *format++) && isdigit (c))
+                       width_specifier = width_specifier * 10 + (c - '0') ;
+
+               switch (c)
+               {       case 0 : /* NULL character. */
+                                       va_end (ap) ;
+                                       return ;
+
+                       case 's': /* string */
+                                       strptr = va_arg (ap, char *) ;
+                                       if (strptr == NULL)
+                                               break ;
+                                       width_specifier -= strlen (strptr) ;
+                                       if (left_align == SF_FALSE)
+                                               while (width_specifier -- > 0)
+                                                       log_putchar (psf, ' ') ;
+                                       while (*strptr)
+                                               log_putchar (psf, *strptr++) ;
+                                       while (width_specifier -- > 0)
+                                               log_putchar (psf, ' ') ;
+                                       break ;
+
+                       case 'd': /* int */
+                                       d = va_arg (ap, int) ;
+
+                                       if (d < 0)
+                                       {       d = -d ;
+                                               sign_char = '-' ;
+                                               if (lead_char != '0' && left_align == SF_FALSE)
+                                                       width_specifier -- ;
+                                               } ;
+
+                                       tens = 1 ;
+                                       width = 1 ;
+                                       while (d / tens >= 10)
+                                       {       tens *= 10 ;
+                                               width ++ ;
+                                               } ;
+
+                                       width_specifier -= width ;
+
+                                       if (sign_char == ' ')
+                                       {       log_putchar (psf, ' ') ;
+                                               width_specifier -- ;
+                                               } ;
+
+                                       if (left_align == SF_FALSE && lead_char != '0')
+                                       {       if (sign_char == '+')
+                                                       width_specifier -- ;
+
+                                               while (width_specifier -- > 0)
+                                                       log_putchar (psf, lead_char) ;
+                                               } ;
+
+                                       if (sign_char == '+' || sign_char == '-')
+                                       {       log_putchar (psf, sign_char) ;
+                                               width_specifier -- ;
+                                               } ;
+
+                                       if (left_align == SF_FALSE)
+                                               while (width_specifier -- > 0)
+                                                       log_putchar (psf, lead_char) ;
+
+                                       while (tens > 0)
+                                       {       log_putchar (psf, '0' + d / tens) ;
+                                               d %= tens ;
+                                               tens /= 10 ;
+                                               } ;
+
+                                       while (width_specifier -- > 0)
+                                               log_putchar (psf, lead_char) ;
+                                       break ;
+
+                       case 'D': /* sf_count_t */
+                                       {       sf_count_t              D, Tens ;
+
+                                               D = va_arg (ap, sf_count_t) ;
+
+                                               if (D == 0)
+                                               {       while (-- width_specifier > 0)
+                                                               log_putchar (psf, lead_char) ;
+                                                       log_putchar (psf, '0') ;
+                                                       break ;
+                                                       }
+                                               if (D < 0)
+                                               {       log_putchar (psf, '-') ;
+                                                       D = -D ;
+                                                       } ;
+                                               Tens = 1 ;
+                                               width = 1 ;
+                                               while (D / Tens >= 10)
+                                               {       Tens *= 10 ;
+                                                       width ++ ;
+                                                       } ;
+
+                                               while (width_specifier > width)
+                                               {       log_putchar (psf, lead_char) ;
+                                                       width_specifier-- ;
+                                                       } ;
+
+                                               while (Tens > 0)
+                                               {       log_putchar (psf, '0' + D / Tens) ;
+                                                       D %= Tens ;
+                                                       Tens /= 10 ;
+                                                       } ;
+                                               } ;
+                                       break ;
+
+                       case 'u': /* unsigned int */
+                                       u = va_arg (ap, unsigned int) ;
+
+                                       tens = 1 ;
+                                       width = 1 ;
+                                       while (u / tens >= 10)
+                                       {       tens *= 10 ;
+                                               width ++ ;
+                                               } ;
+
+                                       width_specifier -= width ;
+
+                                       if (sign_char == ' ')
+                                       {       log_putchar (psf, ' ') ;
+                                               width_specifier -- ;
+                                               } ;
+
+                                       if (left_align == SF_FALSE && lead_char != '0')
+                                       {       if (sign_char == '+')
+                                                       width_specifier -- ;
+
+                                               while (width_specifier -- > 0)
+                                                       log_putchar (psf, lead_char) ;
+                                               } ;
+
+                                       if (sign_char == '+' || sign_char == '-')
+                                       {       log_putchar (psf, sign_char) ;
+                                               width_specifier -- ;
+                                               } ;
+
+                                       if (left_align == SF_FALSE)
+                                               while (width_specifier -- > 0)
+                                                       log_putchar (psf, lead_char) ;
+
+                                       while (tens > 0)
+                                       {       log_putchar (psf, '0' + u / tens) ;
+                                               u %= tens ;
+                                               tens /= 10 ;
+                                               } ;
+
+                                       while (width_specifier -- > 0)
+                                               log_putchar (psf, lead_char) ;
+                                       break ;
+
+                       case 'c': /* char */
+                                       c = va_arg (ap, int) & 0xFF ;
+                                       log_putchar (psf, c) ;
+                                       break ;
+
+                       case 'x': /* hex */
+                       case 'X': /* hex */
+                                       d = va_arg (ap, int) ;
+
+                                       if (d == 0)
+                                       {       while (--width_specifier > 0)
+                                                       log_putchar (psf, lead_char) ;
+                                               log_putchar (psf, '0') ;
+                                               break ;
+                                               } ;
+                                       shift = 28 ;
+                                       width = (width_specifier < 8) ? 8 : width_specifier ;
+                                       while (! ((0xF << shift) & d))
+                                       {       shift -= 4 ;
+                                               width -- ;
+                                               } ;
+
+                                       while (width > 0 && width_specifier > width)
+                                       {       log_putchar (psf, lead_char) ;
+                                               width_specifier-- ;
+                                               } ;
+
+                                       while (shift >= 0)
+                                       {       c = (d >> shift) & 0xF ;
+                                               log_putchar (psf, (c > 9) ? c + 'A' - 10 : c + '0') ;
+                                               shift -= 4 ;
+                                               } ;
+                                       break ;
+
+                       case 'M': /* int2str */
+                                       d = va_arg (ap, int) ;
+                                       if (CPU_IS_LITTLE_ENDIAN)
+                                       {       istr [0] = d & 0xFF ;
+                                               istr [1] = (d >> 8) & 0xFF ;
+                                               istr [2] = (d >> 16) & 0xFF ;
+                                               istr [3] = (d >> 24) & 0xFF ;
+                                               }
+                                       else
+                                       {       istr [3] = d & 0xFF ;
+                                               istr [2] = (d >> 8) & 0xFF ;
+                                               istr [1] = (d >> 16) & 0xFF ;
+                                               istr [0] = (d >> 24) & 0xFF ;
+                                               } ;
+                                       istr [4] = 0 ;
+                                       strptr = istr ;
+                                       while (*strptr)
+                                       {       c = *strptr++ ;
+                                               log_putchar (psf, c) ;
+                                               } ;
+                                       break ;
+
+                       default :
+                                       log_putchar (psf, '*') ;
+                                       log_putchar (psf, c) ;
+                                       log_putchar (psf, '*') ;
+                                       break ;
+                       } /* switch */
+               } /* while */
+
+       va_end (ap) ;
+       return ;
+} /* psf_log_printf */
+
+#ifndef PSF_LOG_PRINTF_ONLY
+/*-----------------------------------------------------------------------------------------------
+**  ASCII header printf functions.
+**  Some formats (ie NIST) use ascii text in their headers.
+**  Format specifiers are the same as the standard printf specifiers (uses vsnprintf).
+**  If this generates a compile error on any system, the author should be notified
+**  so an alternative vsnprintf can be provided.
+*/
+
+void
+psf_asciiheader_printf (SF_PRIVATE *psf, const char *format, ...)
+{      va_list argptr ;
+       int             maxlen ;
+       char    *start ;
+
+       maxlen = strlen ((char*) psf->header) ;
+       start   = ((char*) psf->header) + maxlen ;
+       maxlen  = sizeof (psf->header) - maxlen ;
+
+       va_start (argptr, format) ;
+       LSF_VSNPRINTF (start, maxlen, format, argptr) ;
+       va_end (argptr) ;
+
+       /* Make sure the string is properly terminated. */
+       start [maxlen - 1] = 0 ;
+
+       psf->headindex = strlen ((char*) psf->header) ;
+
+       return ;
+} /* psf_asciiheader_printf */
+
+/*-----------------------------------------------------------------------------------------------
+**  Binary header writing functions. Returns number of bytes written.
+**
+**  Format specifiers for psf_binheader_writef are as follows
+**             m       - marker - four bytes - no endian manipulation
+**
+**             e   - all following numerical values will be little endian
+**             E   - all following numerical values will be big endian
+**
+**             t   - all following O types will be truncated to 4 bytes
+**             T   - switch off truncation of all following O types
+**
+**             1       - single byte value
+**             2       - two byte value
+**             3       - three byte value
+**             4       - four byte value
+**             8       - eight byte value (sometimes written as 4 bytes)
+**
+**             s   - string preceded by a four byte length
+**             S   - string including null terminator
+**             f       - floating point data
+**             d       - double precision floating point data
+**             h       - 16 binary bytes value
+**
+**             b       - binary data (see below)
+**             z   - zero bytes (ses below)
+**             j       - jump forwards or backwards
+**
+**     To write a word followed by an int (both little endian) use:
+**             psf_binheader_writef ("e24", wordval, longval) ;
+**
+**     To write binary data use:
+**             psf_binheader_writef ("b", &bindata, sizeof (bindata)) ;
+**
+**     To write N zero bytes use:
+**                     NOTE: due to platform issues (ie x86-64) you should cast the
+**                     argument to size_t or ensure the variable type is size_t.
+**             psf_binheader_writef ("z", N) ;
+*/
+
+/* These macros may seem a bit messy but do prevent problems with processors which
+** seg. fault when asked to write an int or short to a non-int/short aligned address.
+*/
+
+static inline void
+header_put_byte (SF_PRIVATE *psf, char x)
+{      if (psf->headindex < SIGNED_SIZEOF (psf->header) - 1)
+               psf->header [psf->headindex++] = x ;
+} /* header_put_byte */
+
+#if (CPU_IS_BIG_ENDIAN == 1)
+static inline void
+header_put_marker (SF_PRIVATE *psf, int x)
+{      if (psf->headindex < SIGNED_SIZEOF (psf->header) - 4)
+       {       psf->header [psf->headindex++] = (x >> 24) ;
+               psf->header [psf->headindex++] = (x >> 16) ;
+               psf->header [psf->headindex++] = (x >> 8) ;
+               psf->header [psf->headindex++] = x ;
+               } ;
+} /* header_put_marker */
+
+#elif (CPU_IS_LITTLE_ENDIAN == 1)
+static inline void
+header_put_marker (SF_PRIVATE *psf, int x)
+{      if (psf->headindex < SIGNED_SIZEOF (psf->header) - 4)
+       {       psf->header [psf->headindex++] = x ;
+               psf->header [psf->headindex++] = (x >> 8) ;
+               psf->header [psf->headindex++] = (x >> 16) ;
+               psf->header [psf->headindex++] = (x >> 24) ;
+               } ;
+} /* header_put_marker */
+
+#else
+#      error "Cannot determine endian-ness of processor."
+#endif
+
+
+static inline void
+header_put_be_short (SF_PRIVATE *psf, int x)
+{      if (psf->headindex < SIGNED_SIZEOF (psf->header) - 2)
+       {       psf->header [psf->headindex++] = (x >> 8) ;
+               psf->header [psf->headindex++] = x ;
+               } ;
+} /* header_put_be_short */
+
+static inline void
+header_put_le_short (SF_PRIVATE *psf, int x)
+{      if (psf->headindex < SIGNED_SIZEOF (psf->header) - 2)
+       {       psf->header [psf->headindex++] = x ;
+               psf->header [psf->headindex++] = (x >> 8) ;
+               } ;
+} /* header_put_le_short */
+
+static inline void
+header_put_be_3byte (SF_PRIVATE *psf, int x)
+{      if (psf->headindex < SIGNED_SIZEOF (psf->header) - 3)
+       {       psf->header [psf->headindex++] = (x >> 16) ;
+               psf->header [psf->headindex++] = (x >> 8) ;
+               psf->header [psf->headindex++] = x ;
+               } ;
+} /* header_put_be_3byte */
+
+static inline void
+header_put_le_3byte (SF_PRIVATE *psf, int x)
+{      if (psf->headindex < SIGNED_SIZEOF (psf->header) - 3)
+       {       psf->header [psf->headindex++] = x ;
+               psf->header [psf->headindex++] = (x >> 8) ;
+               psf->header [psf->headindex++] = (x >> 16) ;
+               } ;
+} /* header_put_le_3byte */
+
+static inline void
+header_put_be_int (SF_PRIVATE *psf, int x)
+{      if (psf->headindex < SIGNED_SIZEOF (psf->header) - 4)
+       {       psf->header [psf->headindex++] = (x >> 24) ;
+               psf->header [psf->headindex++] = (x >> 16) ;
+               psf->header [psf->headindex++] = (x >> 8) ;
+               psf->header [psf->headindex++] = x ;
+               } ;
+} /* header_put_be_int */
+
+static inline void
+header_put_le_int (SF_PRIVATE *psf, int x)
+{      if (psf->headindex < SIGNED_SIZEOF (psf->header) - 4)
+       {       psf->header [psf->headindex++] = x ;
+               psf->header [psf->headindex++] = (x >> 8) ;
+               psf->header [psf->headindex++] = (x >> 16) ;
+               psf->header [psf->headindex++] = (x >> 24) ;
+               } ;
+} /* header_put_le_int */
+
+#if (SIZEOF_SF_COUNT_T == 4)
+
+static inline void
+header_put_be_8byte (SF_PRIVATE *psf, sf_count_t x)
+{      if (psf->headindex < SIGNED_SIZEOF (psf->header) - 8)
+       {       psf->header [psf->headindex++] = 0 ;
+               psf->header [psf->headindex++] = 0 ;
+               psf->header [psf->headindex++] = 0 ;
+               psf->header [psf->headindex++] = 0 ;
+               psf->header [psf->headindex++] = (x >> 24) ;
+               psf->header [psf->headindex++] = (x >> 16) ;
+               psf->header [psf->headindex++] = (x >> 8) ;
+               psf->header [psf->headindex++] = x ;
+               } ;
+} /* header_put_be_8byte */
+
+static inline void
+header_put_le_8byte (SF_PRIVATE *psf, sf_count_t x)
+{      if (psf->headindex < SIGNED_SIZEOF (psf->header) - 8)
+       {       psf->header [psf->headindex++] = x ;
+               psf->header [psf->headindex++] = (x >> 8) ;
+               psf->header [psf->headindex++] = (x >> 16) ;
+               psf->header [psf->headindex++] = (x >> 24) ;
+               psf->header [psf->headindex++] = 0 ;
+               psf->header [psf->headindex++] = 0 ;
+               psf->header [psf->headindex++] = 0 ;
+               psf->header [psf->headindex++] = 0 ;
+               } ;
+} /* header_put_le_8byte */
+
+#elif (SIZEOF_SF_COUNT_T == 8)
+
+static inline void
+header_put_be_8byte (SF_PRIVATE *psf, sf_count_t x)
+{      if (psf->headindex < SIGNED_SIZEOF (psf->header) - 8)
+       {       psf->header [psf->headindex++] = (x >> 56) ;
+               psf->header [psf->headindex++] = (x >> 48) ;
+               psf->header [psf->headindex++] = (x >> 40) ;
+               psf->header [psf->headindex++] = (x >> 32) ;
+               psf->header [psf->headindex++] = (x >> 24) ;
+               psf->header [psf->headindex++] = (x >> 16) ;
+               psf->header [psf->headindex++] = (x >> 8) ;
+               psf->header [psf->headindex++] = x ;
+               } ;
+} /* header_put_be_8byte */
+
+static inline void
+header_put_le_8byte (SF_PRIVATE *psf, sf_count_t x)
+{      if (psf->headindex < SIGNED_SIZEOF (psf->header) - 8)
+       {       psf->header [psf->headindex++] = x ;
+               psf->header [psf->headindex++] = (x >> 8) ;
+               psf->header [psf->headindex++] = (x >> 16) ;
+               psf->header [psf->headindex++] = (x >> 24) ;
+               psf->header [psf->headindex++] = (x >> 32) ;
+               psf->header [psf->headindex++] = (x >> 40) ;
+               psf->header [psf->headindex++] = (x >> 48) ;
+               psf->header [psf->headindex++] = (x >> 56) ;
+               } ;
+} /* header_put_le_8byte */
+
+#else
+#error "SIZEOF_SF_COUNT_T is not defined."
+#endif
+
+int
+psf_binheader_writef (SF_PRIVATE *psf, const char *format, ...)
+{      va_list argptr ;
+       sf_count_t              countdata ;
+       unsigned long   longdata ;
+       unsigned int    data ;
+       float                   floatdata ;
+       double                  doubledata ;
+       void                    *bindata ;
+       size_t                  size ;
+       char                    c, *strptr ;
+       int                             count = 0, trunc_8to4 ;
+
+       trunc_8to4 = SF_FALSE ;
+
+       va_start (argptr, format) ;
+
+       while ((c = *format++))
+       {       switch (c)
+               {       case ' ' : /* Do nothing. Just used to space out format string. */
+                                       break ;
+
+                       case 'e' : /* All conversions are now from LE to host. */
+                                       psf->rwf_endian = SF_ENDIAN_LITTLE ;
+                                       break ;
+
+                       case 'E' : /* All conversions are now from BE to host. */
+                                       psf->rwf_endian = SF_ENDIAN_BIG ;
+                                       break ;
+
+                       case 't' : /* All 8 byte values now get written as 4 bytes. */
+                                       trunc_8to4 = SF_TRUE ;
+                                       break ;
+
+                       case 'T' : /* All 8 byte values now get written as 8 bytes. */
+                                       trunc_8to4 = SF_FALSE ;
+                                       break ;
+
+                       case 'm' :
+                                       data = va_arg (argptr, unsigned int) ;
+                                       header_put_marker (psf, data) ;
+                                       count += 4 ;
+                                       break ;
+
+                       case '1' :
+                                       data = va_arg (argptr, unsigned int) ;
+                                       header_put_byte (psf, data) ;
+                                       count += 1 ;
+                                       break ;
+
+                       case '2' :
+                                       data = va_arg (argptr, unsigned int) ;
+                                       if (psf->rwf_endian == SF_ENDIAN_BIG)
+                                       {       header_put_be_short (psf, data) ;
+                                               }
+                                       else
+                                       {       header_put_le_short (psf, data) ;
+                                               } ;
+                                       count += 2 ;
+                                       break ;
+
+                       case '3' : /* tribyte */
+                                       data = va_arg (argptr, unsigned int) ;
+                                       if (psf->rwf_endian == SF_ENDIAN_BIG)
+                                       {       header_put_be_3byte (psf, data) ;
+                                               }
+                                       else
+                                       {       header_put_le_3byte (psf, data) ;
+                                               } ;
+                                       count += 3 ;
+                                       break ;
+
+                       case '4' :
+                                       data = va_arg (argptr, unsigned int) ;
+                                       if (psf->rwf_endian == SF_ENDIAN_BIG)
+                                       {       header_put_be_int (psf, data) ;
+                                               }
+                                       else
+                                       {       header_put_le_int (psf, data) ;
+                                               } ;
+                                       count += 4 ;
+                                       break ;
+
+                       case '8' :
+                                       countdata = va_arg (argptr, sf_count_t) ;
+                                       if (psf->rwf_endian == SF_ENDIAN_BIG && trunc_8to4 == SF_FALSE)
+                                       {       header_put_be_8byte (psf, countdata) ;
+                                               count += 8 ;
+                                               }
+                                       else if (psf->rwf_endian == SF_ENDIAN_LITTLE && trunc_8to4 == SF_FALSE)
+                                       {       header_put_le_8byte (psf, countdata) ;
+                                               count += 8 ;
+                                               }
+                                       else if (psf->rwf_endian == SF_ENDIAN_BIG && trunc_8to4 == SF_TRUE)
+                                       {       longdata = countdata & 0xFFFFFFFF ;
+                                               header_put_be_int (psf, longdata) ;
+                                               count += 4 ;
+                                               }
+                                       else if (psf->rwf_endian == SF_ENDIAN_LITTLE && trunc_8to4 == SF_TRUE)
+                                       {       longdata = countdata & 0xFFFFFFFF ;
+                                               header_put_le_int (psf, longdata) ;
+                                               count += 4 ;
+                                               }
+                                       break ;
+
+                       case 'f' :
+                                       /* Floats are passed as doubles. Is this always true? */
+                                       floatdata = (float) va_arg (argptr, double) ;
+                                       if (psf->rwf_endian == SF_ENDIAN_BIG)
+                                               float32_be_write (floatdata, psf->header + psf->headindex) ;
+                                       else
+                                               float32_le_write (floatdata, psf->header + psf->headindex) ;
+                                       psf->headindex += 4 ;
+                                       count += 4 ;
+                                       break ;
+
+                       case 'd' :
+                                       doubledata = va_arg (argptr, double) ;
+                                       if (psf->rwf_endian == SF_ENDIAN_BIG)
+                                               double64_be_write (doubledata, psf->header + psf->headindex) ;
+                                       else
+                                               double64_le_write (doubledata, psf->header + psf->headindex) ;
+                                       psf->headindex += 8 ;
+                                       count += 8 ;
+                                       break ;
+
+                       case 's' :
+                                       /* Write a C string (guaranteed to have a zero terminator). */
+                                       strptr = va_arg (argptr, char *) ;
+                                       size = strlen (strptr) + 1 ;
+                                       size += (size & 1) ;
+                                       if (psf->rwf_endian == SF_ENDIAN_BIG)
+                                               header_put_be_int (psf, size) ;
+                                       else
+                                               header_put_le_int (psf, size) ;
+                                       memcpy (&(psf->header [psf->headindex]), strptr, size) ;
+                                       psf->headindex += size ;
+                                       psf->header [psf->headindex - 1] = 0 ;
+                                       count += 4 + size ;
+                                       break ;
+
+                       case 'S' :
+                                       /*
+                                       **      Write an AIFF style string (no zero terminator but possibly
+                                       **      an extra pad byte if the string length is odd).
+                                       */
+                                       strptr = va_arg (argptr, char *) ;
+                                       size = strlen (strptr) ;
+                                       if (psf->rwf_endian == SF_ENDIAN_BIG)
+                                               header_put_be_int (psf, size) ;
+                                       else
+                                               header_put_le_int (psf, size) ;
+                                       memcpy (&(psf->header [psf->headindex]), strptr, size + 1) ;
+                                       size += (size & 1) ;
+                                       psf->headindex += size ;
+                                       psf->header [psf->headindex] = 0 ;
+                                       count += 4 + size ;
+                                       break ;
+
+                       case 'b' :
+                                       bindata = va_arg (argptr, void *) ;
+                                       size    = va_arg (argptr, size_t) ;
+                                       memcpy (&(psf->header [psf->headindex]), bindata, size) ;
+                                       psf->headindex += size ;
+                                       count += size ;
+                                       break ;
+
+                       case 'z' :
+                                       size = va_arg (argptr, size_t) ;
+                                       count += size ;
+                                       while (size)
+                                       {       psf->header [psf->headindex] = 0 ;
+                                               psf->headindex ++ ;
+                                               size -- ;
+                                               } ;
+                                       break ;
+
+                       case 'h' :
+                                       bindata = va_arg (argptr, void *) ;
+                                       memcpy (&(psf->header [psf->headindex]), bindata, 16) ;
+                                       psf->headindex += 16 ;
+                                       count += 16 ;
+                                       break ;
+
+                       case 'j' :
+                                       size = va_arg (argptr, size_t) ;
+                                       psf->headindex += size ;
+                                       count = size ;
+                                       break ;
+
+                       default :
+                               psf_log_printf (psf, "*** Invalid format specifier `%c'\n", c) ;
+                               psf->error = SFE_INTERNAL ;
+                               break ;
+                       } ;
+               } ;
+
+       va_end (argptr) ;
+       return count ;
+} /* psf_binheader_writef */
+
+/*-----------------------------------------------------------------------------------------------
+**  Binary header reading functions. Returns number of bytes read.
+**
+**     Format specifiers are the same as for header write function above with the following
+**     additions:
+**
+**             p   - jump a given number of position from start of file.
+**
+**     If format is NULL, psf_binheader_readf returns the current offset.
+*/
+
+#if (CPU_IS_BIG_ENDIAN == 1)
+#define        GET_MARKER(ptr) (       ((ptr) [0] << 24)       | ((ptr) [1] << 16) |   \
+                                                       ((ptr) [2] << 8)        | ((ptr) [3]) )
+
+#elif (CPU_IS_LITTLE_ENDIAN == 1)
+#define        GET_MARKER(ptr) (       ((ptr) [0])                     | ((ptr) [1] << 8) |    \
+                                                       ((ptr) [2] << 16)       | ((ptr) [3] << 24) )
+
+#else
+#      error "Cannot determine endian-ness of processor."
+#endif
+
+#define        GET_LE_SHORT(ptr)       ( ((ptr) [1] << 8) | ((ptr) [0]) )
+#define        GET_BE_SHORT(ptr)       ( ((ptr) [0] << 8) | ((ptr) [1]) )
+
+#define        GET_LE_3BYTE(ptr)       (       ((ptr) [2] << 16) | ((ptr) [1] << 8) | ((ptr) [0]) )
+#define        GET_BE_3BYTE(ptr)       (       ((ptr) [0] << 16) | ((ptr) [1] << 8) | ((ptr) [2]) )
+
+#define        GET_LE_INT(ptr)         (       ((ptr) [3] << 24)       | ((ptr) [2] << 16) |   \
+                                                               ((ptr) [1] << 8)        | ((ptr) [0]) )
+
+#define        GET_BE_INT(ptr)         (       ((ptr) [0] << 24)       | ((ptr) [1] << 16) |   \
+                                                               ((ptr) [2] << 8)        | ((ptr) [3]) )
+
+#if (SIZEOF_LONG == 4)
+#define        GET_LE_8BYTE(ptr)       (       ((ptr) [3] << 24)       | ((ptr) [2] << 16) |   \
+                                                               ((ptr) [1] << 8)        | ((ptr) [0]) )
+
+#define        GET_BE_8BYTE(ptr)       (       ((ptr) [4] << 24)       | ((ptr) [5] << 16) |   \
+                                                               ((ptr) [6] << 8)        | ((ptr) [7]) )
+#else
+#define        GET_LE_8BYTE(ptr)       (       (((ptr) [7] * 1L) << 56) | (((ptr) [6] * 1L) << 48) |   \
+                                                               (((ptr) [5] * 1L) << 40) | (((ptr) [4] * 1L) << 32) |   \
+                                                               (((ptr) [3] * 1L) << 24) | (((ptr) [2] * 1L) << 16) |   \
+                                                               (((ptr) [1] * 1L) << 8 ) | ((ptr) [0]))
+
+#define        GET_BE_8BYTE(ptr)       (       (((ptr) [0] * 1L) << 56) | (((ptr) [1] * 1L) << 48) |   \
+                                                               (((ptr) [2] * 1L) << 40) | (((ptr) [3] * 1L) << 32) |   \
+                                                               (((ptr) [4] * 1L) << 24) | (((ptr) [5] * 1L) << 16) |   \
+                                                               (((ptr) [6] * 1L) << 8 ) | ((ptr) [7]))
+
+#endif
+
+static int
+header_read (SF_PRIVATE *psf, void *ptr, int bytes)
+{      int count = 0 ;
+
+       if (psf->headindex >= SIGNED_SIZEOF (psf->header))
+       {       memset (ptr, 0, SIGNED_SIZEOF (psf->header) - psf->headindex) ;
+
+               /* This is the best that we can do. */
+               psf_fseek (psf, bytes, SEEK_CUR) ;
+               return bytes ;
+               } ;
+
+       if (psf->headindex + bytes > SIGNED_SIZEOF (psf->header))
+       {       int most ;
+
+               most = SIGNED_SIZEOF (psf->header) - psf->headindex ;
+               psf_fread (psf->header + psf->headend, 1, most, psf) ;
+               memset (ptr + most, 0, bytes - most) ;
+
+               psf_fseek (psf, bytes - most, SEEK_CUR) ;
+               return bytes ;
+               } ;
+
+       if (psf->headindex + bytes > psf->headend)
+       {       count = psf_fread (psf->header + psf->headend, 1, bytes - (psf->headend - psf->headindex), psf) ;
+               if (count != bytes - (int) (psf->headend - psf->headindex))
+               {       psf_log_printf (psf, "Error : psf_fread returned short count.\n") ;
+                       return 0 ;
+                       } ;
+               psf->headend += count ;
+               } ;
+
+       memcpy (ptr, psf->header + psf->headindex, bytes) ;
+       psf->headindex += bytes ;
+
+       return bytes ;
+} /* header_read */
+
+static void
+header_seek (SF_PRIVATE *psf, sf_count_t position, int whence)
+{
+
+       switch (whence)
+       {       case SEEK_SET :
+                       if (position > SIGNED_SIZEOF (psf->header))
+                       {       /* Too much header to cache so just seek instead. */
+                               psf_fseek (psf, position, whence) ;
+                               return ;
+                               } ;
+                       if (position > psf->headend)
+                               psf->headend += psf_fread (psf->header + psf->headend, 1, position - psf->headend, psf) ;
+                       psf->headindex = position ;
+                       break ;
+
+               case SEEK_CUR :
+                       if (psf->headindex + position < 0)
+                               break ;
+
+                       if (psf->headindex >= SIGNED_SIZEOF (psf->header))
+                       {       psf_fseek (psf, position, whence) ;
+                               return ;
+                               } ;
+
+                       if (psf->headindex + position <= psf->headend)
+                       {       psf->headindex += position ;
+                               break ;
+                               } ;
+
+                       if (psf->headindex + position > SIGNED_SIZEOF (psf->header))
+                       {       /* Need to jump this without caching it. */
+                               psf->headindex = psf->headend ;
+                               psf_fseek (psf, position, SEEK_CUR) ;
+                               break ;
+                               } ;
+
+                       psf->headend += psf_fread (psf->header + psf->headend, 1, position - (psf->headend - psf->headindex), psf) ;
+                       psf->headindex = psf->headend ;
+                       break ;
+
+               case SEEK_END :
+               default :
+                       psf_log_printf (psf, "Bad whence param in header_seek().\n") ;
+                       break ;
+               } ;
+
+       return ;
+} /* header_seek */
+
+static int
+header_gets (SF_PRIVATE *psf, char *ptr, int bufsize)
+{
+       int             k ;
+
+       for (k = 0 ; k < bufsize - 1 ; k++)
+       {       if (psf->headindex < psf->headend)
+               {       ptr [k] = psf->header [psf->headindex] ;
+                       psf->headindex ++ ;
+                       }
+               else
+               {       psf->headend += psf_fread (psf->header + psf->headend, 1, 1, psf) ;
+                       ptr [k] = psf->header [psf->headindex] ;
+                       psf->headindex = psf->headend ;
+                       } ;
+
+               if (ptr [k] == '\n')
+                       break ;
+               } ;
+
+       ptr [k] = 0 ;
+
+       return k ;
+} /* header_gets */
+
+int
+psf_binheader_readf (SF_PRIVATE *psf, char const *format, ...)
+{      va_list                 argptr ;
+       sf_count_t              *countptr, countdata ;
+       unsigned char   *ucptr, sixteen_bytes [16] ;
+       unsigned int    *intptr, intdata ;
+       unsigned short  *shortptr ;
+       char                    *charptr ;
+       float                   *floatptr ;
+       double                  *doubleptr ;
+       char                    c ;
+       int                             byte_count = 0, count ;
+
+       if (! format)
+               return psf_ftell (psf) ;
+
+       va_start (argptr, format) ;
+
+       while ((c = *format++))
+       {       switch (c)
+               {       case 'e' : /* All conversions are now from LE to host. */
+                                       psf->rwf_endian = SF_ENDIAN_LITTLE ;
+                                       break ;
+
+                       case 'E' : /* All conversions are now from BE to host. */
+                                       psf->rwf_endian = SF_ENDIAN_BIG ;
+                                       break ;
+
+                       case 'm' :
+                                       intptr = va_arg (argptr, unsigned int*) ;
+                                       ucptr = (unsigned char*) intptr ;
+                                       byte_count += header_read (psf, ucptr, sizeof (int)) ;
+                                       *intptr = GET_MARKER (ucptr) ;
+                                       break ;
+
+                       case 'h' :
+                                       intptr = va_arg (argptr, unsigned int*) ;
+                                       ucptr = (unsigned char*) intptr ;
+                                       byte_count += header_read (psf, sixteen_bytes, sizeof (sixteen_bytes)) ;
+                                       {       int k ;
+                                               intdata = 0 ;
+                                               for (k = 0 ; k < 16 ; k++)
+                                                       intdata ^= sixteen_bytes [k] << k ;
+                                               }
+                                       *intptr = intdata ;
+                                       break ;
+
+                       case '1' :
+                                       charptr = va_arg (argptr, char*) ;
+                                       *charptr = 0 ;
+                                       byte_count += header_read (psf, charptr, sizeof (char)) ;
+                                       break ;
+
+                       case '2' :
+                                       shortptr = va_arg (argptr, unsigned short*) ;
+                                       *shortptr = 0 ;
+                                       ucptr = (unsigned char*) shortptr ;
+                                       byte_count += header_read (psf, ucptr, sizeof (short)) ;
+                                       if (psf->rwf_endian == SF_ENDIAN_BIG)
+                                               *shortptr = GET_BE_SHORT (ucptr) ;
+                                       else
+                                               *shortptr = GET_LE_SHORT (ucptr) ;
+                                       break ;
+
+                       case '3' :
+                                       intptr = va_arg (argptr, unsigned int*) ;
+                                       *intptr = 0 ;
+                                       byte_count += header_read (psf, sixteen_bytes, 3) ;
+                                       if (psf->rwf_endian == SF_ENDIAN_BIG)
+                                               *intptr = GET_BE_3BYTE (sixteen_bytes) ;
+                                       else
+                                               *intptr = GET_LE_3BYTE (sixteen_bytes) ;
+                                       break ;
+
+                       case '4' :
+                                       intptr = va_arg (argptr, unsigned int*) ;
+                                       *intptr = 0 ;
+                                       ucptr = (unsigned char*) intptr ;
+                                       byte_count += header_read (psf, ucptr, sizeof (int)) ;
+                                       if (psf->rwf_endian == SF_ENDIAN_BIG)
+                                               *intptr = GET_BE_INT (ucptr) ;
+                                       else
+                                               *intptr = GET_LE_INT (ucptr) ;
+                                       break ;
+
+                       case '8' :
+                                       countptr = va_arg (argptr, sf_count_t *) ;
+                                       *countptr = 0 ;
+                                       byte_count += header_read (psf, sixteen_bytes, 8) ;
+                                       if (psf->rwf_endian == SF_ENDIAN_BIG)
+                                               countdata = GET_BE_8BYTE (sixteen_bytes) ;
+                                       else
+                                               countdata = GET_LE_8BYTE (sixteen_bytes) ;
+                                       *countptr = countdata ;
+                                       break ;
+
+                       case 'f' : /* Float conversion */
+                                       floatptr = va_arg (argptr, float *) ;
+                                       *floatptr = 0.0 ;
+                                       byte_count += header_read (psf, floatptr, sizeof (float)) ;
+                                       if (psf->rwf_endian == SF_ENDIAN_BIG)
+                                               *floatptr = float32_be_read ((unsigned char*) floatptr) ;
+                                       else
+                                               *floatptr = float32_le_read ((unsigned char*) floatptr) ;
+                                       break ;
+
+                       case 'd' : /* double conversion */
+                                       doubleptr = va_arg (argptr, double *) ;
+                                       *doubleptr = 0.0 ;
+                                       byte_count += header_read (psf, doubleptr, sizeof (double)) ;
+                                       if (psf->rwf_endian == SF_ENDIAN_BIG)
+                                               *doubleptr = double64_be_read ((unsigned char*) doubleptr) ;
+                                       else
+                                               *doubleptr = double64_le_read ((unsigned char*) doubleptr) ;
+                                       break ;
+
+                       case 's' :
+                                       psf_log_printf (psf, "Format conversion 's' not implemented yet.\n") ;
+                                       /*
+                                       strptr = va_arg (argptr, char *) ;
+                                       size   = strlen (strptr) + 1 ;
+                                       size  += (size & 1) ;
+                                       longdata = H2LE_INT (size) ;
+                                       get_int (psf, longdata) ;
+                                       memcpy (&(psf->header [psf->headindex]), strptr, size) ;
+                                       psf->headindex += size ;
+                                       */
+                                       break ;
+
+                       case 'b' :
+                                       charptr = va_arg (argptr, char*) ;
+                                       count = va_arg (argptr, int) ;
+                                       if (count > 0)
+                                               byte_count += header_read (psf, charptr, count) ;
+                                       break ;
+
+                       case 'G' :
+                                       charptr = va_arg (argptr, char*) ;
+                                       count = va_arg (argptr, int) ;
+                                       if (count > 0)
+                                               byte_count += header_gets (psf, charptr, count) ;
+                                       break ;
+
+                       case 'z' :
+                                       psf_log_printf (psf, "Format conversion 'z' not implemented yet.\n") ;
+                                       /*
+                                       size    = va_arg (argptr, size_t) ;
+                                       while (size)
+                                       {       psf->header [psf->headindex] = 0 ;
+                                               psf->headindex ++ ;
+                                               size -- ;
+                                               } ;
+                                       */
+                                       break ;
+
+                       case 'p' :
+                                       /* Get the seek position first. */
+                                       count = va_arg (argptr, int) ;
+                                       header_seek (psf, count, SEEK_SET) ;
+                                       byte_count = count ;
+                                       break ;
+
+                       case 'j' :
+                                       /* Get the seek position first. */
+                                       count = va_arg (argptr, int) ;
+                                       header_seek (psf, count, SEEK_CUR) ;
+                                       byte_count += count ;
+                                       break ;
+
+                       default :
+                               psf_log_printf (psf, "*** Invalid format specifier `%c'\n", c) ;
+                               psf->error = SFE_INTERNAL ;
+                               break ;
+                       } ;
+               } ;
+
+       va_end (argptr) ;
+
+       return byte_count ;
+} /* psf_binheader_readf */
+
+/*-----------------------------------------------------------------------------------------------
+*/
+
+sf_count_t
+psf_default_seek (SF_PRIVATE *psf, int mode, sf_count_t samples_from_start)
+{      sf_count_t position, retval ;
+
+       if (! (psf->blockwidth && psf->dataoffset >= 0))
+       {       psf->error = SFE_BAD_SEEK ;
+               return  PSF_SEEK_ERROR ;
+               } ;
+
+       if (! psf->sf.seekable)
+       {       psf->error = SFE_NOT_SEEKABLE ;
+               return  PSF_SEEK_ERROR ;
+               } ;
+
+       position = psf->dataoffset + psf->blockwidth * samples_from_start ;
+
+       if ((retval = psf_fseek (psf, position, SEEK_SET)) != position)
+       {       psf->error = SFE_SEEK_FAILED ;
+               return PSF_SEEK_ERROR ;
+               } ;
+
+       mode = mode ;
+
+       return samples_from_start ;
+} /* psf_default_seek */
+
+/*-----------------------------------------------------------------------------------------------
+*/
+
+void
+psf_hexdump (void *ptr, int len)
+{      char    ascii [17], *data ;
+       int             k, m ;
+
+       if ((data = ptr) == NULL)
+               return ;
+       if (len <= 0)
+               return ;
+
+       puts ("") ;
+       for (k = 0 ; k < len ; k += 16)
+       {       memset (ascii, ' ', sizeof (ascii)) ;
+
+               printf ("%08X: ", k) ;
+               for (m = 0 ; m < 16 && k + m < len ; m++)
+               {       printf (m == 8 ? " %02X " : "%02X ", data [k + m] & 0xFF) ;
+                       ascii [m] = isprint (data [k + m]) ? data [k + m] : '.' ;
+                       } ;
+
+               if (m <= 8) printf (" ") ;
+               for ( ; m < 16 ; m++) printf ("   ") ;
+
+               ascii [16] = 0 ;
+               printf (" %s\n", ascii) ;
+               } ;
+
+       puts ("") ;
+} /* psf_hexdump */
+
+void
+psf_log_SF_INFO (SF_PRIVATE *psf)
+{      psf_log_printf (psf, "---------------------------------\n") ;
+
+       psf_log_printf (psf, " Sample rate :   %d\n", psf->sf.samplerate) ;
+       psf_log_printf (psf, " Frames      :   %D\n", psf->sf.frames) ;
+       psf_log_printf (psf, " Channels    :   %d\n", psf->sf.channels) ;
+
+       psf_log_printf (psf, " Format      :   0x%X\n", psf->sf.format) ;
+       psf_log_printf (psf, " Sections    :   %d\n", psf->sf.sections) ;
+       psf_log_printf (psf, " Seekable    :   %s\n", psf->sf.seekable ? "TRUE" : "FALSE") ;
+
+       psf_log_printf (psf, "---------------------------------\n") ;
+} /* psf_dump_SFINFO */
+
+/*========================================================================================
+*/
+
+SF_INSTRUMENT *
+psf_instrument_alloc (void)
+{      SF_INSTRUMENT *instr ;
+
+       instr = calloc (1, sizeof (SF_INSTRUMENT)) ;
+
+       if (instr == NULL)
+               return NULL ;
+
+       /* Set non-zero default values. */
+       instr->basenote = -1 ;
+       instr->velocity_lo = -1 ;
+       instr->velocity_hi = -1 ;
+       instr->key_lo = -1 ;
+       instr->key_hi = -1 ;
+
+       return instr ;
+} /* psf_instrument_alloc */
+
+void*
+psf_memset (void *s, int c, sf_count_t len)
+{      char    *ptr ;
+       int     setcount ;
+
+       ptr = (char *) s ;
+
+       while (len > 0)
+       {       setcount = (len > 0x10000000) ? 0x10000000 : (int) len ;
+
+               memset (ptr, c, setcount) ;
+
+               ptr += setcount ;
+               len -= setcount ;
+               } ;
+
+       return s ;
+} /* psf_memset */
+
+void psf_get_date_str (char *str, int maxlen)
+{      time_t          current ;
+       struct tm       timedata, *tmptr ;
+
+       time (&current) ;
+
+#if defined (HAVE_GMTIME_R)
+       /* If the re-entrant version is available, use it. */
+       tmptr = gmtime_r (&current, &timedata) ;
+#elif defined (HAVE_GMTIME)
+       /* Otherwise use the standard one and copy the data to local storage. */
+       tmptr = gmtime (&current) ;
+       memcpy (&timedata, tmptr, sizeof (timedata)) ;
+#else
+       tmptr = NULL ;
+#endif
+
+       if (tmptr)
+               LSF_SNPRINTF (str, maxlen, "%4d-%02d-%02d %02d:%02d:%02d UTC",
+                       1900 + timedata.tm_year, timedata.tm_mon, timedata.tm_mday,
+                       timedata.tm_hour, timedata.tm_min, timedata.tm_sec) ;
+       else
+               LSF_SNPRINTF (str, maxlen, "Unknown date") ;
+
+       return ;
+} /* psf_get_date_str */
+
+int
+subformat_to_bytewidth (int format)
+{
+       switch (format)
+       {       case SF_FORMAT_PCM_U8 :
+               case SF_FORMAT_PCM_S8 :
+                               return 1 ;
+               case SF_FORMAT_PCM_16 :
+                               return 2 ;
+               case SF_FORMAT_PCM_24 :
+                               return 3 ;
+               case SF_FORMAT_PCM_32 :
+               case SF_FORMAT_FLOAT :
+                               return 4 ;
+               case SF_FORMAT_DOUBLE :
+                               return 8 ;
+               } ;
+
+       return 0 ;
+} /* subformat_to_bytewidth */
+
+int
+s_bitwidth_to_subformat (int bits)
+{      static int array [] =
+       {       SF_FORMAT_PCM_S8, SF_FORMAT_PCM_16, SF_FORMAT_PCM_24, SF_FORMAT_PCM_32
+               } ;
+
+       if (bits < 8 || bits > 32)
+               return 0 ;
+
+       return array [((bits + 7) / 8) - 1] ;
+} /* bitwidth_to_subformat */
+
+int
+u_bitwidth_to_subformat (int bits)
+{      static int array [] =
+       {       SF_FORMAT_PCM_U8, SF_FORMAT_PCM_16, SF_FORMAT_PCM_24, SF_FORMAT_PCM_32
+               } ;
+
+       if (bits < 8 || bits > 32)
+               return 0 ;
+
+       return array [((bits + 7) / 8) - 1] ;
+} /* bitwidth_to_subformat */
+
+#endif /* PSF_LOG_PRINTF_ONLY */
+
+/*
+** Do not edit or modify anything in this comment block.
+** The arch-tag line is a file identity tag for the GNU Arch
+** revision control system.
+**
+** arch-tag: 33e9795e-f717-461a-9feb-65d083a56395
+*/
diff --git a/libs/libsndfile/src/common.h b/libs/libsndfile/src/common.h
new file mode 100644 (file)
index 0000000..c08ff67
--- /dev/null
@@ -0,0 +1,766 @@
+/*
+** Copyright (C) 1999-2006 Erik de Castro Lopo <erikd@mega-nerd.com>
+**
+** This program is free software; you can redistribute it and/or modify
+** it under the terms of the GNU Lesser General Public License as published by
+** the Free Software Foundation; either version 2.1 of the License, or
+** (at your option) any later version.
+**
+** This program is distributed in the hope that it will be useful,
+** but WITHOUT ANY WARRANTY; without even the implied warranty of
+** MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+** GNU Lesser General Public License for more details.
+**
+** You should have received a copy of the GNU Lesser General Public License
+** along with this program; if not, write to the Free Software
+** Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA.
+*/
+
+#ifndef SNDFILE_COMMON_H
+#define SNDFILE_COMMON_H
+
+#include "sfconfig.h"
+
+#include <stdlib.h>
+
+#if HAVE_STDINT_H
+#include <stdint.h>
+#endif
+
+#ifndef SNDFILE_H
+#include "sndfile.h"
+#elif HAVE_INTTYPES_H
+#include <inttypes.h>
+#endif
+
+#ifdef __cplusplus
+#error "This code is not designed to be compiled with a C++ compiler."
+#endif
+
+#ifdef UNUSED
+#elif defined (__GNUC__)
+#      define UNUSED(x) UNUSED_ ## x __attribute__ ((unused))
+#elif defined (__LCLINT__)
+#      define UNUSED(x) /*@unused@*/ x
+#else
+#      define UNUSED(x) x
+#endif
+
+#ifdef __GNUC__
+#      define WARN_UNUSED      __attribute__ ((warn_unused_result))
+#else
+#      define WARN_UNUSED
+#endif
+
+#define        SF_BUFFER_LEN                   (8192*2)
+#define        SF_FILENAME_LEN                 (512)
+#define SF_SYSERR_LEN                  (256)
+#define SF_MAX_STRINGS                 (16)
+#define SF_STR_BUFFER_LEN              (8192)
+#define        SF_HEADER_LEN                   (4100 + SF_STR_BUFFER_LEN)
+
+#define        PSF_SEEK_ERROR                  ((sf_count_t) -1)
+
+
+#define        BITWIDTH2BYTES(x)       (((x) + 7) / 8)
+
+/*     For some reason sizeof returns an unsigned  value which causes
+**     a warning when that value is added or subtracted from a signed
+**     value. Use SIGNED_SIZEOF instead.
+*/
+#define                SIGNED_SIZEOF(x)        ((int) sizeof (x))
+
+#define                ARRAY_LEN(x)    ((int) (sizeof (x) / sizeof ((x) [0])))
+
+#define                SF_MAX(a,b)             ((a) > (b) ? (a) : (b))
+#define                SF_MIN(a,b)             ((a) < (b) ? (a) : (b))
+
+enum
+{      /* PEAK chunk location. */
+       SF_PEAK_START           = 42,
+       SF_PEAK_END                     = 43,
+
+       /* PEAK chunk location. */
+       SF_SCALE_MAX            = 52,
+       SF_SCALE_MIN            = 53,
+
+       /* str_flags values. */
+       SF_STR_ALLOW_START      = 0x0100,
+       SF_STR_ALLOW_END        = 0x0200,
+
+       /* Location of strings. */
+       SF_STR_LOCATE_START     = 0x0400,
+       SF_STR_LOCATE_END       = 0x0800,
+
+       SFD_TYPEMASK            = 0x0FFFFFFF
+} ;
+
+#define                SFM_MASK        (SFM_READ | SFM_WRITE | SFM_RDWR)
+#define                SFM_UNMASK      (~SFM_MASK)
+
+/*---------------------------------------------------------------------------------------
+** Formats that may be supported at some time in the future.
+** When support is finalised, these values move to src/sndfile.h.
+*/
+
+enum
+{      /* Work in progress. */
+
+       /* Formats supported read only. */
+       SF_FORMAT_WVE                   = 0x4020000,            /* Psion ALaw Sound File */
+       SF_FORMAT_TXW                   = 0x4030000,            /* Yamaha TX16 sampler file */
+       SF_FORMAT_DWD                   = 0x4040000,            /* DiamondWare Digirized */
+
+       /* Following are detected but not supported. */
+       SF_FORMAT_OGG                   = 0x4090000,
+
+       SF_FORMAT_REX                   = 0x40A0000,            /* Propellorheads Rex/Rcy */
+       SF_FORMAT_REX2                  = 0x40D0000,            /* Propellorheads Rex2 */
+       SF_FORMAT_KRZ                   = 0x40E0000,            /* Kurzweil sampler file */
+       SF_FORMAT_WMA                   = 0x4100000,            /* Windows Media Audio. */
+       SF_FORMAT_SHN                   = 0x4110000,            /* Shorten. */
+
+       /* Unsupported encodings. */
+       SF_FORMAT_VORBIS                = 0x1001,
+
+       SF_FORMAT_SVX_FIB               = 0x1020,               /* SVX Fibonacci Delta encoding. */
+       SF_FORMAT_SVX_EXP               = 0x1021,               /* SVX Exponential Delta encoding. */
+
+       SF_FORMAT_PCM_N                 = 0x1030
+} ;
+
+/*---------------------------------------------------------------------------------------
+**     PEAK_CHUNK - This chunk type is common to both AIFF and WAVE files although their
+**     endian encodings are different.
+*/
+
+typedef struct
+{      double          value ;         /* signed value of peak */
+       sf_count_t      position ;      /* the sample frame for the peak */
+} PEAK_POS ;
+
+typedef struct
+{      /* libsndfile internal : write a PEAK chunk at the start or end of the file? */
+       int                             peak_loc ;
+
+       /* WAV/AIFF */
+       unsigned int    version ;       /* version of the PEAK chunk */
+       unsigned int    timestamp ;     /* secs since 1/1/1970  */
+
+       /* CAF */
+       unsigned int    edit_number ;
+
+#if HAVE_FLEXIBLE_ARRAY
+       /* the per channel peak info */
+       PEAK_POS                peaks [] ;
+#else
+       /*
+       ** This is not ISO compliant C. It works on some compilers which
+       ** don't support the ISO standard flexible struct array which is
+       ** used above. If your compiler doesn't like this I suggest you find
+       ** youself a 1999 ISO C standards compilant compiler. GCC-3.X is
+       ** highly recommended.
+       */
+       PEAK_POS                peaks [0] ;
+#endif
+} PEAK_INFO ;
+
+static inline PEAK_INFO *
+peak_info_calloc (int channels)
+{      return calloc (1, sizeof (PEAK_INFO) + channels * sizeof (PEAK_POS)) ;
+} /* peak_info_calloc */
+
+typedef struct
+{      int             type ;
+       int             flags ;
+       char    *str ;
+} STR_DATA ;
+
+static inline size_t
+make_size_t (int x)
+{      return (size_t) x ;
+} /* size_t_of_int */
+
+/*=======================================================================================
+**     SF_PRIVATE stuct - a pointer to this struct is passed back to the caller of the
+**     sf_open_XXXX functions. The caller however has no knowledge of the struct's
+**     contents.
+*/
+
+typedef struct sf_private_tag
+{      /* Force the compiler to double align the start of buffer. */
+       union
+       {       double                  dbuf    [SF_BUFFER_LEN / sizeof (double)] ;
+#if (defined (SIZEOF_INT64_T) && (SIZEOF_INT64_T == 8))
+               int64_t                 lbuf    [SF_BUFFER_LEN / sizeof (int64_t)] ;
+#else
+               long                    lbuf    [SF_BUFFER_LEN / sizeof (double)] ;
+#endif
+               float                   fbuf    [SF_BUFFER_LEN / sizeof (float)] ;
+               int                             ibuf    [SF_BUFFER_LEN / sizeof (int)] ;
+               short                   sbuf    [SF_BUFFER_LEN / sizeof (short)] ;
+               char                    cbuf    [SF_BUFFER_LEN / sizeof (char)] ;
+               signed char             scbuf   [SF_BUFFER_LEN / sizeof (signed char)] ;
+               unsigned char   ucbuf   [SF_BUFFER_LEN / sizeof (signed char)] ;
+               } u ;
+
+       char                    filepath        [SF_FILENAME_LEN] ;
+       char                    rsrcpath        [SF_FILENAME_LEN] ;
+       char                    directory       [SF_FILENAME_LEN] ;
+       char                    filename        [SF_FILENAME_LEN / 4] ;
+
+       char                    syserr          [SF_SYSERR_LEN] ;
+
+       /* logbuffer and logindex should only be changed within the logging functions
+       ** of common.c
+       */
+       char                    logbuffer       [SF_BUFFER_LEN] ;
+       unsigned char   header          [SF_HEADER_LEN] ; /* Must be unsigned */
+       int                             rwf_endian ;    /* Header endian-ness flag. */
+
+       /* Storage and housekeeping data for adding/reading strings from
+       ** sound files.
+       */
+       STR_DATA                strings [SF_MAX_STRINGS] ;
+       char                    str_storage [SF_STR_BUFFER_LEN] ;
+       char                    *str_end ;
+       int                             str_flags ;
+
+       /* Guard value. If this changes the buffers above have overflowed. */
+       int                             Magick ;
+
+       /* Index variables for maintaining logbuffer and header above. */
+       int                             logindex ;
+       int                             headindex, headend ;
+       int                             has_text ;
+       int                             do_not_close_descriptor ;
+
+#if USE_WINDOWS_API
+       /*
+       **      These fields can only be used in src/file_io.c.
+       **      They are basically the same as a windows file HANDLE.
+       */
+       void                    *hfile, *hrsrc, *hsaved ;
+#else
+       /* These fields can only be used in src/file_io.c. */
+       int                     filedes, rsrcdes, savedes ;
+#endif
+
+       int                             error ;
+
+       int                             mode ;                  /* Open mode : SFM_READ, SFM_WRITE or SFM_RDWR. */
+       int                             endian ;                /* File endianness : SF_ENDIAN_LITTLE or SF_ENDIAN_BIG. */
+       int                             float_endswap ; /* Need to endswap float32s? */
+
+       /*
+       ** Maximum float value for calculating the multiplier for
+       ** float/double to short/int conversions.
+       */
+       int                             float_int_mult ;
+       float                   float_max ;
+
+       /* Vairables for handling pipes. */
+       int                             is_pipe ;               /* True if file is a pipe. */
+       sf_count_t              pipeoffset ;    /* Number of bytes read from a pipe. */
+
+       /* True if clipping must be performed on float->int conversions. */
+       int                             add_clipping ;
+
+       SF_INFO                 sf ;
+
+       int                             have_written ;  /* Has a single write been done to the file? */
+       PEAK_INFO               *peak_info ;
+
+       /* Loop Info */
+       SF_LOOP_INFO    *loop_info ;
+       SF_INSTRUMENT   *instrument ;
+
+       /* Broadcast (EBU) Info */
+       SF_BROADCAST_INFO *broadcast_info ;
+
+       sf_count_t              filelength ;    /* Overall length of (embedded) file. */
+       sf_count_t              fileoffset ;    /* Offset in number of bytes from beginning of file. */
+
+       sf_count_t              rsrclength ;    /* Length of the resource fork (if it exists). */
+
+       sf_count_t              dataoffset ;    /* Offset in number of bytes from beginning of file. */
+       sf_count_t              datalength ;    /* Length in bytes of the audio data. */
+       sf_count_t              dataend ;               /* Offset to file tailer. */
+
+       int                             blockwidth ;    /* Size in bytes of one set of interleaved samples. */
+       int                             bytewidth ;             /* Size in bytes of one sample (one channel). */
+
+       void                    *dither ;
+       void                    *interleave ;
+
+       int                             last_op ;               /* Last operation; either SFM_READ or SFM_WRITE */
+       sf_count_t              read_current ;
+       sf_count_t              write_current ;
+
+       void                    *fdata ;                /*      This is a pointer to dynamically allocated file format
+                                                                       **      specific data.
+                                                                       */
+
+       SF_DITHER_INFO  write_dither ;
+       SF_DITHER_INFO  read_dither ;
+
+       int                             norm_double ;
+       int                             norm_float ;
+
+       int                             auto_header ;
+
+       int                             ieee_replace ;
+       /* A set of file specific function pointers */
+
+       sf_count_t              (*read_short)   (struct sf_private_tag*, short *ptr, sf_count_t len) ;
+       sf_count_t              (*read_int)             (struct sf_private_tag*, int *ptr, sf_count_t len) ;
+       sf_count_t              (*read_float)   (struct sf_private_tag*, float *ptr, sf_count_t len) ;
+       sf_count_t              (*read_double)  (struct sf_private_tag*, double *ptr, sf_count_t len) ;
+
+       sf_count_t              (*write_short)  (struct sf_private_tag*, const short *ptr, sf_count_t len) ;
+       sf_count_t              (*write_int)    (struct sf_private_tag*, const int *ptr, sf_count_t len) ;
+       sf_count_t              (*write_float)  (struct sf_private_tag*, const float *ptr, sf_count_t len) ;
+       sf_count_t              (*write_double) (struct sf_private_tag*, const double *ptr, sf_count_t len) ;
+
+       sf_count_t              (*seek)                 (struct sf_private_tag*, int mode, sf_count_t samples_from_start) ;
+       int                             (*write_header) (struct sf_private_tag*, int calc_length) ;
+       int                             (*command)              (struct sf_private_tag*, int command, void *data, int datasize) ;
+
+       /*
+       **      Separate close functions for the codec and the container.
+       **      The codec close function is always called first.
+       */
+       int                             (*codec_close)          (struct sf_private_tag*) ;
+       int                             (*container_close)      (struct sf_private_tag*) ;
+
+       char                    *format_desc ;
+
+       /* Virtual I/O functions. */
+       int                                     virtual_io ;
+       SF_VIRTUAL_IO           vio ;
+       void                            *vio_user_data ;
+} SF_PRIVATE ;
+
+
+
+enum
+{      SFE_NO_ERROR                            = SF_ERR_NO_ERROR,
+       SFE_BAD_OPEN_FORMAT                     = SF_ERR_UNRECOGNISED_FORMAT,
+       SFE_SYSTEM                                      = SF_ERR_SYSTEM,
+       SFE_MALFORMED_FILE                      = SF_ERR_MALFORMED_FILE,
+       SFE_UNSUPPORTED_ENCODING        = SF_ERR_UNSUPPORTED_ENCODING,
+
+       SFE_BAD_FILE,
+       SFE_BAD_FILE_READ,
+       SFE_OPEN_FAILED,
+       SFE_BAD_SNDFILE_PTR,
+       SFE_BAD_SF_INFO_PTR,
+       SFE_BAD_SF_INCOMPLETE,
+       SFE_BAD_FILE_PTR,
+       SFE_BAD_INT_PTR,
+       SFE_BAD_STAT_SIZE,
+       SFE_MALLOC_FAILED,
+       SFE_UNIMPLEMENTED,
+       SFE_BAD_READ_ALIGN,
+       SFE_BAD_WRITE_ALIGN,
+       SFE_UNKNOWN_FORMAT,
+       SFE_NOT_READMODE,
+       SFE_NOT_WRITEMODE,
+       SFE_BAD_MODE_RW,
+       SFE_BAD_SF_INFO,
+       SFE_BAD_OFFSET,
+       SFE_NO_EMBED_SUPPORT,
+       SFE_NO_EMBEDDED_RDWR,
+       SFE_NO_PIPE_WRITE,
+
+       SFE_INTERNAL,
+       SFE_BAD_CONTROL_CMD,
+       SFE_BAD_ENDIAN,
+       SFE_CHANNEL_COUNT,
+       SFE_BAD_RDWR_FORMAT,
+
+       SFE_BAD_VIRTUAL_IO,
+
+       SFE_INTERLEAVE_MODE,
+       SFE_INTERLEAVE_SEEK,
+       SFE_INTERLEAVE_READ,
+
+       SFE_BAD_SEEK,
+       SFE_NOT_SEEKABLE,
+       SFE_AMBIGUOUS_SEEK,
+       SFE_WRONG_SEEK,
+       SFE_SEEK_FAILED,
+
+       SFE_BAD_OPEN_MODE,
+       SFE_OPEN_PIPE_RDWR,
+       SFE_RDWR_POSITION,
+       SFE_RDWR_BAD_HEADER,
+
+       SFE_STR_NO_SUPPORT,
+       SFE_STR_NOT_WRITE,
+       SFE_STR_MAX_DATA,
+       SFE_STR_MAX_COUNT,
+       SFE_STR_BAD_TYPE,
+       SFE_STR_NO_ADD_END,
+       SFE_STR_BAD_STRING,
+       SFE_STR_WEIRD,
+
+       SFE_WAV_NO_RIFF,
+       SFE_WAV_NO_WAVE,
+       SFE_WAV_NO_FMT,
+       SFE_WAV_FMT_SHORT,
+       SFE_WAV_BAD_FACT,
+       SFE_WAV_BAD_PEAK,
+       SFE_WAV_PEAK_B4_FMT,
+       SFE_WAV_BAD_FORMAT,
+       SFE_WAV_BAD_BLOCKALIGN,
+       SFE_WAV_NO_DATA,
+       SFE_WAV_BAD_LIST,
+       SFE_WAV_ADPCM_NOT4BIT,
+       SFE_WAV_ADPCM_CHANNELS,
+       SFE_WAV_GSM610_FORMAT,
+       SFE_WAV_UNKNOWN_CHUNK,
+       SFE_WAV_WVPK_DATA,
+
+       SFE_AIFF_NO_FORM,
+       SFE_AIFF_AIFF_NO_FORM,
+       SFE_AIFF_COMM_NO_FORM,
+       SFE_AIFF_SSND_NO_COMM,
+       SFE_AIFF_UNKNOWN_CHUNK,
+       SFE_AIFF_COMM_CHUNK_SIZE,
+       SFE_AIFF_BAD_COMM_CHUNK,
+       SFE_AIFF_PEAK_B4_COMM,
+       SFE_AIFF_BAD_PEAK,
+       SFE_AIFF_NO_SSND,
+       SFE_AIFF_NO_DATA,
+       SFE_AIFF_RW_SSND_NOT_LAST,
+
+       SFE_AU_UNKNOWN_FORMAT,
+       SFE_AU_NO_DOTSND,
+       SFE_AU_EMBED_BAD_LEN,
+
+       SFE_RAW_READ_BAD_SPEC,
+       SFE_RAW_BAD_BITWIDTH,
+       SFE_RAW_BAD_FORMAT,
+
+       SFE_PAF_NO_MARKER,
+       SFE_PAF_VERSION,
+       SFE_PAF_UNKNOWN_FORMAT,
+       SFE_PAF_SHORT_HEADER,
+
+       SFE_SVX_NO_FORM,
+       SFE_SVX_NO_BODY,
+       SFE_SVX_NO_DATA,
+       SFE_SVX_BAD_COMP,
+       SFE_SVX_BAD_NAME_LENGTH,
+
+       SFE_NIST_BAD_HEADER,
+       SFE_NIST_CRLF_CONVERISON,
+       SFE_NIST_BAD_ENCODING,
+
+       SFE_VOC_NO_CREATIVE,
+       SFE_VOC_BAD_FORMAT,
+       SFE_VOC_BAD_VERSION,
+       SFE_VOC_BAD_MARKER,
+       SFE_VOC_BAD_SECTIONS,
+       SFE_VOC_MULTI_SAMPLERATE,
+       SFE_VOC_MULTI_SECTION,
+       SFE_VOC_MULTI_PARAM,
+       SFE_VOC_SECTION_COUNT,
+       SFE_VOC_NO_PIPE,
+
+       SFE_IRCAM_NO_MARKER,
+       SFE_IRCAM_BAD_CHANNELS,
+       SFE_IRCAM_UNKNOWN_FORMAT,
+
+       SFE_W64_64_BIT,
+       SFE_W64_NO_RIFF,
+       SFE_W64_NO_WAVE,
+       SFE_W64_NO_FMT,
+       SFE_W64_NO_DATA,
+       SFE_W64_FMT_SHORT,
+       SFE_W64_FMT_TOO_BIG,
+       SFE_W64_ADPCM_NOT4BIT,
+       SFE_W64_ADPCM_CHANNELS,
+       SFE_W64_GSM610_FORMAT,
+
+       SFE_MAT4_BAD_NAME,
+       SFE_MAT4_NO_SAMPLERATE,
+       SFE_MAT4_ZERO_CHANNELS,
+
+       SFE_MAT5_BAD_ENDIAN,
+       SFE_MAT5_NO_BLOCK,
+       SFE_MAT5_SAMPLE_RATE,
+       SFE_MAT5_ZERO_CHANNELS,
+
+       SFE_PVF_NO_PVF1,
+       SFE_PVF_BAD_HEADER,
+       SFE_PVF_BAD_BITWIDTH,
+
+       SFE_DWVW_BAD_BITWIDTH,
+       SFE_G72X_NOT_MONO,
+
+       SFE_XI_BAD_HEADER,
+       SFE_XI_EXCESS_SAMPLES,
+       SFE_XI_NO_PIPE,
+
+       SFE_HTK_NO_PIPE,
+
+       SFE_SDS_NOT_SDS,
+       SFE_SDS_BAD_BIT_WIDTH,
+
+       SFE_SD2_FD_DISALLOWED,
+       SFE_SD2_BAD_DATA_OFFSET,
+       SFE_SD2_BAD_MAP_OFFSET,
+       SFE_SD2_BAD_DATA_LENGTH,
+       SFE_SD2_BAD_MAP_LENGTH,
+       SFE_SD2_BAD_RSRC,
+       SFE_SD2_BAD_SAMPLE_SIZE,
+
+       SFE_FLAC_BAD_HEADER,
+       SFE_FLAC_NEW_DECODER,
+       SFE_FLAC_INIT_DECODER,
+       SFE_FLAC_LOST_SYNC,
+       SFE_FLAC_BAD_SAMPLE_RATE,
+       SFE_FLAC_UNKOWN_ERROR,
+
+       SFE_MAX_ERROR                   /* This must be last in list. */
+} ;
+
+int subformat_to_bytewidth (int format) ;
+int s_bitwidth_to_subformat (int bits) ;
+int u_bitwidth_to_subformat (int bits) ;
+
+/*  Functions for reading and writing floats and doubles on processors
+**     with non-IEEE floats/doubles.
+*/
+float  float32_be_read         (unsigned char *cptr) ;
+float  float32_le_read         (unsigned char *cptr) ;
+void   float32_be_write        (float in, unsigned char *out) ;
+void   float32_le_write        (float in, unsigned char *out) ;
+
+double double64_be_read        (unsigned char *cptr) ;
+double double64_le_read        (unsigned char *cptr) ;
+void   double64_be_write       (double in, unsigned char *out) ;
+void   double64_le_write       (double in, unsigned char *out) ;
+
+/* Functions for writing to the internal logging buffer. */
+
+void   psf_log_printf          (SF_PRIVATE *psf, const char *format, ...) ;
+void   psf_log_SF_INFO         (SF_PRIVATE *psf) ;
+
+void   psf_hexdump (void *ptr, int len) ;
+
+/* Functions used when writing file headers. */
+
+int            psf_binheader_writef    (SF_PRIVATE *psf, const char *format, ...) ;
+void   psf_asciiheader_printf  (SF_PRIVATE *psf, const char *format, ...) ;
+
+/* Functions used when reading file headers. */
+
+int            psf_binheader_readf     (SF_PRIVATE *psf, char const *format, ...) ;
+
+/* Functions used in the write function for updating the peak chunk. */
+
+void   peak_update_short       (SF_PRIVATE *psf, short *ptr, size_t items) ;
+void   peak_update_int         (SF_PRIVATE *psf, int *ptr, size_t items) ;
+void   peak_update_double      (SF_PRIVATE *psf, double *ptr, size_t items) ;
+
+/* Functions defined in command.c. */
+
+int            psf_get_format_simple_count     (void) ;
+int            psf_get_format_simple           (SF_FORMAT_INFO *data) ;
+
+int            psf_get_format_info                     (SF_FORMAT_INFO *data) ;
+
+int            psf_get_format_major_count      (void) ;
+int            psf_get_format_major            (SF_FORMAT_INFO *data) ;
+
+int            psf_get_format_subtype_count    (void) ;
+int            psf_get_format_subtype          (SF_FORMAT_INFO *data) ;
+
+void   psf_generate_format_desc (SF_PRIVATE *psf) ;
+
+double psf_calc_signal_max                     (SF_PRIVATE *psf, int normalize) ;
+int            psf_calc_max_all_channels       (SF_PRIVATE *psf, double *peaks, int normalize) ;
+
+int            psf_get_signal_max                      (SF_PRIVATE *psf, double *peak) ;
+int            psf_get_max_all_channels        (SF_PRIVATE *psf, double *peaks) ;
+
+/* Functions in strings.c. */
+
+const char* psf_get_string (SF_PRIVATE *psf, int str_type) ;
+int psf_set_string (SF_PRIVATE *psf, int str_type, const char *str) ;
+int psf_store_string (SF_PRIVATE *psf, int str_type, const char *str) ;
+
+/* Default seek function. Use for PCM and float encoded data. */
+sf_count_t     psf_default_seek (SF_PRIVATE *psf, int mode, sf_count_t samples_from_start) ;
+
+/* Generate the currebt date as a string. */
+void   psf_get_date_str (char *str, int maxlen) ;
+
+int macos_guess_file_type (SF_PRIVATE *psf, const char *filename) ;
+
+/*------------------------------------------------------------------------------------
+**     File I/O functions which will allow access to large files (> 2 Gig) on
+**     some 32 bit OSes. Implementation in file_io.c.
+*/
+
+int psf_fopen (SF_PRIVATE *psf, const char *pathname, int flags) ;
+int psf_set_stdio (SF_PRIVATE *psf, int mode) ;
+int psf_file_valid (SF_PRIVATE *psf) ;
+void psf_set_file (SF_PRIVATE *psf, int fd) ;
+void psf_init_files (SF_PRIVATE *psf) ;
+void psf_use_rsrc (SF_PRIVATE *psf, int on_off) ;
+
+sf_count_t psf_fseek (SF_PRIVATE *psf, sf_count_t offset, int whence) ;
+sf_count_t psf_fread (void *ptr, sf_count_t bytes, sf_count_t count, SF_PRIVATE *psf) ;
+sf_count_t psf_fwrite (const void *ptr, sf_count_t bytes, sf_count_t count, SF_PRIVATE *psf) ;
+sf_count_t psf_fgets (char *buffer, sf_count_t bufsize, SF_PRIVATE *psf) ;
+sf_count_t psf_ftell (SF_PRIVATE *psf) ;
+sf_count_t psf_get_filelen (SF_PRIVATE *psf) ;
+
+void psf_fsync (SF_PRIVATE *psf) ;
+
+int psf_is_pipe (SF_PRIVATE *psf) ;
+
+int psf_ftruncate (SF_PRIVATE *psf, sf_count_t len) ;
+int psf_fclose (SF_PRIVATE *psf) ;
+
+/* Open and close the resource fork of a file. */
+int psf_open_rsrc (SF_PRIVATE *psf, int mode) ;
+int psf_close_rsrc (SF_PRIVATE *psf) ;
+
+/*
+void psf_fclearerr (SF_PRIVATE *psf) ;
+int psf_ferror (SF_PRIVATE *psf) ;
+*/
+
+/*------------------------------------------------------------------------------------
+** Functions for reading and writing different file formats.
+*/
+
+int            aiff_open       (SF_PRIVATE *psf) ;
+int            au_open         (SF_PRIVATE *psf) ;
+int            avr_open        (SF_PRIVATE *psf) ;
+int            htk_open        (SF_PRIVATE *psf) ;
+int            ircam_open      (SF_PRIVATE *psf) ;
+int            mat4_open       (SF_PRIVATE *psf) ;
+int            mat5_open       (SF_PRIVATE *psf) ;
+int            nist_open       (SF_PRIVATE *psf) ;
+int            paf_open        (SF_PRIVATE *psf) ;
+int            pvf_open        (SF_PRIVATE *psf) ;
+int            raw_open        (SF_PRIVATE *psf) ;
+int            sd2_open        (SF_PRIVATE *psf) ;
+int            sds_open        (SF_PRIVATE *psf) ;
+int            svx_open        (SF_PRIVATE *psf) ;
+int            voc_open        (SF_PRIVATE *psf) ;
+int            w64_open        (SF_PRIVATE *psf) ;
+int            wav_open        (SF_PRIVATE *psf) ;
+int            xi_open         (SF_PRIVATE *psf) ;
+int            flac_open       (SF_PRIVATE *psf) ;
+int            caf_open        (SF_PRIVATE *psf) ;
+
+/* In progress. Do not currently work. */
+
+int            mpeg_open       (SF_PRIVATE *psf) ;
+int            ogg_open        (SF_PRIVATE *psf) ;
+int            rx2_open        (SF_PRIVATE *psf) ;
+int            txw_open        (SF_PRIVATE *psf) ;
+int            wve_open        (SF_PRIVATE *psf) ;
+int            dwd_open        (SF_PRIVATE *psf) ;
+
+int            macbinary3_open (SF_PRIVATE *psf) ;
+
+/*------------------------------------------------------------------------------------
+**     Init functions for a number of common data encodings.
+*/
+
+int            pcm_init                (SF_PRIVATE *psf) ;
+int            ulaw_init               (SF_PRIVATE *psf) ;
+int            alaw_init               (SF_PRIVATE *psf) ;
+int            float32_init    (SF_PRIVATE *psf) ;
+int            double64_init   (SF_PRIVATE *psf) ;
+int            dwvw_init               (SF_PRIVATE *psf, int bitwidth) ;
+int            gsm610_init             (SF_PRIVATE *psf) ;
+int            vox_adpcm_init  (SF_PRIVATE *psf) ;
+int            flac_init               (SF_PRIVATE *psf) ;
+int            g72x_init               (SF_PRIVATE * psf) ;
+
+int    dither_init             (SF_PRIVATE *psf, int mode) ;
+
+int            wav_w64_ima_init (SF_PRIVATE *psf, int blockalign, int samplesperblock) ;
+int            wav_w64_msadpcm_init (SF_PRIVATE *psf, int blockalign, int samplesperblock) ;
+
+int            aiff_ima_init (SF_PRIVATE *psf, int blockalign, int samplesperblock) ;
+
+int            interleave_init (SF_PRIVATE *psf) ;
+
+/*------------------------------------------------------------------------------------
+** Other helper functions.
+*/
+
+void   *psf_memset (void *s, int c, sf_count_t n) ;
+
+SF_INSTRUMENT * psf_instrument_alloc (void) ;
+
+
+SF_BROADCAST_INFO* broadcast_info_alloc (void) ;
+int            broadcast_info_copy (SF_BROADCAST_INFO* dst, SF_BROADCAST_INFO* src) ;
+int            broadcast_add_coding_history (SF_BROADCAST_INFO* bext, unsigned int channels, unsigned int samplerate) ;
+
+/*------------------------------------------------------------------------------------
+** Here's how we fix systems which don't snprintf / vsnprintf.
+** Systems without these functions should use the
+*/
+
+#if USE_WINDOWS_API
+#define        LSF_SNPRINTF    _snprintf
+#elif          (HAVE_SNPRINTF && ! FORCE_MISSING_SNPRINTF)
+#define        LSF_SNPRINTF    snprintf
+#else
+int missing_snprintf (char *str, size_t n, char const *fmt, ...) ;
+#define        LSF_SNPRINTF    missing_snprintf
+#endif
+
+#if USE_WINDOWS_API
+#define        LSF_VSNPRINTF   _vsnprintf
+#elif          (HAVE_VSNPRINTF && ! FORCE_MISSING_SNPRINTF)
+#define        LSF_VSNPRINTF   vsnprintf
+#else
+int missing_vsnprintf (char *str, size_t n, const char *fmt, ...) ;
+#define        LSF_VSNPRINTF   missing_vsnprintf
+#endif
+
+/*------------------------------------------------------------------------------------
+** Extra commands for sf_command(). Not for public use yet.
+*/
+
+enum
+{      SFC_TEST_AIFF_ADD_INST_CHUNK    = 0x2000,
+       SFC_TEST_WAV_ADD_INFO_CHUNK             = 0x2010
+} ;
+
+/*
+** Maybe, one day, make these functions or something like them, public.
+**
+** Buffer to buffer dithering. Pointer in and out are allowed to point
+** to the same buffer for in-place dithering.
+*/
+
+#if 0
+int sf_dither_short            (const SF_DITHER_INFO *dither, const short *in, short *out, int count) ;
+int sf_dither_int              (const SF_DITHER_INFO *dither, const int *in, int *out, int count) ;
+int sf_dither_float            (const SF_DITHER_INFO *dither, const float *in, float *out, int count) ;
+int sf_dither_double   (const SF_DITHER_INFO *dither, const double *in, double *out, int count) ;
+#endif
+
+#endif /* SNDFILE_COMMON_H */
+
+/*
+** Do not edit or modify anything in this comment block.
+** The arch-tag line is a file identity tag for the GNU Arch
+** revision control system.
+**
+** arch-tag: 7b45c0ee-5835-4a18-a4ef-994e4cd95b67
+*/
diff --git a/libs/libsndfile/src/config.h.in b/libs/libsndfile/src/config.h.in
new file mode 100644 (file)
index 0000000..4b3d844
--- /dev/null
@@ -0,0 +1,247 @@
+/* src/config.h.in.  Generated from configure.ac by autoheader.  */
+
+/* Set to 1 if the compile is GNU GCC. */
+#undef COMPILER_IS_GCC
+
+/* Target processor clips on negative float to int conversion. */
+#undef CPU_CLIPS_NEGATIVE
+
+/* Target processor clips on positive float to int conversion. */
+#undef CPU_CLIPS_POSITIVE
+
+/* Target processor is big endian. */
+#undef CPU_IS_BIG_ENDIAN
+
+/* Target processor is little endian. */
+#undef CPU_IS_LITTLE_ENDIAN
+
+/* Set to 1 to enable experimental code. */
+#undef ENABLE_EXPERIMENTAL_CODE
+
+/* Major version of GCC or 3 otherwise. */
+#undef GCC_MAJOR_VERSION
+
+/* Define to 1 if you have the <alsa/asoundlib.h> header file. */
+#undef HAVE_ALSA_ASOUNDLIB_H
+
+/* Define to 1 if you have the <byteswap.h> header file. */
+#undef HAVE_BYTESWAP_H
+
+/* Define to 1 if you have the `calloc' function. */
+#undef HAVE_CALLOC
+
+/* Define to 1 if you have the `ceil' function. */
+#undef HAVE_CEIL
+
+/* Set to 1 if S_IRGRP is defined. */
+#undef HAVE_DECL_S_IRGRP
+
+/* Define to 1 if you have the <endian.h> header file. */
+#undef HAVE_ENDIAN_H
+
+/* Define to 1 if you have the `fdatasync' function. */
+#undef HAVE_FDATASYNC
+
+/* Define to 1 if you have libflac 1.1.1 */
+#undef HAVE_FLAC_1_1_1
+
+/* Define to 1 if you have the <FLAC/all.h> header file. */
+#undef HAVE_FLAC_ALL_H
+
+/* Set to 1 if the compile supports the struct hack. */
+#undef HAVE_FLEXIBLE_ARRAY
+
+/* Define to 1 if you have the `floor' function. */
+#undef HAVE_FLOOR
+
+/* Define to 1 if you have the `fmod' function. */
+#undef HAVE_FMOD
+
+/* Define to 1 if you have the `free' function. */
+#undef HAVE_FREE
+
+/* Define to 1 if you have the `fstat' function. */
+#undef HAVE_FSTAT
+
+/* Define to 1 if you have the `fsync' function. */
+#undef HAVE_FSYNC
+
+/* Define to 1 if you have the `ftruncate' function. */
+#undef HAVE_FTRUNCATE
+
+/* Define to 1 if you have the `getpagesize' function. */
+#undef HAVE_GETPAGESIZE
+
+/* Define to 1 if you have the `gmtime' function. */
+#undef HAVE_GMTIME
+
+/* Define to 1 if you have the `gmtime_r' function. */
+#undef HAVE_GMTIME_R
+
+/* Define to 1 if you have the <inttypes.h> header file. */
+#undef HAVE_INTTYPES_H
+
+/* Define to 1 if you have the `m' library (-lm). */
+#undef HAVE_LIBM
+
+/* Define to 1 if you have the <locale.h> header file. */
+#undef HAVE_LOCALE_H
+
+/* Define if you have C99's lrint function. */
+#undef HAVE_LRINT
+
+/* Define if you have C99's lrintf function. */
+#undef HAVE_LRINTF
+
+/* Define to 1 if you have the `lseek' function. */
+#undef HAVE_LSEEK
+
+/* Define to 1 if you have the `malloc' function. */
+#undef HAVE_MALLOC
+
+/* Define to 1 if you have the <memory.h> header file. */
+#undef HAVE_MEMORY_H
+
+/* Define to 1 if you have the `mmap' function. */
+#undef HAVE_MMAP
+
+/* Define to 1 if you have the `open' function. */
+#undef HAVE_OPEN
+
+/* Define to 1 if you have the `pread' function. */
+#undef HAVE_PREAD
+
+/* Define to 1 if you have the `pwrite' function. */
+#undef HAVE_PWRITE
+
+/* Define to 1 if you have the `read' function. */
+#undef HAVE_READ
+
+/* Define to 1 if you have the `realloc' function. */
+#undef HAVE_REALLOC
+
+/* Define to 1 if you have the `setlocale' function. */
+#undef HAVE_SETLOCALE
+
+/* Define to 1 if you have the `snprintf' function. */
+#undef HAVE_SNPRINTF
+
+/* Set to 1 if you have libsqlite3. */
+#undef HAVE_SQLITE3
+
+/* Define to 1 if the system has the type `ssize_t'. */
+#undef HAVE_SSIZE_T
+
+/* Define to 1 if you have the <stdint.h> header file. */
+#undef HAVE_STDINT_H
+
+/* Define to 1 if you have the <stdlib.h> header file. */
+#undef HAVE_STDLIB_H
+
+/* Define to 1 if you have the <strings.h> header file. */
+#undef HAVE_STRINGS_H
+
+/* Define to 1 if you have the <string.h> header file. */
+#undef HAVE_STRING_H
+
+/* Define to 1 if you have the <sys/stat.h> header file. */
+#undef HAVE_SYS_STAT_H
+
+/* Define to 1 if you have the <sys/types.h> header file. */
+#undef HAVE_SYS_TYPES_H
+
+/* Define to 1 if you have <sys/wait.h> that is POSIX.1 compatible. */
+#undef HAVE_SYS_WAIT_H
+
+/* Define to 1 if you have the <unistd.h> header file. */
+#undef HAVE_UNISTD_H
+
+/* Define to 1 if you have the `vsnprintf' function. */
+#undef HAVE_VSNPRINTF
+
+/* Define to 1 if you have the `write' function. */
+#undef HAVE_WRITE
+
+/* Set to 1 if compiling for MacOSX */
+#undef OS_IS_MACOSX
+
+/* Set to 1 if compiling for Win32 */
+#undef OS_IS_WIN32
+
+/* Define to the address where bug reports for this package should be sent. */
+#undef PACKAGE_BUGREPORT
+
+/* Define to the full name of this package. */
+#undef PACKAGE_NAME
+
+/* Define to the full name and version of this package. */
+#undef PACKAGE_STRING
+
+/* Define to the one symbol short name of this package. */
+#undef PACKAGE_TARNAME
+
+/* Define to the version of this package. */
+#undef PACKAGE_VERSION
+
+/* Set to maximum allowed value of sf_count_t type. */
+#undef SF_COUNT_MAX
+
+/* The size of a `double', as computed by sizeof. */
+#undef SIZEOF_DOUBLE
+
+/* The size of a `float', as computed by sizeof. */
+#undef SIZEOF_FLOAT
+
+/* The size of a `int', as computed by sizeof. */
+#undef SIZEOF_INT
+
+/* The size of a `int64_t', as computed by sizeof. */
+#undef SIZEOF_INT64_T
+
+/* The size of a `loff_t', as computed by sizeof. */
+#undef SIZEOF_LOFF_T
+
+/* The size of a `long', as computed by sizeof. */
+#undef SIZEOF_LONG
+
+/* The size of a `long long', as computed by sizeof. */
+#undef SIZEOF_LONG_LONG
+
+/* The size of a `off64_t', as computed by sizeof. */
+#undef SIZEOF_OFF64_T
+
+/* The size of a `off_t', as computed by sizeof. */
+#undef SIZEOF_OFF_T
+
+/* Set to sizeof (long) if unknown. */
+#undef SIZEOF_SF_COUNT_T
+
+/* The size of a `short', as computed by sizeof. */
+#undef SIZEOF_SHORT
+
+/* The size of a `size_t', as computed by sizeof. */
+#undef SIZEOF_SIZE_T
+
+/* The size of a `ssize_t', as computed by sizeof. */
+#undef SIZEOF_SSIZE_T
+
+/* The size of a `void*', as computed by sizeof. */
+#undef SIZEOF_VOIDP
+
+/* Define to 1 if you have the ANSI C header files. */
+#undef STDC_HEADERS
+
+/* Set to long if unknown. */
+#undef TYPEOF_SF_COUNT_T
+
+/* Set to 1 to use the native windows API */
+#undef USE_WINDOWS_API
+
+/* Number of bits in a file offset, on hosts where this is settable. */
+#undef _FILE_OFFSET_BITS
+
+/* Define to make fseeko etc. visible, on some hosts. */
+#undef _LARGEFILE_SOURCE
+
+/* Define for large files, on AIX-style hosts. */
+#undef _LARGE_FILES
diff --git a/libs/libsndfile/src/cygsndfile.def b/libs/libsndfile/src/cygsndfile.def
new file mode 100644 (file)
index 0000000..510aa8e
--- /dev/null
@@ -0,0 +1,39 @@
+; Auto-generated by create_symbols_file.py
+
+LIBRARY cygsndfile-1.dll
+EXPORTS
+
+sf_command           @1
+sf_open              @2
+sf_close             @3
+sf_seek              @4
+sf_error             @7
+sf_perror            @8
+sf_error_str         @9
+sf_error_number      @10
+sf_format_check      @11
+sf_read_raw          @16
+sf_readf_short       @17
+sf_readf_int         @18
+sf_readf_float       @19
+sf_readf_double      @20
+sf_read_short        @21
+sf_read_int          @22
+sf_read_float        @23
+sf_read_double       @24
+sf_write_raw         @32
+sf_writef_short      @33
+sf_writef_int        @34
+sf_writef_float      @35
+sf_writef_double     @36
+sf_write_short       @37
+sf_write_int         @38
+sf_write_float       @39
+sf_write_double      @40
+sf_strerror          @50
+sf_get_string        @60
+sf_set_string        @61
+sf_open_fd           @70
+sf_open_virtual      @80
+sf_write_sync        @90
+
diff --git a/libs/libsndfile/src/dither.c b/libs/libsndfile/src/dither.c
new file mode 100644 (file)
index 0000000..873f1bb
--- /dev/null
@@ -0,0 +1,535 @@
+/*
+** Copyright (C) 2003,2005 Erik de Castro Lopo <erikd@mega-nerd.com>
+**
+** This program is free software; you can redistribute it and/or modify
+** it under the terms of the GNU Lesser General Public License as published by
+** the Free Software Foundation; either version 2.1 of the License, or
+** (at your option) any later version.
+**
+** This program is distributed in the hope that it will be useful,
+** but WITHOUT ANY WARRANTY; without even the implied warranty of
+** MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+** GNU Lesser General Public License for more details.
+**
+** You should have received a copy of the GNU Lesser General Public License
+** along with this program; if not, write to the Free Software
+** Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA.
+*/
+
+#include       "sfconfig.h"
+
+#include       <stdlib.h>
+
+#include       "sndfile.h"
+#include       "sfendian.h"
+#include       "common.h"
+
+/*============================================================================
+**     Rule number 1 is to only apply dither when going from a larger bitwidth
+**     to a smaller bitwidth. This can happen on both read and write.
+**
+**     Need to apply dither on all conversions marked X below.
+**
+**     Dither on write:
+**
+**                                                                             Input
+**                                     |       short           int                     float           double
+**                     --------+-----------------------------------------------
+**             O       8 bit   |       X                       X                       X                       X
+**             u       16 bit  |       none            X                       X                       X
+**             t       24 bit  |       none            X                       X                       X
+**             p       32 bit  |       none            none            X                       X
+**             u       float   |       none            none            none            none
+**             t       double  |       none            none            none            none
+**
+**     Dither on read:
+**
+**                                                                             Input
+**             O                       |       8 bit   16 bit  24 bit  32 bit  float   double
+**             u       --------+-------------------------------------------------
+**             t       short   |       none    none    X               X               X               X
+**             p       int             |       none    none    none    X               X               X
+**             u       float   |       none    none    none    none    none    none
+**             t       double  |       none    none    none    none    none    none
+*/
+
+#define        SFE_DITHER_BAD_PTR      666
+#define        SFE_DITHER_BAD_TYPE     667
+
+typedef struct
+{      int                     read_short_dither_bits, read_int_dither_bits ;
+       int                     write_short_dither_bits, write_int_dither_bits ;
+       double          read_float_dither_scale, read_double_dither_bits ;
+       double          write_float_dither_scale, write_double_dither_bits ;
+
+       sf_count_t      (*read_short)   (SF_PRIVATE *psf, short *ptr, sf_count_t len) ;
+       sf_count_t      (*read_int)             (SF_PRIVATE *psf, int *ptr, sf_count_t len) ;
+       sf_count_t      (*read_float)   (SF_PRIVATE *psf, float *ptr, sf_count_t len) ;
+       sf_count_t      (*read_double)  (SF_PRIVATE *psf, double *ptr, sf_count_t len) ;
+
+       sf_count_t      (*write_short)  (SF_PRIVATE *psf, const short *ptr, sf_count_t len) ;
+       sf_count_t      (*write_int)    (SF_PRIVATE *psf, const int *ptr, sf_count_t len) ;
+       sf_count_t      (*write_float)  (SF_PRIVATE *psf, const float *ptr, sf_count_t len) ;
+       sf_count_t      (*write_double) (SF_PRIVATE *psf, const double *ptr, sf_count_t len) ;
+
+       double buffer [SF_BUFFER_LEN / sizeof (double)] ;
+} DITHER_DATA ;
+
+static sf_count_t dither_read_short            (SF_PRIVATE *psf, short *ptr, sf_count_t len) ;
+static sf_count_t dither_read_int              (SF_PRIVATE *psf, int *ptr, sf_count_t len) ;
+
+static sf_count_t dither_write_short   (SF_PRIVATE *psf, const short *ptr, sf_count_t len) ;
+static sf_count_t dither_write_int             (SF_PRIVATE *psf, const int *ptr, sf_count_t len) ;
+static sf_count_t dither_write_float   (SF_PRIVATE *psf, const float *ptr, sf_count_t len) ;
+static sf_count_t dither_write_double  (SF_PRIVATE *psf, const double *ptr, sf_count_t len) ;
+
+int
+dither_init (SF_PRIVATE *psf, int mode)
+{      DITHER_DATA *pdither ;
+
+       pdither = psf->dither ; /* This may be NULL. */
+
+       /* Turn off dither on read. */
+       if (mode == SFM_READ && psf->read_dither.type == SFD_NO_DITHER)
+       {       if (pdither == NULL)
+                       return 0 ; /* Dither is already off, so just return. */
+
+               if (pdither->read_short)
+                       psf->read_short = pdither->read_short ;
+               if (pdither->read_int)
+                       psf->read_int = pdither->read_int ;
+               if (pdither->read_float)
+                       psf->read_float = pdither->read_float ;
+               if (pdither->read_double)
+                       psf->read_double = pdither->read_double ;
+               return 0 ;
+               } ;
+
+       /* Turn off dither on write. */
+       if (mode == SFM_WRITE && psf->write_dither.type == SFD_NO_DITHER)
+       {       if (pdither == NULL)
+                       return 0 ; /* Dither is already off, so just return. */
+
+               if (pdither->write_short)
+                       psf->write_short = pdither->write_short ;
+               if (pdither->write_int)
+                       psf->write_int = pdither->write_int ;
+               if (pdither->write_float)
+                       psf->write_float = pdither->write_float ;
+               if (pdither->write_double)
+                       psf->write_double = pdither->write_double ;
+               return 0 ;
+               } ;
+
+       /* Turn on dither on read if asked. */
+       if (mode == SFM_READ && psf->read_dither.type != 0)
+       {       if (pdither == NULL)
+                       pdither = psf->dither = calloc (1, sizeof (DITHER_DATA)) ;
+               if (pdither == NULL)
+                       return SFE_MALLOC_FAILED ;
+
+               switch (psf->sf.format & SF_FORMAT_SUBMASK)
+               {       case SF_FORMAT_DOUBLE :
+                       case SF_FORMAT_FLOAT :
+                                       pdither->read_int = psf->read_int ;
+                                       psf->read_int = dither_read_int ;
+
+                       case SF_FORMAT_PCM_32 :
+                       case SF_FORMAT_PCM_24 :
+                       case SF_FORMAT_PCM_16 :
+                       case SF_FORMAT_PCM_S8 :
+                       case SF_FORMAT_PCM_U8 :
+                                       pdither->read_short = psf->read_short ;
+                                       psf->read_short = dither_read_short ;
+
+                       default : break ;
+                       } ;
+               } ;
+
+       /* Turn on dither on write if asked. */
+       if (mode == SFM_WRITE && psf->write_dither.type != 0)
+       {       if (pdither == NULL)
+                       pdither = psf->dither = calloc (1, sizeof (DITHER_DATA)) ;
+               if (pdither == NULL)
+                       return SFE_MALLOC_FAILED ;
+
+               switch (psf->sf.format & SF_FORMAT_SUBMASK)
+               {       case SF_FORMAT_DOUBLE :
+                       case SF_FORMAT_FLOAT :
+                                       pdither->write_int = psf->write_int ;
+                                       psf->write_int = dither_write_int ;
+
+                       case SF_FORMAT_PCM_32 :
+                       case SF_FORMAT_PCM_24 :
+                       case SF_FORMAT_PCM_16 :
+                       case SF_FORMAT_PCM_S8 :
+                       case SF_FORMAT_PCM_U8 :
+
+                       default : break ;
+                       } ;
+
+               pdither->write_short = psf->write_short ;
+               psf->write_short = dither_write_short ;
+
+               pdither->write_int = psf->write_int ;
+               psf->write_int = dither_write_int ;
+
+               pdither->write_float = psf->write_float ;
+               psf->write_float = dither_write_float ;
+
+               pdither->write_double = psf->write_double ;
+               psf->write_double = dither_write_double ;
+               } ;
+
+       return 0 ;
+} /* dither_init */
+
+/*==============================================================================
+*/
+
+static void dither_short       (const short *in, short *out, int frames, int channels) ;
+static void dither_int         (const int *in, int *out, int frames, int channels) ;
+
+static void dither_float       (const float *in, float *out, int frames, int channels) ;
+static void dither_double      (const double *in, double *out, int frames, int channels) ;
+
+static sf_count_t
+dither_read_short (SF_PRIVATE *psf, short *ptr, sf_count_t len)
+{      psf = psf ;
+       ptr = ptr ;
+       return len ;
+} /* dither_read_short */
+
+static sf_count_t
+dither_read_int (SF_PRIVATE *psf, int *ptr, sf_count_t len)
+{      psf = psf ;
+       ptr = ptr ;
+       return len ;
+} /* dither_read_int */
+
+/*------------------------------------------------------------------------------
+*/
+
+static sf_count_t
+dither_write_short     (SF_PRIVATE *psf, const short *ptr, sf_count_t len)
+{      DITHER_DATA *pdither ;
+       int                     bufferlen, writecount, thiswrite ;
+       sf_count_t      total = 0 ;
+
+       if ((pdither = psf->dither) == NULL)
+       {       psf->error = SFE_DITHER_BAD_PTR ;
+               return 0 ;
+               } ;
+
+       switch (psf->sf.format & SF_FORMAT_SUBMASK)
+       {       case SF_FORMAT_PCM_S8 :
+               case SF_FORMAT_PCM_U8 :
+               case SF_FORMAT_DPCM_8 :
+                               break ;
+
+               default :
+                       return pdither->write_short (psf, ptr, len) ;
+               } ;
+
+       bufferlen = sizeof (pdither->buffer) / sizeof (short) ;
+
+       while (len > 0)
+       {       writecount = (len >= bufferlen) ? bufferlen : (int) len ;
+               writecount /= psf->sf.channels ;
+               writecount *= psf->sf.channels ;
+
+               dither_short (ptr, (short*) pdither->buffer, writecount / psf->sf.channels, psf->sf.channels) ;
+
+               thiswrite = pdither->write_short (psf, (short*) pdither->buffer, writecount) ;
+               total += thiswrite ;
+               len -= thiswrite ;
+               if (thiswrite < writecount)
+                       break ;
+               } ;
+
+       return total ;
+} /* dither_write_short */
+
+static sf_count_t
+dither_write_int       (SF_PRIVATE *psf, const int *ptr, sf_count_t len)
+{      DITHER_DATA *pdither ;
+       int                     bufferlen, writecount, thiswrite ;
+       sf_count_t      total = 0 ;
+
+       if ((pdither = psf->dither) == NULL)
+       {       psf->error = SFE_DITHER_BAD_PTR ;
+               return 0 ;
+               } ;
+
+       switch (psf->sf.format & SF_FORMAT_SUBMASK)
+       {       case SF_FORMAT_PCM_S8 :
+               case SF_FORMAT_PCM_U8 :
+               case SF_FORMAT_PCM_16 :
+               case SF_FORMAT_PCM_24 :
+
+               case SF_FORMAT_DPCM_8 :
+               case SF_FORMAT_DPCM_16 :
+                               break ;
+
+               default :
+                       return pdither->write_int (psf, ptr, len) ;
+               } ;
+
+
+       bufferlen = sizeof (pdither->buffer) / sizeof (int) ;
+
+       while (len > 0)
+       {       writecount = (len >= bufferlen) ? bufferlen : (int) len ;
+               writecount /= psf->sf.channels ;
+               writecount *= psf->sf.channels ;
+
+               dither_int (ptr, (int*) pdither->buffer, writecount / psf->sf.channels, psf->sf.channels) ;
+
+               thiswrite = pdither->write_int (psf, (int*) pdither->buffer, writecount) ;
+               total += thiswrite ;
+               len -= thiswrite ;
+               if (thiswrite < writecount)
+                       break ;
+               } ;
+
+       return total ;
+} /* dither_write_int */
+
+static sf_count_t
+dither_write_float     (SF_PRIVATE *psf, const float *ptr, sf_count_t len)
+{      DITHER_DATA *pdither ;
+       int                     bufferlen, writecount, thiswrite ;
+       sf_count_t      total = 0 ;
+
+       if ((pdither = psf->dither) == NULL)
+       {       psf->error = SFE_DITHER_BAD_PTR ;
+               return 0 ;
+               } ;
+
+       switch (psf->sf.format & SF_FORMAT_SUBMASK)
+       {       case SF_FORMAT_PCM_S8 :
+               case SF_FORMAT_PCM_U8 :
+               case SF_FORMAT_PCM_16 :
+               case SF_FORMAT_PCM_24 :
+
+               case SF_FORMAT_DPCM_8 :
+               case SF_FORMAT_DPCM_16 :
+                               break ;
+
+               default :
+                       return pdither->write_float (psf, ptr, len) ;
+               } ;
+
+       bufferlen = sizeof (pdither->buffer) / sizeof (float) ;
+
+       while (len > 0)
+       {       writecount = (len >= bufferlen) ? bufferlen : (float) len ;
+               writecount /= psf->sf.channels ;
+               writecount *= psf->sf.channels ;
+
+               dither_float (ptr, (float*) pdither->buffer, writecount / psf->sf.channels, psf->sf.channels) ;
+
+               thiswrite = pdither->write_float (psf, (float*) pdither->buffer, writecount) ;
+               total += thiswrite ;
+               len -= thiswrite ;
+               if (thiswrite < writecount)
+                       break ;
+               } ;
+
+       return total ;
+} /* dither_write_float */
+
+static sf_count_t
+dither_write_double    (SF_PRIVATE *psf, const double *ptr, sf_count_t len)
+{      DITHER_DATA *pdither ;
+       int                     bufferlen, writecount, thiswrite ;
+       sf_count_t      total = 0 ;
+
+       if ((pdither = psf->dither) == NULL)
+       {       psf->error = SFE_DITHER_BAD_PTR ;
+               return 0 ;
+               } ;
+
+       switch (psf->sf.format & SF_FORMAT_SUBMASK)
+       {       case SF_FORMAT_PCM_S8 :
+               case SF_FORMAT_PCM_U8 :
+               case SF_FORMAT_PCM_16 :
+               case SF_FORMAT_PCM_24 :
+
+               case SF_FORMAT_DPCM_8 :
+               case SF_FORMAT_DPCM_16 :
+                               break ;
+
+               default :
+                       return pdither->write_double (psf, ptr, len) ;
+               } ;
+
+
+       bufferlen = sizeof (pdither->buffer) / sizeof (double) ;
+
+       while (len > 0)
+       {       writecount = (len >= bufferlen) ? bufferlen : (double) len ;
+               writecount /= psf->sf.channels ;
+               writecount *= psf->sf.channels ;
+
+               dither_double (ptr, (double*) pdither->buffer, writecount / psf->sf.channels, psf->sf.channels) ;
+
+               thiswrite = pdither->write_double (psf, (double*) pdither->buffer, writecount) ;
+               total += thiswrite ;
+               len -= thiswrite ;
+               if (thiswrite < writecount)
+                       break ;
+               } ;
+
+       return total ;
+} /* dither_write_double */
+
+/*==============================================================================
+*/
+
+static void
+dither_short (const short *in, short *out, int frames, int channels)
+{      int ch, k ;
+
+       for (ch = 0 ; ch < channels ; ch++)
+               for (k = ch ; k < channels * frames ; k += channels)
+                       out [k] = in [k] ;
+
+} /* dither_short */
+
+static void
+dither_int (const int *in, int *out, int frames, int channels)
+{      int ch, k ;
+
+       for (ch = 0 ; ch < channels ; ch++)
+               for (k = ch ; k < channels * frames ; k += channels)
+                       out [k] = in [k] ;
+
+} /* dither_int */
+
+static void
+dither_float (const float *in, float *out, int frames, int channels)
+{      int ch, k ;
+
+       for (ch = 0 ; ch < channels ; ch++)
+               for (k = ch ; k < channels * frames ; k += channels)
+                       out [k] = in [k] ;
+
+} /* dither_float */
+
+static void
+dither_double (const double *in, double *out, int frames, int channels)
+{      int ch, k ;
+
+       for (ch = 0 ; ch < channels ; ch++)
+               for (k = ch ; k < channels * frames ; k += channels)
+                       out [k] = in [k] ;
+
+} /* dither_double */
+
+/*==============================================================================
+*/
+#if 0
+
+/*
+** Not made public because this (maybe) requires storage of state information.
+**
+** Also maybe need separate state info for each channel!!!!
+*/
+
+int
+DO_NOT_USE_sf_dither_short (const SF_DITHER_INFO *dither, const short *in, short *out, int frames, int channels)
+{      int ch, k ;
+
+       if (! dither)
+               return SFE_DITHER_BAD_PTR ;
+
+       switch (dither->type & SFD_TYPEMASK)
+       {       case SFD_WHITE :
+               case SFD_TRIANGULAR_PDF :
+                               for (ch = 0 ; ch < channels ; ch++)
+                                       for (k = ch ; k < channels * frames ; k += channels)
+                                               out [k] = in [k] ;
+                               break ;
+
+               default :
+                       return SFE_DITHER_BAD_TYPE ;
+               } ;
+
+       return 0 ;
+} /* DO_NOT_USE_sf_dither_short */
+
+int
+DO_NOT_USE_sf_dither_int (const SF_DITHER_INFO *dither, const int *in, int *out, int frames, int channels)
+{      int ch, k ;
+
+       if (! dither)
+               return SFE_DITHER_BAD_PTR ;
+
+       switch (dither->type & SFD_TYPEMASK)
+       {       case SFD_WHITE :
+               case SFD_TRIANGULAR_PDF :
+                               for (ch = 0 ; ch < channels ; ch++)
+                                       for (k = ch ; k < channels * frames ; k += channels)
+                                               out [k] = in [k] ;
+                               break ;
+
+               default :
+                       return SFE_DITHER_BAD_TYPE ;
+               } ;
+
+       return 0 ;
+} /* DO_NOT_USE_sf_dither_int */
+
+int
+DO_NOT_USE_sf_dither_float (const SF_DITHER_INFO *dither, const float *in, float *out, int frames, int channels)
+{      int ch, k ;
+
+       if (! dither)
+               return SFE_DITHER_BAD_PTR ;
+
+       switch (dither->type & SFD_TYPEMASK)
+       {       case SFD_WHITE :
+               case SFD_TRIANGULAR_PDF :
+                               for (ch = 0 ; ch < channels ; ch++)
+                                       for (k = ch ; k < channels * frames ; k += channels)
+                                               out [k] = in [k] ;
+                               break ;
+
+               default :
+                       return SFE_DITHER_BAD_TYPE ;
+               } ;
+
+       return 0 ;
+} /* DO_NOT_USE_sf_dither_float */
+
+int
+DO_NOT_USE_sf_dither_double (const SF_DITHER_INFO *dither, const double *in, double *out, int frames, int channels)
+{      int ch, k ;
+
+       if (! dither)
+               return SFE_DITHER_BAD_PTR ;
+
+       switch (dither->type & SFD_TYPEMASK)
+       {       case SFD_WHITE :
+               case SFD_TRIANGULAR_PDF :
+                               for (ch = 0 ; ch < channels ; ch++)
+                                       for (k = ch ; k < channels * frames ; k += channels)
+                                               out [k] = in [k] ;
+                               break ;
+
+               default :
+                       return SFE_DITHER_BAD_TYPE ;
+               } ;
+
+       return 0 ;
+} /* DO_NOT_USE_sf_dither_double */
+
+#endif
+/*
+** Do not edit or modify anything in this comment block.
+** The arch-tag line is a file identity tag for the GNU Arch 
+** revision control system.
+**
+** arch-tag: 673fad58-5314-421c-9144-9d54bfdf104c
+*/
diff --git a/libs/libsndfile/src/double64.c b/libs/libsndfile/src/double64.c
new file mode 100644 (file)
index 0000000..9a6f8f1
--- /dev/null
@@ -0,0 +1,1009 @@
+/*
+** Copyright (C) 1999-2005 Erik de Castro Lopo <erikd@mega-nerd.com>
+**
+** This program is free software; you can redistribute it and/or modify
+** it under the terms of the GNU Lesser General Public License as published by
+** the Free Software Foundation; either version 2.1 of the License, or
+** (at your option) any later version.
+**
+** This program is distributed in the hope that it will be useful,
+** but WITHOUT ANY WARRANTY; without even the implied warranty of
+** MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+** GNU Lesser General Public License for more details.
+**
+** You should have received a copy of the GNU Lesser General Public License
+** along with this program; if not, write to the Free Software
+** Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA.
+*/
+
+#include       "sfconfig.h"
+
+#include       <stdio.h>
+#include       <stdlib.h>
+#include       <string.h>
+
+#include       "sndfile.h"
+#include       "sfendian.h"
+#include       "common.h"
+#include       "float_cast.h"
+
+#if CPU_IS_LITTLE_ENDIAN
+       #define DOUBLE64_READ   double64_le_read
+       #define DOUBLE64_WRITE  double64_le_write
+#elif CPU_IS_BIG_ENDIAN
+       #define DOUBLE64_READ   double64_be_read
+       #define DOUBLE64_WRITE  double64_be_write
+#endif
+
+/* A 32 number which will not overflow when multiplied by sizeof (double). */
+#define SENSIBLE_LEN   (0x8000000)
+
+/*--------------------------------------------------------------------------------------------
+**     Processor floating point capabilities. double64_get_capability () returns one of the
+**     latter three values.
+*/
+
+enum
+{      DOUBLE_UNKNOWN          = 0x00,
+       DOUBLE_CAN_RW_LE        = 0x23,
+       DOUBLE_CAN_RW_BE        = 0x34,
+       DOUBLE_BROKEN_LE        = 0x45,
+       DOUBLE_BROKEN_BE        = 0x56
+} ;
+
+/*--------------------------------------------------------------------------------------------
+**     Prototypes for private functions.
+*/
+
+static sf_count_t              host_read_d2s   (SF_PRIVATE *psf, short *ptr, sf_count_t len) ;
+static sf_count_t              host_read_d2i   (SF_PRIVATE *psf, int *ptr, sf_count_t len) ;
+static sf_count_t              host_read_d2f   (SF_PRIVATE *psf, float *ptr, sf_count_t len) ;
+static sf_count_t              host_read_d             (SF_PRIVATE *psf, double *ptr, sf_count_t len) ;
+
+static sf_count_t              host_write_s2d  (SF_PRIVATE *psf, const short *ptr, sf_count_t len) ;
+static sf_count_t              host_write_i2d  (SF_PRIVATE *psf, const int *ptr, sf_count_t len) ;
+static sf_count_t              host_write_f2d  (SF_PRIVATE *psf, const float *ptr, sf_count_t len) ;
+static sf_count_t              host_write_d    (SF_PRIVATE *psf, const double *ptr, sf_count_t len) ;
+
+static void            double64_peak_update    (SF_PRIVATE *psf, const double *buffer, int count, sf_count_t indx) ;
+
+static int             double64_get_capability (SF_PRIVATE *psf) ;
+
+static sf_count_t      replace_read_d2s        (SF_PRIVATE *psf, short *ptr, sf_count_t len) ;
+static sf_count_t      replace_read_d2i        (SF_PRIVATE *psf, int *ptr, sf_count_t len) ;
+static sf_count_t      replace_read_d2f        (SF_PRIVATE *psf, float *ptr, sf_count_t len) ;
+static sf_count_t      replace_read_d  (SF_PRIVATE *psf, double *ptr, sf_count_t len) ;
+
+static sf_count_t      replace_write_s2d       (SF_PRIVATE *psf, const short *ptr, sf_count_t len) ;
+static sf_count_t      replace_write_i2d       (SF_PRIVATE *psf, const int *ptr, sf_count_t len) ;
+static sf_count_t      replace_write_f2d       (SF_PRIVATE *psf, const float *ptr, sf_count_t len) ;
+static sf_count_t      replace_write_d (SF_PRIVATE *psf, const double *ptr, sf_count_t len) ;
+
+static void    d2bd_read (double *buffer, int count) ;
+static void    bd2d_write (double *buffer, int count) ;
+
+/*--------------------------------------------------------------------------------------------
+**     Exported functions.
+*/
+
+int
+double64_init  (SF_PRIVATE *psf)
+{      static int double64_caps ;
+
+       double64_caps = double64_get_capability (psf) ;
+
+       psf->blockwidth = sizeof (double) * psf->sf.channels ;
+
+       if (psf->mode == SFM_READ || psf->mode == SFM_RDWR)
+       {       switch (psf->endian + double64_caps)
+               {       case (SF_ENDIAN_BIG + DOUBLE_CAN_RW_BE) :
+                                       psf->float_endswap = SF_FALSE ;
+                                       psf->read_short         = host_read_d2s ;
+                                       psf->read_int           = host_read_d2i ;
+                                       psf->read_float         = host_read_d2f ;
+                                       psf->read_double        = host_read_d ;
+                                       break ;
+
+                       case (SF_ENDIAN_LITTLE + DOUBLE_CAN_RW_LE) :
+                                       psf->float_endswap = SF_FALSE ;
+                                       psf->read_short         = host_read_d2s ;
+                                       psf->read_int           = host_read_d2i ;
+                                       psf->read_float         = host_read_d2f ;
+                                       psf->read_double        = host_read_d ;
+                                       break ;
+
+                       case (SF_ENDIAN_BIG + DOUBLE_CAN_RW_LE) :
+                                       psf->float_endswap = SF_TRUE ;
+                                       psf->read_short         = host_read_d2s ;
+                                       psf->read_int           = host_read_d2i ;
+                                       psf->read_float         = host_read_d2f ;
+                                       psf->read_double        = host_read_d ;
+                                       break ;
+
+                       case (SF_ENDIAN_LITTLE + DOUBLE_CAN_RW_BE) :
+                                       psf->float_endswap = SF_TRUE ;
+                                       psf->read_short         = host_read_d2s ;
+                                       psf->read_int           = host_read_d2i ;
+                                       psf->read_float         = host_read_d2f ;
+                                       psf->read_double        = host_read_d ;
+                                       break ;
+
+                       /* When the CPU is not IEEE compatible. */
+                       case (SF_ENDIAN_BIG + DOUBLE_BROKEN_BE) :
+                                       psf->float_endswap = SF_FALSE ;
+                                       psf->read_short         = replace_read_d2s ;
+                                       psf->read_int           = replace_read_d2i ;
+                                       psf->read_float         = replace_read_d2f ;
+                                       psf->read_double        = replace_read_d ;
+                                       break ;
+
+                       case (SF_ENDIAN_LITTLE + DOUBLE_BROKEN_LE) :
+                                       psf->float_endswap = SF_FALSE ;
+                                       psf->read_short         = replace_read_d2s ;
+                                       psf->read_int           = replace_read_d2i ;
+                                       psf->read_float         = replace_read_d2f ;
+                                       psf->read_double        = replace_read_d ;
+                                       break ;
+
+                       case (SF_ENDIAN_BIG + DOUBLE_BROKEN_LE) :
+                                       psf->float_endswap = SF_TRUE ;
+                                       psf->read_short         = replace_read_d2s ;
+                                       psf->read_int           = replace_read_d2i ;
+                                       psf->read_float         = replace_read_d2f ;
+                                       psf->read_double        = replace_read_d ;
+                                       break ;
+
+                       case (SF_ENDIAN_LITTLE + DOUBLE_BROKEN_BE) :
+                                       psf->float_endswap = SF_TRUE ;
+                                       psf->read_short         = replace_read_d2s ;
+                                       psf->read_int           = replace_read_d2i ;
+                                       psf->read_float         = replace_read_d2f ;
+                                       psf->read_double        = replace_read_d ;
+                                       break ;
+
+                       default : break ;
+                       } ;
+               } ;
+
+       if (psf->mode == SFM_WRITE || psf->mode == SFM_RDWR)
+       {       switch (psf->endian + double64_caps)
+               {       case (SF_ENDIAN_LITTLE + DOUBLE_CAN_RW_LE) :
+                                       psf->float_endswap = SF_FALSE ;
+                                       psf->write_short        = host_write_s2d ;
+                                       psf->write_int          = host_write_i2d ;
+                                       psf->write_float        = host_write_f2d ;
+                                       psf->write_double       = host_write_d ;
+                                       break ;
+
+                       case (SF_ENDIAN_BIG + DOUBLE_CAN_RW_BE) :
+                                       psf->float_endswap = SF_FALSE ;
+                                       psf->write_short        = host_write_s2d ;
+                                       psf->write_int          = host_write_i2d ;
+                                       psf->write_float        = host_write_f2d ;
+                                       psf->write_double       = host_write_d ;
+                                       break ;
+
+                       case (SF_ENDIAN_BIG + DOUBLE_CAN_RW_LE) :
+                                       psf->float_endswap = SF_TRUE ;
+                                       psf->write_short        = host_write_s2d ;
+                                       psf->write_int          = host_write_i2d ;
+                                       psf->write_float        = host_write_f2d ;
+                                       psf->write_double       = host_write_d ;
+                                       break ;
+
+                       case (SF_ENDIAN_LITTLE + DOUBLE_CAN_RW_BE) :
+                                       psf->float_endswap = SF_TRUE ;
+                                       psf->write_short        = host_write_s2d ;
+                                       psf->write_int          = host_write_i2d ;
+                                       psf->write_float        = host_write_f2d ;
+                                       psf->write_double       = host_write_d ;
+                                       break ;
+
+                       /* When the CPU is not IEEE compatible. */
+                       case (SF_ENDIAN_LITTLE + DOUBLE_BROKEN_LE) :
+                                       psf->float_endswap = SF_FALSE ;
+                                       psf->write_short        = replace_write_s2d ;
+                                       psf->write_int          = replace_write_i2d ;
+                                       psf->write_float        = replace_write_f2d ;
+                                       psf->write_double       = replace_write_d ;
+                                       break ;
+
+                       case (SF_ENDIAN_BIG + DOUBLE_BROKEN_BE) :
+                                       psf->float_endswap = SF_FALSE ;
+                                       psf->write_short        = replace_write_s2d ;
+                                       psf->write_int          = replace_write_i2d ;
+                                       psf->write_float        = replace_write_f2d ;
+                                       psf->write_double       = replace_write_d ;
+                                       break ;
+
+                       case (SF_ENDIAN_BIG + DOUBLE_BROKEN_LE) :
+                                       psf->float_endswap = SF_TRUE ;
+                                       psf->write_short        = replace_write_s2d ;
+                                       psf->write_int          = replace_write_i2d ;
+                                       psf->write_float        = replace_write_f2d ;
+                                       psf->write_double       = replace_write_d ;
+                                       break ;
+
+                       case (SF_ENDIAN_LITTLE + DOUBLE_BROKEN_BE) :
+                                       psf->float_endswap = SF_TRUE ;
+                                       psf->write_short        = replace_write_s2d ;
+                                       psf->write_int          = replace_write_i2d ;
+                                       psf->write_float        = replace_write_f2d ;
+                                       psf->write_double       = replace_write_d ;
+                                       break ;
+
+                       default : break ;
+                       } ;
+               } ;
+
+       if (psf->filelength > psf->dataoffset)
+       {       psf->datalength = (psf->dataend > 0) ? psf->dataend - psf->dataoffset :
+                                                       psf->filelength - psf->dataoffset ;
+               }
+       else
+               psf->datalength = 0 ;
+
+       psf->sf.frames = psf->datalength / psf->blockwidth ;
+
+       return 0 ;
+} /* double64_init */
+
+/*----------------------------------------------------------------------------
+** From : http://www.hpcf.cam.ac.uk/fp_formats.html
+**
+** 64 bit double precision layout (big endian)
+**       Sign                          bit 0
+**       Exponent                      bits 1-11
+**       Mantissa                      bits 12-63
+**       Exponent Offset       1023
+**
+**            double             single
+**
+** +INF     7FF0000000000000     7F800000
+** -INF     FFF0000000000000     FF800000
+**  NaN     7FF0000000000001     7F800001
+**                to               to
+**          7FFFFFFFFFFFFFFF     7FFFFFFF
+**                and              and
+**          FFF0000000000001     FF800001
+**                to               to
+**          FFFFFFFFFFFFFFFF     FFFFFFFF
+** +OVER    7FEFFFFFFFFFFFFF     7F7FFFFF
+** -OVER    FFEFFFFFFFFFFFFF     FF7FFFFF
+** +UNDER   0010000000000000     00800000
+** -UNDER   8010000000000000     80800000
+*/
+
+double
+double64_be_read (unsigned char *cptr)
+{      int             exponent, negative, upper, lower ;
+       double  dvalue ;
+
+       negative = (cptr [0] & 0x80) ? 1 : 0 ;
+       exponent = ((cptr [0] & 0x7F) << 4) | ((cptr [1] >> 4) & 0xF) ;
+
+       /* Might not have a 64 bit long, so load the mantissa into a double. */
+       upper = (((cptr [1] & 0xF) << 24) | (cptr [2] << 16) | (cptr [3] << 8) | cptr [4]) ;
+       lower = (cptr [5] << 16) | (cptr [6] << 8) | cptr [7] ;
+
+       if (exponent == 0 && upper == 0 && lower == 0)
+               return 0.0 ;
+
+       dvalue = upper + lower / ((double) 0x1000000) ;
+       dvalue += 0x10000000 ;
+
+       exponent = exponent - 0x3FF ;
+
+       dvalue = dvalue / ((double) 0x10000000) ;
+
+       if (negative)
+               dvalue *= -1 ;
+
+       if (exponent > 0)
+               dvalue *= (1 << exponent) ;
+       else if (exponent < 0)
+               dvalue /= (1 << abs (exponent)) ;
+
+       return dvalue ;
+} /* double64_be_read */
+
+double
+double64_le_read (unsigned char *cptr)
+{      int             exponent, negative, upper, lower ;
+       double  dvalue ;
+
+       negative = (cptr [7] & 0x80) ? 1 : 0 ;
+       exponent = ((cptr [7] & 0x7F) << 4) | ((cptr [6] >> 4) & 0xF) ;
+
+       /* Might not have a 64 bit long, so load the mantissa into a double. */
+       upper = ((cptr [6] & 0xF) << 24) | (cptr [5] << 16) | (cptr [4] << 8) | cptr [3] ;
+       lower = (cptr [2] << 16) | (cptr [1] << 8) | cptr [0] ;
+
+       if (exponent == 0 && upper == 0 && lower == 0)
+               return 0.0 ;
+
+       dvalue = upper + lower / ((double) 0x1000000) ;
+       dvalue += 0x10000000 ;
+
+       exponent = exponent - 0x3FF ;
+
+       dvalue = dvalue / ((double) 0x10000000) ;
+
+       if (negative)
+               dvalue *= -1 ;
+
+       if (exponent > 0)
+               dvalue *= (1 << exponent) ;
+       else if (exponent < 0)
+               dvalue /= (1 << abs (exponent)) ;
+
+       return dvalue ;
+} /* double64_le_read */
+
+void
+double64_be_write (double in, unsigned char *out)
+{      int             exponent, mantissa ;
+
+       memset (out, 0, sizeof (double)) ;
+
+       if (fabs (in) < 1e-30)
+               return ;
+
+       if (in < 0.0)
+       {       in *= -1.0 ;
+               out [0] |= 0x80 ;
+               } ;
+
+       in = frexp (in, &exponent) ;
+
+       exponent += 1022 ;
+
+       out [0] |= (exponent >> 4) & 0x7F ;
+       out [1] |= (exponent << 4) & 0xF0 ;
+
+       in *= 0x20000000 ;
+       mantissa = lrint (floor (in)) ;
+
+       out [1] |= (mantissa >> 24) & 0xF ;
+       out [2] = (mantissa >> 16) & 0xFF ;
+       out [3] = (mantissa >> 8) & 0xFF ;
+       out [4] = mantissa & 0xFF ;
+
+       in = fmod (in, 1.0) ;
+       in *= 0x1000000 ;
+       mantissa = lrint (floor (in)) ;
+
+       out [5] = (mantissa >> 16) & 0xFF ;
+       out [6] = (mantissa >> 8) & 0xFF ;
+       out [7] = mantissa & 0xFF ;
+
+       return ;
+} /* double64_be_write */
+
+void
+double64_le_write (double in, unsigned char *out)
+{      int             exponent, mantissa ;
+
+       memset (out, 0, sizeof (double)) ;
+
+       if (fabs (in) < 1e-30)
+               return ;
+
+       if (in < 0.0)
+       {       in *= -1.0 ;
+               out [7] |= 0x80 ;
+               } ;
+
+       in = frexp (in, &exponent) ;
+
+       exponent += 1022 ;
+
+       out [7] |= (exponent >> 4) & 0x7F ;
+       out [6] |= (exponent << 4) & 0xF0 ;
+
+       in *= 0x20000000 ;
+       mantissa = lrint (floor (in)) ;
+
+       out [6] |= (mantissa >> 24) & 0xF ;
+       out [5] = (mantissa >> 16) & 0xFF ;
+       out [4] = (mantissa >> 8) & 0xFF ;
+       out [3] = mantissa & 0xFF ;
+
+       in = fmod (in, 1.0) ;
+       in *= 0x1000000 ;
+       mantissa = lrint (floor (in)) ;
+
+       out [2] = (mantissa >> 16) & 0xFF ;
+       out [1] = (mantissa >> 8) & 0xFF ;
+       out [0] = mantissa & 0xFF ;
+
+       return ;
+} /* double64_le_write */
+
+/*==============================================================================================
+**     Private functions.
+*/
+
+static void
+double64_peak_update   (SF_PRIVATE *psf, const double *buffer, int count, sf_count_t indx)
+{      int     chan ;
+       int             k, position ;
+       float   fmaxval ;
+
+       for (chan = 0 ; chan < psf->sf.channels ; chan++)
+       {       fmaxval = fabs (buffer [chan]) ;
+               position = 0 ;
+               for (k = chan ; k < count ; k += psf->sf.channels)
+                       if (fmaxval < fabs (buffer [k]))
+                       {       fmaxval = fabs (buffer [k]) ;
+                               position = k ;
+                               } ;
+
+               if (fmaxval > psf->peak_info->peaks [chan].value)
+               {       psf->peak_info->peaks [chan].value = fmaxval ;
+                       psf->peak_info->peaks [chan].position = psf->write_current + indx + (position / psf->sf.channels) ;
+                       } ;
+               } ;
+
+       return ;
+} /* double64_peak_update */
+
+static int
+double64_get_capability        (SF_PRIVATE *psf)
+{      union
+       {       double                  d ;
+               int                             i [2] ;
+               unsigned char   c [8] ;
+       } data ;
+
+       data.d = 1.234567890123456789 ; /* Some abitrary value. */
+
+       if (! psf->ieee_replace)
+       {       /* If this test is true ints and floats are compatible and little endian. */
+               if (data.i [0] == 0x428c59fb && data.i [1] == 0x3ff3c0ca &&
+                       data.c [0] == 0xfb && data.c [2] == 0x8c && data.c [4] == 0xca && data.c [6] == 0xf3)
+                       return DOUBLE_CAN_RW_LE ;
+
+               /* If this test is true ints and floats are compatible and big endian. */
+               if ((data.i [0] == 0x3ff3c0ca && data.i [1] == 0x428c59fb) &&
+                       (data.c [0] == 0x3f && data.c [2] == 0xc0 && data.c [4] == 0x42 && data.c [6] == 0x59))
+                       return DOUBLE_CAN_RW_BE ;
+               } ;
+
+       /* Doubles are broken. Don't expect reading or writing to be fast. */
+       psf_log_printf (psf, "Using IEEE replacement code for double.\n") ;
+
+       return (CPU_IS_LITTLE_ENDIAN) ? DOUBLE_BROKEN_LE : DOUBLE_BROKEN_BE ;
+} /* double64_get_capability */
+
+/*=======================================================================================
+*/
+
+static inline void
+d2s_array (const double *src, int count, short *dest, double scale)
+{      while (--count >= 0)
+       {       dest [count] = lrint (scale * src [count]) ;
+               } ;
+} /* d2s_array */
+
+static inline void
+d2i_array (const double *src, int count, int *dest, double scale)
+{      while (--count >= 0)
+       {       dest [count] = lrint (scale * src [count]) ;
+               } ;
+} /* d2i_array */
+
+static inline void
+d2f_array (const double *src, int count, float *dest)
+{      while (--count >= 0)
+       {       dest [count] = src [count] ;
+               } ;
+} /* d2f_array */
+
+static inline void
+s2d_array (const short *src, double *dest, int count)
+{      while (--count >= 0)
+       {       dest [count] = src [count] ;
+               } ;
+} /* s2d_array */
+
+static inline void
+i2d_array (const int *src, double *dest, int count)
+{      while (--count >= 0)
+       {       dest [count] = src [count] ;
+               } ;
+} /* i2d_array */
+
+static inline void
+f2d_array (const float *src, double *dest, int count)
+{      while (--count >= 0)
+       {       dest [count] = src [count] ;
+               } ;
+} /* f2d_array */
+
+/*----------------------------------------------------------------------------------------------
+*/
+
+static sf_count_t
+host_read_d2s  (SF_PRIVATE *psf, short *ptr, sf_count_t len)
+{      int                     bufferlen, readcount ;
+       sf_count_t      total = 0 ;
+       double          scale ;
+
+       bufferlen = ARRAY_LEN (psf->u.dbuf) ;
+       scale = (psf->float_int_mult == 0) ? 1.0 : 0x7FFF / psf->float_max ;
+
+       while (len > 0)
+       {       if (len < bufferlen)
+                       bufferlen = (int) len ;
+               readcount = psf_fread (psf->u.dbuf, sizeof (double), bufferlen, psf) ;
+
+               if (psf->float_endswap == SF_TRUE)
+                       endswap_double_array (psf->u.dbuf, readcount) ;
+
+               d2s_array (psf->u.dbuf, readcount, ptr + total, scale) ;
+               total += readcount ;
+               len -= readcount ;
+               if (readcount < bufferlen)
+                       break ;
+               } ;
+
+       return total ;
+} /* host_read_d2s */
+
+static sf_count_t
+host_read_d2i  (SF_PRIVATE *psf, int *ptr, sf_count_t len)
+{      int                     bufferlen, readcount ;
+       sf_count_t      total = 0 ;
+       double          scale ;
+       bufferlen = ARRAY_LEN (psf->u.dbuf) ;
+       scale = (psf->float_int_mult == 0) ? 1.0 : 0x7FFFFFFF / psf->float_max ;
+
+       while (len > 0)
+       {       if (len < bufferlen)
+                       bufferlen = (int) len ;
+               readcount = psf_fread (psf->u.dbuf, sizeof (double), bufferlen, psf) ;
+
+               if (psf->float_endswap == SF_TRUE)
+                       endswap_double_array (psf->u.dbuf, bufferlen) ;
+
+               d2i_array (psf->u.dbuf, readcount, ptr + total, scale) ;
+               total += readcount ;
+               len -= readcount ;
+               if (readcount < bufferlen)
+                       break ;
+               } ;
+
+       return total ;
+} /* host_read_d2i */
+
+static sf_count_t
+host_read_d2f  (SF_PRIVATE *psf, float *ptr, sf_count_t len)
+{      int                     bufferlen, readcount ;
+       sf_count_t      total = 0 ;
+
+       bufferlen = ARRAY_LEN (psf->u.dbuf) ;
+
+       while (len > 0)
+       {       if (len < bufferlen)
+                       bufferlen = (int) len ;
+               readcount = psf_fread (psf->u.dbuf, sizeof (double), bufferlen, psf) ;
+
+               if (psf->float_endswap == SF_TRUE)
+                       endswap_double_array (psf->u.dbuf, bufferlen) ;
+
+               d2f_array (psf->u.dbuf, readcount, ptr + total) ;
+               total += readcount ;
+               len -= readcount ;
+               if (readcount < bufferlen)
+                       break ;
+               } ;
+
+       return total ;
+} /* host_read_d2f */
+
+static sf_count_t
+host_read_d    (SF_PRIVATE *psf, double *ptr, sf_count_t len)
+{      int                     bufferlen ;
+       sf_count_t      readcount, total = 0 ;
+
+       readcount = psf_fread (ptr, sizeof (double), len, psf) ;
+
+       if (psf->float_endswap != SF_TRUE)
+               return readcount ;
+
+       /* If the read length was sensible, endswap output in one go. */
+       if (readcount < SENSIBLE_LEN)
+       {       endswap_double_array (ptr, readcount) ;
+               return readcount ;
+               } ;
+
+       bufferlen = SENSIBLE_LEN ;
+       while (len > 0)
+       {       if (len < bufferlen)
+                       bufferlen = (int) len ;
+
+               endswap_double_array (ptr + total, bufferlen) ;
+
+               total += bufferlen ;
+               len -= bufferlen ;
+               } ;
+
+       return total ;
+} /* host_read_d */
+
+static sf_count_t
+host_write_s2d (SF_PRIVATE *psf, const short *ptr, sf_count_t len)
+{      int                     bufferlen, writecount ;
+       sf_count_t      total = 0 ;
+
+       bufferlen = ARRAY_LEN (psf->u.dbuf) ;
+
+       while (len > 0)
+       {       if (len < bufferlen)
+                       bufferlen = (int) len ;
+
+               s2d_array (ptr + total, psf->u.dbuf, bufferlen) ;
+
+               if (psf->peak_info)
+                       double64_peak_update (psf, psf->u.dbuf, bufferlen, total / psf->sf.channels) ;
+
+               if (psf->float_endswap == SF_TRUE)
+                       endswap_double_array (psf->u.dbuf, bufferlen) ;
+
+               writecount = psf_fwrite (psf->u.dbuf, sizeof (double), bufferlen, psf) ;
+               total += writecount ;
+               if (writecount < bufferlen)
+                       break ;
+               len -= writecount ;
+               } ;
+
+       return total ;
+} /* host_write_s2d */
+
+static sf_count_t
+host_write_i2d (SF_PRIVATE *psf, const int *ptr, sf_count_t len)
+{      int                     bufferlen, writecount ;
+       sf_count_t      total = 0 ;
+
+       bufferlen = ARRAY_LEN (psf->u.dbuf) ;
+
+       while (len > 0)
+       {       if (len < bufferlen)
+                       bufferlen = (int) len ;
+               i2d_array (ptr + total, psf->u.dbuf, bufferlen) ;
+
+               if (psf->peak_info)
+                       double64_peak_update (psf, psf->u.dbuf, bufferlen, total / psf->sf.channels) ;
+
+               if (psf->float_endswap == SF_TRUE)
+                       endswap_double_array (psf->u.dbuf, bufferlen) ;
+
+               writecount = psf_fwrite (psf->u.dbuf, sizeof (double), bufferlen, psf) ;
+               total += writecount ;
+               if (writecount < bufferlen)
+                       break ;
+               len -= writecount ;
+               } ;
+
+       return total ;
+} /* host_write_i2d */
+
+static sf_count_t
+host_write_f2d (SF_PRIVATE *psf, const float *ptr, sf_count_t len)
+{      int                     bufferlen, writecount ;
+       sf_count_t      total = 0 ;
+
+       bufferlen = ARRAY_LEN (psf->u.dbuf) ;
+
+       while (len > 0)
+       {       if (len < bufferlen)
+                       bufferlen = (int) len ;
+               f2d_array (ptr + total, psf->u.dbuf, bufferlen) ;
+
+               if (psf->peak_info)
+                       double64_peak_update (psf, psf->u.dbuf, bufferlen, total / psf->sf.channels) ;
+
+               if (psf->float_endswap == SF_TRUE)
+                       endswap_double_array (psf->u.dbuf, bufferlen) ;
+
+               writecount = psf_fwrite (psf->u.dbuf, sizeof (double), bufferlen, psf) ;
+               total += writecount ;
+               if (writecount < bufferlen)
+                       break ;
+               len -= writecount ;
+               } ;
+
+       return total ;
+} /* host_write_f2d */
+
+static sf_count_t
+host_write_d   (SF_PRIVATE *psf, const double *ptr, sf_count_t len)
+{      int                     bufferlen, writecount ;
+       sf_count_t      total = 0 ;
+
+       if (psf->peak_info)
+               double64_peak_update (psf, ptr, len, 0) ;
+
+       if (psf->float_endswap != SF_TRUE)
+               return psf_fwrite (ptr, sizeof (double), len, psf) ;
+
+       bufferlen = ARRAY_LEN (psf->u.dbuf) ;
+
+       while (len > 0)
+       {       if (len < bufferlen)
+                       bufferlen = (int) len ;
+
+               endswap_double_copy (psf->u.dbuf, ptr + total, bufferlen) ;
+
+               writecount = psf_fwrite (psf->u.dbuf, sizeof (double), bufferlen, psf) ;
+               total += writecount ;
+               if (writecount < bufferlen)
+                       break ;
+               len -= writecount ;
+               } ;
+
+       return total ;
+} /* host_write_d */
+
+/*=======================================================================================
+*/
+
+static sf_count_t
+replace_read_d2s       (SF_PRIVATE *psf, short *ptr, sf_count_t len)
+{      int                     bufferlen, readcount ;
+       sf_count_t      total = 0 ;
+       double          scale ;
+
+       bufferlen = ARRAY_LEN (psf->u.dbuf) ;
+       scale = (psf->float_int_mult == 0) ? 1.0 : 0x7FFF / psf->float_max ;
+
+       while (len > 0)
+       {       if (len < bufferlen)
+                       bufferlen = (int) len ;
+               readcount = psf_fread (psf->u.dbuf, sizeof (double), bufferlen, psf) ;
+
+               if (psf->float_endswap == SF_TRUE)
+                       endswap_double_array (psf->u.dbuf, bufferlen) ;
+
+               d2bd_read (psf->u.dbuf, bufferlen) ;
+
+               d2s_array (psf->u.dbuf, readcount, ptr + total, scale) ;
+               total += readcount ;
+               if (readcount < bufferlen)
+                       break ;
+               len -= readcount ;
+               } ;
+
+       return total ;
+} /* replace_read_d2s */
+
+static sf_count_t
+replace_read_d2i       (SF_PRIVATE *psf, int *ptr, sf_count_t len)
+{      int                     bufferlen, readcount ;
+       sf_count_t      total = 0 ;
+       double          scale ;
+
+       bufferlen = ARRAY_LEN (psf->u.dbuf) ;
+       scale = (psf->float_int_mult == 0) ? 1.0 : 0x7FFFFFFF / psf->float_max ;
+
+       while (len > 0)
+       {       if (len < bufferlen)
+                       bufferlen = (int) len ;
+               readcount = psf_fread (psf->u.dbuf, sizeof (double), bufferlen, psf) ;
+
+               if (psf->float_endswap == SF_TRUE)
+                       endswap_double_array (psf->u.dbuf, bufferlen) ;
+
+               d2bd_read (psf->u.dbuf, bufferlen) ;
+
+               d2i_array (psf->u.dbuf, readcount, ptr + total, scale) ;
+               total += readcount ;
+               if (readcount < bufferlen)
+                       break ;
+               len -= readcount ;
+               } ;
+
+       return total ;
+} /* replace_read_d2i */
+
+static sf_count_t
+replace_read_d2f       (SF_PRIVATE *psf, float *ptr, sf_count_t len)
+{      int                     bufferlen, readcount ;
+       sf_count_t      total = 0 ;
+
+       bufferlen = ARRAY_LEN (psf->u.dbuf) ;
+
+       while (len > 0)
+       {       if (len < bufferlen)
+                       bufferlen = (int) len ;
+               readcount = psf_fread (psf->u.dbuf, sizeof (double), bufferlen, psf) ;
+
+               if (psf->float_endswap == SF_TRUE)
+                       endswap_double_array (psf->u.dbuf, bufferlen) ;
+
+               d2bd_read (psf->u.dbuf, bufferlen) ;
+
+               memcpy (ptr + total, psf->u.dbuf, bufferlen * sizeof (double)) ;
+
+               total += readcount ;
+               if (readcount < bufferlen)
+                       break ;
+               len -= readcount ;
+               } ;
+
+       return total ;
+} /* replace_read_d2f */
+
+static sf_count_t
+replace_read_d (SF_PRIVATE *psf, double *ptr, sf_count_t len)
+{      int                     bufferlen, readcount ;
+       sf_count_t      total = 0 ;
+
+       /* FIXME : This is probably nowhere near optimal. */
+       bufferlen = ARRAY_LEN (psf->u.dbuf) ;
+
+       while (len > 0)
+       {       if (len < bufferlen)
+                       bufferlen = (int) len ;
+               readcount = psf_fread (psf->u.dbuf, sizeof (double), bufferlen, psf) ;
+
+               if (psf->float_endswap == SF_TRUE)
+                       endswap_double_array (psf->u.dbuf, readcount) ;
+
+               d2bd_read (psf->u.dbuf, readcount) ;
+
+               memcpy (ptr + total, psf->u.dbuf, readcount * sizeof (double)) ;
+
+               total += readcount ;
+               if (readcount < bufferlen)
+                       break ;
+               len -= readcount ;
+               } ;
+
+       return total ;
+} /* replace_read_d */
+
+static sf_count_t
+replace_write_s2d      (SF_PRIVATE *psf, const short *ptr, sf_count_t len)
+{      int                     bufferlen, writecount ;
+       sf_count_t      total = 0 ;
+
+       bufferlen = ARRAY_LEN (psf->u.dbuf) ;
+
+       while (len > 0)
+       {       if (len < bufferlen)
+                       bufferlen = (int) len ;
+               s2d_array (ptr + total, psf->u.dbuf, bufferlen) ;
+
+               if (psf->peak_info)
+                       double64_peak_update (psf, psf->u.dbuf, bufferlen, total / psf->sf.channels) ;
+
+               bd2d_write (psf->u.dbuf, bufferlen) ;
+
+               if (psf->float_endswap == SF_TRUE)
+                       endswap_double_array (psf->u.dbuf, bufferlen) ;
+
+               writecount = psf_fwrite (psf->u.dbuf, sizeof (double), bufferlen, psf) ;
+               total += writecount ;
+               if (writecount < bufferlen)
+                       break ;
+               len -= writecount ;
+               } ;
+
+       return total ;
+} /* replace_write_s2d */
+
+static sf_count_t
+replace_write_i2d      (SF_PRIVATE *psf, const int *ptr, sf_count_t len)
+{      int                     bufferlen, writecount ;
+       sf_count_t      total = 0 ;
+
+       bufferlen = ARRAY_LEN (psf->u.dbuf) ;
+
+       while (len > 0)
+       {       if (len < bufferlen)
+                       bufferlen = (int) len ;
+               i2d_array (ptr + total, psf->u.dbuf, bufferlen) ;
+
+               if (psf->peak_info)
+                       double64_peak_update (psf, psf->u.dbuf, bufferlen, total / psf->sf.channels) ;
+
+               bd2d_write (psf->u.dbuf, bufferlen) ;
+
+               if (psf->float_endswap == SF_TRUE)
+                       endswap_double_array (psf->u.dbuf, bufferlen) ;
+
+               writecount = psf_fwrite (psf->u.dbuf, sizeof (double), bufferlen, psf) ;
+               total += writecount ;
+               if (writecount < bufferlen)
+                       break ;
+               len -= writecount ;
+               } ;
+
+       return total ;
+} /* replace_write_i2d */
+
+static sf_count_t
+replace_write_f2d      (SF_PRIVATE *psf, const float *ptr, sf_count_t len)
+{      int                     bufferlen, writecount ;
+       sf_count_t      total = 0 ;
+
+       bufferlen = ARRAY_LEN (psf->u.dbuf) ;
+
+       while (len > 0)
+       {       if (len < bufferlen)
+                       bufferlen = (int) len ;
+               f2d_array (ptr + total, psf->u.dbuf, bufferlen) ;
+
+               bd2d_write (psf->u.dbuf, bufferlen) ;
+
+               if (psf->float_endswap == SF_TRUE)
+                       endswap_double_array (psf->u.dbuf, bufferlen) ;
+
+               writecount = psf_fwrite (psf->u.dbuf, sizeof (double), bufferlen, psf) ;
+               total += writecount ;
+               if (writecount < bufferlen)
+                       break ;
+               len -= writecount ;
+               } ;
+
+       return total ;
+} /* replace_write_f2d */
+
+static sf_count_t
+replace_write_d        (SF_PRIVATE *psf, const double *ptr, sf_count_t len)
+{      int                     bufferlen, writecount ;
+       sf_count_t      total = 0 ;
+
+       /* FIXME : This is probably nowhere near optimal. */
+       if (psf->peak_info)
+               double64_peak_update (psf, ptr, len, 0) ;
+
+       bufferlen = ARRAY_LEN (psf->u.dbuf) ;
+
+       while (len > 0)
+       {       if (len < bufferlen)
+                       bufferlen = (int) len ;
+
+               memcpy (psf->u.dbuf, ptr + total, bufferlen * sizeof (double)) ;
+
+               bd2d_write (psf->u.dbuf, bufferlen) ;
+
+               if (psf->float_endswap == SF_TRUE)
+                       endswap_double_array (psf->u.dbuf, bufferlen) ;
+
+               writecount = psf_fwrite (psf->u.dbuf, sizeof (double), bufferlen, psf) ;
+               total += writecount ;
+               if (writecount < bufferlen)
+                       break ;
+               len -= writecount ;
+               } ;
+
+       return total ;
+} /* replace_write_d */
+
+/*----------------------------------------------------------------------------------------------
+*/
+
+static void
+d2bd_read (double *buffer, int count)
+{      while (--count >= 0)
+       {       buffer [count] = DOUBLE64_READ ((unsigned char *) (buffer + count)) ;
+               } ;
+} /* d2bd_read */
+
+static void
+bd2d_write (double *buffer, int count)
+{      while (--count >= 0)
+       {       DOUBLE64_WRITE (buffer [count], (unsigned char*) (buffer + count)) ;
+               } ;
+} /* bd2d_write */
+
+/*
+** Do not edit or modify anything in this comment block.
+** The arch-tag line is a file identity tag for the GNU Arch
+** revision control system.
+**
+** arch-tag: 4ee243b7-8c7a-469b-869c-e9aa0ee3b77f
+*/
diff --git a/libs/libsndfile/src/dwd.c b/libs/libsndfile/src/dwd.c
new file mode 100644 (file)
index 0000000..a33bae0
--- /dev/null
@@ -0,0 +1,210 @@
+/*
+** Copyright (C) 2002-2004 Erik de Castro Lopo <erikd@mega-nerd.com>
+**
+** This program is free software; you can redistribute it and/or modify
+** it under the terms of the GNU Lesser General Public License as published by
+** the Free Software Foundation; either version 2.1 of the License, or
+** (at your option) any later version.
+**
+** This program is distributed in the hope that it will be useful,
+** but WITHOUT ANY WARRANTY; without even the implied warranty of
+** MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+** GNU Lesser General Public License for more details.
+**
+** You should have received a copy of the GNU Lesser General Public License
+** along with this program; if not, write to the Free Software
+** Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA.
+*/
+
+#include       "sfconfig.h"
+
+#include       <stdio.h>
+#include       <fcntl.h>
+#include       <string.h>
+#include       <ctype.h>
+
+#include       "sndfile.h"
+#include       "sfendian.h"
+#include       "common.h"
+
+#if (ENABLE_EXPERIMENTAL_CODE == 0)
+
+int
+dwd_open       (SF_PRIVATE *psf)
+{      if (psf)
+               return SFE_UNIMPLEMENTED ;
+       return (psf && 0) ;
+} /* dwd_open */
+
+#else
+
+/*------------------------------------------------------------------------------
+** Macros to handle big/little endian issues.
+*/
+
+#define SFE_DWD_NO_DWD                 1666
+#define SFE_DWD_BAND_BIT_WIDTH         1667
+#define SFE_DWD_COMPRESSION            1668
+
+#define        DWD_IDENTIFIER          "DiamondWare Digitized\n\0\x1a"
+#define        DWD_IDENTIFIER_LEN      24
+
+#define        DWD_HEADER_LEN          57
+
+/*------------------------------------------------------------------------------
+** Typedefs.
+*/
+
+/*------------------------------------------------------------------------------
+** Private static functions.
+*/
+
+static int     dwd_read_header (SF_PRIVATE *psf) ;
+
+static int     dwd_close               (SF_PRIVATE *psf) ;
+
+/*------------------------------------------------------------------------------
+** Public function.
+*/
+
+int
+dwd_open (SF_PRIVATE *psf)
+{      int     subformat, error = 0 ;
+
+       if (psf->mode == SFM_READ || (psf->mode == SFM_RDWR && psf->filelength > 0))
+       {       if ((error = dwd_read_header (psf)))
+                       return error ;
+               } ;
+
+       if ((psf->sf.format & SF_FORMAT_TYPEMASK) != SF_FORMAT_DWD)
+               return  SFE_BAD_OPEN_FORMAT ;
+
+       subformat = psf->sf.format & SF_FORMAT_SUBMASK ;
+
+       if (psf->mode == SFM_WRITE || psf->mode == SFM_RDWR)
+       {
+               /*-psf->endian = psf->sf.format & SF_FORMAT_ENDMASK ;
+               if (CPU_IS_LITTLE_ENDIAN && psf->endian == SF_ENDIAN_CPU)
+                       psf->endian = SF_ENDIAN_LITTLE ;
+               else if (psf->endian != SF_ENDIAN_LITTLE)
+                       psf->endian = SF_ENDIAN_BIG ;
+
+               if (! (encoding = dwd_write_header (psf, SF_FALSE)))
+                       return psf->error ;
+
+               psf->write_header = dwd_write_header ;
+               -*/
+               } ;
+
+       psf->container_close = dwd_close ;
+
+       /*-psf->blockwidth = psf->bytewidth * psf->sf.channels ;-*/
+
+       return error ;
+} /* dwd_open */
+
+/*------------------------------------------------------------------------------
+*/
+
+static int
+dwd_close      (SF_PRIVATE *psf)
+{
+       psf = psf ;
+
+       return 0 ;
+} /* dwd_close */
+
+/* This struct contains all the fields of interest om the DWD header, but does not
+** do so in the same order and layout as the actual file, header.
+** No assumptions are made about the packing of this struct.
+*/
+typedef struct
+{      unsigned char major, minor, compression, channels, bitwidth ;
+       unsigned short srate, maxval ;
+       unsigned int id, datalen, frames, offset ;
+} DWD_HEADER ;
+
+static int
+dwd_read_header (SF_PRIVATE *psf)
+{      DWD_HEADER      dwdh ;
+
+       memset (psf->u.cbuf, 0, sizeof (psf->u.cbuf)) ;
+       /* Set position to start of file to begin reading header. */
+       psf_binheader_readf (psf, "pb", 0, psf->u.cbuf, DWD_IDENTIFIER_LEN) ;
+
+       if (memcmp (psf->u.cbuf, DWD_IDENTIFIER, DWD_IDENTIFIER_LEN) != 0)
+               return SFE_DWD_NO_DWD ;
+
+       psf_log_printf (psf, "Read only : DiamondWare Digitized (.dwd)\n", psf->u.cbuf) ;
+
+       psf_binheader_readf (psf, "11", &dwdh.major, &dwdh.minor) ;
+       psf_binheader_readf (psf, "e4j1", &dwdh.id, 1, &dwdh.compression) ;
+       psf_binheader_readf (psf, "e211", &dwdh.srate, &dwdh.channels, &dwdh.bitwidth) ;
+       psf_binheader_readf (psf, "e24", &dwdh.maxval, &dwdh.datalen) ;
+       psf_binheader_readf (psf, "e44", &dwdh.frames, &dwdh.offset) ;
+
+       psf_log_printf (psf, "  Version Major : %d\n  Version Minor : %d\n  Unique ID     : %08X\n",
+                                               dwdh.major, dwdh.minor, dwdh.id) ;
+       psf_log_printf (psf, "  Compression   : %d => ", dwdh.compression) ;
+
+       if (dwdh.compression != 0)
+       {       psf_log_printf (psf, "Unsupported compression\n") ;
+               return SFE_DWD_COMPRESSION ;
+               }
+       else
+               psf_log_printf (psf, "None\n") ;
+
+       psf_log_printf (psf, "  Sample Rate   : %d\n  Channels      : %d\n"
+                                                "  Bit Width     : %d\n",
+                                                dwdh.srate, dwdh.channels, dwdh.bitwidth) ;
+
+       switch (dwdh.bitwidth)
+       {       case 8 :
+                               psf->sf.format = SF_FORMAT_DWD | SF_FORMAT_PCM_S8 ;
+                               psf->bytewidth = 1 ;
+                               break ;
+
+               case 16 :
+                               psf->sf.format = SF_FORMAT_DWD | SF_FORMAT_PCM_16 ;
+                               psf->bytewidth = 2 ;
+                               break ;
+
+               default :
+                               psf_log_printf (psf, "*** Bad bit width %d\n", dwdh.bitwidth) ;
+                               return SFE_DWD_BAND_BIT_WIDTH ;
+                               } ;
+
+       if (psf->filelength != dwdh.offset + dwdh.datalen)
+       {       psf_log_printf (psf, "  Data Length   : %d (should be %D)\n", dwdh.datalen, psf->filelength - dwdh.offset) ;
+               dwdh.datalen = (unsigned int) (psf->filelength - dwdh.offset) ;
+               }
+       else
+               psf_log_printf (psf, "  Data Length   : %d\n", dwdh.datalen) ;
+
+       psf_log_printf (psf, "  Max Value     : %d\n", dwdh.maxval) ;
+       psf_log_printf (psf, "  Frames        : %d\n", dwdh.frames) ;
+       psf_log_printf (psf, "  Data Offset   : %d\n", dwdh.offset) ;
+
+       psf->datalength = dwdh.datalen ;
+       psf->dataoffset = dwdh.offset ;
+
+       psf->endian = SF_ENDIAN_LITTLE ;
+
+       psf->sf.samplerate = dwdh.srate ;
+       psf->sf.channels = dwdh.channels ;
+       psf->sf.sections = 1 ;
+
+       return pcm_init (psf) ;
+} /* dwd_read_header */
+
+/*------------------------------------------------------------------------------
+*/
+
+#endif
+/*
+** Do not edit or modify anything in this comment block.
+** The arch-tag line is a file identity tag for the GNU Arch 
+** revision control system.
+**
+** arch-tag: a5e1d2a6-a840-4039-a0e7-e1a43eb05a4f
+*/
diff --git a/libs/libsndfile/src/dwvw.c b/libs/libsndfile/src/dwvw.c
new file mode 100644 (file)
index 0000000..dc9ae77
--- /dev/null
@@ -0,0 +1,671 @@
+/*
+** Copyright (C) 2002-2005 Erik de Castro Lopo <erikd@mega-nerd.com>
+**
+** This program is free software; you can redistribute it and/or modify
+** it under the terms of the GNU Lesser General Public License as published by
+** the Free Software Foundation; either version 2.1 of the License, or
+** (at your option) any later version.
+**
+** This program is distributed in the hope that it will be useful,
+** but WITHOUT ANY WARRANTY; without even the implied warranty of
+** MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+** GNU Lesser General Public License for more details.
+**
+** You should have received a copy of the GNU Lesser General Public License
+** along with this program; if not, write to the Free Software
+** Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA.
+*/
+
+/*===========================================================================
+** Delta Word Variable Width
+**
+** This decoder and encoder were implemented using information found in this
+** document : http://home.swbell.net/rubywand/R011SNDFMTS.TXT
+**
+** According to the document, the algorithm "was invented 1991 by Magnus
+** Lidstrom and is copyright 1993 by NuEdge Development".
+*/
+
+#include       "sfconfig.h"
+
+#include       <stdio.h>
+#include       <stdlib.h>
+#include       <string.h>
+
+#include       "sndfile.h"
+#include       "sfendian.h"
+#include       "float_cast.h"
+#include       "common.h"
+
+typedef struct
+{      int             dwm_maxsize, bit_width, max_delta, span ;
+       int             samplecount ;
+       int             bit_count, bits, last_delta_width, last_sample ;
+       struct
+       {       int                             index, end ;
+               unsigned char   buffer [256] ;
+       } b ;
+} DWVW_PRIVATE ;
+
+/*============================================================================================
+*/
+
+static sf_count_t dwvw_read_s (SF_PRIVATE *psf, short *ptr, sf_count_t len) ;
+static sf_count_t dwvw_read_i (SF_PRIVATE *psf, int *ptr, sf_count_t len) ;
+static sf_count_t dwvw_read_f (SF_PRIVATE *psf, float *ptr, sf_count_t len) ;
+static sf_count_t dwvw_read_d (SF_PRIVATE *psf, double *ptr, sf_count_t len) ;
+
+static sf_count_t dwvw_write_s (SF_PRIVATE *psf, const short *ptr, sf_count_t len) ;
+static sf_count_t dwvw_write_i (SF_PRIVATE *psf, const int *ptr, sf_count_t len) ;
+static sf_count_t dwvw_write_f (SF_PRIVATE *psf, const float *ptr, sf_count_t len) ;
+static sf_count_t dwvw_write_d (SF_PRIVATE *psf, const double *ptr, sf_count_t len) ;
+
+static sf_count_t      dwvw_seek       (SF_PRIVATE *psf, int mode, sf_count_t offset) ;
+static int     dwvw_close      (SF_PRIVATE *psf) ;
+
+static int     dwvw_decode_data (SF_PRIVATE *psf, DWVW_PRIVATE *pdwvw, int *ptr, int len) ;
+static int     dwvw_decode_load_bits (SF_PRIVATE *psf, DWVW_PRIVATE *pdwvw, int bit_count) ;
+
+static int     dwvw_encode_data (SF_PRIVATE *psf, DWVW_PRIVATE *pdwvw, const int *ptr, int len) ;
+static void dwvw_encode_store_bits (SF_PRIVATE *psf, DWVW_PRIVATE *pdwvw, int data, int new_bits) ;
+static void dwvw_read_reset (DWVW_PRIVATE *pdwvw) ;
+
+/*============================================================================================
+** DWVW initialisation function.
+*/
+
+int
+dwvw_init (SF_PRIVATE *psf, int bitwidth)
+{      DWVW_PRIVATE    *pdwvw ;
+
+       if (psf->fdata != NULL)
+       {       psf_log_printf (psf, "*** psf->fdata is not NULL.\n") ;
+               return SFE_INTERNAL ;
+               } ;
+
+       if (bitwidth > 24)
+               return SFE_DWVW_BAD_BITWIDTH ;
+
+       if (psf->mode == SFM_RDWR)
+               return SFE_BAD_MODE_RW ;
+
+       if ((pdwvw = calloc (1, sizeof (DWVW_PRIVATE))) == NULL)
+               return SFE_MALLOC_FAILED ;
+
+       psf->fdata = (void*) pdwvw ;
+
+       pdwvw->bit_width        = bitwidth ;
+       pdwvw->dwm_maxsize      = bitwidth / 2 ;
+       pdwvw->max_delta        = 1 << (bitwidth - 1) ;
+       pdwvw->span                     = 1 << bitwidth ;
+
+       dwvw_read_reset (pdwvw) ;
+
+       if (psf->mode == SFM_READ)
+       {       psf->read_short         = dwvw_read_s ;
+               psf->read_int           = dwvw_read_i ;
+               psf->read_float         = dwvw_read_f ;
+               psf->read_double        = dwvw_read_d ;
+               } ;
+
+       if (psf->mode == SFM_WRITE)
+       {       psf->write_short        = dwvw_write_s ;
+               psf->write_int          = dwvw_write_i ;
+               psf->write_float        = dwvw_write_f ;
+               psf->write_double       = dwvw_write_d ;
+               } ;
+
+       psf->codec_close = dwvw_close ;
+       psf->seek = dwvw_seek ;
+
+       /* FIXME : This is bogus. */
+       psf->sf.frames = SF_COUNT_MAX ;
+       psf->datalength = psf->sf.frames ;
+       /* EMXIF : This is bogus. */
+
+       return 0 ;
+} /* dwvw_init */
+
+/*--------------------------------------------------------------------------------------------
+*/
+
+static int
+dwvw_close (SF_PRIVATE *psf)
+{      DWVW_PRIVATE *pdwvw ;
+
+       if (psf->fdata == NULL)
+               return 0 ;
+       pdwvw = (DWVW_PRIVATE*) psf->fdata ;
+
+       if (psf->mode == SFM_WRITE)
+       {       static int last_values [12] = { 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0 } ;
+
+               /* Write 8 zero samples to fully flush output. */
+               dwvw_encode_data (psf, pdwvw, last_values, 12) ;
+
+               /* Write the last buffer worth of data to disk. */
+               psf_fwrite (pdwvw->b.buffer, 1, pdwvw->b.index, psf) ;
+
+               if (psf->write_header)
+                       psf->write_header (psf, SF_TRUE) ;
+               } ;
+
+       return 0 ;
+} /* dwvw_close */
+
+static sf_count_t
+dwvw_seek      (SF_PRIVATE *psf, int mode, sf_count_t offset)
+{      DWVW_PRIVATE *pdwvw ;
+
+       mode = mode ;
+
+       if (! psf->fdata)
+       {       psf->error = SFE_INTERNAL ;
+               return PSF_SEEK_ERROR ;
+               } ;
+
+       pdwvw = (DWVW_PRIVATE*) psf->fdata ;
+
+       if (offset == 0)
+       {       psf_fseek (psf, psf->dataoffset, SEEK_SET) ;
+               dwvw_read_reset (pdwvw) ;
+               return 0 ;
+               } ;
+
+       psf->error = SFE_BAD_SEEK ;
+       return  PSF_SEEK_ERROR ;
+} /* dwvw_seek */
+
+
+/*==============================================================================
+*/
+
+static sf_count_t
+dwvw_read_s (SF_PRIVATE *psf, short *ptr, sf_count_t len)
+{      DWVW_PRIVATE *pdwvw ;
+       int             *iptr ;
+       int             k, bufferlen, readcount = 0, count ;
+       sf_count_t      total = 0 ;
+
+       if (! psf->fdata)
+               return 0 ;
+       pdwvw = (DWVW_PRIVATE*) psf->fdata ;
+
+       iptr = psf->u.ibuf ;
+       bufferlen = ARRAY_LEN (psf->u.ibuf) ;
+       while (len > 0)
+       {       readcount = (len >= bufferlen) ? bufferlen : len ;
+               count = dwvw_decode_data (psf, pdwvw, iptr, readcount) ;
+               for (k = 0 ; k < readcount ; k++)
+                       ptr [total + k] = iptr [k] >> 16 ;
+
+               total += count ;
+               len -= readcount ;
+               if (count != readcount)
+                       break ;
+               } ;
+
+       return total ;
+} /* dwvw_read_s */
+
+static sf_count_t
+dwvw_read_i (SF_PRIVATE *psf, int *ptr, sf_count_t len)
+{      DWVW_PRIVATE *pdwvw ;
+       int                     readcount, count ;
+       sf_count_t      total = 0 ;
+
+       if (! psf->fdata)
+               return 0 ;
+       pdwvw = (DWVW_PRIVATE*) psf->fdata ;
+
+       while (len > 0)
+       {       readcount = (len > 0x10000000) ? 0x10000000 : (int) len ;
+
+               count = dwvw_decode_data (psf, pdwvw, ptr, readcount) ;
+
+               total += count ;
+               len -= count ;
+
+               if (count != readcount)
+                       break ;
+               } ;
+
+       return total ;
+} /* dwvw_read_i */
+
+static sf_count_t
+dwvw_read_f (SF_PRIVATE *psf, float *ptr, sf_count_t len)
+{      DWVW_PRIVATE *pdwvw ;
+       int             *iptr ;
+       int             k, bufferlen, readcount = 0, count ;
+       sf_count_t      total = 0 ;
+       float   normfact ;
+
+       if (! psf->fdata)
+               return 0 ;
+       pdwvw = (DWVW_PRIVATE*) psf->fdata ;
+
+       normfact = (psf->norm_float == SF_TRUE) ? 1.0 / ((float) 0x80000000) : 1.0 ;
+
+       iptr = psf->u.ibuf ;
+       bufferlen = ARRAY_LEN (psf->u.ibuf) ;
+       while (len > 0)
+       {       readcount = (len >= bufferlen) ? bufferlen : len ;
+               count = dwvw_decode_data (psf, pdwvw, iptr, readcount) ;
+               for (k = 0 ; k < readcount ; k++)
+                       ptr [total + k] = normfact * (float) (iptr [k]) ;
+
+               total += count ;
+               len -= readcount ;
+               if (count != readcount)
+                       break ;
+               } ;
+
+       return total ;
+} /* dwvw_read_f */
+
+static sf_count_t
+dwvw_read_d (SF_PRIVATE *psf, double *ptr, sf_count_t len)
+{      DWVW_PRIVATE *pdwvw ;
+       int             *iptr ;
+       int             k, bufferlen, readcount = 0, count ;
+       sf_count_t      total = 0 ;
+       double  normfact ;
+
+       if (! psf->fdata)
+               return 0 ;
+       pdwvw = (DWVW_PRIVATE*) psf->fdata ;
+
+       normfact = (psf->norm_double == SF_TRUE) ? 1.0 / ((double) 0x80000000) : 1.0 ;
+
+       iptr = psf->u.ibuf ;
+       bufferlen = ARRAY_LEN (psf->u.ibuf) ;
+       while (len > 0)
+       {       readcount = (len >= bufferlen) ? bufferlen : len ;
+               count = dwvw_decode_data (psf, pdwvw, iptr, readcount) ;
+               for (k = 0 ; k < readcount ; k++)
+                       ptr [total + k] = normfact * (double) (iptr [k]) ;
+
+               total += count ;
+               len -= readcount ;
+               if (count != readcount)
+                       break ;
+               } ;
+
+       return total ;
+} /* dwvw_read_d */
+
+static int
+dwvw_decode_data (SF_PRIVATE *psf, DWVW_PRIVATE *pdwvw, int *ptr, int len)
+{      int     count ;
+       int delta_width_modifier, delta_width, delta_negative, delta, sample ;
+
+       /* Restore state from last decode call. */
+       delta_width = pdwvw->last_delta_width ;
+       sample = pdwvw->last_sample ;
+
+       for (count = 0 ; count < len ; count++)
+       {       /* If bit_count parameter is zero get the delta_width_modifier. */
+               delta_width_modifier = dwvw_decode_load_bits (psf, pdwvw, -1) ;
+
+               /* Check for end of input bit stream. Break loop if end. */
+               if (delta_width_modifier < 0)
+                       break ;
+
+               if (delta_width_modifier && dwvw_decode_load_bits (psf, pdwvw, 1))
+                       delta_width_modifier = - delta_width_modifier ;
+
+               /* Calculate the current word width. */
+               delta_width = (delta_width + delta_width_modifier + pdwvw->bit_width) % pdwvw->bit_width ;
+
+               /* Load the delta. */
+               delta = 0 ;
+               if (delta_width)
+               {       delta = dwvw_decode_load_bits (psf, pdwvw, delta_width - 1) | (1 << (delta_width - 1)) ;
+                       delta_negative = dwvw_decode_load_bits (psf, pdwvw, 1) ;
+                       if (delta == pdwvw->max_delta - 1)
+                               delta += dwvw_decode_load_bits (psf, pdwvw, 1) ;
+                       if (delta_negative)
+                               delta = -delta ;
+                       } ;
+
+               /* Calculate the sample */
+               sample += delta ;
+
+               if (sample >= pdwvw->max_delta)
+                       sample -= pdwvw->span ;
+               else if (sample < - pdwvw->max_delta)
+                       sample += pdwvw->span ;
+
+               /* Store the sample justifying to the most significant bit. */
+               ptr [count] = sample << (32 - pdwvw->bit_width) ;
+
+               if (pdwvw->b.end == 0 && pdwvw->bit_count == 0)
+                       break ;
+               } ;
+
+       pdwvw->last_delta_width = delta_width ;
+       pdwvw->last_sample = sample ;
+
+       pdwvw->samplecount += count ;
+
+       return count ;
+} /* dwvw_decode_data */
+
+static int
+dwvw_decode_load_bits (SF_PRIVATE *psf, DWVW_PRIVATE *pdwvw, int bit_count)
+{      int output = 0, get_dwm = SF_FALSE ;
+
+       /*
+       **      Depending on the value of parameter bit_count, either get the
+       **      required number of bits (ie bit_count > 0) or the
+       **      delta_width_modifier (otherwise).
+       */
+
+       if (bit_count < 0)
+       {       get_dwm = SF_TRUE ;
+               /* modify bit_count to ensure we have enought bits for finding dwm. */
+               bit_count = pdwvw->dwm_maxsize ;
+               } ;
+
+       /* Load bits in bit reseviour. */
+       while (pdwvw->bit_count < bit_count)
+       {       if (pdwvw->b.index >= pdwvw->b.end)
+               {       pdwvw->b.end = psf_fread (pdwvw->b.buffer, 1, sizeof (pdwvw->b.buffer), psf) ;
+                       pdwvw->b.index = 0 ;
+                       } ;
+
+               /* Check for end of input stream. */
+               if (bit_count < 8 && pdwvw->b.end == 0)
+                       return -1 ;
+
+               pdwvw->bits = (pdwvw->bits << 8) ;
+
+               if (pdwvw->b.index < pdwvw->b.end)
+               {       pdwvw->bits |= pdwvw->b.buffer [pdwvw->b.index] ;
+                       pdwvw->b.index ++ ;
+                       } ;
+               pdwvw->bit_count += 8 ;
+               } ;
+
+       /* If asked to get bits do so. */
+       if (! get_dwm)
+       {       output = (pdwvw->bits >> (pdwvw->bit_count - bit_count)) & ((1 << bit_count) - 1) ;
+               pdwvw->bit_count -= bit_count ;
+               return output ;
+               } ;
+
+       /* Otherwise must have been asked to get delta_width_modifier. */
+       while (output < (pdwvw->dwm_maxsize))
+       {       pdwvw->bit_count -= 1 ;
+               if (pdwvw->bits & (1 << pdwvw->bit_count))
+                       break ;
+               output += 1 ;
+               } ;
+
+       return output ;
+} /* dwvw_decode_load_bits */
+
+static void
+dwvw_read_reset (DWVW_PRIVATE *pdwvw)
+{      pdwvw->samplecount              = 0 ;
+       pdwvw->b.index                  = 0 ;
+       pdwvw->b.end                    = 0 ;
+       pdwvw->bit_count                = 0 ;
+       pdwvw->bits                             = 0 ;
+       pdwvw->last_delta_width = 0 ;
+       pdwvw->last_sample              = 0 ;
+} /* dwvw_read_reset */
+
+static void
+dwvw_encode_store_bits (SF_PRIVATE *psf, DWVW_PRIVATE *pdwvw, int data, int new_bits)
+{      int     byte ;
+
+       /* Shift the bits into the resevoir. */
+       pdwvw->bits = (pdwvw->bits << new_bits) | (data & ((1 << new_bits) - 1)) ;
+       pdwvw->bit_count += new_bits ;
+
+       /* Transfer bit to buffer. */
+       while (pdwvw->bit_count >= 8)
+       {       byte = pdwvw->bits >> (pdwvw->bit_count -       8) ;
+               pdwvw->bit_count -= 8 ;
+               pdwvw->b.buffer [pdwvw->b.index] = byte & 0xFF ;
+               pdwvw->b.index ++ ;
+               } ;
+
+       if (pdwvw->b.index > SIGNED_SIZEOF (pdwvw->b.buffer) - 4)
+       {       psf_fwrite (pdwvw->b.buffer, 1, pdwvw->b.index, psf) ;
+               pdwvw->b.index = 0 ;
+               } ;
+
+       return ;
+} /* dwvw_encode_store_bits */
+
+#if 0
+/* Debigging routine. */
+static void
+dump_bits (DWVW_PRIVATE *pdwvw)
+{      int k, mask ;
+
+       for (k = 0 ; k < 10 && k < pdwvw->b.index ; k++)
+       {       mask = 0x80 ;
+               while (mask)
+               {       putchar (mask & pdwvw->b.buffer [k] ? '1' : '0') ;
+                       mask >>= 1 ;
+                       } ;
+               putchar (' ') ;
+               }
+
+       for (k = pdwvw->bit_count - 1 ; k >= 0 ; k --)
+               putchar (pdwvw->bits & (1 << k) ? '1' : '0') ;
+
+       putchar ('\n') ;
+} /* dump_bits */
+#endif
+
+#define HIGHEST_BIT(x,count)           \
+                       {       int y = x ;                     \
+                               (count) = 0 ;           \
+                               while (y)                       \
+                               {       (count) ++ ;    \
+                                       y >>= 1 ;               \
+                                       } ;                             \
+                               } ;
+
+static int
+dwvw_encode_data (SF_PRIVATE *psf, DWVW_PRIVATE *pdwvw, const int *ptr, int len)
+{      int     count ;
+       int delta_width_modifier, delta, delta_negative, delta_width, extra_bit ;
+
+       for (count = 0 ; count < len ; count++)
+       {       delta = (ptr [count] >> (32 - pdwvw->bit_width)) - pdwvw->last_sample ;
+
+               /* Calculate extra_bit if needed. */
+               extra_bit = -1 ;
+               delta_negative = 0 ;
+               if (delta < -pdwvw->max_delta)
+                       delta = pdwvw->max_delta + (delta % pdwvw->max_delta) ;
+               else if (delta == -pdwvw->max_delta)
+               {       extra_bit = 1 ;
+                       delta_negative = 1 ;
+                       delta = pdwvw->max_delta - 1 ;
+                       }
+               else if (delta > pdwvw->max_delta)
+               {       delta_negative = 1 ;
+                       delta = pdwvw->span - delta ;
+                       delta = abs (delta) ;
+                       }
+               else if (delta == pdwvw->max_delta)
+               {       extra_bit = 1 ;
+                       delta = pdwvw->max_delta - 1 ;
+                       }
+               else if (delta < 0)
+               {       delta_negative = 1 ;
+                       delta = abs (delta) ;
+                       } ;
+
+               if (delta == pdwvw->max_delta - 1 && extra_bit == -1)
+                       extra_bit = 0 ;
+
+               /* Find width in bits of delta */
+               HIGHEST_BIT (delta, delta_width) ;
+
+               /* Calculate the delta_width_modifier */
+               delta_width_modifier = (delta_width - pdwvw->last_delta_width) % pdwvw->bit_width ;
+               if (delta_width_modifier > pdwvw->dwm_maxsize)
+                       delta_width_modifier -= pdwvw->bit_width ;
+               if (delta_width_modifier < -pdwvw->dwm_maxsize)
+                       delta_width_modifier += pdwvw->bit_width ;
+
+               /* Write delta_width_modifier zeros, followed by terminating '1'. */
+               dwvw_encode_store_bits (psf, pdwvw, 0, abs (delta_width_modifier)) ;
+               if (abs (delta_width_modifier) != pdwvw->dwm_maxsize)
+                       dwvw_encode_store_bits (psf, pdwvw, 1, 1) ;
+
+               /*  Write delta_width_modifier sign. */
+               if (delta_width_modifier < 0)
+                       dwvw_encode_store_bits (psf, pdwvw, 1, 1) ;
+               if (delta_width_modifier > 0)
+                       dwvw_encode_store_bits (psf, pdwvw, 0, 1) ;
+
+               /* Write delta and delta sign bit. */
+               if (delta_width)
+               {       dwvw_encode_store_bits (psf, pdwvw, delta, abs (delta_width) - 1) ;
+                       dwvw_encode_store_bits (psf, pdwvw, (delta_negative ? 1 : 0), 1) ;
+                       } ;
+
+               /* Write extra bit!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!! */
+               if (extra_bit >= 0)
+                       dwvw_encode_store_bits (psf, pdwvw, extra_bit, 1) ;
+
+               pdwvw->last_sample = ptr [count] >> (32 - pdwvw->bit_width) ;
+               pdwvw->last_delta_width = delta_width ;
+               } ;
+
+       pdwvw->samplecount += count ;
+
+       return count ;
+} /* dwvw_encode_data */
+
+static sf_count_t
+dwvw_write_s (SF_PRIVATE *psf, const short *ptr, sf_count_t len)
+{      DWVW_PRIVATE *pdwvw ;
+       int             *iptr ;
+       int             k, bufferlen, writecount = 0, count ;
+       sf_count_t      total = 0 ;
+
+       if (! psf->fdata)
+               return 0 ;
+       pdwvw = (DWVW_PRIVATE*) psf->fdata ;
+
+       iptr = psf->u.ibuf ;
+       bufferlen = ARRAY_LEN (psf->u.ibuf) ;
+       while (len > 0)
+       {       writecount = (len >= bufferlen) ? bufferlen : len ;
+               for (k = 0 ; k < writecount ; k++)
+                       iptr [k] = ptr [total + k] << 16 ;
+               count = dwvw_encode_data (psf, pdwvw, iptr, writecount) ;
+
+               total += count ;
+               len -= writecount ;
+               if (count != writecount)
+                       break ;
+               } ;
+
+       return total ;
+} /* dwvw_write_s */
+
+static sf_count_t
+dwvw_write_i (SF_PRIVATE *psf, const int *ptr, sf_count_t len)
+{      DWVW_PRIVATE *pdwvw ;
+       int                     writecount, count ;
+       sf_count_t      total = 0 ;
+
+       if (! psf->fdata)
+               return 0 ;
+       pdwvw = (DWVW_PRIVATE*) psf->fdata ;
+
+       while (len > 0)
+       {       writecount = (len > 0x10000000) ? 0x10000000 : (int) len ;
+
+               count = dwvw_encode_data (psf, pdwvw, ptr, writecount) ;
+
+               total += count ;
+               len -= count ;
+
+               if (count != writecount)
+                       break ;
+               } ;
+
+       return total ;
+} /* dwvw_write_i */
+
+static sf_count_t
+dwvw_write_f (SF_PRIVATE *psf, const float *ptr, sf_count_t len)
+{      DWVW_PRIVATE *pdwvw ;
+       int                     *iptr ;
+       int                     k, bufferlen, writecount = 0, count ;
+       sf_count_t      total = 0 ;
+       float           normfact ;
+
+       if (! psf->fdata)
+               return 0 ;
+       pdwvw = (DWVW_PRIVATE*) psf->fdata ;
+
+       normfact = (psf->norm_float == SF_TRUE) ? (1.0 * 0x7FFFFFFF) : 1.0 ;
+
+       iptr = psf->u.ibuf ;
+       bufferlen = ARRAY_LEN (psf->u.ibuf) ;
+       while (len > 0)
+       {       writecount = (len >= bufferlen) ? bufferlen : len ;
+               for (k = 0 ; k < writecount ; k++)
+                       iptr [k] = lrintf (normfact * ptr [total + k]) ;
+               count = dwvw_encode_data (psf, pdwvw, iptr, writecount) ;
+
+               total += count ;
+               len -= writecount ;
+               if (count != writecount)
+                       break ;
+               } ;
+
+       return total ;
+} /* dwvw_write_f */
+
+static sf_count_t
+dwvw_write_d (SF_PRIVATE *psf, const double *ptr, sf_count_t len)
+{      DWVW_PRIVATE *pdwvw ;
+       int                     *iptr ;
+       int                     k, bufferlen, writecount = 0, count ;
+       sf_count_t      total = 0 ;
+       double          normfact ;
+
+       if (! psf->fdata)
+               return 0 ;
+       pdwvw = (DWVW_PRIVATE*) psf->fdata ;
+
+       normfact = (psf->norm_double == SF_TRUE) ? (1.0 * 0x7FFFFFFF) : 1.0 ;
+
+       iptr = psf->u.ibuf ;
+       bufferlen = ARRAY_LEN (psf->u.ibuf) ;
+       while (len > 0)
+       {       writecount = (len >= bufferlen) ? bufferlen : len ;
+               for (k = 0 ; k < writecount ; k++)
+                       iptr [k] = lrint (normfact * ptr [total + k]) ;
+               count = dwvw_encode_data (psf, pdwvw, iptr, writecount) ;
+
+               total += count ;
+               len -= writecount ;
+               if (count != writecount)
+                       break ;
+               } ;
+
+       return total ;
+} /* dwvw_write_d */
+
+/*
+** Do not edit or modify anything in this comment block.
+** The arch-tag line is a file identity tag for the GNU Arch 
+** revision control system.
+**
+** arch-tag: 1ca09552-b01f-4d7f-9bcf-612f834fe41d
+*/
diff --git a/libs/libsndfile/src/file_io.c b/libs/libsndfile/src/file_io.c
new file mode 100644 (file)
index 0000000..d80e17d
--- /dev/null
@@ -0,0 +1,1537 @@
+/*
+** Copyright (C) 2002-2005 Erik de Castro Lopo <erikd@mega-nerd.com>
+** Copyright (C) 2003 Ross Bencina <rbencina@iprimus.com.au>
+**
+** This program is free software; you can redistribute it and/or modify
+** it under the terms of the GNU Lesser General Public License as published by
+** the Free Software Foundation; either version 2.1 of the License, or
+** (at your option) any later version.
+**
+** This program is distributed in the hope that it will be useful,
+** but WITHOUT ANY WARRANTY; without even the implied warranty of
+** MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+** GNU Lesser General Public License for more details.
+**
+** You should have received a copy of the GNU Lesser General Public License
+** along with this program; if not, write to the Free Software
+** Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA.
+*/
+
+/*
+**     The file is split into three sections as follows:
+**             - The top section (USE_WINDOWS_API == 0) for Linux, Unix and MacOSX
+**                     systems (including Cygwin).
+**             - The middle section (USE_WINDOWS_API == 1) for microsoft windows
+**                     (including MinGW) using the native windows API.
+**             - A legacy windows section which attempted to work around grevious
+**                     bugs in microsoft's POSIX implementation.
+*/
+
+/*
+**     The header file sfconfig.h MUST be included before the others to ensure
+**     that large file support is enabled correctly on Unix systems.
+*/
+
+#include "sfconfig.h"
+
+#include <stdio.h>
+#include <stdlib.h>
+
+#if HAVE_UNISTD_H
+#include <unistd.h>
+#endif
+
+#if (HAVE_DECL_S_IRGRP == 0)
+#include <sf_unistd.h>
+#endif
+
+#include <string.h>
+#include <fcntl.h>
+#include <errno.h>
+#include <sys/stat.h>
+
+#include "sndfile.h"
+#include "common.h"
+
+#define        SENSIBLE_SIZE   (0x40000000)
+
+static void psf_log_syserr (SF_PRIVATE *psf, int error) ;
+
+#if (USE_WINDOWS_API == 0)
+
+/*------------------------------------------------------------------------------
+** Win32 stuff at the bottom of the file. Unix and other sensible OSes here.
+*/
+
+static int psf_close_fd (int fd) ;
+static int psf_open_fd (const char * path, int mode) ;
+static sf_count_t psf_get_filelen_fd (int fd) ;
+
+int
+psf_fopen (SF_PRIVATE *psf, const char *pathname, int open_mode)
+{
+       psf->error = 0 ;
+       psf->filedes = psf_open_fd (pathname, open_mode) ;
+
+       if (psf->filedes == - SFE_BAD_OPEN_MODE)
+       {       psf->error = SFE_BAD_OPEN_MODE ;
+               psf->filedes = -1 ;
+               return psf->error ;
+               } ;
+
+       if (psf->filedes == -1)
+               psf_log_syserr (psf, errno) ;
+
+       psf->mode = open_mode ;
+
+       return psf->error ;
+} /* psf_fopen */
+
+int
+psf_fclose (SF_PRIVATE *psf)
+{      int retval ;
+
+       if (psf->virtual_io)
+               return 0 ;
+
+       if (psf->do_not_close_descriptor)
+       {       psf->filedes = -1 ;
+               return 0 ;
+               } ;
+
+       if ((retval = psf_close_fd (psf->filedes)) == -1)
+               psf_log_syserr (psf, errno) ;
+
+       psf->filedes = -1 ;
+
+       return retval ;
+} /* psf_fclose */
+
+int
+psf_open_rsrc (SF_PRIVATE *psf, int open_mode)
+{
+       if (psf->rsrcdes > 0)
+               return 0 ;
+
+       /* Test for MacOSX style resource fork on HPFS or HPFS+ filesystems. */
+       LSF_SNPRINTF (psf->rsrcpath, sizeof (psf->rsrcpath), "%s/rsrc", psf->filepath) ;
+       psf->error = SFE_NO_ERROR ;
+       if ((psf->rsrcdes = psf_open_fd (psf->rsrcpath, open_mode)) >= 0)
+       {       psf->rsrclength = psf_get_filelen_fd (psf->rsrcdes) ;
+               if (psf->rsrclength > 0 || (open_mode & SFM_WRITE))
+                       return SFE_NO_ERROR ;
+               psf_close_fd (psf->rsrcdes) ;
+               psf->rsrcdes = -1 ;
+               } ;
+
+       if (psf->rsrcdes == - SFE_BAD_OPEN_MODE)
+       {       psf->error = SFE_BAD_OPEN_MODE ;
+               return psf->error ;
+               } ;
+
+       /*
+       ** Now try for a resource fork stored as a separate file in the same
+       ** directory, but preceded with a dot underscore.
+       */
+       LSF_SNPRINTF (psf->rsrcpath, sizeof (psf->rsrcpath), "%s._%s", psf->directory, psf->filename) ;
+       psf->error = SFE_NO_ERROR ;
+       if ((psf->rsrcdes = psf_open_fd (psf->rsrcpath, open_mode)) >= 0)
+       {       psf->rsrclength = psf_get_filelen_fd (psf->rsrcdes) ;
+               return SFE_NO_ERROR ;
+               } ;
+
+       /*
+       ** Now try for a resource fork stored in a separate file in the
+       ** .AppleDouble/ directory.
+       */
+       LSF_SNPRINTF (psf->rsrcpath, sizeof (psf->rsrcpath), "%s.AppleDouble/%s", psf->directory, psf->filename) ;
+       psf->error = SFE_NO_ERROR ;
+       if ((psf->rsrcdes = psf_open_fd (psf->rsrcpath, open_mode)) >= 0)
+       {       psf->rsrclength = psf_get_filelen_fd (psf->rsrcdes) ;
+               return SFE_NO_ERROR ;
+               } ;
+
+       /* No resource file found. */
+       if (psf->rsrcdes == -1)
+               psf_log_syserr (psf, errno) ;
+
+       psf->rsrcdes = -1 ;
+
+       return psf->error ;
+} /* psf_open_rsrc */
+
+sf_count_t
+psf_get_filelen (SF_PRIVATE *psf)
+{      sf_count_t      filelen ;
+
+       if (psf->virtual_io)
+               return psf->vio.get_filelen (psf->vio_user_data) ;
+
+       filelen = psf_get_filelen_fd (psf->filedes) ;
+
+       if (filelen == -1)
+       {       psf_log_syserr (psf, errno) ;
+               return (sf_count_t) -1 ;
+               } ;
+
+       if (filelen == -SFE_BAD_STAT_SIZE)
+       {       psf->error = SFE_BAD_STAT_SIZE ;
+               return (sf_count_t) -1 ;
+               } ;
+
+       switch (psf->mode)
+       {       case SFM_WRITE :
+                       filelen = filelen - psf->fileoffset ;
+                       break ;
+
+               case SFM_READ :
+                       if (psf->fileoffset > 0 && psf->filelength > 0)
+                               filelen = psf->filelength ;
+                       break ;
+
+               case SFM_RDWR :
+                       /*
+                       ** Cannot open embedded files SFM_RDWR so we don't need to
+                       ** subtract psf->fileoffset. We already have the answer we
+                       ** need.
+                       */
+                       break ;
+
+               default :
+                       /* Shouldn't be here, so return error. */
+                       filelen = -1 ;
+               } ;
+
+       return filelen ;
+} /* psf_get_filelen */
+
+int
+psf_close_rsrc (SF_PRIVATE *psf)
+{
+       if (psf->rsrcdes >= 0)
+               psf_close_fd (psf->rsrcdes) ;
+       psf->rsrcdes = -1 ;
+       return 0 ;
+} /* psf_close_rsrc */
+
+int
+psf_set_stdio (SF_PRIVATE *psf, int mode)
+{      int     error = 0 ;
+
+       switch (mode)
+       {       case SFM_RDWR :
+                               error = SFE_OPEN_PIPE_RDWR ;
+                               break ;
+
+               case SFM_READ :
+                               psf->filedes = 0 ;
+                               break ;
+
+               case SFM_WRITE :
+                               psf->filedes = 1 ;
+                               break ;
+
+               default :
+                               error = SFE_BAD_OPEN_MODE ;
+                               break ;
+               } ;
+       psf->filelength = 0 ;
+
+       return error ;
+} /* psf_set_stdio */
+
+void
+psf_set_file (SF_PRIVATE *psf, int fd)
+{      psf->filedes = fd ;
+} /* psf_set_file */
+
+int
+psf_file_valid (SF_PRIVATE *psf)
+{      return (psf->filedes >= 0) ? SF_TRUE : SF_FALSE ;
+} /* psf_set_file */
+
+sf_count_t
+psf_fseek (SF_PRIVATE *psf, sf_count_t offset, int whence)
+{      sf_count_t      new_position ;
+
+       if (psf->virtual_io)
+               return psf->vio.seek (offset, whence, psf->vio_user_data) ;
+
+       switch (whence)
+       {       case SEEK_SET :
+                               offset += psf->fileoffset ;
+                               break ;
+
+               case SEEK_END :
+                               if (psf->mode == SFM_WRITE)
+                               {       new_position = lseek (psf->filedes, offset, whence) ;
+
+                                       if (new_position < 0)
+                                               psf_log_syserr (psf, errno) ;
+
+                                       return new_position - psf->fileoffset ;
+                                       } ;
+
+                               /* Transform SEEK_END into a SEEK_SET, ie find the file
+                               ** length add the requested offset (should be <= 0) to
+                               ** get the offset wrt the start of file.
+                               */
+                               whence = SEEK_SET ;
+                               offset = lseek (psf->filedes, 0, SEEK_END) + offset ;
+                               break ;
+
+               default :
+                               /* No need to do anything about SEEK_CUR. */
+                               break ;
+               } ;
+
+       new_position = lseek (psf->filedes, offset, whence) ;
+
+       if (new_position < 0)
+               psf_log_syserr (psf, errno) ;
+
+       new_position -= psf->fileoffset ;
+
+       return new_position ;
+} /* psf_fseek */
+
+sf_count_t
+psf_fread (void *ptr, sf_count_t bytes, sf_count_t items, SF_PRIVATE *psf)
+{      sf_count_t total = 0 ;
+       ssize_t count ;
+
+       if (psf->virtual_io)
+               return psf->vio.read (ptr, bytes*items, psf->vio_user_data) / bytes ;
+
+       items *= bytes ;
+
+       /* Do this check after the multiplication above. */
+       if (items <= 0)
+               return 0 ;
+
+       while (items > 0)
+       {       /* Break the read down to a sensible size. */
+               count = (items > SENSIBLE_SIZE) ? SENSIBLE_SIZE : (ssize_t) items ;
+
+               count = read (psf->filedes, ((char*) ptr) + total, (size_t) count) ;
+
+               if (count == -1)
+               {       if (errno == EINTR)
+                               continue ;
+
+                       psf_log_syserr (psf, errno) ;
+                       break ;
+                       } ;
+
+               if (count == 0)
+                       break ;
+
+               total += count ;
+               items -= count ;
+               } ;
+
+       if (psf->is_pipe)
+               psf->pipeoffset += total ;
+
+       return total / bytes ;
+} /* psf_fread */
+
+sf_count_t
+psf_fwrite (const void *ptr, sf_count_t bytes, sf_count_t items, SF_PRIVATE *psf)
+{      sf_count_t total = 0 ;
+       ssize_t count ;
+
+       if (psf->virtual_io)
+               return psf->vio.write (ptr, bytes*items, psf->vio_user_data) / bytes ;
+
+       items *= bytes ;
+
+       /* Do this check after the multiplication above. */
+       if (items <= 0)
+               return 0 ;
+
+       while (items > 0)
+       {       /* Break the writes down to a sensible size. */
+               count = (items > SENSIBLE_SIZE) ? SENSIBLE_SIZE : items ;
+
+               count = write (psf->filedes, ((const char*) ptr) + total, count) ;
+
+               if (count == -1)
+               {       if (errno == EINTR)
+                               continue ;
+
+                       psf_log_syserr (psf, errno) ;
+                       break ;
+                       } ;
+
+               if (count == 0)
+                       break ;
+
+               total += count ;
+               items -= count ;
+               } ;
+
+       if (psf->is_pipe)
+               psf->pipeoffset += total ;
+
+       return total / bytes ;
+} /* psf_fwrite */
+
+sf_count_t
+psf_ftell (SF_PRIVATE *psf)
+{      sf_count_t pos ;
+
+       if (psf->virtual_io)
+               return psf->vio.tell (psf->vio_user_data) ;
+
+       if (psf->is_pipe)
+               return psf->pipeoffset ;
+
+       pos = lseek (psf->filedes, 0, SEEK_CUR) ;
+
+       if (pos == ((sf_count_t) -1))
+       {       psf_log_syserr (psf, errno) ;
+               return -1 ;
+               } ;
+
+       return pos - psf->fileoffset ;
+} /* psf_ftell */
+
+static int
+psf_close_fd (int fd)
+{      int retval ;
+
+       while ((retval = close (fd)) == -1 && errno == EINTR)
+               /* Do nothing. */ ;
+
+       return retval ;
+} /* psf_close_fd */
+
+sf_count_t
+psf_fgets (char *buffer, sf_count_t bufsize, SF_PRIVATE *psf)
+{      sf_count_t      k = 0 ;
+       sf_count_t              count ;
+
+       while (k < bufsize - 1)
+       {       count = read (psf->filedes, &(buffer [k]), 1) ;
+
+               if (count == -1)
+               {       if (errno == EINTR)
+                               continue ;
+
+                       psf_log_syserr (psf, errno) ;
+                       break ;
+                       } ;
+
+               if (count == 0 || buffer [k++] == '\n')
+                       break ;
+               } ;
+
+       buffer [k] = 0 ;
+
+       return k ;
+} /* psf_fgets */
+
+int
+psf_is_pipe (SF_PRIVATE *psf)
+{      struct stat statbuf ;
+
+       if (psf->virtual_io)
+               return SF_FALSE ;
+
+       if (fstat (psf->filedes, &statbuf) == -1)
+       {       psf_log_syserr (psf, errno) ;
+               /* Default to maximum safety. */
+               return SF_TRUE ;
+               } ;
+
+       if (S_ISFIFO (statbuf.st_mode) || S_ISSOCK (statbuf.st_mode))
+               return SF_TRUE ;
+
+       return SF_FALSE ;
+} /* psf_is_pipe */
+
+static sf_count_t
+psf_get_filelen_fd (int fd)
+{      struct stat statbuf ;
+
+       /*
+       ** Sanity check.
+       ** If everything is OK, this will be optimised out.
+       */
+       if (sizeof (statbuf.st_size) == 4 && sizeof (sf_count_t) == 8)
+               return (sf_count_t) -SFE_BAD_STAT_SIZE ;
+
+       if (fstat (fd, &statbuf) == -1)
+               return (sf_count_t) -1 ;
+
+       return statbuf.st_size ;
+} /* psf_get_filelen_fd */
+
+int
+psf_ftruncate (SF_PRIVATE *psf, sf_count_t len)
+{      int retval ;
+
+       /* Returns 0 on success, non-zero on failure. */
+       if (len < 0)
+               return -1 ;
+
+       if ((sizeof (off_t) < sizeof (sf_count_t)) && len > 0x7FFFFFFF)
+               return -1 ;
+
+       retval = ftruncate (psf->filedes, len) ;
+
+       if (retval == -1)
+               psf_log_syserr (psf, errno) ;
+
+       return retval ;
+} /* psf_ftruncate */
+
+void
+psf_init_files (SF_PRIVATE *psf)
+{      psf->filedes = -1 ;
+       psf->rsrcdes = -1 ;
+       psf->savedes = -1 ;
+} /* psf_init_files */
+
+void
+psf_use_rsrc (SF_PRIVATE *psf, int on_off)
+{
+       if (on_off)
+       {       if (psf->filedes != psf->rsrcdes)
+               {       psf->savedes = psf->filedes ;
+                       psf->filedes = psf->rsrcdes ;
+                       } ;
+               }
+       else if (psf->filedes == psf->rsrcdes)
+               psf->filedes = psf->savedes ;
+
+       return ;
+} /* psf_use_rsrc */
+
+static int
+psf_open_fd (const char * pathname, int open_mode)
+{      int fd, oflag, mode ;
+
+       /*
+       ** Sanity check. If everything is OK, this test and the printfs will
+       ** be optimised out. This is meant to catch the problems caused by
+       ** "sfconfig.h" being included after <stdio.h>.
+       */
+       if (sizeof (off_t) != sizeof (sf_count_t))
+       {       puts ("\n\n*** Fatal error : sizeof (off_t) != sizeof (sf_count_t)") ;
+               puts ("*** This means that libsndfile was not configured correctly.\n") ;
+               exit (1) ;
+               } ;
+
+       switch (open_mode)
+       {       case SFM_READ :
+                               oflag = O_RDONLY ;
+                               mode = 0 ;
+                               break ;
+
+               case SFM_WRITE :
+                               oflag = O_WRONLY | O_CREAT | O_TRUNC ;
+                               mode = S_IRUSR | S_IWUSR | S_IRGRP | S_IROTH ;
+                               break ;
+
+               case SFM_RDWR :
+                               oflag = O_RDWR | O_CREAT ;
+                               mode = S_IRUSR | S_IWUSR | S_IRGRP | S_IROTH ;
+                               break ;
+
+               default :
+                               return - SFE_BAD_OPEN_MODE ;
+                               break ;
+               } ;
+
+#if OS_IS_WIN32
+       /* For Cygwin. */
+       oflag |= O_BINARY ;
+#endif
+
+       if (mode == 0)
+               fd = open (pathname, oflag) ;
+       else
+               fd = open (pathname, oflag, mode) ;
+
+       return fd ;
+} /* psf_open_fd */
+
+static void
+psf_log_syserr (SF_PRIVATE *psf, int error)
+{
+       /* Only log an error if no error has been set yet. */
+       if (psf->error == 0)
+       {       psf->error = SFE_SYSTEM ;
+               LSF_SNPRINTF (psf->syserr, sizeof (psf->syserr), "System error : %s.", strerror (error)) ;
+               } ;
+
+       return ;
+} /* psf_log_syserr */
+
+void
+psf_fsync (SF_PRIVATE *psf)
+{
+#if HAVE_FSYNC
+    if (psf->mode == SFM_WRITE || psf->mode == SFM_RDWR)
+        fsync (psf->filedes) ;
+#else
+    psf = NULL ;
+#endif
+} /* psf_fsync */
+
+#elif  USE_WINDOWS_API
+
+/* Win32 file i/o functions implemented using native Win32 API */
+
+#include <windows.h>
+#include <io.h>
+
+#ifndef HAVE_SSIZE_T
+typedef long ssize_t ;
+#endif
+
+static int psf_close_handle (HANDLE handle) ;
+static HANDLE psf_open_handle (const char * path, int mode) ;
+static sf_count_t psf_get_filelen_handle (HANDLE handle) ;
+
+/* USE_WINDOWS_API */ int
+psf_fopen (SF_PRIVATE *psf, const char *pathname, int open_mode)
+{
+       psf->error = 0 ;
+       psf->hfile = psf_open_handle (pathname, open_mode) ;
+
+       if (psf->hfile == NULL)
+               psf_log_syserr (psf, errno) ;
+
+       psf->mode = open_mode ;
+
+       return psf->error ;
+} /* psf_fopen */
+
+/* USE_WINDOWS_API */ int
+psf_fclose (SF_PRIVATE *psf)
+{      int retval ;
+
+       if (psf->virtual_io)
+               return 0 ;
+
+       if (psf->do_not_close_descriptor)
+       {       psf->hfile = NULL ;
+               return 0 ;
+               } ;
+
+       if ((retval = psf_close_handle (psf->hfile)) == -1)
+               psf_log_syserr (psf, errno) ;
+
+       psf->hfile = NULL ;
+
+       return retval ;
+} /* psf_fclose */
+
+/* USE_WINDOWS_API */ int
+psf_open_rsrc (SF_PRIVATE *psf, int open_mode)
+{
+       if (psf->hrsrc != NULL)
+               return 0 ;
+
+       /* Test for MacOSX style resource fork on HPFS or HPFS+ filesystems. */
+       LSF_SNPRINTF (psf->rsrcpath, sizeof (psf->rsrcpath), "%s/rsrc", psf->filepath) ;
+       psf->error = SFE_NO_ERROR ;
+       if ((psf->hrsrc = psf_open_handle (psf->rsrcpath, open_mode)) != NULL)
+       {       psf->rsrclength = psf_get_filelen_handle (psf->hrsrc) ;
+               return SFE_NO_ERROR ;
+               } ;
+
+       /*
+       ** Now try for a resource fork stored as a separate file in the same
+       ** directory, but preceded with a dot underscore.
+       */
+       LSF_SNPRINTF (psf->rsrcpath, sizeof (psf->rsrcpath), "%s._%s", psf->directory, psf->filename) ;
+       psf->error = SFE_NO_ERROR ;
+       if ((psf->hrsrc = psf_open_handle (psf->rsrcpath, open_mode)) != NULL)
+       {       psf->rsrclength = psf_get_filelen_handle (psf->hrsrc) ;
+               return SFE_NO_ERROR ;
+               } ;
+
+       /*
+       ** Now try for a resource fork stored in a separate file in the
+       ** .AppleDouble/ directory.
+       */
+       LSF_SNPRINTF (psf->rsrcpath, sizeof (psf->rsrcpath), "%s.AppleDouble/%s", psf->directory, psf->filename) ;
+       psf->error = SFE_NO_ERROR ;
+       if ((psf->hrsrc = psf_open_handle (psf->rsrcpath, open_mode)) != NULL)
+       {       psf->rsrclength = psf_get_filelen_handle (psf->hrsrc) ;
+               return SFE_NO_ERROR ;
+               } ;
+
+       /* No resource file found. */
+       if (psf->hrsrc == NULL)
+               psf_log_syserr (psf, errno) ;
+
+       psf->hrsrc = NULL ;
+
+       return psf->error ;
+} /* psf_open_rsrc */
+
+/* USE_WINDOWS_API */ sf_count_t
+psf_get_filelen (SF_PRIVATE *psf)
+{      sf_count_t      filelen ;
+
+       if (psf->virtual_io)
+               return psf->vio.get_filelen (psf->vio_user_data) ;
+
+       filelen = psf_get_filelen_handle (psf->hfile) ;
+
+       if (filelen == -1)
+       {       psf_log_syserr (psf, errno) ;
+               return (sf_count_t) -1 ;
+               } ;
+
+       if (filelen == -SFE_BAD_STAT_SIZE)
+       {       psf->error = SFE_BAD_STAT_SIZE ;
+               return (sf_count_t) -1 ;
+               } ;
+
+       switch (psf->mode)
+       {       case SFM_WRITE :
+                       filelen = filelen - psf->fileoffset ;
+                       break ;
+
+               case SFM_READ :
+                       if (psf->fileoffset > 0 && psf->filelength > 0)
+                               filelen = psf->filelength ;
+                       break ;
+
+               case SFM_RDWR :
+                       /*
+                       ** Cannot open embedded files SFM_RDWR so we don't need to
+                       ** subtract psf->fileoffset. We already have the answer we
+                       ** need.
+                       */
+                       break ;
+
+               default :
+                       /* Shouldn't be here, so return error. */
+                       filelen = -1 ;
+               } ;
+
+       return filelen ;
+} /* psf_get_filelen */
+
+/* USE_WINDOWS_API */ void
+psf_init_files (SF_PRIVATE *psf)
+{      psf->hfile = NULL ;
+       psf->hrsrc = NULL ;
+       psf->hsaved = NULL ;
+} /* psf_init_files */
+
+/* USE_WINDOWS_API */ void
+psf_use_rsrc (SF_PRIVATE *psf, int on_off)
+{
+       if (on_off)
+       {       if (psf->hfile != psf->hrsrc)
+               {       psf->hsaved = psf->hfile ;
+                       psf->hfile = psf->hrsrc ;
+                       } ;
+               }
+       else if (psf->hfile == psf->hrsrc)
+               psf->hfile = psf->hsaved ;
+
+       return ;
+} /* psf_use_rsrc */
+
+/* USE_WINDOWS_API */ static HANDLE
+psf_open_handle (const char * pathname, int open_mode)
+{      DWORD dwDesiredAccess ;
+       DWORD dwShareMode ;
+       DWORD dwCreationDistribution ;
+       HANDLE handle ;
+
+       switch (open_mode)
+       {       case SFM_READ :
+                               dwDesiredAccess = GENERIC_READ ;
+                               dwShareMode = FILE_SHARE_READ | FILE_SHARE_WRITE ;
+                               dwCreationDistribution = OPEN_EXISTING ;
+                               break ;
+
+               case SFM_WRITE :
+                               dwDesiredAccess = GENERIC_WRITE ;
+                               dwShareMode = FILE_SHARE_READ | FILE_SHARE_WRITE ;
+                               dwCreationDistribution = CREATE_ALWAYS ;
+                               break ;
+
+               case SFM_RDWR :
+                               dwDesiredAccess = GENERIC_READ | GENERIC_WRITE ;
+                               dwShareMode = FILE_SHARE_READ | FILE_SHARE_WRITE ;
+                               dwCreationDistribution = OPEN_ALWAYS ;
+                               break ;
+
+               default :
+                               return NULL ;
+               } ;
+
+       handle = CreateFile (
+                       pathname,                                       /* pointer to name of the file */
+                       dwDesiredAccess,                        /* access (read-write) mode */
+                       dwShareMode,                            /* share mode */
+                       0,                                                      /* pointer to security attributes */
+                       dwCreationDistribution,         /* how to create */
+                       FILE_ATTRIBUTE_NORMAL,          /* file attributes (could use FILE_FLAG_SEQUENTIAL_SCAN) */
+                       NULL                                            /* handle to file with attributes to copy */
+                       ) ;
+
+       if (handle == INVALID_HANDLE_VALUE)
+               return NULL ;
+
+       return handle ;
+} /* psf_open_handle */
+
+/* USE_WINDOWS_API */ static void
+psf_log_syserr (SF_PRIVATE *psf, int error)
+{      LPVOID lpMsgBuf ;
+
+       /* Only log an error if no error has been set yet. */
+       if (psf->error == 0)
+       {       psf->error = SFE_SYSTEM ;
+
+               FormatMessage (
+                       FORMAT_MESSAGE_ALLOCATE_BUFFER | FORMAT_MESSAGE_FROM_SYSTEM,
+                       NULL,
+                       error,
+                       MAKELANGID (LANG_NEUTRAL, SUBLANG_DEFAULT),
+                       (LPTSTR) &lpMsgBuf,
+                       0,
+                       NULL
+                       ) ;
+
+               LSF_SNPRINTF (psf->syserr, sizeof (psf->syserr), "System error : %s", lpMsgBuf) ;
+               LocalFree (lpMsgBuf) ;
+               } ;
+
+       return ;
+} /* psf_log_syserr */
+
+
+/* USE_WINDOWS_API */ int
+psf_close_rsrc (SF_PRIVATE *psf)
+{
+       if (psf->hrsrc != NULL)
+               psf_close_handle (psf->hrsrc) ;
+       psf->hrsrc = NULL ;
+       return 0 ;
+} /* psf_close_rsrc */
+
+
+/* USE_WINDOWS_API */ int
+psf_set_stdio (SF_PRIVATE *psf, int mode)
+{      HANDLE  handle = NULL ;
+       int     error = 0 ;
+
+       switch (mode)
+       {       case SFM_RDWR :
+                               error = SFE_OPEN_PIPE_RDWR ;
+                               break ;
+
+               case SFM_READ :
+                               handle = GetStdHandle (STD_INPUT_HANDLE) ;
+                               psf->do_not_close_descriptor = 1 ;
+                               break ;
+
+               case SFM_WRITE :
+                               handle = GetStdHandle (STD_OUTPUT_HANDLE) ;
+                               psf->do_not_close_descriptor = 1 ;
+                               break ;
+
+               default :
+                               error = SFE_BAD_OPEN_MODE ;
+                               break ;
+               } ;
+
+       psf->hfile = handle ;
+       psf->filelength = 0 ;
+
+       return error ;
+} /* psf_set_stdio */
+
+/* USE_WINDOWS_API */ void
+psf_set_file (SF_PRIVATE *psf, int fd)
+{      HANDLE handle ;
+       long osfhandle ;
+
+       osfhandle = _get_osfhandle (fd) ;
+       handle = (HANDLE) osfhandle ;
+
+       psf->hfile = handle ;
+} /* psf_set_file */
+
+/* USE_WINDOWS_API */ int
+psf_file_valid (SF_PRIVATE *psf)
+{      if (psf->hfile == NULL)
+               return SF_FALSE ;
+       if (psf->hfile == INVALID_HANDLE_VALUE)
+               return SF_FALSE ;
+       return SF_TRUE ;
+} /* psf_set_file */
+
+/* USE_WINDOWS_API */ sf_count_t
+psf_fseek (SF_PRIVATE *psf, sf_count_t offset, int whence)
+{      sf_count_t new_position ;
+       LONG lDistanceToMove, lDistanceToMoveHigh ;
+       DWORD dwMoveMethod ;
+       DWORD dwResult, dwError ;
+
+       if (psf->virtual_io)
+               return psf->vio.seek (offset, whence, psf->vio_user_data) ;
+
+       switch (whence)
+       {       case SEEK_SET :
+                               offset += psf->fileoffset ;
+                               dwMoveMethod = FILE_BEGIN ;
+                               break ;
+
+               case SEEK_END :
+                               dwMoveMethod = FILE_END ;
+                               break ;
+
+               default :
+                               dwMoveMethod = FILE_CURRENT ;
+                               break ;
+               } ;
+
+       lDistanceToMove = (DWORD) (offset & 0xFFFFFFFF) ;
+       lDistanceToMoveHigh = (DWORD) ((offset >> 32) & 0xFFFFFFFF) ;
+
+       dwResult = SetFilePointer (psf->hfile, lDistanceToMove, &lDistanceToMoveHigh, dwMoveMethod) ;
+
+       if (dwResult == 0xFFFFFFFF)
+               dwError = GetLastError () ;
+       else
+               dwError = NO_ERROR ;
+
+       if (dwError != NO_ERROR)
+       {       psf_log_syserr (psf, dwError) ;
+               return -1 ;
+               } ;
+
+       new_position = (dwResult + ((__int64) lDistanceToMoveHigh << 32)) - psf->fileoffset ;
+
+       return new_position ;
+} /* psf_fseek */
+
+/* USE_WINDOWS_API */ sf_count_t
+psf_fread (void *ptr, sf_count_t bytes, sf_count_t items, SF_PRIVATE *psf)
+{      sf_count_t total = 0 ;
+       ssize_t count ;
+       DWORD dwNumberOfBytesRead ;
+
+       if (psf->virtual_io)
+               return psf->vio.read (ptr, bytes*items, psf->vio_user_data) / bytes ;
+
+       items *= bytes ;
+
+       /* Do this check after the multiplication above. */
+       if (items <= 0)
+               return 0 ;
+
+       while (items > 0)
+       {       /* Break the writes down to a sensible size. */
+               count = (items > SENSIBLE_SIZE) ? SENSIBLE_SIZE : (ssize_t) items ;
+
+               if (ReadFile (psf->hfile, ((char*) ptr) + total, count, &dwNumberOfBytesRead, 0) == 0)
+               {       psf_log_syserr (psf, GetLastError ()) ;
+                       break ;
+                       }
+               else
+                       count = dwNumberOfBytesRead ;
+
+               if (count == 0)
+                       break ;
+
+               total += count ;
+               items -= count ;
+               } ;
+
+       if (psf->is_pipe)
+               psf->pipeoffset += total ;
+
+       return total / bytes ;
+} /* psf_fread */
+
+/* USE_WINDOWS_API */ sf_count_t
+psf_fwrite (const void *ptr, sf_count_t bytes, sf_count_t items, SF_PRIVATE *psf)
+{      sf_count_t total = 0 ;
+       ssize_t  count ;
+       DWORD dwNumberOfBytesWritten ;
+
+       if (psf->virtual_io)
+               return psf->vio.write (ptr, bytes * items, psf->vio_user_data) / bytes ;
+
+       items *= bytes ;
+
+       /* Do this check after the multiplication above. */
+       if (items <= 0)
+               return 0 ;
+
+       while (items > 0)
+       {       /* Break the writes down to a sensible size. */
+               count = (items > SENSIBLE_SIZE) ? SENSIBLE_SIZE : (ssize_t) items ;
+
+               if (WriteFile (psf->hfile, ((const char*) ptr) + total, count, &dwNumberOfBytesWritten, 0) == 0)
+               {       psf_log_syserr (psf, GetLastError ()) ;
+                       break ;
+                       }
+               else
+                       count = dwNumberOfBytesWritten ;
+
+               if (count == 0)
+                       break ;
+
+               total += count ;
+               items -= count ;
+               } ;
+
+       if (psf->is_pipe)
+               psf->pipeoffset += total ;
+
+       return total / bytes ;
+} /* psf_fwrite */
+
+/* USE_WINDOWS_API */ sf_count_t
+psf_ftell (SF_PRIVATE *psf)
+{      sf_count_t pos ;
+       LONG lDistanceToMoveLow, lDistanceToMoveHigh ;
+       DWORD dwResult, dwError ;
+
+       if (psf->virtual_io)
+               return psf->vio.tell (psf->vio_user_data) ;
+
+       if (psf->is_pipe)
+               return psf->pipeoffset ;
+
+       lDistanceToMoveLow = 0 ;
+       lDistanceToMoveHigh = 0 ;
+
+       dwResult = SetFilePointer (psf->hfile, lDistanceToMoveLow, &lDistanceToMoveHigh, FILE_CURRENT) ;
+
+       if (dwResult == 0xFFFFFFFF)
+               dwError = GetLastError () ;
+       else
+               dwError = NO_ERROR ;
+
+       if (dwError != NO_ERROR)
+       {       psf_log_syserr (psf, dwError) ;
+               return -1 ;
+               } ;
+
+       pos = (dwResult + ((__int64) lDistanceToMoveHigh << 32)) ;
+
+       return pos - psf->fileoffset ;
+} /* psf_ftell */
+
+/* USE_WINDOWS_API */ static int
+psf_close_handle (HANDLE handle)
+{      if (CloseHandle (handle) == 0)
+               return -1 ;
+
+       return 0 ;
+} /* psf_close_handle */
+
+/* USE_WINDOWS_API */ sf_count_t
+psf_fgets (char *buffer, sf_count_t bufsize, SF_PRIVATE *psf)
+{      sf_count_t k = 0 ;
+       sf_count_t count ;
+       DWORD dwNumberOfBytesRead ;
+
+       while (k < bufsize - 1)
+       {       if (ReadFile (psf->hfile, &(buffer [k]), 1, &dwNumberOfBytesRead, 0) == 0)
+               {       psf_log_syserr (psf, GetLastError ()) ;
+                       break ;
+                       }
+               else
+               {       count = dwNumberOfBytesRead ;
+                       /* note that we only check for '\n' not other line endings such as CRLF */
+                       if (count == 0 || buffer [k++] == '\n')
+                               break ;
+                       } ;
+               } ;
+
+       buffer [k] = 0 ;
+
+       return k ;
+} /* psf_fgets */
+
+/* USE_WINDOWS_API */ int
+psf_is_pipe (SF_PRIVATE *psf)
+{
+       if (psf->virtual_io)
+               return SF_FALSE ;
+
+       if (GetFileType (psf->hfile) == FILE_TYPE_DISK)
+               return SF_FALSE ;
+
+       /* Default to maximum safety. */
+       return SF_TRUE ;
+} /* psf_is_pipe */
+
+/* USE_WINDOWS_API */ sf_count_t
+psf_get_filelen_handle (HANDLE handle)
+{      sf_count_t filelen ;
+       DWORD dwFileSizeLow, dwFileSizeHigh, dwError = NO_ERROR ;
+
+       dwFileSizeLow = GetFileSize (handle, &dwFileSizeHigh) ;
+
+       if (dwFileSizeLow == 0xFFFFFFFF)
+               dwError = GetLastError () ;
+
+       if (dwError != NO_ERROR)
+               return (sf_count_t) -1 ;
+
+       filelen = dwFileSizeLow + ((__int64) dwFileSizeHigh << 32) ;
+
+       return filelen ;
+} /* psf_get_filelen_handle */
+
+/* USE_WINDOWS_API */ void
+psf_fsync (SF_PRIVATE *psf)
+{      FlushFileBuffers (psf->hfile) ;
+} /* psf_fsync */
+
+
+/* USE_WINDOWS_API */ int
+psf_ftruncate (SF_PRIVATE *psf, sf_count_t len)
+{      int retval = 0 ;
+       LONG lDistanceToMoveLow, lDistanceToMoveHigh ;
+       DWORD dwResult, dwError = NO_ERROR ;
+
+       /* This implementation trashes the current file position.
+       ** should it save and restore it? what if the current position is past
+       ** the new end of file?
+       */
+
+       /* Returns 0 on success, non-zero on failure. */
+       if (len < 0)
+               return 1 ;
+
+       lDistanceToMoveLow = (DWORD) (len & 0xFFFFFFFF) ;
+       lDistanceToMoveHigh = (DWORD) ((len >> 32) & 0xFFFFFFFF) ;
+
+       dwResult = SetFilePointer (psf->hfile, lDistanceToMoveLow, &lDistanceToMoveHigh, FILE_BEGIN) ;
+
+       if (dwResult == 0xFFFFFFFF)
+               dwError = GetLastError () ;
+
+       if (dwError != NO_ERROR)
+       {       retval = -1 ;
+               psf_log_syserr (psf, dwError) ;
+               }
+       else
+       {       /* Note: when SetEndOfFile is used to extend a file, the contents of the
+               ** new portion of the file is undefined. This is unlike chsize(),
+               ** which guarantees that the new portion of the file will be zeroed.
+               ** Not sure if this is important or not.
+               */
+               if (SetEndOfFile (psf->hfile) == 0)
+               {       retval = -1 ;
+                       psf_log_syserr (psf, GetLastError ()) ;
+                       } ;
+               } ;
+
+       return retval ;
+} /* psf_ftruncate */
+
+
+#else
+/* Win32 file i/o functions implemented using Unix-style file i/o API */
+
+/* Win32 has a 64 file offset seek function:
+**
+**             __int64 _lseeki64 (int handle, __int64 offset, int origin) ;
+**
+** It also has a 64 bit fstat function:
+**
+**             int fstati64 (int, struct _stati64) ;
+**
+** but the fscking thing doesn't work!!!!! The file size parameter returned
+** by this function is only valid up until more data is written at the end of
+** the file. That makes this function completely 100% useless.
+*/
+
+#include <io.h>
+#include <direct.h>
+
+#ifndef HAVE_SSIZE_T
+typedef long ssize_t ;
+#endif
+
+/* Win32 */ int
+psf_fopen (SF_PRIVATE *psf, const char *pathname, int open_mode)
+{      int oflag, mode ;
+
+       switch (open_mode)
+       {       case SFM_READ :
+                               oflag = O_RDONLY | O_BINARY ;
+                               mode = 0 ;
+                               break ;
+
+               case SFM_WRITE :
+                               oflag = O_WRONLY | O_CREAT | O_TRUNC | O_BINARY ;
+                               mode = S_IRUSR | S_IWUSR | S_IRGRP ;
+                               break ;
+
+               case SFM_RDWR :
+                               oflag = O_RDWR | O_CREAT | O_BINARY ;
+                               mode = S_IRUSR | S_IWUSR | S_IRGRP ;
+                               break ;
+
+               default :
+                               psf->error = SFE_BAD_OPEN_MODE ;
+                               return -1 ;
+                               break ;
+               } ;
+
+       if (mode == 0)
+               psf->filedes = open (pathname, oflag) ;
+       else
+               psf->filedes = open (pathname, oflag, mode) ;
+
+       if (psf->filedes == -1)
+               psf_log_syserr (psf, errno) ;
+
+       return psf->filedes ;
+} /* psf_fopen */
+
+/* Win32 */ sf_count_t
+psf_fseek (SF_PRIVATE *psf, sf_count_t offset, int whence)
+{      sf_count_t      new_position ;
+
+       if (psf->virtual_io)
+               return psf->vio.seek (offset, whence, psf->vio_user_data) ;
+
+       switch (whence)
+       {       case SEEK_SET :
+                               offset += psf->fileoffset ;
+                               break ;
+
+               case SEEK_END :
+                               if (psf->mode == SFM_WRITE)
+                               {       new_position = _lseeki64 (psf->filedes, offset, whence) ;
+
+                                       if (new_position < 0)
+                                               psf_log_syserr (psf, errno) ;
+
+                                       return new_position - psf->fileoffset ;
+                                       } ;
+
+                               /* Transform SEEK_END into a SEEK_SET, ie find the file
+                               ** length add the requested offset (should be <= 0) to
+                               ** get the offset wrt the start of file.
+                               */
+                               whence = SEEK_SET ;
+                               offset = _lseeki64 (psf->filedes, 0, SEEK_END) + offset ;
+                               break ;
+
+               default :
+                               /* No need to do anything about SEEK_CUR. */
+                               break ;
+               } ;
+
+       /*
+       ** Bypass weird Win32-ism if necessary.
+       ** _lseeki64() returns an "invalid parameter" error if called with the
+       ** offset == 0 and whence == SEEK_CUR.
+       *** Use the _telli64() function instead.
+       */
+       if (offset == 0 && whence == SEEK_CUR)
+               new_position = _telli64 (psf->filedes) ;
+       else
+               new_position = _lseeki64 (psf->filedes, offset, whence) ;
+
+       if (new_position < 0)
+               psf_log_syserr (psf, errno) ;
+
+       new_position -= psf->fileoffset ;
+
+       return new_position ;
+} /* psf_fseek */
+
+/* Win32 */ sf_count_t
+psf_fread (void *ptr, sf_count_t bytes, sf_count_t items, SF_PRIVATE *psf)
+{      sf_count_t total = 0 ;
+       ssize_t  count ;
+
+       if (psf->virtual_io)
+               return psf->vio.read (ptr, bytes*items, psf->vio_user_data) / bytes ;
+
+       items *= bytes ;
+
+       /* Do this check after the multiplication above. */
+       if (items <= 0)
+               return 0 ;
+
+       while (items > 0)
+       {       /* Break the writes down to a sensible size. */
+               count = (items > SENSIBLE_SIZE) ? SENSIBLE_SIZE : (ssize_t) items ;
+
+               count = read (psf->filedes, ((char*) ptr) + total, (size_t) count) ;
+
+               if (count == -1)
+               {       if (errno == EINTR)
+                               continue ;
+
+                       psf_log_syserr (psf, errno) ;
+                       break ;
+                       } ;
+
+               if (count == 0)
+                       break ;
+
+               total += count ;
+               items -= count ;
+               } ;
+
+       return total / bytes ;
+} /* psf_fread */
+
+/* Win32 */ sf_count_t
+psf_fwrite (const void *ptr, sf_count_t bytes, sf_count_t items, SF_PRIVATE *psf)
+{      sf_count_t total = 0 ;
+       ssize_t  count ;
+
+       if (psf->virtual_io)
+               return psf->vio.write (ptr, bytes*items, psf->vio_user_data) / bytes ;
+
+       items *= bytes ;
+
+       /* Do this check after the multiplication above. */
+       if (items <= 0)
+               return 0 ;
+
+       while (items > 0)
+       {       /* Break the writes down to a sensible size. */
+               count = (items > SENSIBLE_SIZE) ? SENSIBLE_SIZE : items ;
+
+               count = write (psf->filedes, ((const char*) ptr) + total, count) ;
+
+               if (count == -1)
+               {       if (errno == EINTR)
+                               continue ;
+
+                       psf_log_syserr (psf, errno) ;
+                       break ;
+                       } ;
+
+               if (count == 0)
+                       break ;
+
+               total += count ;
+               items -= count ;
+               } ;
+
+       return total / bytes ;
+} /* psf_fwrite */
+
+/* Win32 */ sf_count_t
+psf_ftell (SF_PRIVATE *psf)
+{      sf_count_t pos ;
+
+       if (psf->virtual_io)
+               return psf->vio.tell (psf->vio_user_data) ;
+
+       pos = _telli64 (psf->filedes) ;
+
+       if (pos == ((sf_count_t) -1))
+       {       psf_log_syserr (psf, errno) ;
+               return -1 ;
+               } ;
+
+       return pos - psf->fileoffset ;
+} /* psf_ftell */
+
+/* Win32 */ int
+psf_fclose (SF_PRIVATE *psf)
+{      int retval ;
+
+       while ((retval = close (psf->filedes)) == -1 && errno == EINTR)
+               /* Do nothing. */ ;
+
+       if (retval == -1)
+               psf_log_syserr (psf, errno) ;
+
+       psf->filedes = -1 ;
+
+       return retval ;
+} /* psf_fclose */
+
+/* Win32 */ sf_count_t
+psf_fgets (char *buffer, sf_count_t bufsize, SF_PRIVATE *psf)
+{      sf_count_t      k = 0 ;
+       sf_count_t      count ;
+
+       while (k < bufsize - 1)
+       {       count = read (psf->filedes, &(buffer [k]), 1) ;
+
+               if (count == -1)
+               {       if (errno == EINTR)
+                               continue ;
+
+                       psf_log_syserr (psf, errno) ;
+                       break ;
+                       } ;
+
+               if (count == 0 || buffer [k++] == '\n')
+                       break ;
+               } ;
+
+       buffer [k] = 0 ;
+
+       return k ;
+} /* psf_fgets */
+
+/* Win32 */ int
+psf_is_pipe (SF_PRIVATE *psf)
+{      struct stat statbuf ;
+
+       if (psf->virtual_io)
+               return SF_FALSE ;
+
+       /* Not sure if this works. */
+       if (fstat (psf->filedes, &statbuf) == -1)
+       {       psf_log_syserr (psf, errno) ;
+               /* Default to maximum safety. */
+               return SF_TRUE ;
+               } ;
+
+       /* These macros are defined in Win32/unistd.h. */
+       if (S_ISFIFO (statbuf.st_mode) || S_ISSOCK (statbuf.st_mode))
+               return SF_TRUE ;
+
+       return SF_FALSE ;
+} /* psf_checkpipe */
+
+/* Win32 */ sf_count_t
+psf_get_filelen (SF_PRIVATE *psf)
+{
+#if 0
+       /*
+       ** Windoze is SOOOOO FUCKED!!!!!!!
+       ** This code should work but doesn't. Why?
+       ** Code below does work.
+       */
+       struct _stati64 statbuf ;
+
+       if (_fstati64 (psf->filedes, &statbuf))
+       {       psf_log_syserr (psf, errno) ;
+               return (sf_count_t) -1 ;
+               } ;
+
+       return statbuf.st_size ;
+#else
+       sf_count_t current, filelen ;
+
+       if (psf->virtual_io)
+               return psf->vio.get_filelen (psf->vio_user_data) ;
+
+       if ((current = _telli64 (psf->filedes)) < 0)
+       {       psf_log_syserr (psf, errno) ;
+               return (sf_count_t) -1 ;
+               } ;
+
+       /*
+       ** Lets face it, windoze if FUBAR!!!
+       **
+       ** For some reason, I have to call _lseeki64() TWICE to get to the
+       ** end of the file.
+       **
+       ** This might have been avoided if windows had implemented the POSIX
+       ** standard function fsync() but NO, that would have been too easy.
+       **
+       ** I am VERY close to saying that windoze will no longer be supported
+       ** by libsndfile and changing the license to GPL at the same time.
+       */
+
+       _lseeki64 (psf->filedes, 0, SEEK_END) ;
+
+       if ((filelen = _lseeki64 (psf->filedes, 0, SEEK_END)) < 0)
+       {       psf_log_syserr (psf, errno) ;
+               return (sf_count_t) -1 ;
+               } ;
+
+       if (filelen > current)
+               _lseeki64 (psf->filedes, current, SEEK_SET) ;
+
+       switch (psf->mode)
+       {       case SFM_WRITE :
+                       filelen = filelen - psf->fileoffset ;
+                       break ;
+
+               case SFM_READ :
+                       if (psf->fileoffset > 0 && psf->filelength > 0)
+                               filelen = psf->filelength ;
+                       break ;
+
+               case SFM_RDWR :
+                       /*
+                       ** Cannot open embedded files SFM_RDWR so we don't need to
+                       ** subtract psf->fileoffset. We already have the answer we
+                       ** need.
+                       */
+                       break ;
+
+               default :
+                       filelen = 0 ;
+               } ;
+
+       return filelen ;
+#endif
+} /* psf_get_filelen */
+
+/* Win32 */ int
+psf_ftruncate (SF_PRIVATE *psf, sf_count_t len)
+{      int retval ;
+
+       /* Returns 0 on success, non-zero on failure. */
+       if (len < 0)
+               return 1 ;
+
+       /* The global village idiots at micorsoft decided to implement
+       ** nearly all the required 64 bit file offset functions except
+       ** for one, truncate. The fscking morons!
+       **
+       ** This is not 64 bit file offset clean. Somone needs to clean
+       ** this up.
+       */
+       if (len > 0x7FFFFFFF)
+               return -1 ;
+
+       retval = chsize (psf->filedes, len) ;
+
+       if (retval == -1)
+               psf_log_syserr (psf, errno) ;
+
+       return retval ;
+} /* psf_ftruncate */
+
+
+static void
+psf_log_syserr (SF_PRIVATE *psf, int error)
+{
+       /* Only log an error if no error has been set yet. */
+       if (psf->error == 0)
+       {       psf->error = SFE_SYSTEM ;
+               LSF_SNPRINTF (psf->syserr, sizeof (psf->syserr), "System error : %s", strerror (error)) ;
+               } ;
+
+       return ;
+} /* psf_log_syserr */
+
+#endif
+
+/*
+** Do not edit or modify anything in this comment block.
+** The arch-tag line is a file identity tag for the GNU Arch
+** revision control system.
+**
+** arch-tag: 749740d7-ecc7-47bd-8cf7-600f31d32e6d
+*/
diff --git a/libs/libsndfile/src/flac.c b/libs/libsndfile/src/flac.c
new file mode 100644 (file)
index 0000000..1f0872f
--- /dev/null
@@ -0,0 +1,1156 @@
+/*
+** Copyright (C) 2004, 2005 Erik de Castro Lopo <erikd@mega-nerd.com>
+** Copyright (C) 2004 Tobias Gehrig <tgehrig@ira.uka.de>
+**
+** This program is free software ; you can redistribute it and/or modify
+** it under the terms of the GNU Lesser General Public License as published by
+** the Free Software Foundation ; either version 2.1 of the License, or
+** (at your option) any later version.
+**
+** This program is distributed in the hope that it will be useful,
+** but WITHOUT ANY WARRANTY ; without even the implied warranty of
+** MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+** GNU Lesser General Public License for more details.
+**
+** You should have received a copy of the GNU Lesser General Public License
+** along with this program ; if not, write to the Free Software
+** Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA.
+*/
+
+#include       "sfconfig.h"
+
+#include       <stdio.h>
+#include       <stdlib.h>
+#include       <fcntl.h>
+#include       <string.h>
+#include       <ctype.h>
+
+#include       "sndfile.h"
+#include       "common.h"
+
+
+#ifndef HAVE_FLAC_ALL_H
+
+int
+flac_open (SF_PRIVATE *psf)
+{      if (psf)
+               return SFE_UNIMPLEMENTED ;
+       return (psf && 0) ;
+} /* flac_open */
+
+
+#else
+
+#include       <FLAC/all.h>
+
+#include       "sfendian.h"
+#include       "float_cast.h"
+
+/*------------------------------------------------------------------------------
+** Private static functions.
+*/
+
+#define ENC_BUFFER_SIZE 4096
+
+typedef enum
+{      PFLAC_PCM_SHORT = 0,
+       PFLAC_PCM_INT = 1,
+       PFLAC_PCM_FLOAT = 2,
+       PFLAC_PCM_DOUBLE = 3
+} PFLAC_PCM ;
+
+typedef struct
+{      FLAC__SeekableStreamDecoder *fsd ;
+       FLAC__SeekableStreamEncoder *fse ;
+       PFLAC_PCM pcmtype ;
+       void* ptr ;
+       unsigned pos, len, remain ;
+
+       const FLAC__int32 * const * wbuffer ;
+       FLAC__int32 * rbuffer [FLAC__MAX_CHANNELS] ;
+
+       FLAC__int32* encbuffer ;
+       unsigned bufferpos ;
+
+       const FLAC__Frame *frame ;
+       FLAC__bool bufferbackup ;
+} FLAC_PRIVATE ;
+
+static sf_count_t      flac_seek (SF_PRIVATE *psf, int mode, sf_count_t offset) ;
+static int                     flac_close (SF_PRIVATE *psf) ;
+
+static int                     flac_enc_init (SF_PRIVATE *psf) ;
+static int                     flac_read_header (SF_PRIVATE *psf) ;
+
+static sf_count_t      flac_read_flac2s (SF_PRIVATE *psf, short *ptr, sf_count_t len) ;
+static sf_count_t      flac_read_flac2i (SF_PRIVATE *psf, int *ptr, sf_count_t len) ;
+static sf_count_t      flac_read_flac2f (SF_PRIVATE *psf, float *ptr, sf_count_t len) ;
+static sf_count_t      flac_read_flac2d (SF_PRIVATE *psf, double *ptr, sf_count_t len) ;
+
+static sf_count_t      flac_write_s2flac (SF_PRIVATE *psf, const short *ptr, sf_count_t len) ;
+static sf_count_t      flac_write_i2flac (SF_PRIVATE *psf, const int *ptr, sf_count_t len) ;
+static sf_count_t      flac_write_f2flac (SF_PRIVATE *psf, const float *ptr, sf_count_t len) ;
+static sf_count_t      flac_write_d2flac (SF_PRIVATE *psf, const double *ptr, sf_count_t len) ;
+
+static void            f2flac8_array (const float *src, FLAC__int32 *dest, int count, int normalize) ;
+static void            f2flac16_array (const float *src, FLAC__int32 *dest, int count, int normalize) ;
+static void            f2flac24_array (const float *src, FLAC__int32 *dest, int count, int normalize) ;
+static void            f2flac8_clip_array (const float *src, FLAC__int32 *dest, int count, int normalize) ;
+static void            f2flac16_clip_array (const float *src, FLAC__int32 *dest, int count, int normalize) ;
+static void            f2flac24_clip_array (const float *src, FLAC__int32 *dest, int count, int normalize) ;
+static void            d2flac8_array (const double *src, FLAC__int32 *dest, int count, int normalize) ;
+static void            d2flac16_array (const double *src, FLAC__int32 *dest, int count, int normalize) ;
+static void            d2flac24_array (const double *src, FLAC__int32 *dest, int count, int normalize) ;
+static void            d2flac8_clip_array (const double *src, FLAC__int32 *dest, int count, int normalize) ;
+static void            d2flac16_clip_array (const double *src, FLAC__int32 *dest, int count, int normalize) ;
+static void            d2flac24_clip_array (const double *src, FLAC__int32 *dest, int count, int normalize) ;
+
+static int flac_command (SF_PRIVATE *psf, int command, void *data, int datasize) ;
+
+/* Decoder Callbacks */
+static FLAC__SeekableStreamDecoderReadStatus sf_flac_read_callback (const FLAC__SeekableStreamDecoder *decoder, FLAC__byte buffer [], unsigned *bytes, void *client_data) ;
+static FLAC__SeekableStreamDecoderSeekStatus sf_flac_seek_callback (const FLAC__SeekableStreamDecoder *decoder, FLAC__uint64 absolute_byte_offset, void *client_data) ;
+static FLAC__SeekableStreamDecoderTellStatus sf_flac_tell_callback (const FLAC__SeekableStreamDecoder *decoder, FLAC__uint64 *absolute_byte_offset, void *client_data) ;
+static FLAC__SeekableStreamDecoderLengthStatus sf_flac_length_callback (const FLAC__SeekableStreamDecoder *decoder, FLAC__uint64 *stream_length, void *client_data) ;
+static FLAC__bool sf_flac_eof_callback (const FLAC__SeekableStreamDecoder *decoder, void *client_data) ;
+static FLAC__StreamDecoderWriteStatus sf_flac_write_callback (const FLAC__SeekableStreamDecoder *decoder, const FLAC__Frame *frame, const FLAC__int32 * const buffer [], void *client_data) ;
+static void sf_flac_meta_callback (const FLAC__SeekableStreamDecoder *decoder, const FLAC__StreamMetadata *metadata, void *client_data) ;
+static void sf_flac_error_callback (const FLAC__SeekableStreamDecoder *decoder, FLAC__StreamDecoderErrorStatus status, void *client_data) ;
+
+/* Encoder Callbacks */
+static FLAC__SeekableStreamEncoderSeekStatus sf_flac_enc_seek_callback (const FLAC__SeekableStreamEncoder *encoder, FLAC__uint64 absolute_byte_offset, void *client_data) ;
+#ifdef HAVE_FLAC_1_1_1
+static FLAC__SeekableStreamEncoderTellStatus sf_flac_enc_tell_callback (const FLAC__SeekableStreamEncoder *encoder, FLAC__uint64 *absolute_byte_offset, void *client_data) ;
+#endif
+static FLAC__StreamEncoderWriteStatus sf_flac_enc_write_callback (const FLAC__SeekableStreamEncoder *encoder, const FLAC__byte buffer [], unsigned bytes, unsigned samples, unsigned current_frame, void *client_data) ;
+
+static const int legal_sample_rates [] =
+{      8000, 16000, 22050, 24000, 32000, 44100, 48000, 96000
+} ;
+
+static inline void
+s2flac8_array (const short *src, FLAC__int32 *dest, int count)
+{      while (--count >= 0)
+               dest [count] = src [count] >> 8 ;
+} /* s2flac8_array */
+
+static inline void
+s2flac16_array (const short *src, FLAC__int32 *dest, int count)
+{      while (--count >= 0)
+               dest [count] = src [count] ;
+} /* s2flac16_array */
+
+static inline void
+s2flac24_array (const short *src, FLAC__int32 *dest, int count)
+{      while (--count >= 0)
+               dest [count] = src [count] << 8 ;
+} /* s2flac24_array */
+
+static inline void
+i2flac8_array (const int *src, FLAC__int32 *dest, int count)
+{      while (--count >= 0)
+               dest [count] = src [count] >> 24 ;
+} /* i2flac8_array */
+
+static inline void
+i2flac16_array (const int *src, FLAC__int32 *dest, int count)
+{
+  while (--count >= 0)
+    dest [count] = src [count] >> 16 ;
+} /* i2flac16_array */
+
+static inline void
+i2flac24_array (const int *src, FLAC__int32 *dest, int count)
+{      while (--count >= 0)
+               dest [count] = src [count] >> 8 ;
+} /* i2flac24_array */
+
+static sf_count_t
+flac_buffer_copy (SF_PRIVATE *psf)
+{      FLAC_PRIVATE* pflac = (FLAC_PRIVATE*) psf->fdata ;
+       const FLAC__Frame *frame = pflac->frame ;
+       const FLAC__int32* const *buffer = pflac->wbuffer ;
+       unsigned i = 0, j, offset ;
+
+       if (pflac->ptr == NULL)
+       {       /*
+               **      Not sure why this code is here and not elsewhere.
+               **      Removing it causes valgrind errors.
+               */
+               pflac->bufferbackup = SF_TRUE ;
+               for (i = 0 ; i < frame->header.channels ; i++)
+               {       if (pflac->rbuffer [i] == NULL)
+                               pflac->rbuffer [i] = calloc (frame->header.blocksize, sizeof (FLAC__int32)) ;
+                       memcpy (pflac->rbuffer [i], buffer [i], frame->header.blocksize * sizeof (FLAC__int32)) ;
+                       } ;
+               pflac->wbuffer = (const FLAC__int32* const*) pflac->rbuffer ;
+
+               return 0 ;
+               } ;
+
+       switch (pflac->pcmtype)
+       {       case PFLAC_PCM_SHORT :
+                       {       short *retpcm = ((short*) pflac->ptr) ;
+                               int shift = 16 - frame->header.bits_per_sample ;
+                               if (shift < 0)
+                               {       shift = abs (shift) ;
+                                       for (i = 0 ; i < frame->header.blocksize && pflac->remain > 0 ; i++)
+                                       {       offset = pflac->pos + i * frame->header.channels ;
+                                               for (j = 0 ; j < frame->header.channels ; j++)
+                                                       retpcm [offset + j] = buffer [j][pflac->bufferpos] >> shift ;
+                                               pflac->remain -= frame->header.channels ;
+                                               pflac->bufferpos++ ;
+                                               }
+                                       }
+                               else
+                               {       for (i = 0 ; i < frame->header.blocksize && pflac->remain > 0 ; i++)
+                                       {       offset = pflac->pos + i * frame->header.channels ;
+
+                                               if (pflac->bufferpos >= frame->header.blocksize)
+                                                       break ;
+
+                                               for (j = 0 ; j < frame->header.channels ; j++)
+                                                       retpcm [offset + j] = (buffer [j][pflac->bufferpos]) << shift ;
+
+                                               pflac->remain -= frame->header.channels ;
+                                               pflac->bufferpos++ ;
+                                               } ;
+                                       } ;
+                               } ;
+                       break ;
+
+               case PFLAC_PCM_INT :
+                       {       int *retpcm = ((int*) pflac->ptr) ;
+                               int shift = 32 - frame->header.bits_per_sample ;
+                               for (i = 0 ; i < frame->header.blocksize && pflac->remain > 0 ; i++)
+                               {       offset = pflac->pos + i * frame->header.channels ;
+
+                                       if (pflac->bufferpos >= frame->header.blocksize)
+                                               break ;
+
+                                       for (j = 0 ; j < frame->header.channels ; j++)
+                                               retpcm [offset + j] = buffer [j][pflac->bufferpos] << shift ;
+                                       pflac->remain -= frame->header.channels ;
+                                       pflac->bufferpos++ ;
+                                       } ;
+                               } ;
+                       break ;
+
+               case PFLAC_PCM_FLOAT :
+                       {       float *retpcm = ((float*) pflac->ptr) ;
+                               float norm = (psf->norm_float == SF_TRUE) ? 1.0 / (1 << (frame->header.bits_per_sample - 1)) : 1.0 ;
+
+                               for (i = 0 ; i < frame->header.blocksize && pflac->remain > 0 ; i++)
+                               {       offset = pflac->pos + i * frame->header.channels ;
+
+                                       if (pflac->bufferpos >= frame->header.blocksize)
+                                               break ;
+
+                                       for (j = 0 ; j < frame->header.channels ; j++)
+                                               retpcm [offset + j] = buffer [j][pflac->bufferpos] * norm ;
+                                       pflac->remain -= frame->header.channels ;
+                                       pflac->bufferpos++ ;
+                                       } ;
+                               } ;
+                       break ;
+
+               case PFLAC_PCM_DOUBLE :
+                       {       double *retpcm = ((double*) pflac->ptr) ;
+                               double norm = (psf->norm_double == SF_TRUE) ? 1.0 / (1 << (frame->header.bits_per_sample - 1)) : 1.0 ;
+
+                               for (i = 0 ; i < frame->header.blocksize && pflac->remain > 0 ; i++)
+                               {       offset = pflac->pos + i * frame->header.channels ;
+
+                                       if (pflac->bufferpos >= frame->header.blocksize)
+                                               break ;
+
+                                       for (j = 0 ; j < frame->header.channels ; j++)
+                                               retpcm [offset + j] = buffer [j][pflac->bufferpos] * norm ;
+                                       pflac->remain -= frame->header.channels ;
+                                       pflac->bufferpos++ ;
+                                       } ;
+                               } ;
+                       break ;
+
+               default :
+                       return 0 ;
+               } ;
+
+       offset = i * frame->header.channels ;
+       pflac->pos += i * frame->header.channels ;
+
+       return offset ;
+} /* flac_buffer_copy */
+
+
+static FLAC__SeekableStreamDecoderReadStatus
+sf_flac_read_callback (const FLAC__SeekableStreamDecoder * UNUSED (decoder), FLAC__byte buffer [], unsigned *bytes, void *client_data)
+{      SF_PRIVATE *psf = (SF_PRIVATE*) client_data ;
+
+       *bytes = psf_fread (buffer, 1, *bytes, psf) ;
+       if (*bytes > 0 && psf->error == 0)
+               return FLAC__SEEKABLE_STREAM_DECODER_READ_STATUS_OK ;
+
+    return FLAC__SEEKABLE_STREAM_DECODER_READ_STATUS_ERROR ;
+} /* sf_flac_read_callback */
+
+static FLAC__SeekableStreamDecoderSeekStatus
+sf_flac_seek_callback (const FLAC__SeekableStreamDecoder * UNUSED (decoder), FLAC__uint64 absolute_byte_offset, void *client_data)
+{      SF_PRIVATE *psf = (SF_PRIVATE*) client_data ;
+
+       psf_fseek (psf, absolute_byte_offset, SEEK_SET) ;
+       if (psf->error)
+               return FLAC__SEEKABLE_STREAM_DECODER_SEEK_STATUS_ERROR ;
+
+       return FLAC__SEEKABLE_STREAM_DECODER_SEEK_STATUS_OK ;
+} /* sf_flac_seek_callback */
+
+static FLAC__SeekableStreamDecoderTellStatus
+sf_flac_tell_callback (const FLAC__SeekableStreamDecoder * UNUSED (decoder), FLAC__uint64 *absolute_byte_offset, void *client_data)
+{      SF_PRIVATE *psf = (SF_PRIVATE*) client_data ;
+
+       *absolute_byte_offset = psf_ftell (psf) ;
+       if (psf->error)
+               return FLAC__SEEKABLE_STREAM_DECODER_TELL_STATUS_ERROR ;
+
+       return FLAC__SEEKABLE_STREAM_DECODER_TELL_STATUS_OK ;
+} /* sf_flac_tell_callback */
+
+static FLAC__SeekableStreamDecoderLengthStatus
+sf_flac_length_callback (const FLAC__SeekableStreamDecoder * UNUSED (decoder), FLAC__uint64 *stream_length, void *client_data)
+{      SF_PRIVATE *psf = (SF_PRIVATE*) client_data ;
+
+       if ((*stream_length = psf->filelength) == 0)
+               return FLAC__SEEKABLE_STREAM_DECODER_LENGTH_STATUS_ERROR ;
+
+       return FLAC__SEEKABLE_STREAM_DECODER_LENGTH_STATUS_OK ;
+} /* sf_flac_length_callback */
+
+static FLAC__bool
+sf_flac_eof_callback (const FLAC__SeekableStreamDecoder *UNUSED (decoder), void *client_data)
+{      SF_PRIVATE *psf = (SF_PRIVATE*) client_data ;
+
+       if (psf_ftell (psf) == psf->filelength)
+               return SF_TRUE ;
+
+    return SF_FALSE ;
+} /* sf_flac_eof_callback */
+
+static FLAC__StreamDecoderWriteStatus
+sf_flac_write_callback (const FLAC__SeekableStreamDecoder * UNUSED (decoder), const FLAC__Frame *frame, const FLAC__int32 * const buffer [], void *client_data)
+{      SF_PRIVATE *psf = (SF_PRIVATE*) client_data ;
+       FLAC_PRIVATE* pflac = (FLAC_PRIVATE*) psf->fdata ;
+
+       pflac->frame = frame ;
+       pflac->bufferpos = 0 ;
+
+       pflac->bufferbackup = SF_FALSE ;
+       pflac->wbuffer = buffer ;
+
+       flac_buffer_copy (psf) ;
+
+       return FLAC__STREAM_DECODER_WRITE_STATUS_CONTINUE ;
+} /* sf_flac_write_callback */
+
+static void
+sf_flac_meta_callback (const FLAC__SeekableStreamDecoder * UNUSED (decoder), const FLAC__StreamMetadata *metadata, void *client_data)
+{      SF_PRIVATE *psf = (SF_PRIVATE*) client_data ;
+
+       switch (metadata->type)
+       {       case FLAC__METADATA_TYPE_STREAMINFO :
+                       psf->sf.channels = metadata->data.stream_info.channels ;
+                       psf->sf.samplerate = metadata->data.stream_info.sample_rate ;
+                       psf->sf.frames = metadata->data.stream_info.total_samples ;
+
+                       switch (metadata->data.stream_info.bits_per_sample)
+                       {       case 8 :
+                                       psf->sf.format |= SF_FORMAT_PCM_S8 ;
+                                       break ;
+                               case 16 :
+                                       psf->sf.format |= SF_FORMAT_PCM_16 ;
+                                       break ;
+                               case 24 :
+                                       psf->sf.format |= SF_FORMAT_PCM_24 ;
+                                       break ;
+                               default :
+                                       psf_log_printf (psf, "sf_flac_meta_callback : bits_per_sample %d not yet implemented.\n", metadata->data.stream_info.bits_per_sample) ;
+                                       break ;
+                               } ;
+                       break ;
+
+               default :
+                       psf_log_printf (psf, "sf_flac_meta_callback : metadata-type %d not yet implemented.\n", metadata->type) ;
+               break ;
+               } ;
+
+       return ;
+} /* sf_flac_meta_callback */
+
+static void
+sf_flac_error_callback (const FLAC__SeekableStreamDecoder * UNUSED (decoder), FLAC__StreamDecoderErrorStatus status, void *client_data)
+{      SF_PRIVATE *psf = (SF_PRIVATE*) client_data ;
+
+       psf_log_printf (psf, "ERROR : %s\n", FLAC__StreamDecoderErrorStatusString [status]) ;
+
+       switch (status)
+       {       case FLAC__STREAM_DECODER_ERROR_STATUS_LOST_SYNC :
+                       psf->error = SFE_FLAC_LOST_SYNC ;
+                       break ;
+               case FLAC__STREAM_DECODER_ERROR_STATUS_BAD_HEADER :
+                       psf->error = SFE_FLAC_BAD_HEADER ;
+                       break ;
+               default :
+                       psf->error = SFE_FLAC_UNKOWN_ERROR ;
+                       break ;
+               } ;
+
+       return ;
+} /* sf_flac_error_callback */
+
+static FLAC__SeekableStreamEncoderSeekStatus
+sf_flac_enc_seek_callback (const FLAC__SeekableStreamEncoder * UNUSED (encoder), FLAC__uint64 absolute_byte_offset, void *client_data)
+{      SF_PRIVATE *psf = (SF_PRIVATE*) client_data ;
+
+       psf_fseek (psf, absolute_byte_offset, SEEK_SET) ;
+       if (psf->error)
+               return FLAC__SEEKABLE_STREAM_ENCODER_SEEK_STATUS_ERROR ;
+
+    return FLAC__SEEKABLE_STREAM_ENCODER_SEEK_STATUS_OK ;
+} /* sf_flac_enc_seek_callback */
+
+#ifdef HAVE_FLAC_1_1_1
+static FLAC__SeekableStreamEncoderTellStatus
+sf_flac_enc_tell_callback (const FLAC__SeekableStreamEncoder *UNUSED (encoder), FLAC__uint64 *absolute_byte_offset, void *client_data)
+{      SF_PRIVATE *psf = (SF_PRIVATE*) client_data ;
+
+       *absolute_byte_offset = psf_ftell (psf) ;
+       if (psf->error)
+               return FLAC__SEEKABLE_STREAM_ENCODER_TELL_STATUS_ERROR ;
+
+       return FLAC__SEEKABLE_STREAM_ENCODER_TELL_STATUS_OK ;
+} /* sf_flac_enc_tell_callback */
+#endif
+
+static FLAC__StreamEncoderWriteStatus
+sf_flac_enc_write_callback (const FLAC__SeekableStreamEncoder * UNUSED (encoder), const FLAC__byte buffer [], unsigned bytes, unsigned UNUSED (samples), unsigned UNUSED (current_frame), void *client_data)
+{      SF_PRIVATE *psf = (SF_PRIVATE*) client_data ;
+
+       if (psf_fwrite (buffer, 1, bytes, psf) == bytes && psf->error == 0)
+               return FLAC__STREAM_ENCODER_WRITE_STATUS_OK ;
+
+       return FLAC__STREAM_ENCODER_WRITE_STATUS_FATAL_ERROR ;
+} /* sf_flac_enc_write_callback */
+
+/*------------------------------------------------------------------------------
+** Public function.
+*/
+
+int
+flac_open      (SF_PRIVATE *psf)
+{      int             subformat ;
+       int             error = 0 ;
+
+       FLAC_PRIVATE* pflac = calloc (1, sizeof (FLAC_PRIVATE)) ;
+       psf->fdata = pflac ;
+
+       if (psf->mode == SFM_RDWR)
+               return SFE_UNIMPLEMENTED ;
+
+       if (psf->mode == SFM_READ)
+       {       if ((error = flac_read_header (psf)))
+                       return error ;
+               } ;
+
+       subformat = psf->sf.format & SF_FORMAT_SUBMASK ;
+
+       if (psf->mode == SFM_WRITE)
+       {       if ((psf->sf.format & SF_FORMAT_TYPEMASK) != SF_FORMAT_FLAC)
+                       return  SFE_BAD_OPEN_FORMAT ;
+
+               psf->endian = SF_ENDIAN_BIG ;
+
+               if ((error = flac_enc_init (psf)))
+                       return error ;
+               } ;
+
+       psf->datalength = psf->filelength ;
+       psf->dataoffset = 0 ;
+       psf->blockwidth = 0 ;
+       psf->bytewidth = 1 ;
+
+       psf->container_close = flac_close ;
+       psf->seek = flac_seek ;
+       psf->command = flac_command ;
+
+       psf->blockwidth = psf->bytewidth * psf->sf.channels ;
+
+       switch (subformat)
+       {       case SF_FORMAT_PCM_S8 :         /* 8-bit FLAC.  */
+               case SF_FORMAT_PCM_16 : /* 16-bit FLAC. */
+               case SF_FORMAT_PCM_24 : /* 24-bit FLAC. */
+                       error = flac_init (psf) ;
+                       break ;
+
+               default : return SFE_UNIMPLEMENTED ;
+               } ;
+
+       return error ;
+} /* flac_open */
+
+/*------------------------------------------------------------------------------
+*/
+
+static int
+flac_close     (SF_PRIVATE *psf)
+{      FLAC_PRIVATE* pflac ;
+       int k ;
+
+       if ((pflac = (FLAC_PRIVATE*) psf->fdata) == NULL)
+               return 0 ;
+
+       if (psf->mode == SFM_WRITE)
+       {       FLAC__seekable_stream_encoder_finish (pflac->fse) ;
+               FLAC__seekable_stream_encoder_delete (pflac->fse) ;
+               if (pflac->encbuffer)
+                       free (pflac->encbuffer) ;
+               } ;
+
+       if (psf->mode == SFM_READ)
+       {       FLAC__seekable_stream_decoder_finish (pflac->fsd) ;
+               FLAC__seekable_stream_decoder_delete (pflac->fsd) ;
+               } ;
+
+       for (k = 0 ; k < ARRAY_LEN (pflac->rbuffer) ; k++)
+               free (pflac->rbuffer [k]) ;
+
+       free (pflac) ;
+       psf->fdata = NULL ;
+
+       return 0 ;
+} /* flac_close */
+
+static int
+flac_enc_init (SF_PRIVATE *psf)
+{      FLAC_PRIVATE* pflac = (FLAC_PRIVATE*) psf->fdata ;
+       unsigned bps ;
+       int k, found ;
+
+       found = 0 ;
+       for (k = 0 ; k < ARRAY_LEN (legal_sample_rates) ; k++)
+               if (psf->sf.samplerate == legal_sample_rates [k])
+               {       found = 1 ;
+                       break ;
+                       } ;
+
+       if (found == 0)
+               return SFE_FLAC_BAD_SAMPLE_RATE ;
+
+       psf_fseek (psf, 0, SEEK_SET) ;
+       if ((pflac->fse = FLAC__seekable_stream_encoder_new ()) == NULL)
+               return SFE_FLAC_NEW_DECODER ;
+       FLAC__seekable_stream_encoder_set_write_callback (pflac->fse, sf_flac_enc_write_callback) ;
+       FLAC__seekable_stream_encoder_set_seek_callback (pflac->fse, sf_flac_enc_seek_callback) ;
+
+#ifdef HAVE_FLAC_1_1_1
+       FLAC__seekable_stream_encoder_set_tell_callback (pflac->fse, sf_flac_enc_tell_callback) ;
+#endif
+       FLAC__seekable_stream_encoder_set_client_data (pflac->fse, psf) ;
+       FLAC__seekable_stream_encoder_set_channels (pflac->fse, psf->sf.channels) ;
+       FLAC__seekable_stream_encoder_set_sample_rate (pflac->fse, psf->sf.samplerate) ;
+
+       switch (psf->sf.format & SF_FORMAT_SUBMASK)
+       {       case SF_FORMAT_PCM_S8 :
+                       bps = 8 ;
+                       break ;
+               case SF_FORMAT_PCM_16 :
+                       bps = 16 ;
+                       break ;
+               case SF_FORMAT_PCM_24 :
+                       bps = 24 ;
+                       break ;
+
+               default :
+                       bps = 0 ;
+                       break ;
+               } ;
+
+       FLAC__seekable_stream_encoder_set_bits_per_sample (pflac->fse, bps) ;
+
+       if ((bps = FLAC__seekable_stream_encoder_init (pflac->fse)) != FLAC__SEEKABLE_STREAM_DECODER_OK)
+       {       psf_log_printf (psf, "Error : FLAC encoder init returned error : %s\n", FLAC__seekable_stream_encoder_get_resolved_state_string (pflac->fse)) ;
+               return SFE_FLAC_INIT_DECODER ;
+               } ;
+
+       if (psf->error == 0)
+               psf->dataoffset = psf_ftell (psf) ;
+       pflac->encbuffer = calloc (ENC_BUFFER_SIZE, sizeof (FLAC__int32)) ;
+
+       return psf->error ;
+} /* flac_enc_init */
+
+static int
+flac_read_header (SF_PRIVATE *psf)
+{      FLAC_PRIVATE* pflac = (FLAC_PRIVATE*) psf->fdata ;
+
+       psf_fseek (psf, 0, SEEK_SET) ;
+       if ((pflac->fsd = FLAC__seekable_stream_decoder_new ()) == NULL)
+               return SFE_FLAC_NEW_DECODER ;
+
+       FLAC__seekable_stream_decoder_set_read_callback (pflac->fsd, sf_flac_read_callback) ;
+       FLAC__seekable_stream_decoder_set_seek_callback (pflac->fsd, sf_flac_seek_callback) ;
+       FLAC__seekable_stream_decoder_set_tell_callback (pflac->fsd, sf_flac_tell_callback) ;
+       FLAC__seekable_stream_decoder_set_length_callback (pflac->fsd, sf_flac_length_callback) ;
+       FLAC__seekable_stream_decoder_set_eof_callback (pflac->fsd, sf_flac_eof_callback) ;
+       FLAC__seekable_stream_decoder_set_write_callback (pflac->fsd, sf_flac_write_callback) ;
+       FLAC__seekable_stream_decoder_set_metadata_callback (pflac->fsd, sf_flac_meta_callback) ;
+       FLAC__seekable_stream_decoder_set_error_callback (pflac->fsd, sf_flac_error_callback) ;
+       FLAC__seekable_stream_decoder_set_client_data (pflac->fsd, psf) ;
+
+       if (FLAC__seekable_stream_decoder_init (pflac->fsd) != FLAC__SEEKABLE_STREAM_DECODER_OK)
+               return SFE_FLAC_INIT_DECODER ;
+
+       FLAC__seekable_stream_decoder_process_until_end_of_metadata (pflac->fsd) ;
+       if (psf->error == 0)
+       {       FLAC__uint64 position ;
+               FLAC__seekable_stream_decoder_get_decode_position (pflac->fsd, &position) ;
+               psf->dataoffset = position ;
+               } ;
+
+       return psf->error ;
+} /* flac_read_header */
+
+static int
+flac_command (SF_PRIVATE *psf, int command, void *data, int datasize)
+{
+       /* Avoid compiler warnings. */
+       psf = psf ;
+       data = data ;
+       datasize = datasize ;
+
+       switch (command)
+       {       default : break ;
+               } ;
+
+       return 0 ;
+} /* flac_command */
+
+int
+flac_init (SF_PRIVATE *psf)
+{
+       if (psf->mode == SFM_RDWR)
+               return SFE_BAD_MODE_RW ;
+
+       if (psf->mode == SFM_READ)
+       {       psf->read_short         = flac_read_flac2s ;
+               psf->read_int           = flac_read_flac2i ;
+               psf->read_float         = flac_read_flac2f ;
+               psf->read_double        = flac_read_flac2d ;
+               } ;
+
+       if (psf->mode == SFM_WRITE)
+       {       psf->write_short        = flac_write_s2flac ;
+               psf->write_int          = flac_write_i2flac ;
+               psf->write_float        = flac_write_f2flac ;
+               psf->write_double       = flac_write_d2flac ;
+               } ;
+
+       psf->bytewidth = 1 ;
+       psf->blockwidth = psf->sf.channels ;
+
+       if (psf->filelength > psf->dataoffset)
+               psf->datalength = (psf->dataend) ? psf->dataend - psf->dataoffset : psf->filelength - psf->dataoffset ;
+       else
+               psf->datalength = 0 ;
+
+       return 0 ;
+} /* flac_init */
+
+static unsigned
+flac_read_loop (SF_PRIVATE *psf, unsigned len)
+{      FLAC_PRIVATE* pflac = (FLAC_PRIVATE*) psf->fdata ;
+
+       pflac->pos = 0 ;
+       pflac->len = len ;
+       pflac->remain = len ;
+       if (pflac->frame != NULL && pflac->bufferpos < pflac->frame->header.blocksize)
+               flac_buffer_copy (psf) ;
+
+       while (pflac->pos < pflac->len)
+       {       if (FLAC__seekable_stream_decoder_process_single (pflac->fsd) == 0)
+                       break ;
+               if (FLAC__seekable_stream_decoder_get_state (pflac->fsd) != FLAC__SEEKABLE_STREAM_DECODER_OK)
+                       break ;
+               } ;
+
+       pflac->ptr = NULL ;
+
+       return pflac->pos ;
+} /* flac_read_loop */
+
+static sf_count_t
+flac_read_flac2s (SF_PRIVATE *psf, short *ptr, sf_count_t len)
+{      FLAC_PRIVATE* pflac = (FLAC_PRIVATE*) psf->fdata ;
+       sf_count_t total = 0, current ;
+       unsigned readlen ;
+
+       pflac->pcmtype = PFLAC_PCM_SHORT ;
+
+       while (total < len)
+       {       pflac->ptr = ptr + total ;
+               readlen = (len - total > 0x1000000) ? 0x1000000 : (unsigned) (len - total) ;
+               current = flac_read_loop (psf, readlen) ;
+               if (current == 0)
+                       break ;
+               total += current ;
+               } ;
+
+       return total ;
+} /* flac_read_flac2s */
+
+static sf_count_t
+flac_read_flac2i (SF_PRIVATE *psf, int *ptr, sf_count_t len)
+{      FLAC_PRIVATE* pflac = (FLAC_PRIVATE*) psf->fdata ;
+       sf_count_t total = 0, current ;
+       unsigned readlen ;
+
+       pflac->pcmtype = PFLAC_PCM_INT ;
+
+       while (total < len)
+       {       pflac->ptr = ptr + total ;
+               readlen = (len - total > 0x1000000) ? 0x1000000 : (unsigned) (len - total) ;
+               current = flac_read_loop (psf, readlen) ;
+               if (current == 0)
+                       break ;
+               total += current ;
+               } ;
+
+       return total ;
+} /* flac_read_flac2i */
+
+static sf_count_t
+flac_read_flac2f (SF_PRIVATE *psf, float *ptr, sf_count_t len)
+{      FLAC_PRIVATE* pflac = (FLAC_PRIVATE*) psf->fdata ;
+       sf_count_t total = 0, current ;
+       unsigned readlen ;
+
+       pflac->pcmtype = PFLAC_PCM_FLOAT ;
+
+       while (total < len)
+       {       pflac->ptr = ptr + total ;
+               readlen = (len - total > 0x1000000) ? 0x1000000 : (unsigned) (len - total) ;
+               current = flac_read_loop (psf, readlen) ;
+               if (current == 0)
+                       break ;
+               total += current ;
+               } ;
+
+       return total ;
+} /* flac_read_flac2f */
+
+static sf_count_t
+flac_read_flac2d (SF_PRIVATE *psf, double *ptr, sf_count_t len)
+{      FLAC_PRIVATE* pflac = (FLAC_PRIVATE*) psf->fdata ;
+       sf_count_t total = 0, current ;
+       unsigned readlen ;
+
+       pflac->pcmtype = PFLAC_PCM_DOUBLE ;
+
+       while (total < len)
+       {       pflac->ptr = ptr + total ;
+               readlen = (len - total > 0x1000000) ? 0x1000000 : (unsigned) (len - total) ;
+               current = flac_read_loop (psf, readlen) ;
+               if (current == 0)
+                       break ;
+               total += current ;
+               } ;
+
+       return total ;
+} /* flac_read_flac2d */
+
+static sf_count_t
+flac_write_s2flac (SF_PRIVATE *psf, const short *ptr, sf_count_t len)
+{      FLAC_PRIVATE* pflac = (FLAC_PRIVATE*) psf->fdata ;
+       void (*convert) (const short *, FLAC__int32 *, int) ;
+       int bufferlen, writecount, thiswrite ;
+       sf_count_t      total = 0 ;
+       FLAC__int32* buffer = pflac->encbuffer ;
+
+       switch (psf->sf.format & SF_FORMAT_SUBMASK)
+       {       case SF_FORMAT_PCM_S8 :
+                       convert = s2flac8_array ;
+                       break ;
+               case SF_FORMAT_PCM_16 :
+                       convert = s2flac16_array ;
+                       break ;
+                       case SF_FORMAT_PCM_24 :
+                       convert = s2flac24_array ;
+                       break ;
+               default :
+                       return -1 ;
+               } ;
+
+       bufferlen = ENC_BUFFER_SIZE / (sizeof (FLAC__int32) * psf->sf.channels) ;
+       bufferlen *= psf->sf.channels ;
+
+       while (len > 0)
+       {       writecount = (len >= bufferlen) ? bufferlen : (int) len ;
+               convert (ptr + total, buffer, writecount) ;
+               if (FLAC__seekable_stream_encoder_process_interleaved (pflac->fse, buffer, writecount/psf->sf.channels))
+                       thiswrite = writecount ;
+               else
+                       break ;
+               total += thiswrite ;
+               if (thiswrite < writecount)
+                       break ;
+
+               len -= thiswrite ;
+               } ;
+
+       return total ;
+} /* flac_write_s2flac */
+
+static sf_count_t
+flac_write_i2flac (SF_PRIVATE *psf, const int *ptr, sf_count_t len)
+{      FLAC_PRIVATE* pflac = (FLAC_PRIVATE*) psf->fdata ;
+       void (*convert) (const int *, FLAC__int32 *, int) ;
+       int bufferlen, writecount, thiswrite ;
+       sf_count_t      total = 0 ;
+       FLAC__int32* buffer = pflac->encbuffer ;
+
+       switch (psf->sf.format & SF_FORMAT_SUBMASK)
+       {       case SF_FORMAT_PCM_S8 :
+                       convert = i2flac8_array ;
+                       break ;
+               case SF_FORMAT_PCM_16 :
+                       convert = i2flac16_array ;
+                       break ;
+               case SF_FORMAT_PCM_24 :
+                       convert = i2flac24_array ;
+                       break ;
+               default :
+                       return -1 ;
+               } ;
+
+       bufferlen = ENC_BUFFER_SIZE / (sizeof (FLAC__int32) * psf->sf.channels) ;
+       bufferlen *= psf->sf.channels ;
+
+       while (len > 0)
+       {       writecount = (len >= bufferlen) ? bufferlen : (int) len ;
+               convert (ptr + total, buffer, writecount) ;
+               if (FLAC__seekable_stream_encoder_process_interleaved (pflac->fse, buffer, writecount/psf->sf.channels))
+                       thiswrite = writecount ;
+               else
+                       break ;
+               total += thiswrite ;
+               if (thiswrite < writecount)
+                       break ;
+
+               len -= thiswrite ;
+               } ;
+
+       return total ;
+} /* flac_write_i2flac */
+
+static sf_count_t
+flac_write_f2flac (SF_PRIVATE *psf, const float *ptr, sf_count_t len)
+{      FLAC_PRIVATE* pflac = (FLAC_PRIVATE*) psf->fdata ;
+       void (*convert) (const float *, FLAC__int32 *, int, int) ;
+       int bufferlen, writecount, thiswrite ;
+       sf_count_t      total = 0 ;
+       FLAC__int32* buffer = pflac->encbuffer ;
+
+       switch (psf->sf.format & SF_FORMAT_SUBMASK)
+       {       case SF_FORMAT_PCM_S8 :
+                       convert = (psf->add_clipping) ? f2flac8_clip_array : f2flac8_array ;
+                       break ;
+               case SF_FORMAT_PCM_16 :
+                       convert = (psf->add_clipping) ? f2flac16_clip_array : f2flac16_array ;
+                       break ;
+               case SF_FORMAT_PCM_24 :
+                       convert = (psf->add_clipping) ? f2flac24_clip_array : f2flac24_array ;
+                       break ;
+               default :
+                       return -1 ;
+               } ;
+
+       bufferlen = ENC_BUFFER_SIZE / (sizeof (FLAC__int32) * psf->sf.channels) ;
+       bufferlen *= psf->sf.channels ;
+
+       while (len > 0)
+       {       writecount = (len >= bufferlen) ? bufferlen : (int) len ;
+               convert (ptr + total, buffer, writecount, psf->norm_float) ;
+               if (FLAC__seekable_stream_encoder_process_interleaved (pflac->fse, buffer, writecount/psf->sf.channels))
+                       thiswrite = writecount ;
+               else
+                       break ;
+               total += thiswrite ;
+               if (thiswrite < writecount)
+                       break ;
+
+               len -= thiswrite ;
+               } ;
+
+       return total ;
+} /* flac_write_f2flac */
+
+static void
+f2flac8_clip_array (const float *src, FLAC__int32 *dest, int count, int normalize)
+{      float normfact, scaled_value ;
+
+       normfact = normalize ? (8.0 * 0x10) : 1.0 ;
+
+       while (--count >= 0)
+       {       scaled_value = src [count] * normfact ;
+               if (CPU_CLIPS_POSITIVE == 0 && scaled_value >= (1.0 * 0x7F))
+               {       dest [count] = 0x7F ;
+                       continue ;
+                       } ;
+               if (CPU_CLIPS_NEGATIVE == 0 && scaled_value <= (-8.0 * 0x10))
+               {       dest [count] = 0x80 ;
+                       continue ;
+                       } ;
+               dest [count] = lrintf (scaled_value) ;
+               } ;
+
+       return ;
+} /* f2flac8_clip_array */
+
+static void
+f2flac16_clip_array (const float *src, FLAC__int32 *dest, int count, int normalize)
+{
+  float normfact, scaled_value ;
+
+  normfact = normalize ? (8.0 * 0x1000) : 1.0 ;
+
+  while (--count >= 0) {
+    scaled_value = src [count] * normfact ;
+    if (CPU_CLIPS_POSITIVE == 0 && scaled_value >= (1.0 * 0x7FFF)) {
+      dest [count] = 0x7FFF ;
+      continue ;
+    }
+    if (CPU_CLIPS_NEGATIVE == 0 && scaled_value <= (-8.0 * 0x1000)) {
+      dest [count] = 0x8000 ;
+      continue ;
+    }
+    dest [count] = lrintf (scaled_value) ;
+  }
+} /* f2flac16_clip_array */
+
+static void
+f2flac24_clip_array (const float *src, FLAC__int32 *dest, int count, int normalize)
+{      float normfact, scaled_value ;
+
+       normfact = normalize ? (8.0 * 0x100000) : 1.0 ;
+
+       while (--count >= 0)
+       {       scaled_value = src [count] * normfact ;
+               if (CPU_CLIPS_POSITIVE == 0 && scaled_value >= (1.0 * 0x7FFFFF))
+               {       dest [count] = 0x7FFFFF ;
+                       continue ;
+                       } ;
+
+               if (CPU_CLIPS_NEGATIVE == 0 && scaled_value <= (-8.0 * 0x100000))
+               {       dest [count] = 0x800000 ;
+                       continue ;
+                       }
+               dest [count] = lrintf (scaled_value) ;
+               } ;
+
+       return ;
+} /* f2flac24_clip_array */
+
+static void
+f2flac8_array (const float *src, FLAC__int32 *dest, int count, int normalize)
+{      float normfact = normalize ? (1.0 * 0x7F) : 1.0 ;
+
+       while (--count >= 0)
+               dest [count] = lrintf (src [count] * normfact) ;
+} /* f2flac8_array */
+
+static void
+f2flac16_array (const float *src, FLAC__int32 *dest, int count, int normalize)
+{      float normfact = normalize ? (1.0 * 0x7FFF) : 1.0 ;
+
+       while (--count >= 0)
+               dest [count] = lrintf (src [count] * normfact) ;
+} /* f2flac16_array */
+
+static void
+f2flac24_array (const float *src, FLAC__int32 *dest, int count, int normalize)
+{      float normfact = normalize ? (1.0 * 0x7FFFFF) : 1.0 ;
+
+       while (--count >= 0)
+               dest [count] = lrintf (src [count] * normfact) ;
+} /* f2flac24_array */
+
+static sf_count_t
+flac_write_d2flac (SF_PRIVATE *psf, const double *ptr, sf_count_t len)
+{      FLAC_PRIVATE* pflac = (FLAC_PRIVATE*) psf->fdata ;
+       void (*convert) (const double *, FLAC__int32 *, int, int) ;
+       int bufferlen, writecount, thiswrite ;
+       sf_count_t      total = 0 ;
+       FLAC__int32* buffer = pflac->encbuffer ;
+
+       switch (psf->sf.format & SF_FORMAT_SUBMASK)
+       {       case SF_FORMAT_PCM_S8 :
+                       convert = (psf->add_clipping) ? d2flac8_clip_array : d2flac8_array ;
+                       break ;
+               case SF_FORMAT_PCM_16 :
+                       convert = (psf->add_clipping) ? d2flac16_clip_array : d2flac16_array ;
+                       break ;
+               case SF_FORMAT_PCM_24 :
+                       convert = (psf->add_clipping) ? d2flac24_clip_array : d2flac24_array ;
+                       break ;
+               default :
+                       return -1 ;
+               } ;
+
+       bufferlen = ENC_BUFFER_SIZE / (sizeof (FLAC__int32) * psf->sf.channels) ;
+       bufferlen *= psf->sf.channels ;
+
+       while (len > 0)
+       {       writecount = (len >= bufferlen) ? bufferlen : (int) len ;
+               convert (ptr + total, buffer, writecount, psf->norm_double) ;
+               if (FLAC__seekable_stream_encoder_process_interleaved (pflac->fse, buffer, writecount/psf->sf.channels))
+                       thiswrite = writecount ;
+               else
+                       break ;
+               total += thiswrite ;
+               if (thiswrite < writecount)
+                       break ;
+
+               len -= thiswrite ;
+               } ;
+
+       return total ;
+} /* flac_write_d2flac */
+
+static void
+d2flac8_clip_array (const double *src, FLAC__int32 *dest, int count, int normalize)
+{      double normfact, scaled_value ;
+
+       normfact = normalize ? (8.0 * 0x10) : 1.0 ;
+
+       while (--count >= 0)
+       {       scaled_value = src [count] * normfact ;
+               if (CPU_CLIPS_POSITIVE == 0 && scaled_value >= (1.0 * 0x7F))
+               {       dest [count] = 0x7F ;
+                       continue ;
+                       } ;
+               if (CPU_CLIPS_NEGATIVE == 0 && scaled_value <= (-8.0 * 0x10))
+               {       dest [count] = 0x80 ;
+                       continue ;
+                       } ;
+               dest [count] = lrint (scaled_value) ;
+               } ;
+
+       return ;
+} /* d2flac8_clip_array */
+
+static void
+d2flac16_clip_array (const double *src, FLAC__int32 *dest, int count, int normalize)
+{      double normfact, scaled_value ;
+
+       normfact = normalize ? (8.0 * 0x1000) : 1.0 ;
+
+       while (--count >= 0)
+       {       scaled_value = src [count] * normfact ;
+               if (CPU_CLIPS_POSITIVE == 0 && scaled_value >= (1.0 * 0x7FFF))
+               {       dest [count] = 0x7FFF ;
+                       continue ;
+                       } ;
+               if (CPU_CLIPS_NEGATIVE == 0 && scaled_value <= (-8.0 * 0x1000))
+               {       dest [count] = 0x8000 ;
+                       continue ;
+                       } ;
+               dest [count] = lrint (scaled_value) ;
+               } ;
+
+       return ;
+} /* d2flac16_clip_array */
+
+static void
+d2flac24_clip_array (const double *src, FLAC__int32 *dest, int count, int normalize)
+{      double normfact, scaled_value ;
+
+       normfact = normalize ? (8.0 * 0x100000) : 1.0 ;
+
+       while (--count >= 0)
+       {       scaled_value = src [count] * normfact ;
+               if (CPU_CLIPS_POSITIVE == 0 && scaled_value >= (1.0 * 0x7FFFFF))
+               {       dest [count] = 0x7FFFFF ;
+                       continue ;
+                       } ;
+               if (CPU_CLIPS_NEGATIVE == 0 && scaled_value <= (-8.0 * 0x100000))
+               {       dest [count] = 0x800000 ;
+                       continue ;
+                       } ;
+               dest [count] = lrint (scaled_value) ;
+               } ;
+
+       return ;
+} /* d2flac24_clip_array */
+
+static void
+d2flac8_array (const double *src, FLAC__int32 *dest, int count, int normalize)
+{      double normfact = normalize ? (1.0 * 0x7F) : 1.0 ;
+
+       while (--count >= 0)
+               dest [count] = lrint (src [count] * normfact) ;
+} /* d2flac8_array */
+
+static void
+d2flac16_array (const double *src, FLAC__int32 *dest, int count, int normalize)
+{      double normfact = normalize ? (1.0 * 0x7FFF) : 1.0 ;
+
+       while (--count >= 0)
+               dest [count] = lrint (src [count] * normfact) ;
+} /* d2flac16_array */
+
+static void
+d2flac24_array (const double *src, FLAC__int32 *dest, int count, int normalize)
+{      double normfact = normalize ? (1.0 * 0x7FFFFF) : 1.0 ;
+
+       while (--count >= 0)
+               dest [count] = lrint (src [count] * normfact) ;
+} /* d2flac24_array */
+
+static sf_count_t
+flac_seek (SF_PRIVATE *psf, int UNUSED (mode), sf_count_t offset)
+{      FLAC_PRIVATE* pflac = (FLAC_PRIVATE*) psf->fdata ;
+
+       if (pflac == NULL)
+               return 0 ;
+
+       if (psf->dataoffset < 0)
+       {       psf->error = SFE_BAD_SEEK ;
+               return ((sf_count_t) -1) ;
+               } ;
+
+       pflac->frame = NULL ;
+
+       if (psf->mode == SFM_READ)
+       {       FLAC__uint64 position ;
+               if (FLAC__seekable_stream_decoder_seek_absolute (pflac->fsd, offset))
+               {       FLAC__seekable_stream_decoder_get_decode_position (pflac->fsd, &position) ;
+                       return offset ;
+                       } ;
+
+               return ((sf_count_t) -1) ;
+               } ;
+
+       /* Seeking in write mode not yet supported. */
+       psf->error = SFE_BAD_SEEK ;
+
+       return ((sf_count_t) -1) ;
+} /* flac_seek */
+
+#endif
+
+/*
+** Do not edit or modify anything in this comment block.
+** The arch-tag line is a file identity tag for the GNU Arch
+** revision control system.
+**
+** arch-tag: 46d49617-ebff-42b4-8f66-a0e428147360
+*/
diff --git a/libs/libsndfile/src/float32.c b/libs/libsndfile/src/float32.c
new file mode 100644 (file)
index 0000000..b376e60
--- /dev/null
@@ -0,0 +1,961 @@
+/*
+** Copyright (C) 1999-2005 Erik de Castro Lopo <erikd@mega-nerd.com>
+**
+** This program is free software; you can redistribute it and/or modify
+** it under the terms of the GNU Lesser General Public License as published by
+** the Free Software Foundation; either version 2.1 of the License, or
+** (at your option) any later version.
+**
+** This program is distributed in the hope that it will be useful,
+** but WITHOUT ANY WARRANTY; without even the implied warranty of
+** MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+** GNU Lesser General Public License for more details.
+**
+** You should have received a copy of the GNU Lesser General Public License
+** along with this program; if not, write to the Free Software
+** Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA.
+*/
+
+#include       "sfconfig.h"
+
+#include       <stdio.h>
+#include       <stdlib.h>
+#include       <string.h>
+
+#include       "sndfile.h"
+#include       "sfendian.h"
+#include       "common.h"
+#include       "float_cast.h"
+
+#if CPU_IS_LITTLE_ENDIAN
+       #define FLOAT32_READ    float32_le_read
+       #define FLOAT32_WRITE   float32_le_write
+#elif CPU_IS_BIG_ENDIAN
+       #define FLOAT32_READ    float32_be_read
+       #define FLOAT32_WRITE   float32_be_write
+#endif
+
+/*--------------------------------------------------------------------------------------------
+**     Processor floating point capabilities. float32_get_capability () returns one of the
+**     latter four values.
+*/
+
+enum
+{      FLOAT_UNKNOWN           = 0x00,
+       FLOAT_CAN_RW_LE         = 0x12,
+       FLOAT_CAN_RW_BE         = 0x23,
+       FLOAT_BROKEN_LE         = 0x34,
+       FLOAT_BROKEN_BE         = 0x45
+} ;
+
+/*--------------------------------------------------------------------------------------------
+**     Prototypes for private functions.
+*/
+
+static sf_count_t      host_read_f2s   (SF_PRIVATE *psf, short *ptr, sf_count_t len) ;
+static sf_count_t      host_read_f2i   (SF_PRIVATE *psf, int *ptr, sf_count_t len) ;
+static sf_count_t      host_read_f     (SF_PRIVATE *psf, float *ptr, sf_count_t len) ;
+static sf_count_t      host_read_f2d   (SF_PRIVATE *psf, double *ptr, sf_count_t len) ;
+
+static sf_count_t      host_write_s2f  (SF_PRIVATE *psf, const short *ptr, sf_count_t len) ;
+static sf_count_t      host_write_i2f  (SF_PRIVATE *psf, const int *ptr, sf_count_t len) ;
+static sf_count_t      host_write_f    (SF_PRIVATE *psf, const float *ptr, sf_count_t len) ;
+static sf_count_t      host_write_d2f  (SF_PRIVATE *psf, const double *ptr, sf_count_t len) ;
+
+static void            float32_peak_update     (SF_PRIVATE *psf, const float *buffer, int count, sf_count_t indx) ;
+
+static sf_count_t      replace_read_f2s        (SF_PRIVATE *psf, short *ptr, sf_count_t len) ;
+static sf_count_t      replace_read_f2i        (SF_PRIVATE *psf, int *ptr, sf_count_t len) ;
+static sf_count_t      replace_read_f  (SF_PRIVATE *psf, float *ptr, sf_count_t len) ;
+static sf_count_t      replace_read_f2d        (SF_PRIVATE *psf, double *ptr, sf_count_t len) ;
+
+static sf_count_t      replace_write_s2f       (SF_PRIVATE *psf, const short *ptr, sf_count_t len) ;
+static sf_count_t      replace_write_i2f       (SF_PRIVATE *psf, const int *ptr, sf_count_t len) ;
+static sf_count_t      replace_write_f (SF_PRIVATE *psf, const float *ptr, sf_count_t len) ;
+static sf_count_t      replace_write_d2f       (SF_PRIVATE *psf, const double *ptr, sf_count_t len) ;
+
+static void    bf2f_array (float *buffer, int count) ;
+static void    f2bf_array (float *buffer, int count) ;
+
+static int             float32_get_capability  (SF_PRIVATE *psf) ;
+
+/*--------------------------------------------------------------------------------------------
+**     Exported functions.
+*/
+
+int
+float32_init   (SF_PRIVATE *psf)
+{      static int float_caps ;
+
+       float_caps = float32_get_capability (psf) ;
+
+       psf->blockwidth = sizeof (float) * psf->sf.channels ;
+
+       if (psf->mode == SFM_READ || psf->mode == SFM_RDWR)
+       {       switch (psf->endian + float_caps)
+               {       case (SF_ENDIAN_BIG + FLOAT_CAN_RW_BE) :
+                                       psf->float_endswap = SF_FALSE ;
+                                       psf->read_short         = host_read_f2s ;
+                                       psf->read_int           = host_read_f2i ;
+                                       psf->read_float         = host_read_f ;
+                                       psf->read_double        = host_read_f2d ;
+                                       break ;
+
+                       case (SF_ENDIAN_LITTLE + FLOAT_CAN_RW_LE) :
+                                       psf->float_endswap = SF_FALSE ;
+                                       psf->read_short         = host_read_f2s ;
+                                       psf->read_int           = host_read_f2i ;
+                                       psf->read_float         = host_read_f ;
+                                       psf->read_double        = host_read_f2d ;
+                                       break ;
+
+                       case (SF_ENDIAN_BIG + FLOAT_CAN_RW_LE) :
+                                       psf->float_endswap = SF_TRUE ;
+                                       psf->read_short         = host_read_f2s ;
+                                       psf->read_int           = host_read_f2i ;
+                                       psf->read_float         = host_read_f ;
+                                       psf->read_double        = host_read_f2d ;
+                                       break ;
+
+                       case (SF_ENDIAN_LITTLE + FLOAT_CAN_RW_BE) :
+                                       psf->float_endswap = SF_TRUE ;
+                                       psf->read_short         = host_read_f2s ;
+                                       psf->read_int           = host_read_f2i ;
+                                       psf->read_float         = host_read_f ;
+                                       psf->read_double        = host_read_f2d ;
+                                       break ;
+
+                       /* When the CPU is not IEEE compatible. */
+                       case (SF_ENDIAN_BIG + FLOAT_BROKEN_LE) :
+                                       psf->float_endswap = SF_TRUE ;
+                                       psf->read_short         = replace_read_f2s ;
+                                       psf->read_int           = replace_read_f2i ;
+                                       psf->read_float         = replace_read_f ;
+                                       psf->read_double        = replace_read_f2d ;
+                                       break ;
+
+                       case (SF_ENDIAN_LITTLE + FLOAT_BROKEN_LE) :
+                                       psf->float_endswap = SF_FALSE ;
+                                       psf->read_short         = replace_read_f2s ;
+                                       psf->read_int           = replace_read_f2i ;
+                                       psf->read_float         = replace_read_f ;
+                                       psf->read_double        = replace_read_f2d ;
+                                       break ;
+
+                       case (SF_ENDIAN_BIG + FLOAT_BROKEN_BE) :
+                                       psf->float_endswap = SF_FALSE ;
+                                       psf->read_short         = replace_read_f2s ;
+                                       psf->read_int           = replace_read_f2i ;
+                                       psf->read_float         = replace_read_f ;
+                                       psf->read_double        = replace_read_f2d ;
+                                       break ;
+
+                       case (SF_ENDIAN_LITTLE + FLOAT_BROKEN_BE) :
+                                       psf->float_endswap = SF_TRUE ;
+                                       psf->read_short         = replace_read_f2s ;
+                                       psf->read_int           = replace_read_f2i ;
+                                       psf->read_float         = replace_read_f ;
+                                       psf->read_double        = replace_read_f2d ;
+                                       break ;
+
+                       default : break ;
+                       } ;
+               } ;
+
+       if (psf->mode == SFM_WRITE || psf->mode == SFM_RDWR)
+       {       switch (psf->endian + float_caps)
+               {       case (SF_ENDIAN_LITTLE + FLOAT_CAN_RW_LE) :
+                                       psf->float_endswap = SF_FALSE ;
+                                       psf->write_short        = host_write_s2f ;
+                                       psf->write_int          = host_write_i2f ;
+                                       psf->write_float        = host_write_f ;
+                                       psf->write_double       = host_write_d2f ;
+                                       break ;
+
+                       case (SF_ENDIAN_BIG + FLOAT_CAN_RW_BE) :
+                                       psf->float_endswap = SF_FALSE ;
+                                       psf->write_short        = host_write_s2f ;
+                                       psf->write_int          = host_write_i2f ;
+                                       psf->write_float        = host_write_f ;
+                                       psf->write_double       = host_write_d2f ;
+                                       break ;
+
+                       case (SF_ENDIAN_BIG + FLOAT_CAN_RW_LE) :
+                                       psf->float_endswap = SF_TRUE ;
+                                       psf->write_short        = host_write_s2f ;
+                                       psf->write_int          = host_write_i2f ;
+                                       psf->write_float        = host_write_f ;
+                                       psf->write_double       = host_write_d2f ;
+                                       break ;
+
+                       case (SF_ENDIAN_LITTLE + FLOAT_CAN_RW_BE) :
+                                       psf->float_endswap = SF_TRUE ;
+                                       psf->write_short        = host_write_s2f ;
+                                       psf->write_int          = host_write_i2f ;
+                                       psf->write_float        = host_write_f ;
+                                       psf->write_double       = host_write_d2f ;
+                                       break ;
+
+                       /* When the CPU is not IEEE compatible. */
+                       case (SF_ENDIAN_BIG + FLOAT_BROKEN_LE) :
+                                       psf->float_endswap = SF_TRUE ;
+                                       psf->write_short        = replace_write_s2f ;
+                                       psf->write_int          = replace_write_i2f ;
+                                       psf->write_float        = replace_write_f ;
+                                       psf->write_double       = replace_write_d2f ;
+                                       break ;
+
+                       case (SF_ENDIAN_LITTLE + FLOAT_BROKEN_LE) :
+                                       psf->float_endswap = SF_FALSE ;
+                                       psf->write_short        = replace_write_s2f ;
+                                       psf->write_int          = replace_write_i2f ;
+                                       psf->write_float        = replace_write_f ;
+                                       psf->write_double       = replace_write_d2f ;
+                                       break ;
+
+                       case (SF_ENDIAN_BIG + FLOAT_BROKEN_BE) :
+                                       psf->float_endswap = SF_FALSE ;
+                                       psf->write_short        = replace_write_s2f ;
+                                       psf->write_int          = replace_write_i2f ;
+                                       psf->write_float        = replace_write_f ;
+                                       psf->write_double       = replace_write_d2f ;
+                                       break ;
+
+                       case (SF_ENDIAN_LITTLE + FLOAT_BROKEN_BE) :
+                                       psf->float_endswap = SF_TRUE ;
+                                       psf->write_short        = replace_write_s2f ;
+                                       psf->write_int          = replace_write_i2f ;
+                                       psf->write_float        = replace_write_f ;
+                                       psf->write_double       = replace_write_d2f ;
+                                       break ;
+
+                       default : break ;
+                       } ;
+               } ;
+
+       if (psf->filelength > psf->dataoffset)
+       {       psf->datalength = (psf->dataend > 0) ? psf->dataend - psf->dataoffset :
+                                                       psf->filelength - psf->dataoffset ;
+               }
+       else
+               psf->datalength = 0 ;
+
+       psf->sf.frames = psf->datalength / psf->blockwidth ;
+
+       return 0 ;
+} /* float32_init */
+
+float
+float32_be_read (unsigned char *cptr)
+{      int             exponent, mantissa, negative ;
+       float   fvalue ;
+
+       negative = cptr [0] & 0x80 ;
+       exponent = ((cptr [0] & 0x7F) << 1) | ((cptr [1] & 0x80) ? 1 : 0) ;
+       mantissa = ((cptr [1] & 0x7F) << 16) | (cptr [2] << 8) | (cptr [3]) ;
+
+       if (! (exponent || mantissa))
+               return 0.0 ;
+
+       mantissa |= 0x800000 ;
+       exponent = exponent ? exponent - 127 : 0 ;
+
+       fvalue = mantissa ? ((float) mantissa) / ((float) 0x800000) : 0.0 ;
+
+       if (negative)
+               fvalue *= -1 ;
+
+       if (exponent > 0)
+               fvalue *= (1 << exponent) ;
+       else if (exponent < 0)
+               fvalue /= (1 << abs (exponent)) ;
+
+       return fvalue ;
+} /* float32_be_read */
+
+float
+float32_le_read (unsigned char *cptr)
+{      int             exponent, mantissa, negative ;
+       float   fvalue ;
+
+       negative = cptr [3] & 0x80 ;
+       exponent = ((cptr [3] & 0x7F) << 1) | ((cptr [2] & 0x80) ? 1 : 0) ;
+       mantissa = ((cptr [2] & 0x7F) << 16) | (cptr [1] << 8) | (cptr [0]) ;
+
+       if (! (exponent || mantissa))
+               return 0.0 ;
+
+       mantissa |= 0x800000 ;
+       exponent = exponent ? exponent - 127 : 0 ;
+
+       fvalue = mantissa ? ((float) mantissa) / ((float) 0x800000) : 0.0 ;
+
+       if (negative)
+               fvalue *= -1 ;
+
+       if (exponent > 0)
+               fvalue *= (1 << exponent) ;
+       else if (exponent < 0)
+               fvalue /= (1 << abs (exponent)) ;
+
+       return fvalue ;
+} /* float32_le_read */
+
+void
+float32_le_write (float in, unsigned char *out)
+{      int             exponent, mantissa, negative = 0 ;
+
+       memset (out, 0, sizeof (int)) ;
+
+       if (fabs (in) < 1e-30)
+               return ;
+
+       if (in < 0.0)
+       {       in *= -1.0 ;
+               negative = 1 ;
+               } ;
+
+       in = frexp (in, &exponent) ;
+
+       exponent += 126 ;
+
+       in *= (float) 0x1000000 ;
+       mantissa = (((int) in) & 0x7FFFFF) ;
+
+       if (negative)
+               out [3] |= 0x80 ;
+
+       if (exponent & 0x01)
+               out [2] |= 0x80 ;
+
+       out [0] = mantissa & 0xFF ;
+       out [1] = (mantissa >> 8) & 0xFF ;
+       out [2] |= (mantissa >> 16) & 0x7F ;
+       out [3] |= (exponent >> 1) & 0x7F ;
+
+       return ;
+} /* float32_le_write */
+
+void
+float32_be_write (float in, unsigned char *out)
+{      int             exponent, mantissa, negative = 0 ;
+
+       memset (out, 0, sizeof (int)) ;
+
+       if (fabs (in) < 1e-30)
+               return ;
+
+       if (in < 0.0)
+       {       in *= -1.0 ;
+               negative = 1 ;
+               } ;
+
+       in = frexp (in, &exponent) ;
+
+       exponent += 126 ;
+
+       in *= (float) 0x1000000 ;
+       mantissa = (((int) in) & 0x7FFFFF) ;
+
+       if (negative)
+               out [0] |= 0x80 ;
+
+       if (exponent & 0x01)
+               out [1] |= 0x80 ;
+
+       out [3] = mantissa & 0xFF ;
+       out [2] = (mantissa >> 8) & 0xFF ;
+       out [1] |= (mantissa >> 16) & 0x7F ;
+       out [0] |= (exponent >> 1) & 0x7F ;
+
+       return ;
+} /* float32_be_write */
+
+/*==============================================================================================
+**     Private functions.
+*/
+
+static void
+float32_peak_update    (SF_PRIVATE *psf, const float *buffer, int count, sf_count_t indx)
+{      int     chan ;
+       int             k, position ;
+       float   fmaxval ;
+
+       for (chan = 0 ; chan < psf->sf.channels ; chan++)
+       {       fmaxval = fabs (buffer [chan]) ;
+               position = 0 ;
+               for (k = chan ; k < count ; k += psf->sf.channels)
+                       if (fmaxval < fabs (buffer [k]))
+                       {       fmaxval = fabs (buffer [k]) ;
+                               position = k ;
+                               } ;
+
+               if (fmaxval > psf->peak_info->peaks [chan].value)
+               {       psf->peak_info->peaks [chan].value = fmaxval ;
+                       psf->peak_info->peaks [chan].position = psf->write_current + indx + (position / psf->sf.channels) ;
+                       } ;
+               } ;
+
+       return ;
+} /* float32_peak_update */
+
+static int
+float32_get_capability (SF_PRIVATE *psf)
+{      union
+       {       float                   f ;
+               int                             i ;
+               unsigned char   c [4] ;
+       } data ;
+
+       data.f = (float) 1.23456789 ; /* Some abitrary value. */
+
+       if (! psf->ieee_replace)
+       {       /* If this test is true ints and floats are compatible and little endian. */
+               if (data.c [0] == 0x52 && data.c [1] == 0x06 && data.c [2] == 0x9e && data.c [3] == 0x3f)
+                       return FLOAT_CAN_RW_LE ;
+
+               /* If this test is true ints and floats are compatible and big endian. */
+               if (data.c [3] == 0x52 && data.c [2] == 0x06 && data.c [1] == 0x9e && data.c [0] == 0x3f)
+                       return FLOAT_CAN_RW_BE ;
+               } ;
+
+       /* Floats are broken. Don't expect reading or writing to be fast. */
+       psf_log_printf (psf, "Using IEEE replacement code for float.\n") ;
+
+       return (CPU_IS_LITTLE_ENDIAN) ? FLOAT_BROKEN_LE : FLOAT_BROKEN_BE ;
+} /* float32_get_capability */
+
+/*=======================================================================================
+*/
+
+static inline void
+f2s_array (const float *src, int count, short *dest, float scale)
+{      while (--count >= 0)
+       {       dest [count] = lrintf (scale * src [count]) ;
+               } ;
+} /* f2s_array */
+
+static inline void
+f2i_array (const float *src, int count, int *dest, float scale)
+{      while (--count >= 0)
+       {       dest [count] = lrintf (scale * src [count]) ;
+               } ;
+} /* f2i_array */
+
+static inline void
+f2d_array (const float *src, int count, double *dest)
+{      while (--count >= 0)
+       {       dest [count] = src [count] ;
+               } ;
+} /* f2d_array */
+
+static inline void
+s2f_array (const short *src, float *dest, int count)
+{      while (--count >= 0)
+       {       dest [count] = src [count] ;
+               } ;
+
+} /* s2f_array */
+
+static inline void
+i2f_array (const int *src, float *dest, int count)
+{      while (--count >= 0)
+       {       dest [count] = src [count] ;
+               } ;
+} /* i2f_array */
+
+static inline void
+d2f_array (const double *src, float *dest, int count)
+{      while (--count >= 0)
+       {       dest [count] = src [count] ;
+               } ;
+} /* d2f_array */
+
+/*----------------------------------------------------------------------------------------------
+*/
+
+static sf_count_t
+host_read_f2s  (SF_PRIVATE *psf, short *ptr, sf_count_t len)
+{      int                     bufferlen, readcount ;
+       sf_count_t      total = 0 ;
+       float           scale ;
+
+       bufferlen = ARRAY_LEN (psf->u.fbuf) ;
+       scale = (psf->float_int_mult == 0) ? 1.0 : 0x7FFF / psf->float_max ;
+
+       while (len > 0)
+       {       if (len < bufferlen)
+                       bufferlen = (int) len ;
+               readcount = psf_fread (psf->u.fbuf, sizeof (float), bufferlen, psf) ;
+
+/* Fix me : Need lef2s_array */
+               if (psf->float_endswap == SF_TRUE)
+                       endswap_int_array (psf->u.ibuf, bufferlen) ;
+
+               f2s_array (psf->u.fbuf, readcount, ptr + total, scale) ;
+               total += readcount ;
+               if (readcount < bufferlen)
+                       break ;
+               len -= readcount ;
+               } ;
+
+       return total ;
+} /* host_read_f2s */
+
+static sf_count_t
+host_read_f2i  (SF_PRIVATE *psf, int *ptr, sf_count_t len)
+{      int                     bufferlen, readcount ;
+       sf_count_t      total = 0 ;
+       float           scale ;
+
+       bufferlen = ARRAY_LEN (psf->u.fbuf) ;
+       scale = (psf->float_int_mult == 0) ? 1.0 : 0x7FFFFFFF / psf->float_max ;
+
+       while (len > 0)
+       {       if (len < bufferlen)
+                       bufferlen = (int) len ;
+               readcount = psf_fread (psf->u.fbuf, sizeof (float), bufferlen, psf) ;
+
+               if (psf->float_endswap == SF_TRUE)
+                       endswap_int_array (psf->u.ibuf, bufferlen) ;
+
+               f2i_array (psf->u.fbuf, readcount, ptr + total, scale) ;
+               total += readcount ;
+               if (readcount < bufferlen)
+                       break ;
+               len -= readcount ;
+               } ;
+
+       return total ;
+} /* host_read_f2i */
+
+static sf_count_t
+host_read_f    (SF_PRIVATE *psf, float *ptr, sf_count_t len)
+{      int                     bufferlen, readcount ;
+       sf_count_t      total = 0 ;
+
+       if (psf->float_endswap != SF_TRUE)
+               return psf_fread (ptr, sizeof (float), len, psf) ;
+
+       bufferlen = ARRAY_LEN (psf->u.fbuf) ;
+
+       while (len > 0)
+       {       if (len < bufferlen)
+                       bufferlen = (int) len ;
+               readcount = psf_fread (psf->u.fbuf, sizeof (float), bufferlen, psf) ;
+
+               endswap_int_copy ((int*) (ptr + total), psf->u.ibuf, readcount) ;
+
+               total += readcount ;
+               if (readcount < bufferlen)
+                       break ;
+               len -= readcount ;
+               } ;
+
+       return total ;
+} /* host_read_f */
+
+static sf_count_t
+host_read_f2d  (SF_PRIVATE *psf, double *ptr, sf_count_t len)
+{      int                     bufferlen, readcount ;
+       sf_count_t      total = 0 ;
+
+       bufferlen = ARRAY_LEN (psf->u.fbuf) ;
+
+       while (len > 0)
+       {       if (len < bufferlen)
+                       bufferlen = (int) len ;
+               readcount = psf_fread (psf->u.fbuf, sizeof (float), bufferlen, psf) ;
+
+               if (psf->float_endswap == SF_TRUE)
+                       endswap_int_array (psf->u.ibuf, bufferlen) ;
+
+/* Fix me : Need lef2d_array */
+               f2d_array (psf->u.fbuf, readcount, ptr + total) ;
+               total += readcount ;
+               if (readcount < bufferlen)
+                       break ;
+               len -= readcount ;
+               } ;
+
+       return total ;
+} /* host_read_f2d */
+
+static sf_count_t
+host_write_s2f (SF_PRIVATE *psf, const short *ptr, sf_count_t len)
+{      int                     bufferlen, writecount ;
+       sf_count_t      total = 0 ;
+
+       bufferlen = ARRAY_LEN (psf->u.fbuf) ;
+
+       while (len > 0)
+       {       if (len < bufferlen)
+                       bufferlen = (int) len ;
+               s2f_array (ptr + total, psf->u.fbuf, bufferlen) ;
+
+               if (psf->peak_info)
+                       float32_peak_update (psf, psf->u.fbuf, bufferlen, total / psf->sf.channels) ;
+
+               if (psf->float_endswap == SF_TRUE)
+                       endswap_int_array (psf->u.ibuf, bufferlen) ;
+
+               writecount = psf_fwrite (psf->u.fbuf, sizeof (float), bufferlen, psf) ;
+               total += writecount ;
+               if (writecount < bufferlen)
+                       break ;
+               len -= writecount ;
+               } ;
+
+       return total ;
+} /* host_write_s2f */
+
+static sf_count_t
+host_write_i2f (SF_PRIVATE *psf, const int *ptr, sf_count_t len)
+{      int                     bufferlen, writecount ;
+       sf_count_t      total = 0 ;
+
+       bufferlen = ARRAY_LEN (psf->u.fbuf) ;
+
+       while (len > 0)
+       {       if (len < bufferlen)
+                       bufferlen = (int) len ;
+               i2f_array (ptr + total, psf->u.fbuf, bufferlen) ;
+
+               if (psf->peak_info)
+                       float32_peak_update (psf, psf->u.fbuf, bufferlen, total / psf->sf.channels) ;
+
+               if (psf->float_endswap == SF_TRUE)
+                       endswap_int_array (psf->u.ibuf, bufferlen) ;
+
+               writecount = psf_fwrite (psf->u.fbuf, sizeof (float) , bufferlen, psf) ;
+               total += writecount ;
+               if (writecount < bufferlen)
+                       break ;
+               len -= writecount ;
+               } ;
+
+       return total ;
+} /* host_write_i2f */
+
+static sf_count_t
+host_write_f   (SF_PRIVATE *psf, const float *ptr, sf_count_t len)
+{      int                     bufferlen, writecount ;
+       sf_count_t      total = 0 ;
+
+       if (psf->peak_info)
+               float32_peak_update (psf, ptr, len, 0) ;
+
+       if (psf->float_endswap != SF_TRUE)
+               return psf_fwrite (ptr, sizeof (float), len, psf) ;
+
+       bufferlen = ARRAY_LEN (psf->u.fbuf) ;
+
+       while (len > 0)
+       {       if (len < bufferlen)
+                       bufferlen = (int) len ;
+
+               endswap_int_copy (psf->u.ibuf, (const int*) (ptr + total), bufferlen) ;
+
+               writecount = psf_fwrite (psf->u.fbuf, sizeof (float), bufferlen, psf) ;
+               total += writecount ;
+               if (writecount < bufferlen)
+                       break ;
+               len -= writecount ;
+               } ;
+
+       return total ;
+} /* host_write_f */
+
+static sf_count_t
+host_write_d2f (SF_PRIVATE *psf, const double *ptr, sf_count_t len)
+{      int                     bufferlen, writecount ;
+       sf_count_t      total = 0 ;
+
+       bufferlen = ARRAY_LEN (psf->u.fbuf) ;
+
+       while (len > 0)
+       {       if (len < bufferlen)
+                       bufferlen = (int) len ;
+
+               d2f_array (ptr + total, psf->u.fbuf, bufferlen) ;
+
+               if (psf->peak_info)
+                       float32_peak_update (psf, psf->u.fbuf, bufferlen, total / psf->sf.channels) ;
+
+               if (psf->float_endswap == SF_TRUE)
+                       endswap_int_array (psf->u.ibuf, bufferlen) ;
+
+               writecount = psf_fwrite (psf->u.fbuf, sizeof (float), bufferlen, psf) ;
+               total += writecount ;
+               if (writecount < bufferlen)
+                       break ;
+               len -= writecount ;
+               } ;
+
+       return total ;
+} /* host_write_d2f */
+
+/*=======================================================================================
+*/
+
+static sf_count_t
+replace_read_f2s       (SF_PRIVATE *psf, short *ptr, sf_count_t len)
+{      int                     bufferlen, readcount ;
+       sf_count_t      total = 0 ;
+       float           scale ;
+
+       bufferlen = ARRAY_LEN (psf->u.fbuf) ;
+       scale = (psf->float_int_mult == 0) ? 1.0 : 0x7FFF / psf->float_max ;
+
+       while (len > 0)
+       {       if (len < bufferlen)
+                       bufferlen = (int) len ;
+               readcount = psf_fread (psf->u.fbuf, sizeof (float), bufferlen, psf) ;
+
+               if (psf->float_endswap == SF_TRUE)
+                       endswap_int_array (psf->u.ibuf, bufferlen) ;
+
+               bf2f_array (psf->u.fbuf, bufferlen) ;
+
+               f2s_array (psf->u.fbuf, readcount, ptr + total, scale) ;
+               total += readcount ;
+               if (readcount < bufferlen)
+                       break ;
+               len -= readcount ;
+               } ;
+
+       return total ;
+} /* replace_read_f2s */
+
+static sf_count_t
+replace_read_f2i       (SF_PRIVATE *psf, int *ptr, sf_count_t len)
+{      int                     bufferlen, readcount ;
+       sf_count_t      total = 0 ;
+       float           scale ;
+
+       bufferlen = ARRAY_LEN (psf->u.fbuf) ;
+       scale = (psf->float_int_mult == 0) ? 1.0 : 0x7FFF / psf->float_max ;
+
+       while (len > 0)
+       {       if (len < bufferlen)
+                       bufferlen = (int) len ;
+               readcount = psf_fread (psf->u.fbuf, sizeof (float), bufferlen, psf) ;
+
+               if (psf->float_endswap == SF_TRUE)
+                       endswap_int_array (psf->u.ibuf, bufferlen) ;
+
+               bf2f_array (psf->u.fbuf, bufferlen) ;
+
+               f2i_array (psf->u.fbuf, readcount, ptr + total, scale) ;
+               total += readcount ;
+               if (readcount < bufferlen)
+                       break ;
+               len -= readcount ;
+               } ;
+
+       return total ;
+} /* replace_read_f2i */
+
+static sf_count_t
+replace_read_f (SF_PRIVATE *psf, float *ptr, sf_count_t len)
+{      int                     bufferlen, readcount ;
+       sf_count_t      total = 0 ;
+
+       /* FIX THIS */
+
+       bufferlen = ARRAY_LEN (psf->u.fbuf) ;
+
+       while (len > 0)
+       {       if (len < bufferlen)
+                       bufferlen = (int) len ;
+               readcount = psf_fread (psf->u.fbuf, sizeof (float), bufferlen, psf) ;
+
+               if (psf->float_endswap == SF_TRUE)
+                       endswap_int_array (psf->u.ibuf, bufferlen) ;
+
+               bf2f_array (psf->u.fbuf, bufferlen) ;
+
+               memcpy (ptr + total, psf->u.fbuf, bufferlen * sizeof (float)) ;
+
+               total += readcount ;
+               if (readcount < bufferlen)
+                       break ;
+               len -= readcount ;
+               } ;
+
+       return total ;
+} /* replace_read_f */
+
+static sf_count_t
+replace_read_f2d       (SF_PRIVATE *psf, double *ptr, sf_count_t len)
+{      int                     bufferlen, readcount ;
+       sf_count_t      total = 0 ;
+
+       bufferlen = ARRAY_LEN (psf->u.fbuf) ;
+
+       while (len > 0)
+       {       if (len < bufferlen)
+                       bufferlen = (int) len ;
+               readcount = psf_fread (psf->u.fbuf, sizeof (float), bufferlen, psf) ;
+
+               if (psf->float_endswap == SF_TRUE)
+                       endswap_int_array (psf->u.ibuf, bufferlen) ;
+
+               bf2f_array (psf->u.fbuf, bufferlen) ;
+
+               f2d_array (psf->u.fbuf, readcount, ptr + total) ;
+               total += readcount ;
+               if (readcount < bufferlen)
+                       break ;
+               len -= readcount ;
+               } ;
+
+       return total ;
+} /* replace_read_f2d */
+
+static sf_count_t
+replace_write_s2f      (SF_PRIVATE *psf, const short *ptr, sf_count_t len)
+{      int                     bufferlen, writecount ;
+       sf_count_t      total = 0 ;
+
+       bufferlen = ARRAY_LEN (psf->u.fbuf) ;
+
+       while (len > 0)
+       {       if (len < bufferlen)
+                       bufferlen = (int) len ;
+               s2f_array (ptr + total, psf->u.fbuf, bufferlen) ;
+
+               if (psf->peak_info)
+                       float32_peak_update (psf, psf->u.fbuf, bufferlen, total / psf->sf.channels) ;
+
+               f2bf_array (psf->u.fbuf, bufferlen) ;
+
+               if (psf->float_endswap == SF_TRUE)
+                       endswap_int_array (psf->u.ibuf, bufferlen) ;
+
+               writecount = psf_fwrite (psf->u.fbuf, sizeof (float), bufferlen, psf) ;
+               total += writecount ;
+               if (writecount < bufferlen)
+                       break ;
+               len -= writecount ;
+               } ;
+
+       return total ;
+} /* replace_write_s2f */
+
+static sf_count_t
+replace_write_i2f      (SF_PRIVATE *psf, const int *ptr, sf_count_t len)
+{      int                     bufferlen, writecount ;
+       sf_count_t      total = 0 ;
+
+       bufferlen = ARRAY_LEN (psf->u.fbuf) ;
+
+       while (len > 0)
+       {       if (len < bufferlen)
+                       bufferlen = (int) len ;
+               i2f_array (ptr + total, psf->u.fbuf, bufferlen) ;
+
+               if (psf->peak_info)
+                       float32_peak_update (psf, psf->u.fbuf, bufferlen, total / psf->sf.channels) ;
+
+               f2bf_array (psf->u.fbuf, bufferlen) ;
+
+               if (psf->float_endswap == SF_TRUE)
+                       endswap_int_array (psf->u.ibuf, bufferlen) ;
+
+               writecount = psf_fwrite (psf->u.fbuf, sizeof (float), bufferlen, psf) ;
+               total += writecount ;
+               if (writecount < bufferlen)
+                       break ;
+               len -= writecount ;
+               } ;
+
+       return total ;
+} /* replace_write_i2f */
+
+static sf_count_t
+replace_write_f        (SF_PRIVATE *psf, const float *ptr, sf_count_t len)
+{      int                     bufferlen, writecount ;
+       sf_count_t      total = 0 ;
+
+       /* FIX THIS */
+       if (psf->peak_info)
+               float32_peak_update (psf, ptr, len, 0) ;
+
+       bufferlen = ARRAY_LEN (psf->u.fbuf) ;
+
+       while (len > 0)
+       {       if (len < bufferlen)
+                       bufferlen = (int) len ;
+
+               memcpy (psf->u.fbuf, ptr + total, bufferlen * sizeof (float)) ;
+
+               f2bf_array (psf->u.fbuf, bufferlen) ;
+
+               if (psf->float_endswap == SF_TRUE)
+                       endswap_int_array (psf->u.ibuf, bufferlen) ;
+
+               writecount = psf_fwrite (psf->u.fbuf, sizeof (float) , bufferlen, psf) ;
+               total += writecount ;
+               if (writecount < bufferlen)
+                       break ;
+               len -= writecount ;
+               } ;
+
+       return total ;
+} /* replace_write_f */
+
+static sf_count_t
+replace_write_d2f      (SF_PRIVATE *psf, const double *ptr, sf_count_t len)
+{      int                     bufferlen, writecount ;
+       sf_count_t      total = 0 ;
+
+       bufferlen = ARRAY_LEN (psf->u.fbuf) ;
+
+       while (len > 0)
+       {       if (len < bufferlen)
+                       bufferlen = (int) len ;
+               d2f_array (ptr + total, psf->u.fbuf, bufferlen) ;
+
+               if (psf->peak_info)
+                       float32_peak_update (psf, psf->u.fbuf, bufferlen, total / psf->sf.channels) ;
+
+               f2bf_array (psf->u.fbuf, bufferlen) ;
+
+               if (psf->float_endswap == SF_TRUE)
+                       endswap_int_array (psf->u.ibuf, bufferlen) ;
+
+               writecount = psf_fwrite (psf->u.fbuf, sizeof (float), bufferlen, psf) ;
+               total += writecount ;
+               if (writecount < bufferlen)
+                       break ;
+               len -= writecount ;
+               } ;
+
+       return total ;
+} /* replace_write_d2f */
+
+/*----------------------------------------------------------------------------------------------
+*/
+
+static void
+bf2f_array (float *buffer, int count)
+{      while (--count >= 0)
+       {       buffer [count] = FLOAT32_READ ((unsigned char *) (buffer + count)) ;
+               } ;
+} /* bf2f_array */
+
+static void
+f2bf_array (float *buffer, int count)
+{      while (--count >= 0)
+       {       FLOAT32_WRITE (buffer [count], (unsigned char*) (buffer + count)) ;
+               } ;
+} /* f2bf_array */
+
+/*
+** Do not edit or modify anything in this comment block.
+** The arch-tag line is a file identity tag for the GNU Arch
+** revision control system.
+**
+** arch-tag: b6c34917-488c-4145-9648-f4371fc4c889
+*/
diff --git a/libs/libsndfile/src/float_cast.h b/libs/libsndfile/src/float_cast.h
new file mode 100644 (file)
index 0000000..099670a
--- /dev/null
@@ -0,0 +1,262 @@
+/*
+** Copyright (C) 2001-2004 Erik de Castro Lopo <erikd@mega-nerd.com>
+**
+** This program is free software; you can redistribute it and/or modify
+** it under the terms of the GNU Lesser General Public License as published by
+** the Free Software Foundation; either version 2.1 of the License, or
+** (at your option) any later version.
+**
+** This program is distributed in the hope that it will be useful,
+** but WITHOUT ANY WARRANTY; without even the implied warranty of
+** MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+** GNU Lesser General Public License for more details.
+**
+** You should have received a copy of the GNU Lesser General Public License
+** along with this program; if not, write to the Free Software
+** Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA.
+*/
+
+/* Version 1.4 */
+
+#ifndef FLOAT_CAST_HEADER
+#define FLOAT_CAST_HEADER
+
+/*============================================================================
+**     On Intel Pentium processors (especially PIII and probably P4), converting
+**     from float to int is very slow. To meet the C specs, the code produced by
+**     most C compilers targeting Pentium needs to change the FPU rounding mode
+**     before the float to int conversion is performed.
+**
+**     Changing the FPU rounding mode causes the FPU pipeline to be flushed. It
+**     is this flushing of the pipeline which is so slow.
+**
+**     Fortunately the ISO C99 specifications define the functions lrint, lrintf,
+**     llrint and llrintf which fix this problem as a side effect.
+**
+**     On Unix-like systems, the configure process should have detected the
+**     presence of these functions. If they weren't found we have to replace them
+**     here with a standard C cast.
+*/
+
+/*
+**     The C99 prototypes for lrint and lrintf are as follows:
+**
+**             long int lrintf (float x) ;
+**             long int lrint  (double x) ;
+*/
+
+#include "sfconfig.h"
+
+/*
+**     The presence of the required functions are detected during the configure
+**     process and the values HAVE_LRINT and HAVE_LRINTF are set accordingly in
+**     the sfconfig.h file.
+*/
+
+#define                HAVE_LRINT_REPLACEMENT  0
+
+#if (HAVE_LRINT && HAVE_LRINTF)
+
+       /*
+       **      These defines enable functionality introduced with the 1999 ISO C
+       **      standard. They must be defined before the inclusion of math.h to
+       **      engage them. If optimisation is enabled, these functions will be
+       **      inlined. With optimisation switched off, you have to link in the
+       **      maths library using -lm.
+       */
+
+       #define _ISOC9X_SOURCE  1
+       #define _ISOC99_SOURCE  1
+
+       #define __USE_ISOC9X    1
+       #define __USE_ISOC99    1
+
+       #include        <math.h>
+
+#elif (defined (__CYGWIN__))
+
+       #include        <math.h>
+
+       #undef          HAVE_LRINT_REPLACEMENT
+       #define         HAVE_LRINT_REPLACEMENT  1
+
+       #undef  lrint
+       #undef  lrintf
+
+       #define lrint   double2int
+       #define lrintf  float2int
+
+       /*
+       **      The native CYGWIN lrint and lrintf functions are buggy:
+       **              http://sourceware.org/ml/cygwin/2005-06/msg00153.html
+       **              http://sourceware.org/ml/cygwin/2005-09/msg00047.html
+       **      and slow.
+       **      These functions (pulled from the Public Domain MinGW math.h header)
+       **      replace the native versions.
+       */
+
+       static inline long double2int (double in)
+       {       long retval ;
+
+               __asm__ __volatile__
+               (       "fistpl %0"
+                       : "=m" (retval)
+                       : "t" (in)
+                       : "st"
+                       ) ;
+
+               return retval ;
+       } /* double2int */
+
+       static inline long float2int (float in)
+       {       long retval ;
+
+               __asm__ __volatile__
+               (       "fistpl %0"
+                       : "=m" (retval)
+                       : "t" (in)
+                       : "st"
+                       ) ;
+
+               return retval ;
+       } /* float2int */
+
+#elif (defined (WIN32) || defined (_WIN32))
+
+       #undef          HAVE_LRINT_REPLACEMENT
+       #define         HAVE_LRINT_REPLACEMENT  1
+
+       #include        <math.h>
+
+       /*
+       **      Win32 doesn't seem to have these functions.
+       **      Therefore implement inline versions of these functions here.
+       */
+
+       __inline long int
+       lrint (double flt)
+       {       int intgr ;
+
+               _asm
+               {       fld flt
+                       fistp intgr
+                       } ;
+
+               return intgr ;
+       }
+
+       __inline long int
+       lrintf (float flt)
+       {       int intgr ;
+
+               _asm
+               {       fld flt
+                       fistp intgr
+                       } ;
+
+               return intgr ;
+       }
+
+#elif (defined (__MWERKS__) && defined (macintosh))
+
+       /* This MacOS 9 solution was provided by Stephane Letz */
+
+       #undef          HAVE_LRINT_REPLACEMENT
+       #define         HAVE_LRINT_REPLACEMENT  1
+       #include        <math.h>
+
+       #undef  lrint
+       #undef  lrintf
+
+       #define lrint   double2int
+       #define lrintf  float2int
+
+       inline int
+       float2int (register float in)
+       {       long res [2] ;
+
+               asm
+               {       fctiw   in, in
+                       stfd     in, res
+               }
+               return res [1] ;
+       } /* float2int */
+
+       inline int
+       double2int (register double in)
+       {       long res [2] ;
+
+               asm
+               {       fctiw   in, in
+                       stfd     in, res
+               }
+               return res [1] ;
+       } /* double2int */
+
+#elif (defined (__MACH__) && defined (__APPLE__))
+
+       /* For Apple MacOSX. */
+
+       #undef          HAVE_LRINT_REPLACEMENT
+       #define         HAVE_LRINT_REPLACEMENT  1
+       #include        <math.h>
+
+       #undef lrint
+       #undef lrintf
+
+       #define lrint   double2int
+       #define lrintf  float2int
+
+       inline static long
+       float2int (register float in)
+       {       int res [2] ;
+
+               __asm__ __volatile__
+               (       "fctiw  %1, %1\n\t"
+                       "stfd   %1, %0"
+                       : "=m" (res)    /* Output */
+                       : "f" (in)              /* Input */
+                       : "memory"
+                       ) ;
+
+               return res [1] ;
+       } /* lrintf */
+
+       inline static long
+       double2int (register double in)
+       {       int res [2] ;
+
+               __asm__ __volatile__
+               (       "fctiw  %1, %1\n\t"
+                       "stfd   %1, %0"
+                       : "=m" (res)    /* Output */
+                       : "f" (in)              /* Input */
+                       : "memory"
+                       ) ;
+
+               return res [1] ;
+       } /* lrint */
+
+#else
+       #ifndef __sgi
+       #warning "Don't have the functions lrint() and lrintf()."
+       #warning "Replacing these functions with a standard C cast."
+       #endif
+
+       #include        <math.h>
+
+       #define lrint(dbl)              ((long) (dbl))
+       #define lrintf(flt)             ((long) (flt))
+
+#endif
+
+
+#endif /* FLOAT_CAST_HEADER */
+
+/*
+** Do not edit or modify anything in this comment block.
+** The arch-tag line is a file identity tag for the GNU Arch
+** revision control system.
+**
+** arch-tag: 42db1693-ff61-4051-bac1-e4d24c4e30b7
+*/
diff --git a/libs/libsndfile/src/g72x.c b/libs/libsndfile/src/g72x.c
new file mode 100644 (file)
index 0000000..dbbf9da
--- /dev/null
@@ -0,0 +1,615 @@
+/*
+** Copyright (C) 1999-2005 Erik de Castro Lopo <erikd@mega-nerd.com>
+**
+** This program is free software; you can redistribute it and/or modify
+** it under the terms of the GNU Lesser General Public License as published by
+** the Free Software Foundation; either version 2.1 of the License, or
+** (at your option) any later version.
+**
+** This program is distributed in the hope that it will be useful,
+** but WITHOUT ANY WARRANTY; without even the implied warranty of
+** MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+** GNU Lesser General Public License for more details.
+**
+** You should have received a copy of the GNU Lesser General Public License
+** along with this program; if not, write to the Free Software
+** Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA.
+*/
+
+#include "sfconfig.h"
+
+#include <stdio.h>
+#include <stdlib.h>
+#include <string.h>
+
+#include "sndfile.h"
+#include "sfendian.h"
+#include "float_cast.h"
+#include "common.h"
+#include "G72x/g72x.h"
+
+/* This struct is private to the G72x code. */
+struct g72x_state ;
+typedef struct g72x_state G72x_STATE ;
+
+typedef struct
+{      /* Private data. Don't mess with it. */
+       struct g72x_state * private ;
+
+       /* Public data. Read only. */
+       int                             blocksize, samplesperblock, bytesperblock ;
+
+       /* Public data. Read and write. */
+       int                             blocks_total, block_curr, sample_curr ;
+       unsigned char   block   [G72x_BLOCK_SIZE] ;
+       short                   samples [G72x_BLOCK_SIZE] ;
+} G72x_PRIVATE ;
+
+static int     psf_g72x_decode_block (SF_PRIVATE *psf, G72x_PRIVATE *pg72x) ;
+static int     psf_g72x_encode_block (SF_PRIVATE *psf, G72x_PRIVATE *pg72x) ;
+
+static sf_count_t      g72x_read_s (SF_PRIVATE *psf, short *ptr, sf_count_t len) ;
+static sf_count_t      g72x_read_i (SF_PRIVATE *psf, int *ptr, sf_count_t len) ;
+static sf_count_t      g72x_read_f (SF_PRIVATE *psf, float *ptr, sf_count_t len) ;
+static sf_count_t      g72x_read_d (SF_PRIVATE *psf, double *ptr, sf_count_t len) ;
+
+static sf_count_t      g72x_write_s (SF_PRIVATE *psf, const short *ptr, sf_count_t len) ;
+static sf_count_t      g72x_write_i (SF_PRIVATE *psf, const int *ptr, sf_count_t len) ;
+static sf_count_t      g72x_write_f (SF_PRIVATE *psf, const float *ptr, sf_count_t len) ;
+static sf_count_t      g72x_write_d (SF_PRIVATE *psf, const double *ptr, sf_count_t len) ;
+
+static sf_count_t g72x_seek (SF_PRIVATE *psf, int mode, sf_count_t offset) ;
+
+static int     g72x_close (SF_PRIVATE *psf) ;
+
+
+/*============================================================================================
+** WAV G721 Reader initialisation function.
+*/
+
+int
+g72x_init (SF_PRIVATE * psf)
+{      G72x_PRIVATE    *pg72x ;
+       int     bitspersample, bytesperblock, codec ;
+
+       if (psf->fdata != NULL)
+       {       psf_log_printf (psf, "*** psf->fdata is not NULL.\n") ;
+               return SFE_INTERNAL ;
+               } ;
+
+       psf->sf.seekable = SF_FALSE ;
+
+       if (psf->sf.channels != 1)
+               return SFE_G72X_NOT_MONO ;
+
+       if ((pg72x = calloc (1, sizeof (G72x_PRIVATE))) == NULL)
+               return SFE_MALLOC_FAILED ;
+
+       psf->fdata = (void*) pg72x ;
+
+       pg72x->block_curr = 0 ;
+       pg72x->sample_curr = 0 ;
+
+       switch (psf->sf.format & SF_FORMAT_SUBMASK)
+       {       case SF_FORMAT_G721_32 :
+                               codec = G721_32_BITS_PER_SAMPLE ;
+                               bytesperblock = G721_32_BYTES_PER_BLOCK ;
+                               bitspersample = G721_32_BITS_PER_SAMPLE ;
+                               break ;
+
+               case SF_FORMAT_G723_24:
+                               codec = G723_24_BITS_PER_SAMPLE ;
+                               bytesperblock = G723_24_BYTES_PER_BLOCK ;
+                               bitspersample = G723_24_BITS_PER_SAMPLE ;
+                               break ;
+
+               case SF_FORMAT_G723_40:
+                               codec = G723_40_BITS_PER_SAMPLE ;
+                               bytesperblock = G723_40_BYTES_PER_BLOCK ;
+                               bitspersample = G723_40_BITS_PER_SAMPLE ;
+                               break ;
+
+               default : return SFE_UNIMPLEMENTED ;
+               } ;
+
+       psf->blockwidth = psf->bytewidth = 1 ;
+
+       psf->filelength = psf_get_filelen (psf) ;
+       if (psf->filelength < psf->dataoffset)
+               psf->filelength = psf->dataoffset ;
+
+       psf->datalength = psf->filelength - psf->dataoffset ;
+       if (psf->dataend > 0)
+               psf->datalength -= psf->filelength - psf->dataend ;
+
+       if (psf->mode == SFM_READ)
+       {       pg72x->private = g72x_reader_init (codec, &(pg72x->blocksize), &(pg72x->samplesperblock)) ;
+               if (pg72x->private == NULL)
+                       return SFE_MALLOC_FAILED ;
+
+               pg72x->bytesperblock = bytesperblock ;
+
+               psf->read_short         = g72x_read_s ;
+               psf->read_int           = g72x_read_i ;
+               psf->read_float         = g72x_read_f ;
+               psf->read_double        = g72x_read_d ;
+
+               psf->seek = g72x_seek ;
+
+               if (psf->datalength % pg72x->blocksize)
+               {       psf_log_printf (psf, "*** Odd psf->datalength (%D) should be a multiple of %d\n", psf->datalength, pg72x->blocksize) ;
+                       pg72x->blocks_total = (psf->datalength / pg72x->blocksize) + 1 ;
+                       }
+               else
+                       pg72x->blocks_total = psf->datalength / pg72x->blocksize ;
+
+               psf->sf.frames = pg72x->blocks_total * pg72x->samplesperblock ;
+
+               psf_g72x_decode_block (psf, pg72x) ;
+               }
+       else if (psf->mode == SFM_WRITE)
+       {       pg72x->private = g72x_writer_init (codec, &(pg72x->blocksize), &(pg72x->samplesperblock)) ;
+               if (pg72x->private == NULL)
+                       return SFE_MALLOC_FAILED ;
+
+               pg72x->bytesperblock = bytesperblock ;
+
+               psf->write_short        = g72x_write_s ;
+               psf->write_int          = g72x_write_i ;
+               psf->write_float        = g72x_write_f ;
+               psf->write_double       = g72x_write_d ;
+
+               if (psf->datalength % pg72x->blocksize)
+                       pg72x->blocks_total = (psf->datalength / pg72x->blocksize) + 1 ;
+               else
+                       pg72x->blocks_total = psf->datalength / pg72x->blocksize ;
+
+               if (psf->datalength > 0)
+                       psf->sf.frames = (8 * psf->datalength) / bitspersample ;
+
+               if ((psf->sf.frames * bitspersample) / 8 != psf->datalength)
+                       psf_log_printf (psf, "*** Warning : weird psf->datalength.\n") ;
+               } ;
+
+       psf->codec_close        = g72x_close ;
+
+       return 0 ;
+} /* g72x_init */
+
+/*============================================================================================
+** G721 Read Functions.
+*/
+
+static int
+psf_g72x_decode_block (SF_PRIVATE *psf, G72x_PRIVATE *pg72x)
+{      int     k ;
+
+       pg72x->block_curr ++ ;
+       pg72x->sample_curr = 0 ;
+
+       if (pg72x->block_curr > pg72x->blocks_total)
+       {       memset (pg72x->samples, 0, G72x_BLOCK_SIZE * sizeof (short)) ;
+               return 1 ;
+               } ;
+
+       if ((k = psf_fread (pg72x->block, 1, pg72x->bytesperblock, psf)) != pg72x->bytesperblock)
+               psf_log_printf (psf, "*** Warning : short read (%d != %d).\n", k, pg72x->bytesperblock) ;
+
+       pg72x->blocksize = k ;
+       g72x_decode_block (pg72x->private, pg72x->block, pg72x->samples) ;
+
+       return 1 ;
+} /* psf_g72x_decode_block */
+
+static int
+g72x_read_block (SF_PRIVATE *psf, G72x_PRIVATE *pg72x, short *ptr, int len)
+{      int     count, total = 0, indx = 0 ;
+
+       while (indx < len)
+       {       if (pg72x->block_curr > pg72x->blocks_total)
+               {       memset (&(ptr [indx]), 0, (len - indx) * sizeof (short)) ;
+                       return total ;
+                       } ;
+
+               if (pg72x->sample_curr >= pg72x->samplesperblock)
+                       psf_g72x_decode_block (psf, pg72x) ;
+
+               count = pg72x->samplesperblock - pg72x->sample_curr ;
+               count = (len - indx > count) ? count : len - indx ;
+
+               memcpy (&(ptr [indx]), &(pg72x->samples [pg72x->sample_curr]), count * sizeof (short)) ;
+               indx += count ;
+               pg72x->sample_curr += count ;
+               total = indx ;
+               } ;
+
+       return total ;
+} /* g72x_read_block */
+
+static sf_count_t
+g72x_read_s (SF_PRIVATE *psf, short *ptr, sf_count_t len)
+{      G72x_PRIVATE    *pg72x ;
+       int                     readcount, count ;
+       sf_count_t      total = 0 ;
+
+       if (psf->fdata == NULL)
+               return 0 ;
+       pg72x = (G72x_PRIVATE*) psf->fdata ;
+
+       while (len > 0)
+       {       readcount = (len > 0x10000000) ? 0x10000000 : (int) len ;
+
+               count = g72x_read_block (psf, pg72x, ptr, readcount) ;
+
+               total += count ;
+               len -= count ;
+
+               if (count != readcount)
+                       break ;
+               } ;
+
+       return total ;
+} /* g72x_read_s */
+
+static sf_count_t
+g72x_read_i (SF_PRIVATE *psf, int *ptr, sf_count_t len)
+{      G72x_PRIVATE *pg72x ;
+       short           *sptr ;
+       int                     k, bufferlen, readcount = 0, count ;
+       sf_count_t      total = 0 ;
+
+       if (psf->fdata == NULL)
+               return 0 ;
+       pg72x = (G72x_PRIVATE*) psf->fdata ;
+
+       sptr = psf->u.sbuf ;
+       bufferlen = SF_BUFFER_LEN / sizeof (short) ;
+       while (len > 0)
+       {       readcount = (len >= bufferlen) ? bufferlen : len ;
+               count = g72x_read_block (psf, pg72x, sptr, readcount) ;
+
+               for (k = 0 ; k < readcount ; k++)
+                       ptr [total + k] = sptr [k] << 16 ;
+
+               total += count ;
+               len -= readcount ;
+               if (count != readcount)
+                       break ;
+               } ;
+
+       return total ;
+} /* g72x_read_i */
+
+static sf_count_t
+g72x_read_f (SF_PRIVATE *psf, float *ptr, sf_count_t len)
+{      G72x_PRIVATE *pg72x ;
+       short           *sptr ;
+       int                     k, bufferlen, readcount = 0, count ;
+       sf_count_t      total = 0 ;
+       float           normfact ;
+
+       if (psf->fdata == NULL)
+               return 0 ;
+       pg72x = (G72x_PRIVATE*) psf->fdata ;
+
+       normfact = (psf->norm_float == SF_TRUE) ? 1.0 / ((float) 0x8000) : 1.0 ;
+
+       sptr = psf->u.sbuf ;
+       bufferlen = SF_BUFFER_LEN / sizeof (short) ;
+       while (len > 0)
+       {       readcount = (len >= bufferlen) ? bufferlen : len ;
+               count = g72x_read_block (psf, pg72x, sptr, readcount) ;
+               for (k = 0 ; k < readcount ; k++)
+                       ptr [total + k] = normfact * sptr [k] ;
+
+               total += count ;
+               len -= readcount ;
+               if (count != readcount)
+                       break ;
+               } ;
+
+       return total ;
+} /* g72x_read_f */
+
+static sf_count_t
+g72x_read_d (SF_PRIVATE *psf, double *ptr, sf_count_t len)
+{      G72x_PRIVATE *pg72x ;
+       short           *sptr ;
+       int                     k, bufferlen, readcount = 0, count ;
+       sf_count_t      total = 0 ;
+       double          normfact ;
+
+       if (psf->fdata == NULL)
+               return 0 ;
+       pg72x = (G72x_PRIVATE*) psf->fdata ;
+
+       normfact = (psf->norm_double == SF_TRUE) ? 1.0 / ((double) 0x8000) : 1.0 ;
+
+       sptr = psf->u.sbuf ;
+       bufferlen = SF_BUFFER_LEN / sizeof (short) ;
+       while (len > 0)
+       {       readcount = (len >= bufferlen) ? bufferlen : len ;
+               count = g72x_read_block (psf, pg72x, sptr, readcount) ;
+               for (k = 0 ; k < readcount ; k++)
+                       ptr [total + k] = normfact * (double) (sptr [k]) ;
+
+               total += count ;
+               len -= readcount ;
+               if (count != readcount)
+                       break ;
+               } ;
+
+       return total ;
+} /* g72x_read_d */
+
+static sf_count_t
+g72x_seek (SF_PRIVATE *psf, int mode, sf_count_t offset)
+{
+       /* Prevent compiler warnings. */
+       mode ++ ;
+       offset ++ ;
+
+       psf_log_printf (psf, "seek unsupported\n") ;
+
+       /*      No simple solution. To do properly, would need to seek
+       **      to start of file and decode everything up to seek position.
+       **      Maybe implement SEEK_SET to 0 only?
+       */
+       return 0 ;
+
+/*
+**             G72x_PRIVATE    *pg72x ;
+**             int                     newblock, newsample, sample_curr ;
+**
+**             if (psf->fdata == NULL)
+**                     return 0 ;
+**             pg72x = (G72x_PRIVATE*) psf->fdata ;
+**
+**             if (! (psf->datalength && psf->dataoffset))
+**             {       psf->error = SFE_BAD_SEEK ;
+**                     return  PSF_SEEK_ERROR ;
+**                     } ;
+**
+**             sample_curr = (8 * psf->datalength) / G721_32_BITS_PER_SAMPLE ;
+**
+**             switch (whence)
+**             {       case SEEK_SET :
+**                                     if (offset < 0 || offset > sample_curr)
+**                                     {       psf->error = SFE_BAD_SEEK ;
+**                                             return  PSF_SEEK_ERROR ;
+**                                             } ;
+**                                     newblock  = offset / pg72x->samplesperblock ;
+**                                     newsample = offset % pg72x->samplesperblock ;
+**                                     break ;
+**
+**                     case SEEK_CUR :
+**                                     if (psf->current + offset < 0 || psf->current + offset > sample_curr)
+**                                     {       psf->error = SFE_BAD_SEEK ;
+**                                             return  PSF_SEEK_ERROR ;
+**                                             } ;
+**                                     newblock  = (8 * (psf->current + offset)) / pg72x->samplesperblock ;
+**                                     newsample = (8 * (psf->current + offset)) % pg72x->samplesperblock ;
+**                                     break ;
+**
+**                     case SEEK_END :
+**                                     if (offset > 0 || sample_curr + offset < 0)
+**                                     {       psf->error = SFE_BAD_SEEK ;
+**                                             return  PSF_SEEK_ERROR ;
+**                                             } ;
+**                                     newblock  = (sample_curr + offset) / pg72x->samplesperblock ;
+**                                     newsample = (sample_curr + offset) % pg72x->samplesperblock ;
+**                                     break ;
+**
+**                     default :
+**                                     psf->error = SFE_BAD_SEEK ;
+**                                     return  PSF_SEEK_ERROR ;
+**                     } ;
+**
+**             if (psf->mode == SFM_READ)
+**             {       psf_fseek (psf, psf->dataoffset + newblock * pg72x->blocksize, SEEK_SET) ;
+**                     pg72x->block_curr  = newblock ;
+**                     psf_g72x_decode_block (psf, pg72x) ;
+**                     pg72x->sample_curr = newsample ;
+**                     }
+**             else
+**             {       /+* What to do about write??? *+/
+**                     psf->error = SFE_BAD_SEEK ;
+**                     return  PSF_SEEK_ERROR ;
+**                     } ;
+**
+**             psf->current = newblock * pg72x->samplesperblock + newsample ;
+**             return psf->current ;
+**
+*/
+} /* g72x_seek */
+
+/*==========================================================================================
+** G72x Write Functions.
+*/
+
+static int
+psf_g72x_encode_block (SF_PRIVATE *psf, G72x_PRIVATE *pg72x)
+{      int k ;
+
+       /* Encode the samples. */
+       g72x_encode_block (pg72x->private, pg72x->samples, pg72x->block) ;
+
+       /* Write the block to disk. */
+       if ((k = psf_fwrite (pg72x->block, 1, pg72x->blocksize, psf)) != pg72x->blocksize)
+               psf_log_printf (psf, "*** Warning : short write (%d != %d).\n", k, pg72x->blocksize) ;
+
+       pg72x->sample_curr = 0 ;
+       pg72x->block_curr ++ ;
+
+       /* Set samples to zero for next block. */
+       memset (pg72x->samples, 0, G72x_BLOCK_SIZE * sizeof (short)) ;
+
+       return 1 ;
+} /* psf_g72x_encode_block */
+
+static int
+g72x_write_block (SF_PRIVATE *psf, G72x_PRIVATE *pg72x, const short *ptr, int len)
+{      int     count, total = 0, indx = 0 ;
+
+       while (indx < len)
+       {       count = pg72x->samplesperblock - pg72x->sample_curr ;
+
+               if (count > len - indx)
+                       count = len - indx ;
+
+               memcpy (&(pg72x->samples [pg72x->sample_curr]), &(ptr [indx]), count * sizeof (short)) ;
+               indx += count ;
+               pg72x->sample_curr += count ;
+               total = indx ;
+
+               if (pg72x->sample_curr >= pg72x->samplesperblock)
+                       psf_g72x_encode_block (psf, pg72x) ;
+               } ;
+
+       return total ;
+} /* g72x_write_block */
+
+static sf_count_t
+g72x_write_s (SF_PRIVATE *psf, const short *ptr, sf_count_t len)
+{      G72x_PRIVATE    *pg72x ;
+       int                     writecount, count ;
+       sf_count_t      total = 0 ;
+
+       if (psf->fdata == NULL)
+               return 0 ;
+       pg72x = (G72x_PRIVATE*) psf->fdata ;
+
+       while (len > 0)
+       {       writecount = (len > 0x10000000) ? 0x10000000 : (int) len ;
+
+               count = g72x_write_block (psf, pg72x, ptr, writecount) ;
+
+               total += count ;
+               len -= count ;
+               if (count != writecount)
+                       break ;
+               } ;
+
+       return total ;
+} /* g72x_write_s */
+
+static sf_count_t
+g72x_write_i (SF_PRIVATE *psf, const int *ptr, sf_count_t len)
+{      G72x_PRIVATE *pg72x ;
+       short           *sptr ;
+       int                     k, bufferlen, writecount = 0, count ;
+       sf_count_t      total = 0 ;
+
+       if (psf->fdata == NULL)
+               return 0 ;
+       pg72x = (G72x_PRIVATE*) psf->fdata ;
+
+       sptr = psf->u.sbuf ;
+       bufferlen = ((SF_BUFFER_LEN / psf->blockwidth) * psf->blockwidth) / sizeof (short) ;
+       while (len > 0)
+       {       writecount = (len >= bufferlen) ? bufferlen : len ;
+               for (k = 0 ; k < writecount ; k++)
+                       sptr [k] = ptr [total + k] >> 16 ;
+               count = g72x_write_block (psf, pg72x, sptr, writecount) ;
+
+               total += count ;
+               len -= writecount ;
+               if (count != writecount)
+                       break ;
+               } ;
+       return total ;
+} /* g72x_write_i */
+
+static sf_count_t
+g72x_write_f (SF_PRIVATE *psf, const float *ptr, sf_count_t len)
+{      G72x_PRIVATE *pg72x ;
+       short           *sptr ;
+       int                     k, bufferlen, writecount = 0, count ;
+       sf_count_t      total = 0 ;
+       float           normfact ;
+
+       if (psf->fdata == NULL)
+               return 0 ;
+       pg72x = (G72x_PRIVATE*) psf->fdata ;
+
+       normfact = (psf->norm_float == SF_TRUE) ? (1.0 * 0x8000) : 1.0 ;
+
+       sptr = psf->u.sbuf ;
+       bufferlen = ((SF_BUFFER_LEN / psf->blockwidth) * psf->blockwidth) / sizeof (short) ;
+       while (len > 0)
+       {       writecount = (len >= bufferlen) ? bufferlen : len ;
+               for (k = 0 ; k < writecount ; k++)
+                       sptr [k] = lrintf (normfact * ptr [total + k]) ;
+               count = g72x_write_block (psf, pg72x, sptr, writecount) ;
+
+               total += count ;
+               len -= writecount ;
+               if (count != writecount)
+                       break ;
+               } ;
+
+       return total ;
+} /* g72x_write_f */
+
+static sf_count_t
+g72x_write_d (SF_PRIVATE *psf, const double *ptr, sf_count_t len)
+{      G72x_PRIVATE *pg72x ;
+       short           *sptr ;
+       int                     k, bufferlen, writecount = 0, count ;
+       sf_count_t      total = 0 ;
+       double          normfact ;
+
+       if (psf->fdata == NULL)
+               return 0 ;
+       pg72x = (G72x_PRIVATE*) psf->fdata ;
+
+       normfact = (psf->norm_double == SF_TRUE) ? (1.0 * 0x8000) : 1.0 ;
+
+       sptr = psf->u.sbuf ;
+       bufferlen = ((SF_BUFFER_LEN / psf->blockwidth) * psf->blockwidth) / sizeof (short) ;
+       while (len > 0)
+       {       writecount = (len >= bufferlen) ? bufferlen : len ;
+               for (k = 0 ; k < writecount ; k++)
+                       sptr [k] = lrint (normfact * ptr [total + k]) ;
+               count = g72x_write_block (psf, pg72x, sptr, writecount) ;
+
+               total += count ;
+               len -= writecount ;
+               if (count != writecount)
+                       break ;
+               } ;
+
+       return total ;
+} /* g72x_write_d */
+
+static int
+g72x_close (SF_PRIVATE *psf)
+{      G72x_PRIVATE *pg72x ;
+
+       pg72x = (G72x_PRIVATE*) psf->fdata ;
+
+       if (psf->mode == SFM_WRITE)
+       {       /*      If a block has been partially assembled, write it out
+               **      as the final block.
+               */
+
+               if (pg72x->sample_curr && pg72x->sample_curr < G72x_BLOCK_SIZE)
+                       psf_g72x_encode_block (psf, pg72x) ;
+
+               if (psf->write_header)
+                       psf->write_header (psf, SF_FALSE) ;
+               } ;
+
+       /* Only free the pointer allocated by g72x_(reader|writer)_init. */
+       free (pg72x->private) ;
+
+       return 0 ;
+} /* g72x_close */
+
+/*
+** Do not edit or modify anything in this comment block.
+** The arch-tag line is a file identity tag for the GNU Arch
+** revision control system.
+**
+** arch-tag: 3cc5439e-7247-486b-b2e6-11a4affa5744
+*/
diff --git a/libs/libsndfile/src/gsm610.c b/libs/libsndfile/src/gsm610.c
new file mode 100644 (file)
index 0000000..db954cc
--- /dev/null
@@ -0,0 +1,628 @@
+/*
+** Copyright (C) 1999-2006 Erik de Castro Lopo <erikd@mega-nerd.com>
+**
+** This program is free software; you can redistribute it and/or modify
+** it under the terms of the GNU Lesser General Public License as published by
+** the Free Software Foundation; either version 2.1 of the License, or
+** (at your option) any later version.
+**
+** This program is distributed in the hope that it will be useful,
+** but WITHOUT ANY WARRANTY; without even the implied warranty of
+** MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+** GNU Lesser General Public License for more details.
+**
+** You should have received a copy of the GNU Lesser General Public License
+** along with this program; if not, write to the Free Software
+** Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA.
+*/
+
+#include "sfconfig.h"
+
+#include <stdio.h>
+#include <stdlib.h>
+#include <string.h>
+
+#include "sndfile.h"
+#include "sfendian.h"
+#include "float_cast.h"
+#include "common.h"
+#include "wav_w64.h"
+#include "GSM610/gsm.h"
+
+#define        GSM610_BLOCKSIZE                33
+#define        GSM610_SAMPLES                  160
+
+typedef struct gsm610_tag
+{      int                             blocks ;
+       int                             blockcount, samplecount ;
+       int                             samplesperblock, blocksize ;
+
+       int                             (*decode_block) (SF_PRIVATE *psf, struct gsm610_tag *pgsm610) ;
+       int                             (*encode_block) (SF_PRIVATE *psf, struct gsm610_tag *pgsm610) ;
+
+       short                   samples [WAV_W64_GSM610_SAMPLES] ;
+       unsigned char   block [WAV_W64_GSM610_BLOCKSIZE] ;
+
+       /* Damn I hate typedef-ed pointers; yes, gsm is a pointer type. */
+       gsm                             gsm_data ;
+} GSM610_PRIVATE ;
+
+static sf_count_t      gsm610_read_s   (SF_PRIVATE *psf, short *ptr, sf_count_t len) ;
+static sf_count_t      gsm610_read_i   (SF_PRIVATE *psf, int *ptr, sf_count_t len) ;
+static sf_count_t      gsm610_read_f   (SF_PRIVATE *psf, float *ptr, sf_count_t len) ;
+static sf_count_t      gsm610_read_d   (SF_PRIVATE *psf, double *ptr, sf_count_t len) ;
+
+static sf_count_t      gsm610_write_s  (SF_PRIVATE *psf, const short *ptr, sf_count_t len) ;
+static sf_count_t      gsm610_write_i  (SF_PRIVATE *psf, const int *ptr, sf_count_t len) ;
+static sf_count_t      gsm610_write_f  (SF_PRIVATE *psf, const float *ptr, sf_count_t len) ;
+static sf_count_t      gsm610_write_d  (SF_PRIVATE *psf, const double *ptr, sf_count_t len) ;
+
+static int gsm610_read_block   (SF_PRIVATE *psf, GSM610_PRIVATE *pgsm610, short *ptr, int len) ;
+static int gsm610_write_block  (SF_PRIVATE *psf, GSM610_PRIVATE *pgsm610, const short *ptr, int len) ;
+
+static int     gsm610_decode_block     (SF_PRIVATE *psf, GSM610_PRIVATE *pgsm610) ;
+static int     gsm610_encode_block     (SF_PRIVATE *psf, GSM610_PRIVATE *pgsm610) ;
+
+static int     gsm610_wav_decode_block (SF_PRIVATE *psf, GSM610_PRIVATE *pgsm610) ;
+static int     gsm610_wav_encode_block (SF_PRIVATE *psf, GSM610_PRIVATE *pgsm610) ;
+
+static sf_count_t      gsm610_seek     (SF_PRIVATE *psf, int mode, sf_count_t offset) ;
+
+static int     gsm610_close    (SF_PRIVATE *psf) ;
+
+/*============================================================================================
+** WAV GSM610 initialisation function.
+*/
+
+int
+gsm610_init    (SF_PRIVATE *psf)
+{      GSM610_PRIVATE  *pgsm610 ;
+       int             true_flag = 1 ;
+
+       if (psf->fdata != NULL)
+       {       psf_log_printf (psf, "*** psf->fdata is not NULL.\n") ;
+               return SFE_INTERNAL ;
+               } ;
+
+       if (psf->mode == SFM_RDWR)
+               return SFE_BAD_MODE_RW ;
+
+       psf->sf.seekable = SF_FALSE ;
+
+       if ((pgsm610 = calloc (1, sizeof (GSM610_PRIVATE))) == NULL)
+               return SFE_MALLOC_FAILED ;
+
+       psf->fdata = (void*) pgsm610 ;
+
+       memset (pgsm610, 0, sizeof (GSM610_PRIVATE)) ;
+
+/*============================================================
+
+Need separate gsm_data structs for encode and decode.
+
+============================================================*/
+
+       if ((pgsm610->gsm_data = gsm_create ()) == NULL)
+               return SFE_MALLOC_FAILED ;
+
+       switch (psf->sf.format & SF_FORMAT_TYPEMASK)
+       {       case SF_FORMAT_WAV :
+               case SF_FORMAT_WAVEX :
+               case SF_FORMAT_W64 :
+                       gsm_option (pgsm610->gsm_data, GSM_OPT_WAV49, &true_flag) ;
+
+                       pgsm610->encode_block = gsm610_wav_encode_block ;
+                       pgsm610->decode_block = gsm610_wav_decode_block ;
+
+                       pgsm610->samplesperblock = WAV_W64_GSM610_SAMPLES ;
+                       pgsm610->blocksize = WAV_W64_GSM610_BLOCKSIZE ;
+                       break ;
+
+               case SF_FORMAT_AIFF :
+               case SF_FORMAT_RAW :
+                       pgsm610->encode_block = gsm610_encode_block ;
+                       pgsm610->decode_block = gsm610_decode_block ;
+
+                       pgsm610->samplesperblock = GSM610_SAMPLES ;
+                       pgsm610->blocksize = GSM610_BLOCKSIZE ;
+                       break ;
+
+               default :
+                       return SFE_INTERNAL ;
+                       break ;
+               } ;
+
+       if (psf->mode == SFM_READ)
+       {       if (psf->datalength % pgsm610->blocksize == 0)
+                       pgsm610->blocks = psf->datalength / pgsm610->blocksize ;
+               else if (psf->datalength % pgsm610->blocksize == 1 && pgsm610->blocksize == GSM610_BLOCKSIZE)
+               {       /*
+                       **      Weird AIFF specific case.
+                       **      AIFF chunks must be at an odd offset from the start of file and
+                       **      GSM610_BLOCKSIZE is odd which can result in an odd length SSND
+                       **      chunk. The SSND chunk then gets padded on write which means that
+                       **      when it is read the datalength is too big by 1.
+                       */
+                       pgsm610->blocks = psf->datalength / pgsm610->blocksize ;
+                       }
+               else
+               {       psf_log_printf (psf, "*** Warning : data chunk seems to be truncated.\n") ;
+                       pgsm610->blocks = psf->datalength / pgsm610->blocksize + 1 ;
+                       } ;
+
+               psf->sf.frames = pgsm610->samplesperblock * pgsm610->blocks ;
+
+               pgsm610->decode_block (psf, pgsm610) ;  /* Read first block. */
+
+               psf->read_short         = gsm610_read_s ;
+               psf->read_int           = gsm610_read_i ;
+               psf->read_float         = gsm610_read_f ;
+               psf->read_double        = gsm610_read_d ;
+               } ;
+
+       if (psf->mode == SFM_WRITE)
+       {       pgsm610->blockcount = 0 ;
+               pgsm610->samplecount = 0 ;
+
+               psf->write_short        = gsm610_write_s ;
+               psf->write_int          = gsm610_write_i ;
+               psf->write_float        = gsm610_write_f ;
+               psf->write_double       = gsm610_write_d ;
+               } ;
+
+       psf->codec_close = gsm610_close ;
+
+       psf->seek = gsm610_seek ;
+
+       psf->filelength = psf_get_filelen (psf) ;
+       psf->datalength = psf->filelength - psf->dataoffset ;
+
+       return 0 ;
+} /* gsm610_init */
+
+/*============================================================================================
+** GSM 6.10 Read Functions.
+*/
+
+static int
+gsm610_wav_decode_block        (SF_PRIVATE *psf, GSM610_PRIVATE *pgsm610)
+{      int     k ;
+
+       pgsm610->blockcount ++ ;
+       pgsm610->samplecount = 0 ;
+
+       if (pgsm610->blockcount > pgsm610->blocks)
+       {       memset (pgsm610->samples, 0, WAV_W64_GSM610_SAMPLES * sizeof (short)) ;
+               return 1 ;
+               } ;
+
+       if ((k = psf_fread (pgsm610->block, 1, WAV_W64_GSM610_BLOCKSIZE, psf)) != WAV_W64_GSM610_BLOCKSIZE)
+               psf_log_printf (psf, "*** Warning : short read (%d != %d).\n", k, WAV_W64_GSM610_BLOCKSIZE) ;
+
+       if (gsm_decode (pgsm610->gsm_data, pgsm610->block, pgsm610->samples) < 0)
+       {       psf_log_printf (psf, "Error from gsm_decode() on frame : %d\n", pgsm610->blockcount) ;
+               return 0 ;
+               } ;
+
+       if (gsm_decode (pgsm610->gsm_data, pgsm610->block + (WAV_W64_GSM610_BLOCKSIZE + 1) / 2, pgsm610->samples + WAV_W64_GSM610_SAMPLES / 2) < 0)
+       {       psf_log_printf (psf, "Error from gsm_decode() on frame : %d.5\n", pgsm610->blockcount) ;
+               return 0 ;
+               } ;
+
+       return 1 ;
+} /* gsm610_wav_decode_block */
+
+static int
+gsm610_decode_block    (SF_PRIVATE *psf, GSM610_PRIVATE *pgsm610)
+{      int     k ;
+
+       pgsm610->blockcount ++ ;
+       pgsm610->samplecount = 0 ;
+
+       if (pgsm610->blockcount > pgsm610->blocks)
+       {       memset (pgsm610->samples, 0, GSM610_SAMPLES * sizeof (short)) ;
+               return 1 ;
+               } ;
+
+       if ((k = psf_fread (pgsm610->block, 1, GSM610_BLOCKSIZE, psf)) != GSM610_BLOCKSIZE)
+               psf_log_printf (psf, "*** Warning : short read (%d != %d).\n", k, GSM610_BLOCKSIZE) ;
+
+       if (gsm_decode (pgsm610->gsm_data, pgsm610->block, pgsm610->samples) < 0)
+       {       psf_log_printf (psf, "Error from gsm_decode() on frame : %d\n", pgsm610->blockcount) ;
+               return 0 ;
+               } ;
+
+       return 1 ;
+} /* gsm610_decode_block */
+
+static int
+gsm610_read_block      (SF_PRIVATE *psf, GSM610_PRIVATE *pgsm610, short *ptr, int len)
+{      int     count, total = 0, indx = 0 ;
+
+       while (indx < len)
+       {       if (pgsm610->blockcount >= pgsm610->blocks && pgsm610->samplecount >= pgsm610->samplesperblock)
+               {       memset (&(ptr [indx]), 0, (len - indx) * sizeof (short)) ;
+                       return total ;
+                       } ;
+
+               if (pgsm610->samplecount >= pgsm610->samplesperblock)
+                       pgsm610->decode_block (psf, pgsm610) ;
+
+               count = pgsm610->samplesperblock - pgsm610->samplecount ;
+               count = (len - indx > count) ? count : len - indx ;
+
+               memcpy (&(ptr [indx]), &(pgsm610->samples [pgsm610->samplecount]), count * sizeof (short)) ;
+               indx += count ;
+               pgsm610->samplecount += count ;
+               total = indx ;
+               } ;
+
+       return total ;
+} /* gsm610_read_block */
+
+static sf_count_t
+gsm610_read_s  (SF_PRIVATE *psf, short *ptr, sf_count_t len)
+{      GSM610_PRIVATE  *pgsm610 ;
+       int                     readcount, count ;
+       sf_count_t      total = 0 ;
+
+       if (psf->fdata == NULL)
+               return 0 ;
+       pgsm610 = (GSM610_PRIVATE*) psf->fdata ;
+
+       while (len > 0)
+       {       readcount = (len > 0x10000000) ? 0x1000000 : (int) len ;
+
+               count = gsm610_read_block (psf, pgsm610, ptr, readcount) ;
+
+               total += count ;
+               len -= count ;
+
+               if (count != readcount)
+                       break ;
+               } ;
+
+       return total ;
+} /* gsm610_read_s */
+
+static sf_count_t
+gsm610_read_i  (SF_PRIVATE *psf, int *ptr, sf_count_t len)
+{      GSM610_PRIVATE *pgsm610 ;
+       short           *sptr ;
+       int                     k, bufferlen, readcount = 0, count ;
+       sf_count_t      total = 0 ;
+
+       if (psf->fdata == NULL)
+               return 0 ;
+       pgsm610 = (GSM610_PRIVATE*) psf->fdata ;
+
+       sptr = psf->u.sbuf ;
+       bufferlen = ARRAY_LEN (psf->u.sbuf) ;
+       while (len > 0)
+       {       readcount = (len >= bufferlen) ? bufferlen : len ;
+               count = gsm610_read_block (psf, pgsm610, sptr, readcount) ;
+               for (k = 0 ; k < readcount ; k++)
+                       ptr [total + k] = sptr [k] << 16 ;
+
+               total += count ;
+               len -= readcount ;
+               } ;
+       return total ;
+} /* gsm610_read_i */
+
+static sf_count_t
+gsm610_read_f  (SF_PRIVATE *psf, float *ptr, sf_count_t len)
+{      GSM610_PRIVATE *pgsm610 ;
+       short           *sptr ;
+       int                     k, bufferlen, readcount = 0, count ;
+       sf_count_t      total = 0 ;
+       float           normfact ;
+
+       if (psf->fdata == NULL)
+               return 0 ;
+       pgsm610 = (GSM610_PRIVATE*) psf->fdata ;
+
+       normfact = (psf->norm_float == SF_TRUE) ? 1.0 / ((float) 0x8000) : 1.0 ;
+
+       sptr = psf->u.sbuf ;
+       bufferlen = ARRAY_LEN (psf->u.sbuf) ;
+       while (len > 0)
+       {       readcount = (len >= bufferlen) ? bufferlen : len ;
+               count = gsm610_read_block (psf, pgsm610, sptr, readcount) ;
+               for (k = 0 ; k < readcount ; k++)
+                       ptr [total + k] = normfact * sptr [k] ;
+
+               total += count ;
+               len -= readcount ;
+               } ;
+       return total ;
+} /* gsm610_read_f */
+
+static sf_count_t
+gsm610_read_d  (SF_PRIVATE *psf, double *ptr, sf_count_t len)
+{      GSM610_PRIVATE *pgsm610 ;
+       short           *sptr ;
+       int                     k, bufferlen, readcount = 0, count ;
+       sf_count_t      total = 0 ;
+       double          normfact ;
+
+       normfact = (psf->norm_double == SF_TRUE) ? 1.0 / ((double) 0x8000) : 1.0 ;
+
+       if (psf->fdata == NULL)
+               return 0 ;
+       pgsm610 = (GSM610_PRIVATE*) psf->fdata ;
+
+       sptr = psf->u.sbuf ;
+       bufferlen = ARRAY_LEN (psf->u.sbuf) ;
+       while (len > 0)
+       {       readcount = (len >= bufferlen) ? bufferlen : len ;
+               count = gsm610_read_block (psf, pgsm610, sptr, readcount) ;
+               for (k = 0 ; k < readcount ; k++)
+                       ptr [total + k] = normfact * sptr [k] ;
+
+               total += count ;
+               len -= readcount ;
+               } ;
+       return total ;
+} /* gsm610_read_d */
+
+static sf_count_t
+gsm610_seek    (SF_PRIVATE *psf, int mode, sf_count_t offset)
+{      GSM610_PRIVATE *pgsm610 ;
+       int                     newblock, newsample ;
+
+       mode = mode ;
+
+       if (psf->fdata == NULL)
+               return 0 ;
+       pgsm610 = (GSM610_PRIVATE*) psf->fdata ;
+
+       if (psf->dataoffset < 0)
+       {       psf->error = SFE_BAD_SEEK ;
+               return  PSF_SEEK_ERROR ;
+               } ;
+
+       if (offset == 0)
+       {       int true_flag = 1 ;
+
+               psf_fseek (psf, psf->dataoffset, SEEK_SET) ;
+               pgsm610->blockcount = 0 ;
+
+               gsm_init (pgsm610->gsm_data) ;
+               if ((psf->sf.format & SF_FORMAT_TYPEMASK) == SF_FORMAT_WAV ||
+                               (psf->sf.format & SF_FORMAT_TYPEMASK) == SF_FORMAT_W64)
+                       gsm_option (pgsm610->gsm_data, GSM_OPT_WAV49, &true_flag) ;
+
+               pgsm610->decode_block (psf, pgsm610) ;
+               pgsm610->samplecount = 0 ;
+               return 0 ;
+               } ;
+
+       if (offset < 0 || offset > pgsm610->blocks * pgsm610->samplesperblock)
+       {       psf->error = SFE_BAD_SEEK ;
+               return  PSF_SEEK_ERROR ;
+               } ;
+
+       newblock        = offset / pgsm610->samplesperblock ;
+       newsample       = offset % pgsm610->samplesperblock ;
+
+       if (psf->mode == SFM_READ)
+       {       if (psf->read_current != newblock * pgsm610->samplesperblock + newsample)
+               {       psf_fseek (psf, psf->dataoffset + newblock * pgsm610->samplesperblock, SEEK_SET) ;
+                       pgsm610->blockcount = newblock ;
+                       pgsm610->decode_block (psf, pgsm610) ;
+                       pgsm610->samplecount = newsample ;
+                       } ;
+
+               return newblock * pgsm610->samplesperblock + newsample ;
+               } ;
+
+       /* What to do about write??? */
+       psf->error = SFE_BAD_SEEK ;
+       return  PSF_SEEK_ERROR ;
+} /* gsm610_seek */
+
+/*==========================================================================================
+** GSM 6.10 Write Functions.
+*/
+
+static int
+gsm610_encode_block    (SF_PRIVATE *psf, GSM610_PRIVATE *pgsm610)
+{      int k ;
+
+       /* Encode the samples. */
+       gsm_encode (pgsm610->gsm_data, pgsm610->samples, pgsm610->block) ;
+
+       /* Write the block to disk. */
+       if ((k = psf_fwrite (pgsm610->block, 1, GSM610_BLOCKSIZE, psf)) != GSM610_BLOCKSIZE)
+               psf_log_printf (psf, "*** Warning : short write (%d != %d).\n", k, GSM610_BLOCKSIZE) ;
+
+       pgsm610->samplecount = 0 ;
+       pgsm610->blockcount ++ ;
+
+       /* Set samples to zero for next block. */
+       memset (pgsm610->samples, 0, WAV_W64_GSM610_SAMPLES * sizeof (short)) ;
+
+       return 1 ;
+} /* gsm610_encode_block */
+
+static int
+gsm610_wav_encode_block        (SF_PRIVATE *psf, GSM610_PRIVATE *pgsm610)
+{      int k ;
+
+       /* Encode the samples. */
+       gsm_encode (pgsm610->gsm_data, pgsm610->samples, pgsm610->block) ;
+       gsm_encode (pgsm610->gsm_data, pgsm610->samples+WAV_W64_GSM610_SAMPLES/2, pgsm610->block+WAV_W64_GSM610_BLOCKSIZE/2) ;
+
+       /* Write the block to disk. */
+       if ((k = psf_fwrite (pgsm610->block, 1, WAV_W64_GSM610_BLOCKSIZE, psf)) != WAV_W64_GSM610_BLOCKSIZE)
+               psf_log_printf (psf, "*** Warning : short write (%d != %d).\n", k, WAV_W64_GSM610_BLOCKSIZE) ;
+
+       pgsm610->samplecount = 0 ;
+       pgsm610->blockcount ++ ;
+
+       /* Set samples to zero for next block. */
+       memset (pgsm610->samples, 0, WAV_W64_GSM610_SAMPLES * sizeof (short)) ;
+
+       return 1 ;
+} /* gsm610_wav_encode_block */
+
+static int
+gsm610_write_block     (SF_PRIVATE *psf, GSM610_PRIVATE *pgsm610, const short *ptr, int len)
+{      int             count, total = 0, indx = 0 ;
+
+       while (indx < len)
+       {       count = pgsm610->samplesperblock - pgsm610->samplecount ;
+
+               if (count > len - indx)
+                       count = len - indx ;
+
+               memcpy (&(pgsm610->samples [pgsm610->samplecount]), &(ptr [indx]), count * sizeof (short)) ;
+               indx += count ;
+               pgsm610->samplecount += count ;
+               total = indx ;
+
+               if (pgsm610->samplecount >= pgsm610->samplesperblock)
+                       pgsm610->encode_block (psf, pgsm610) ;
+               } ;
+
+       return total ;
+} /* gsm610_write_block */
+
+static sf_count_t
+gsm610_write_s (SF_PRIVATE *psf, const short *ptr, sf_count_t len)
+{      GSM610_PRIVATE  *pgsm610 ;
+       int                     writecount, count ;
+       sf_count_t      total = 0 ;
+
+       if (psf->fdata == NULL)
+               return 0 ;
+       pgsm610 = (GSM610_PRIVATE*) psf->fdata ;
+
+       while (len > 0)
+       {       writecount = (len > 0x10000000) ? 0x10000000 : (int) len ;
+
+               count = gsm610_write_block (psf, pgsm610, ptr, writecount) ;
+
+               total += count ;
+               len -= count ;
+
+               if (count != writecount)
+                       break ;
+               } ;
+
+       return total ;
+} /* gsm610_write_s */
+
+static sf_count_t
+gsm610_write_i (SF_PRIVATE *psf, const int *ptr, sf_count_t len)
+{      GSM610_PRIVATE *pgsm610 ;
+       short           *sptr ;
+       int                     k, bufferlen, writecount = 0, count ;
+       sf_count_t      total = 0 ;
+
+       if (psf->fdata == NULL)
+               return 0 ;
+       pgsm610 = (GSM610_PRIVATE*) psf->fdata ;
+
+       sptr = psf->u.sbuf ;
+       bufferlen = ARRAY_LEN (psf->u.sbuf) ;
+       while (len > 0)
+       {       writecount = (len >= bufferlen) ? bufferlen : len ;
+               for (k = 0 ; k < writecount ; k++)
+                       sptr [k] = ptr [total + k] >> 16 ;
+               count = gsm610_write_block (psf, pgsm610, sptr, writecount) ;
+
+               total += count ;
+               len -= writecount ;
+               } ;
+       return total ;
+} /* gsm610_write_i */
+
+static sf_count_t
+gsm610_write_f (SF_PRIVATE *psf, const float *ptr, sf_count_t len)
+{      GSM610_PRIVATE *pgsm610 ;
+       short           *sptr ;
+       int                     k, bufferlen, writecount = 0, count ;
+       sf_count_t      total = 0 ;
+       float           normfact ;
+
+       if (psf->fdata == NULL)
+               return 0 ;
+       pgsm610 = (GSM610_PRIVATE*) psf->fdata ;
+
+       normfact = (psf->norm_float == SF_TRUE) ? (1.0 * 0x7FFF) : 1.0 ;
+
+       sptr = psf->u.sbuf ;
+       bufferlen = ARRAY_LEN (psf->u.sbuf) ;
+       while (len > 0)
+       {       writecount = (len >= bufferlen) ? bufferlen : len ;
+               for (k = 0 ; k < writecount ; k++)
+                       sptr [k] = lrintf (normfact * ptr [total + k]) ;
+               count = gsm610_write_block (psf, pgsm610, sptr, writecount) ;
+
+               total += count ;
+               len -= writecount ;
+               } ;
+       return total ;
+} /* gsm610_write_f */
+
+static sf_count_t
+gsm610_write_d (SF_PRIVATE *psf, const double *ptr, sf_count_t len)
+{      GSM610_PRIVATE *pgsm610 ;
+       short           *sptr ;
+       int                     k, bufferlen, writecount = 0, count ;
+       sf_count_t      total = 0 ;
+       double          normfact ;
+
+       if (psf->fdata == NULL)
+               return 0 ;
+       pgsm610 = (GSM610_PRIVATE*) psf->fdata ;
+
+       normfact = (psf->norm_double == SF_TRUE) ? (1.0 * 0x7FFF) : 1.0 ;
+
+       sptr = psf->u.sbuf ;
+       bufferlen = ARRAY_LEN (psf->u.sbuf) ;
+       while (len > 0)
+       {       writecount = (len >= bufferlen) ? bufferlen : len ;
+               for (k = 0 ; k < writecount ; k++)
+                       sptr [k] = lrint (normfact * ptr [total + k]) ;
+               count = gsm610_write_block (psf, pgsm610, sptr, writecount) ;
+
+               total += count ;
+               len -= writecount ;
+               } ;
+       return total ;
+} /* gsm610_write_d */
+
+static int
+gsm610_close   (SF_PRIVATE *psf)
+{      GSM610_PRIVATE *pgsm610 ;
+
+       if (psf->fdata == NULL)
+               return 0 ;
+
+       pgsm610 = (GSM610_PRIVATE*) psf->fdata ;
+
+       if (psf->mode == SFM_WRITE)
+       {       /*      If a block has been partially assembled, write it out
+               **      as the final block.
+               */
+
+               if (pgsm610->samplecount && pgsm610->samplecount < pgsm610->samplesperblock)
+                       pgsm610->encode_block (psf, pgsm610) ;
+               } ;
+
+       if (pgsm610->gsm_data)
+               gsm_destroy (pgsm610->gsm_data) ;
+
+       return 0 ;
+} /* gsm610_close */
+
+/*
+** Do not edit or modify anything in this comment block.
+** The arch-tag line is a file identity tag for the GNU Arch 
+** revision control system.
+**
+** arch-tag: 8575187d-af4f-4acf-b9dd-6ff705628345
+*/
diff --git a/libs/libsndfile/src/htk.c b/libs/libsndfile/src/htk.c
new file mode 100644 (file)
index 0000000..716868b
--- /dev/null
@@ -0,0 +1,225 @@
+/*
+** Copyright (C) 2002-2004 Erik de Castro Lopo <erikd@mega-nerd.com>
+**
+** This program is free software; you can redistribute it and/or modify
+** it under the terms of the GNU Lesser General Public License as published by
+** the Free Software Foundation; either version 2.1 of the License, or
+** (at your option) any later version.
+**
+** This program is distributed in the hope that it will be useful,
+** but WITHOUT ANY WARRANTY; without even the implied warranty of
+** MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+** GNU Lesser General Public License for more details.
+**
+** You should have received a copy of the GNU Lesser General Public License
+** along with this program; if not, write to the Free Software
+** Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA.
+*/
+
+#include       "sfconfig.h"
+
+#include       <stdio.h>
+#include       <fcntl.h>
+#include       <string.h>
+#include       <ctype.h>
+
+#include       "sndfile.h"
+#include       "sfendian.h"
+#include       "common.h"
+
+/*------------------------------------------------------------------------------
+** Macros to handle big/little endian issues.
+*/
+
+#define        SFE_HTK_BAD_FILE_LEN    1666
+#define        SFE_HTK_NOT_WAVEFORM    1667
+
+/*------------------------------------------------------------------------------
+** Private static functions.
+*/
+
+static int             htk_close               (SF_PRIVATE *psf) ;
+
+static int             htk_write_header (SF_PRIVATE *psf, int calc_length) ;
+static int             htk_read_header (SF_PRIVATE *psf) ;
+
+/*------------------------------------------------------------------------------
+** Public function.
+*/
+
+int
+htk_open       (SF_PRIVATE *psf)
+{      int             subformat ;
+       int             error = 0 ;
+
+       if (psf->is_pipe)
+               return SFE_HTK_NO_PIPE ;
+
+       if (psf->mode == SFM_READ || (psf->mode == SFM_RDWR && psf->filelength > 0))
+       {       if ((error = htk_read_header (psf)))
+                       return error ;
+               } ;
+
+       subformat = psf->sf.format & SF_FORMAT_SUBMASK ;
+
+       if (psf->mode == SFM_WRITE || psf->mode == SFM_RDWR)
+       {       if ((psf->sf.format & SF_FORMAT_TYPEMASK) != SF_FORMAT_HTK)
+                       return  SFE_BAD_OPEN_FORMAT ;
+
+               psf->endian = SF_ENDIAN_BIG ;
+
+               if (htk_write_header (psf, SF_FALSE))
+                       return psf->error ;
+
+               psf->write_header = htk_write_header ;
+               } ;
+
+       psf->container_close = htk_close ;
+
+       psf->blockwidth = psf->bytewidth * psf->sf.channels ;
+
+       switch (subformat)
+       {       case SF_FORMAT_PCM_16 : /* 16-bit linear PCM. */
+                               error = pcm_init (psf) ;
+                               break ;
+
+               default : break ;
+               } ;
+
+       return error ;
+} /* htk_open */
+
+/*------------------------------------------------------------------------------
+*/
+
+static int
+htk_close      (SF_PRIVATE *psf)
+{
+       if (psf->mode == SFM_WRITE || psf->mode == SFM_RDWR)
+               htk_write_header (psf, SF_TRUE) ;
+
+       return 0 ;
+} /* htk_close */
+
+static int
+htk_write_header (SF_PRIVATE *psf, int calc_length)
+{      sf_count_t      current ;
+       int                     sample_count, sample_period ;
+
+       current = psf_ftell (psf) ;
+
+       if (calc_length)
+               psf->filelength = psf_get_filelen (psf) ;
+
+       /* Reset the current header length to zero. */
+       psf->header [0] = 0 ;
+       psf->headindex = 0 ;
+       psf_fseek (psf, 0, SEEK_SET) ;
+
+       if (psf->filelength > 12)
+               sample_count = (psf->filelength - 12) / 2 ;
+       else
+               sample_count = 0 ;
+
+       sample_period = 10000000 / psf->sf.samplerate ;
+
+       psf_binheader_writef (psf, "E444", sample_count, sample_period, 0x20000) ;
+
+       /* Header construction complete so write it out. */
+       psf_fwrite (psf->header, psf->headindex, 1, psf) ;
+
+       if (psf->error)
+               return psf->error ;
+
+       psf->dataoffset = psf->headindex ;
+
+       if (current > 0)
+               psf_fseek (psf, current, SEEK_SET) ;
+
+       return psf->error ;
+} /* htk_write_header */
+
+/*
+** Found the following info in a comment block within Bill Schottstaedt's
+** sndlib library.
+**
+** HTK format files consist of a contiguous sequence of samples preceded by a
+** header. Each sample is a vector of either 2-byte integers or 4-byte floats.
+** 2-byte integers are used for compressed forms as described below and for
+** vector quantised data as described later in section 5.11. HTK format data
+** files can also be used to store speech waveforms as described in section 5.8.
+**
+** The HTK file format header is 12 bytes long and contains the following data
+**   nSamples   -- number of samples in file (4-byte integer)
+**   sampPeriod -- sample period in 100ns units (4-byte integer)
+**   sampSize   -- number of bytes per sample (2-byte integer)
+**   parmKind   -- a code indicating the sample kind (2-byte integer)
+**
+** The parameter kind  consists of a 6 bit code representing the basic
+** parameter kind plus additional bits for each of the possible qualifiers.
+** The basic parameter kind codes are
+**
+**  0    WAVEFORM    sampled waveform
+**  1    LPC         linear prediction filter coefficients
+**  2    LPREFC      linear prediction reflection coefficients
+**  3    LPCEPSTRA   LPC cepstral coefficients
+**  4    LPDELCEP    LPC cepstra plus delta coefficients
+**  5    IREFC       LPC reflection coef in 16 bit integer format
+**  6    MFCC        mel-frequency cepstral coefficients
+**  7    FBANK       log mel-filter bank channel outputs
+**  8    MELSPEC     linear mel-filter bank channel outputs
+**  9    USER        user defined sample kind
+**  10   DISCRETE    vector quantised data
+**
+** and the bit-encoding for the qualifiers (in octal) is
+**   _E   000100      has energy
+**   _N   000200      absolute energy suppressed
+**   _D   000400      has delta coefficients
+**   _A   001000      has acceleration coefficients
+**   _C   002000      is compressed
+**   _Z   004000      has zero mean static coef.
+**   _K   010000      has CRC checksum
+**   _O   020000      has 0'th cepstral coef.
+*/
+
+static int
+htk_read_header (SF_PRIVATE *psf)
+{      int             sample_count, sample_period, marker ;
+
+       psf_binheader_readf (psf, "pE444", 0, &sample_count, &sample_period, &marker) ;
+
+       if (2 * sample_count + 12 != psf->filelength)
+               return SFE_HTK_BAD_FILE_LEN ;
+
+       if (marker != 0x20000)
+               return SFE_HTK_NOT_WAVEFORM ;
+
+       psf->sf.channels = 1 ;
+       psf->sf.samplerate = 10000000 / sample_period ;
+
+       psf_log_printf (psf, "HTK Waveform file\n  Sample Count  : %d\n  Sample Period : %d => %d Hz\n",
+                               sample_count, sample_period, psf->sf.samplerate) ;
+
+       psf->sf.format = SF_FORMAT_HTK | SF_FORMAT_PCM_16 ;
+       psf->bytewidth = 2 ;
+
+       /* HTK always has a 12 byte header. */
+       psf->dataoffset = 12 ;
+       psf->endian = SF_ENDIAN_BIG ;
+
+       psf->datalength = psf->filelength - psf->dataoffset ;
+
+       psf->blockwidth = psf->sf.channels * psf->bytewidth ;
+
+       if (! psf->sf.frames && psf->blockwidth)
+               psf->sf.frames = (psf->filelength - psf->dataoffset) / psf->blockwidth ;
+
+       return 0 ;
+} /* htk_read_header */
+/*
+** Do not edit or modify anything in this comment block.
+** The arch-tag line is a file identity tag for the GNU Arch 
+** revision control system.
+**
+** arch-tag: c350e972-082e-4c20-8934-03391a723560
+*/
diff --git a/libs/libsndfile/src/ima_adpcm.c b/libs/libsndfile/src/ima_adpcm.c
new file mode 100644 (file)
index 0000000..abc49e5
--- /dev/null
@@ -0,0 +1,976 @@
+/*
+** Copyright (C) 1999-2005 Erik de Castro Lopo <erikd@mega-nerd.com>
+**
+** This program is free software; you can redistribute it and/or modify
+** it under the terms of the GNU Lesser General Public License as published by
+** the Free Software Foundation; either version 2.1 of the License, or
+** (at your option) any later version.
+**
+** This program is distributed in the hope that it will be useful,
+** but WITHOUT ANY WARRANTY; without even the implied warranty of
+** MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+** GNU Lesser General Public License for more details.
+**
+** You should have received a copy of the GNU Lesser General Public License
+** along with this program; if not, write to the Free Software
+** Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA.
+*/
+
+#include       "sfconfig.h"
+
+#include       <stdio.h>
+#include       <stdlib.h>
+#include       <string.h>
+
+#include       "sndfile.h"
+#include       "sfendian.h"
+#include       "float_cast.h"
+#include       "common.h"
+
+typedef struct IMA_ADPCM_PRIVATE_tag
+{      int                     (*decode_block) (SF_PRIVATE *psf, struct IMA_ADPCM_PRIVATE_tag *pima) ;
+       int                     (*encode_block) (SF_PRIVATE *psf, struct IMA_ADPCM_PRIVATE_tag *pima) ;
+
+       int                             channels, blocksize, samplesperblock, blocks ;
+       int                             blockcount, samplecount ;
+       int                             previous [2] ;
+       int                             stepindx [2] ;
+       unsigned char   *block ;
+       short                   *samples ;
+#if HAVE_FLEXIBLE_ARRAY
+       short                   data    [] ; /* ISO C99 struct flexible array. */
+#else
+       short                   data    [0] ; /* This is a hack and might not work. */
+#endif
+} IMA_ADPCM_PRIVATE ;
+
+/*============================================================================================
+** Predefined IMA ADPCM data.
+*/
+
+static int ima_indx_adjust [16] =
+{      -1, -1, -1, -1,         /* +0 - +3, decrease the step size */
+     2,  4,  6,  8,     /* +4 - +7, increase the step size */
+    -1, -1, -1, -1,            /* -0 - -3, decrease the step size */
+     2,  4,  6,  8,            /* -4 - -7, increase the step size */
+} ;
+
+static int ima_step_size [89] =
+{      7, 8, 9, 10, 11, 12, 13, 14, 16, 17, 19, 21, 23, 25, 28, 31, 34, 37, 41, 45,
+       50, 55, 60, 66, 73, 80, 88, 97, 107, 118, 130, 143, 157, 173, 190, 209, 230,
+       253, 279, 307, 337, 371, 408, 449, 494, 544, 598, 658, 724, 796, 876, 963,
+       1060, 1166, 1282, 1411, 1552, 1707, 1878, 2066, 2272, 2499, 2749, 3024, 3327,
+       3660, 4026, 4428, 4871, 5358, 5894, 6484, 7132, 7845, 8630, 9493, 10442,
+       11487, 12635, 13899, 15289, 16818, 18500, 20350, 22385, 24623, 27086, 29794,
+       32767
+} ;
+
+static int ima_reader_init (SF_PRIVATE *psf, int blockalign, int samplesperblock) ;
+static int ima_writer_init (SF_PRIVATE *psf, int blockalign) ;
+
+static int ima_read_block (SF_PRIVATE *psf, IMA_ADPCM_PRIVATE *pima, short *ptr, int len) ;
+static int ima_write_block (SF_PRIVATE *psf, IMA_ADPCM_PRIVATE *pima, const short *ptr, int len) ;
+
+static sf_count_t ima_read_s (SF_PRIVATE *psf, short *ptr, sf_count_t len) ;
+static sf_count_t ima_read_i (SF_PRIVATE *psf, int *ptr, sf_count_t len) ;
+static sf_count_t ima_read_f (SF_PRIVATE *psf, float *ptr, sf_count_t len) ;
+static sf_count_t ima_read_d (SF_PRIVATE *psf, double *ptr, sf_count_t len) ;
+
+static sf_count_t ima_write_s (SF_PRIVATE *psf, const short *ptr, sf_count_t len) ;
+static sf_count_t ima_write_i (SF_PRIVATE *psf, const int *ptr, sf_count_t len) ;
+static sf_count_t ima_write_f (SF_PRIVATE *psf, const float *ptr, sf_count_t len) ;
+static sf_count_t ima_write_d (SF_PRIVATE *psf, const double *ptr, sf_count_t len) ;
+
+static sf_count_t      ima_seek        (SF_PRIVATE *psf, int mode, sf_count_t offset) ;
+
+static int     ima_close       (SF_PRIVATE *psf) ;
+
+static int wav_w64_ima_decode_block (SF_PRIVATE *psf, IMA_ADPCM_PRIVATE *pima) ;
+static int wav_w64_ima_encode_block (SF_PRIVATE *psf, IMA_ADPCM_PRIVATE *pima) ;
+
+/*-static int aiff_ima_reader_init (SF_PRIVATE *psf, int blockalign, int samplesperblock) ;-*/
+static int aiff_ima_decode_block (SF_PRIVATE *psf, IMA_ADPCM_PRIVATE *pima) ;
+static int aiff_ima_encode_block (SF_PRIVATE *psf, IMA_ADPCM_PRIVATE *pima) ;
+
+
+/*============================================================================================
+** IMA ADPCM Reader initialisation function.
+*/
+
+int
+wav_w64_ima_init (SF_PRIVATE *psf, int blockalign, int samplesperblock)
+{      int error ;
+
+       if (psf->fdata != NULL)
+       {       psf_log_printf (psf, "*** psf->fdata is not NULL.\n") ;
+               return SFE_INTERNAL ;
+               } ;
+
+       if (psf->mode == SFM_RDWR)
+               return SFE_BAD_MODE_RW ;
+
+       if (psf->mode == SFM_READ)
+               if ((error = ima_reader_init (psf, blockalign, samplesperblock)))
+                       return error ;
+
+       if (psf->mode == SFM_WRITE)
+               if ((error = ima_writer_init (psf, blockalign)))
+                       return error ;
+
+       psf->codec_close = ima_close ;
+       psf->seek = ima_seek ;
+
+       return 0 ;
+} /* wav_w64_ima_init */
+
+int
+aiff_ima_init (SF_PRIVATE *psf, int blockalign, int samplesperblock)
+{      int error ;
+
+       if (psf->mode == SFM_RDWR)
+               return SFE_BAD_MODE_RW ;
+
+       if (psf->mode == SFM_READ)
+               if ((error = ima_reader_init (psf, blockalign, samplesperblock)))
+                       return error ;
+
+       if (psf->mode == SFM_WRITE)
+               if ((error = ima_writer_init (psf, blockalign)))
+                       return error ;
+
+       psf->codec_close = ima_close ;
+
+       return 0 ;
+} /* aiff_ima_init */
+
+static int
+ima_close      (SF_PRIVATE *psf)
+{      IMA_ADPCM_PRIVATE *pima ;
+
+       pima = (IMA_ADPCM_PRIVATE*) psf->fdata ;
+
+       if (psf->mode == SFM_WRITE)
+       {       /*      If a block has been partially assembled, write it out
+               **      as the final block.
+               */
+               if (pima->samplecount && pima->samplecount < pima->samplesperblock)
+                       pima->encode_block (psf, pima) ;
+
+               psf->sf.frames = pima->samplesperblock * pima->blockcount / psf->sf.channels ;
+               } ;
+
+       return 0 ;
+} /* ima_close */
+
+/*============================================================================================
+** IMA ADPCM Read Functions.
+*/
+
+static int
+ima_reader_init (SF_PRIVATE *psf, int blockalign, int samplesperblock)
+{      IMA_ADPCM_PRIVATE       *pima ;
+       int             pimasize, count ;
+
+       if (psf->mode != SFM_READ)
+               return SFE_BAD_MODE_RW ;
+
+       pimasize = sizeof (IMA_ADPCM_PRIVATE) + blockalign * psf->sf.channels + 3 * psf->sf.channels * samplesperblock ;
+
+       if (! (pima = malloc (pimasize)))
+               return SFE_MALLOC_FAILED ;
+
+       psf->fdata = (void*) pima ;
+
+       memset (pima, 0, pimasize) ;
+
+       pima->samples   = pima->data ;
+       pima->block             = (unsigned char*) (pima->data + samplesperblock * psf->sf.channels) ;
+
+       pima->channels                  = psf->sf.channels ;
+       pima->blocksize                 = blockalign ;
+       pima->samplesperblock   = samplesperblock ;
+
+       psf->filelength = psf_get_filelen (psf) ;
+       psf->datalength = (psf->dataend) ? psf->dataend - psf->dataoffset :
+                                                       psf->filelength - psf->dataoffset ;
+
+       if (psf->datalength % pima->blocksize)
+               pima->blocks = psf->datalength / pima->blocksize + 1 ;
+       else
+               pima->blocks = psf->datalength / pima->blocksize ;
+
+       switch (psf->sf.format & SF_FORMAT_TYPEMASK)
+       {       case SF_FORMAT_WAV :
+               case SF_FORMAT_W64 :
+                               count = 2 * (pima->blocksize - 4 * pima->channels) / pima->channels + 1 ;
+
+                               if (pima->samplesperblock != count)
+                                       psf_log_printf (psf, "*** Warning : samplesperblock should be %d.\n", count) ;
+
+                               pima->decode_block = wav_w64_ima_decode_block ;
+
+                               psf->sf.frames = pima->samplesperblock * pima->blocks ;
+                               break ;
+
+               case SF_FORMAT_AIFF :
+                               psf_log_printf (psf, "still need to check block count\n") ;
+                               pima->decode_block = aiff_ima_decode_block ;
+                               psf->sf.frames = pima->samplesperblock * pima->blocks / pima->channels ;
+                               break ;
+
+               default :
+                               psf_log_printf (psf, "ima_reader_init: bad psf->sf.format\n") ;
+                               return SFE_INTERNAL ;
+                               break ;
+               } ;
+
+       pima->decode_block (psf, pima) ;        /* Read first block. */
+
+       psf->read_short         = ima_read_s ;
+       psf->read_int           = ima_read_i ;
+       psf->read_float         = ima_read_f ;
+       psf->read_double        = ima_read_d ;
+
+       return 0 ;
+} /* ima_reader_init */
+
+static int
+aiff_ima_decode_block (SF_PRIVATE *psf, IMA_ADPCM_PRIVATE *pima)
+{      unsigned char *blockdata ;
+       int             chan, k, diff, bytecode ;
+       short   step, stepindx, predictor, *sampledata ;
+
+static int count = 0 ;
+count ++ ;
+
+       pima->blockcount += pima->channels ;
+       pima->samplecount = 0 ;
+
+       if (pima->blockcount > pima->blocks)
+       {       memset (pima->samples, 0, pima->samplesperblock * pima->channels * sizeof (short)) ;
+               return 1 ;
+               } ;
+
+       if ((k = psf_fread (pima->block, 1, pima->blocksize * pima->channels, psf)) != pima->blocksize * pima->channels)
+               psf_log_printf (psf, "*** Warning : short read (%d != %d).\n", k, pima->blocksize) ;
+
+       /* Read and check the block header. */
+       for (chan = 0 ; chan < pima->channels ; chan++)
+       {       blockdata = pima->block + chan * 34 ;
+               sampledata = pima->samples + chan ;
+
+               predictor = (blockdata [0] << 8) | (blockdata [1] & 0x80) ;
+               stepindx = blockdata [1] & 0x7F ;
+
+{
+if (count < 5)
+printf ("\nchan: %d    predictor: %d    stepindx: %d (%d)\n",
+       chan, predictor, stepindx, ima_step_size [stepindx]) ;
+}
+               /* FIXME : Do this a better way. */
+               if (stepindx < 0) stepindx = 0 ;
+               else if (stepindx > 88) stepindx = 88 ;
+
+               /*
+               **      Pull apart the packed 4 bit samples and store them in their
+               **      correct sample positions.
+               */
+               for (k = 0 ; k < pima->blocksize - 2 ; k++)
+               {       bytecode = blockdata [k + 2] ;
+                       sampledata [pima->channels * (2 * k + 0)] = bytecode & 0xF ;
+                       sampledata [pima->channels * (2 * k + 1)] = (bytecode >> 4) & 0xF ;
+                       } ;
+
+               /* Decode the encoded 4 bit samples. */
+               for (k = 0 ; k < pima->samplesperblock ; k ++)
+               {       step = ima_step_size [stepindx] ;
+
+                       bytecode = pima->samples [pima->channels * k + chan] ;
+
+                       stepindx += ima_indx_adjust [bytecode] ;
+
+                       if (stepindx < 0) stepindx = 0 ;
+                       else if (stepindx > 88) stepindx = 88 ;
+
+                       diff = step >> 3 ;
+                       if (bytecode & 1)       diff += step >> 2 ;
+                       if (bytecode & 2)       diff += step >> 1 ;
+                       if (bytecode & 4)       diff += step ;
+                       if (bytecode & 8)       diff = -diff ;
+
+                       predictor += diff ;
+
+                       pima->samples [pima->channels * k + chan] = predictor ;
+                       } ;
+               } ;
+
+if (count < 5)
+{
+       for (k = 0 ; k < 10 ; k++)
+               printf ("% 7d,", pima->samples [k]) ;
+       puts ("") ;
+}
+
+       return 1 ;
+} /* aiff_ima_decode_block */
+
+static int
+aiff_ima_encode_block (SF_PRIVATE *psf, IMA_ADPCM_PRIVATE *pima)
+{      int             chan, k, step, diff, vpdiff, blockindx, indx ;
+       short   bytecode, mask ;
+
+static int count = 0 ;
+if (0 && count == 0)
+{      pima->samples [0] = 0 ;
+       printf ("blocksize : %d\n", pima->blocksize) ;
+       printf ("pima->stepindx [0] : %d\n", pima->stepindx [0]) ;
+       }
+count ++ ;
+
+       /* Encode the block header. */
+       for (chan = 0 ; chan < pima->channels ; chan ++)
+       {       blockindx = chan * pima->blocksize ;
+
+               pima->block [blockindx] = (pima->samples [chan] >> 8) & 0xFF ;
+               pima->block [blockindx + 1] = (pima->samples [chan] & 0x80) + (pima->stepindx [chan] & 0x7F) ;
+
+               pima->previous [chan] = pima->samples [chan] ;
+               } ;
+
+       /* Encode second and later samples for every block as a 4 bit value. */
+       for (k = pima->channels ; k < (pima->samplesperblock * pima->channels) ; k ++)
+       {       chan = (pima->channels > 1) ? (k % 2) : 0 ;
+
+               diff = pima->samples [k] - pima->previous [chan] ;
+
+               bytecode = 0 ;
+               step = ima_step_size [pima->stepindx [chan]] ;
+               vpdiff = step >> 3 ;
+               if (diff < 0)
+               {       bytecode = 8 ;
+                       diff = -diff ;
+                       } ;
+               mask = 4 ;
+               while (mask)
+               {       if (diff >= step)
+                       {       bytecode |= mask ;
+                               diff -= step ;
+                               vpdiff += step ;
+                               } ;
+                       step >>= 1 ;
+                       mask >>= 1 ;
+                       } ;
+
+               if (bytecode & 8)
+                       pima->previous [chan] -= vpdiff ;
+               else
+                       pima->previous [chan] += vpdiff ;
+
+               if (pima->previous [chan] > 32767)
+                       pima->previous [chan] = 32767 ;
+               else if (pima->previous [chan] < -32768)
+                       pima->previous [chan] = -32768 ;
+
+               pima->stepindx [chan] += ima_indx_adjust [bytecode] ;
+               if (pima->stepindx [chan] < 0)
+                       pima->stepindx [chan] = 0 ;
+               else if (pima->stepindx [chan] > 88)
+                       pima->stepindx [chan] = 88 ;
+
+               pima->samples [k] = bytecode ;
+               } ;
+
+       /* Pack the 4 bit encoded samples. */
+
+       for (chan = 0 ; chan < pima->channels ; chan ++)
+       {       for (indx = pima->channels ; indx < pima->channels * pima->samplesperblock ; indx += 2 * pima->channels)
+               {       blockindx = chan * pima->blocksize + 2 + indx / 2 ;
+
+if (0 && count ++ < 5)
+       printf ("chan: %d    blockindx: %3d    indx: %3d\n", chan, blockindx, indx) ;
+
+                       pima->block [blockindx] = pima->samples [indx] & 0x0F ;
+                       pima->block [blockindx] |= (pima->samples [indx + pima->channels] << 4) & 0xF0 ;
+                       } ;
+               } ;
+
+       /* Write the block to disk. */
+
+       if ((k = psf_fwrite (pima->block, 1, pima->channels * pima->blocksize, psf)) != pima->channels * pima->blocksize)
+               psf_log_printf (psf, "*** Warning : short write (%d != %d).\n", k, pima->channels * pima->blocksize) ;
+
+       memset (pima->samples, 0, pima->channels * pima->samplesperblock * sizeof (short)) ;
+       pima->samplecount = 0 ;
+       pima->blockcount ++ ;
+
+       return 1 ;
+} /* aiff_ima_encode_block */
+
+static int
+wav_w64_ima_decode_block (SF_PRIVATE *psf, IMA_ADPCM_PRIVATE *pima)
+{      int             chan, k, current, blockindx, indx, indxstart, diff ;
+       short   step, bytecode, stepindx [2] ;
+
+       pima->blockcount ++ ;
+       pima->samplecount = 0 ;
+
+       if (pima->blockcount > pima->blocks)
+       {       memset (pima->samples, 0, pima->samplesperblock * pima->channels * sizeof (short)) ;
+               return 1 ;
+               } ;
+
+       if ((k = psf_fread (pima->block, 1, pima->blocksize, psf)) != pima->blocksize)
+               psf_log_printf (psf, "*** Warning : short read (%d != %d).\n", k, pima->blocksize) ;
+
+       /* Read and check the block header. */
+
+       for (chan = 0 ; chan < pima->channels ; chan++)
+       {       current = pima->block [chan*4] | (pima->block [chan*4+1] << 8) ;
+               if (current & 0x8000)
+                       current -= 0x10000 ;
+
+               stepindx [chan] = pima->block [chan*4+2] ;
+               if (stepindx [chan] < 0)
+                       stepindx [chan] = 0 ;
+               else if (stepindx [chan] > 88)
+                       stepindx [chan] = 88 ;
+
+               if (pima->block [chan*4+3] != 0)
+                       psf_log_printf (psf, "IMA ADPCM synchronisation error.\n") ;
+
+               pima->samples [chan] = current ;
+               } ;
+
+       /*
+       **      Pull apart the packed 4 bit samples and store them in their
+       **      correct sample positions.
+       */
+
+       blockindx = 4 * pima->channels ;
+
+       indxstart = pima->channels ;
+       while (blockindx < pima->blocksize)
+       {       for (chan = 0 ; chan < pima->channels ; chan++)
+               {       indx = indxstart + chan ;
+                       for (k = 0 ; k < 4 ; k++)
+                       {       bytecode = pima->block [blockindx++] ;
+                               pima->samples [indx] = bytecode & 0x0F ;
+                               indx += pima->channels ;
+                               pima->samples [indx] = (bytecode >> 4) & 0x0F ;
+                               indx += pima->channels ;
+                               } ;
+                       } ;
+               indxstart += 8 * pima->channels ;
+               } ;
+
+       /* Decode the encoded 4 bit samples. */
+
+       for (k = pima->channels ; k < (pima->samplesperblock * pima->channels) ; k ++)
+       {       chan = (pima->channels > 1) ? (k % 2) : 0 ;
+
+               bytecode = pima->samples [k] & 0xF ;
+
+               step = ima_step_size [stepindx [chan]] ;
+               current = pima->samples [k - pima->channels] ;
+
+               diff = step >> 3 ;
+               if (bytecode & 1)
+                       diff += step >> 2 ;
+               if (bytecode & 2)
+                       diff += step >> 1 ;
+               if (bytecode & 4)
+                       diff += step ;
+               if (bytecode & 8)
+                       diff = -diff ;
+
+               current += diff ;
+
+               if (current > 32767)
+                       current = 32767 ;
+               else if (current < -32768)
+                       current = -32768 ;
+
+               stepindx [chan] += ima_indx_adjust [bytecode] ;
+
+               if (stepindx [chan] < 0)
+                       stepindx [chan] = 0 ;
+               else if (stepindx [chan] > 88)
+                       stepindx [chan] = 88 ;
+
+               pima->samples [k] = current ;
+               } ;
+
+       return 1 ;
+} /* wav_w64_ima_decode_block */
+
+static int
+wav_w64_ima_encode_block (SF_PRIVATE *psf, IMA_ADPCM_PRIVATE *pima)
+{      int             chan, k, step, diff, vpdiff, blockindx, indx, indxstart ;
+       short   bytecode, mask ;
+
+       /* Encode the block header. */
+       for (chan = 0 ; chan < pima->channels ; chan++)
+       {       pima->block [chan*4]    = pima->samples [chan] & 0xFF ;
+               pima->block [chan*4+1]  = (pima->samples [chan] >> 8) & 0xFF ;
+
+               pima->block [chan*4+2] = pima->stepindx [chan] ;
+               pima->block [chan*4+3] = 0 ;
+
+               pima->previous [chan] = pima->samples [chan] ;
+               } ;
+
+       /* Encode the samples as 4 bit. */
+
+       for (k = pima->channels ; k < (pima->samplesperblock * pima->channels) ; k ++)
+       {       chan = (pima->channels > 1) ? (k % 2) : 0 ;
+
+               diff = pima->samples [k] - pima->previous [chan] ;
+
+               bytecode = 0 ;
+               step = ima_step_size [pima->stepindx [chan]] ;
+               vpdiff = step >> 3 ;
+               if (diff < 0)
+               {       bytecode = 8 ;
+                       diff = -diff ;
+                       } ;
+               mask = 4 ;
+               while (mask)
+               {       if (diff >= step)
+                       {       bytecode |= mask ;
+                               diff -= step ;
+                               vpdiff += step ;
+                               } ;
+                       step >>= 1 ;
+                       mask >>= 1 ;
+                       } ;
+
+               if (bytecode & 8)
+                       pima->previous [chan] -= vpdiff ;
+               else
+                       pima->previous [chan] += vpdiff ;
+
+               if (pima->previous [chan] > 32767)
+                       pima->previous [chan] = 32767 ;
+               else if (pima->previous [chan] < -32768)
+                       pima->previous [chan] = -32768 ;
+
+               pima->stepindx [chan] += ima_indx_adjust [bytecode] ;
+               if (pima->stepindx [chan] < 0)
+                       pima->stepindx [chan] = 0 ;
+               else if (pima->stepindx [chan] > 88)
+                       pima->stepindx [chan] = 88 ;
+
+               pima->samples [k] = bytecode ;
+               } ;
+
+       /* Pack the 4 bit encoded samples. */
+
+       blockindx = 4 * pima->channels ;
+
+       indxstart = pima->channels ;
+       while (blockindx < pima->blocksize)
+       {       for (chan = 0 ; chan < pima->channels ; chan++)
+               {       indx = indxstart + chan ;
+                       for (k = 0 ; k < 4 ; k++)
+                       {       pima->block [blockindx] = pima->samples [indx] & 0x0F ;
+                               indx += pima->channels ;
+                               pima->block [blockindx] |= (pima->samples [indx] << 4) & 0xF0 ;
+                               indx += pima->channels ;
+                               blockindx ++ ;
+                               } ;
+                       } ;
+               indxstart += 8 * pima->channels ;
+               } ;
+
+       /* Write the block to disk. */
+
+       if ((k = psf_fwrite (pima->block, 1, pima->blocksize, psf)) != pima->blocksize)
+               psf_log_printf (psf, "*** Warning : short write (%d != %d).\n", k, pima->blocksize) ;
+
+       memset (pima->samples, 0, pima->samplesperblock * sizeof (short)) ;
+       pima->samplecount = 0 ;
+       pima->blockcount ++ ;
+
+       return 1 ;
+} /* wav_w64_ima_encode_block */
+
+static int
+ima_read_block (SF_PRIVATE *psf, IMA_ADPCM_PRIVATE *pima, short *ptr, int len)
+{      int             count, total = 0, indx = 0 ;
+
+       while (indx < len)
+       {       if (pima->blockcount >= pima->blocks && pima->samplecount >= pima->samplesperblock)
+               {       memset (&(ptr [indx]), 0, (size_t) ((len - indx) * sizeof (short))) ;
+                       return total ;
+                       } ;
+
+               if (pima->samplecount >= pima->samplesperblock)
+                       pima->decode_block (psf, pima) ;
+
+               count = (pima->samplesperblock - pima->samplecount) * pima->channels ;
+               count = (len - indx > count) ? count : len - indx ;
+
+               memcpy (&(ptr [indx]), &(pima->samples [pima->samplecount * pima->channels]), count * sizeof (short)) ;
+               indx += count ;
+               pima->samplecount += count / pima->channels ;
+               total = indx ;
+               } ;
+
+       return total ;
+} /* ima_read_block */
+
+static sf_count_t
+ima_read_s (SF_PRIVATE *psf, short *ptr, sf_count_t len)
+{      IMA_ADPCM_PRIVATE       *pima ;
+       int                     readcount, count ;
+       sf_count_t      total = 0 ;
+
+       if (! psf->fdata)
+               return 0 ;
+       pima = (IMA_ADPCM_PRIVATE*) psf->fdata ;
+
+       while (len > 0)
+       {       readcount = (len > 0x10000000) ? 0x10000000 : (int) len ;
+
+               count = ima_read_block (psf, pima, ptr, readcount) ;
+
+               total += count ;
+               len -= count ;
+               if (count != readcount)
+                       break ;
+               } ;
+
+       return total ;
+} /* ima_read_s */
+
+static sf_count_t
+ima_read_i (SF_PRIVATE *psf, int *ptr, sf_count_t len)
+{      IMA_ADPCM_PRIVATE *pima ;
+       short           *sptr ;
+       int                     k, bufferlen, readcount, count ;
+       sf_count_t      total = 0 ;
+
+       if (! psf->fdata)
+               return 0 ;
+       pima = (IMA_ADPCM_PRIVATE*) psf->fdata ;
+
+       sptr = psf->u.sbuf ;
+       bufferlen = ARRAY_LEN (psf->u.sbuf) ;
+       while (len > 0)
+       {       readcount = (len >= bufferlen) ? bufferlen : (int) len ;
+               count = ima_read_block (psf, pima, sptr, readcount) ;
+               for (k = 0 ; k < readcount ; k++)
+                       ptr [total + k] = ((int) sptr [k]) << 16 ;
+               total += count ;
+               len -= readcount ;
+               if (count != readcount)
+                       break ;
+               } ;
+
+       return total ;
+} /* ima_read_i */
+
+static sf_count_t
+ima_read_f (SF_PRIVATE *psf, float *ptr, sf_count_t len)
+{      IMA_ADPCM_PRIVATE *pima ;
+       short           *sptr ;
+       int                     k, bufferlen, readcount, count ;
+       sf_count_t      total = 0 ;
+       float           normfact ;
+
+       if (! psf->fdata)
+               return 0 ;
+       pima = (IMA_ADPCM_PRIVATE*) psf->fdata ;
+
+       normfact = (psf->norm_float == SF_TRUE) ? 1.0 / ((float) 0x8000) : 1.0 ;
+
+       sptr = psf->u.sbuf ;
+       bufferlen = ARRAY_LEN (psf->u.sbuf) ;
+       while (len > 0)
+       {       readcount = (len >= bufferlen) ? bufferlen : (int) len ;
+               count = ima_read_block (psf, pima, sptr, readcount) ;
+               for (k = 0 ; k < readcount ; k++)
+                       ptr [total + k] = normfact * (float) (sptr [k]) ;
+               total += count ;
+               len -= readcount ;
+               if (count != readcount)
+                       break ;
+               } ;
+
+       return total ;
+} /* ima_read_f */
+
+static sf_count_t
+ima_read_d (SF_PRIVATE *psf, double *ptr, sf_count_t len)
+{      IMA_ADPCM_PRIVATE *pima ;
+       short           *sptr ;
+       int                     k, bufferlen, readcount, count ;
+       sf_count_t      total = 0 ;
+       double          normfact ;
+
+       if (! psf->fdata)
+               return 0 ;
+       pima = (IMA_ADPCM_PRIVATE*) psf->fdata ;
+
+       normfact = (psf->norm_double == SF_TRUE) ? 1.0 / ((double) 0x8000) : 1.0 ;
+
+       sptr = psf->u.sbuf ;
+       bufferlen = ARRAY_LEN (psf->u.sbuf) ;
+       while (len > 0)
+       {       readcount = (len >= bufferlen) ? bufferlen : (int) len ;
+               count = ima_read_block (psf, pima, sptr, readcount) ;
+               for (k = 0 ; k < readcount ; k++)
+                       ptr [total + k] = normfact * (double) (sptr [k]) ;
+               total += count ;
+               len -= readcount ;
+               if (count != readcount)
+                       break ;
+               } ;
+
+       return total ;
+} /* ima_read_d */
+
+static sf_count_t
+ima_seek (SF_PRIVATE *psf, int mode, sf_count_t offset)
+{      IMA_ADPCM_PRIVATE *pima ;
+       int                     newblock, newsample ;
+
+       if (! psf->fdata)
+               return 0 ;
+       pima = (IMA_ADPCM_PRIVATE*) psf->fdata ;
+
+       if (psf->datalength < 0 || psf->dataoffset < 0)
+       {       psf->error = SFE_BAD_SEEK ;
+               return PSF_SEEK_ERROR ;
+               } ;
+
+       if (offset == 0)
+       {       psf_fseek (psf, psf->dataoffset, SEEK_SET) ;
+               pima->blockcount = 0 ;
+               pima->decode_block (psf, pima) ;
+               pima->samplecount = 0 ;
+               return 0 ;
+               } ;
+
+       if (offset < 0 || offset > pima->blocks * pima->samplesperblock)
+       {       psf->error = SFE_BAD_SEEK ;
+               return  PSF_SEEK_ERROR ;
+               } ;
+
+       newblock        = offset / pima->samplesperblock ;
+       newsample       = offset % pima->samplesperblock ;
+
+       if (mode == SFM_READ)
+       {       psf_fseek (psf, psf->dataoffset + newblock * pima->blocksize, SEEK_SET) ;
+               pima->blockcount = newblock ;
+               pima->decode_block (psf, pima) ;
+               pima->samplecount = newsample ;
+               }
+       else
+       {       /* What to do about write??? */
+               psf->error = SFE_BAD_SEEK ;
+               return  PSF_SEEK_ERROR ;
+               } ;
+
+       return newblock * pima->samplesperblock + newsample ;
+} /* ima_seek */
+
+/*==========================================================================================
+** IMA ADPCM Write Functions.
+*/
+
+static int
+ima_writer_init (SF_PRIVATE *psf, int blockalign)
+{      IMA_ADPCM_PRIVATE       *pima ;
+       int                                     samplesperblock ;
+       unsigned int            pimasize ;
+
+       if (psf->mode != SFM_WRITE)
+               return SFE_BAD_MODE_RW ;
+
+       samplesperblock = 2 * (blockalign - 4 * psf->sf.channels) / psf->sf.channels + 1 ;
+
+       pimasize = sizeof (IMA_ADPCM_PRIVATE) + blockalign + 3 * psf->sf.channels * samplesperblock ;
+
+       if ((pima = calloc (1, pimasize)) == NULL)
+               return SFE_MALLOC_FAILED ;
+
+       psf->fdata = (void*) pima ;
+
+       pima->channels                  = psf->sf.channels ;
+       pima->blocksize                 = blockalign ;
+       pima->samplesperblock   = samplesperblock ;
+
+       pima->block             = (unsigned char*) pima->data ;
+       pima->samples   = (short*) (pima->data + blockalign) ;
+
+       pima->samplecount = 0 ;
+
+       switch (psf->sf.format & SF_FORMAT_TYPEMASK)
+       {       case SF_FORMAT_WAV :
+               case SF_FORMAT_W64 :
+                               pima->encode_block = wav_w64_ima_encode_block ;
+                               break ;
+
+               case SF_FORMAT_AIFF :
+                               pima->encode_block = aiff_ima_encode_block ;
+                               break ;
+
+               default :
+                               psf_log_printf (psf, "ima_reader_init: bad psf->sf.format\n") ;
+                               return SFE_INTERNAL ;
+                               break ;
+               } ;
+
+       psf->write_short        = ima_write_s ;
+       psf->write_int          = ima_write_i ;
+       psf->write_float        = ima_write_f ;
+       psf->write_double       = ima_write_d ;
+
+       return 0 ;
+} /* ima_writer_init */
+
+/*==========================================================================================
+*/
+
+static int
+ima_write_block (SF_PRIVATE *psf, IMA_ADPCM_PRIVATE *pima, const short *ptr, int len)
+{      int             count, total = 0, indx = 0 ;
+
+       while (indx < len)
+       {       count = (pima->samplesperblock - pima->samplecount) * pima->channels ;
+
+               if (count > len - indx)
+                       count = len - indx ;
+
+               memcpy (&(pima->samples [pima->samplecount * pima->channels]), &(ptr [total]), count * sizeof (short)) ;
+               indx += count ;
+               pima->samplecount += count / pima->channels ;
+               total = indx ;
+
+               if (pima->samplecount >= pima->samplesperblock)
+                       pima->encode_block (psf, pima) ;
+               } ;
+
+       return total ;
+} /* ima_write_block */
+
+static sf_count_t
+ima_write_s (SF_PRIVATE *psf, const short *ptr, sf_count_t len)
+{      IMA_ADPCM_PRIVATE       *pima ;
+       int                     writecount, count ;
+       sf_count_t      total = 0 ;
+
+       if (! psf->fdata)
+               return 0 ;
+       pima = (IMA_ADPCM_PRIVATE*) psf->fdata ;
+
+       while (len)
+       {       writecount = (len > 0x10000000) ? 0x10000000 : (int) len ;
+
+               count = ima_write_block (psf, pima, ptr, writecount) ;
+
+               total += count ;
+               len -= count ;
+               if (count != writecount)
+                       break ;
+               } ;
+
+       return total ;
+} /* ima_write_s */
+
+static sf_count_t
+ima_write_i (SF_PRIVATE *psf, const int *ptr, sf_count_t len)
+{      IMA_ADPCM_PRIVATE *pima ;
+       short           *sptr ;
+       int                     k, bufferlen, writecount, count ;
+       sf_count_t      total = 0 ;
+
+       if (! psf->fdata)
+               return 0 ;
+       pima = (IMA_ADPCM_PRIVATE*) psf->fdata ;
+
+       sptr = psf->u.sbuf ;
+       bufferlen = ARRAY_LEN (psf->u.sbuf) ;
+       while (len > 0)
+       {       writecount = (len >= bufferlen) ? bufferlen : (int) len ;
+               for (k = 0 ; k < writecount ; k++)
+                       sptr [k] = ptr [total + k] >> 16 ;
+               count = ima_write_block (psf, pima, sptr, writecount) ;
+               total += count ;
+               len -= writecount ;
+               if (count != writecount)
+                       break ;
+               } ;
+
+       return total ;
+} /* ima_write_i */
+
+static sf_count_t
+ima_write_f (SF_PRIVATE *psf, const float *ptr, sf_count_t len)
+{      IMA_ADPCM_PRIVATE *pima ;
+       short           *sptr ;
+       int                     k, bufferlen, writecount, count ;
+       sf_count_t      total = 0 ;
+       float           normfact ;
+
+       if (! psf->fdata)
+               return 0 ;
+       pima = (IMA_ADPCM_PRIVATE*) psf->fdata ;
+
+       normfact = (psf->norm_float == SF_TRUE) ? (1.0 * 0x7FFF) : 1.0 ;
+
+       sptr = psf->u.sbuf ;
+       bufferlen = ARRAY_LEN (psf->u.sbuf) ;
+       while (len > 0)
+       {       writecount = (len >= bufferlen) ? bufferlen : (int) len ;
+               for (k = 0 ; k < writecount ; k++)
+                       sptr [k] = lrintf (normfact * ptr [total + k]) ;
+               count = ima_write_block (psf, pima, sptr, writecount) ;
+               total += count ;
+               len -= writecount ;
+               if (count != writecount)
+                       break ;
+               } ;
+
+       return total ;
+} /* ima_write_f */
+
+static sf_count_t
+ima_write_d (SF_PRIVATE *psf, const double *ptr, sf_count_t len)
+{      IMA_ADPCM_PRIVATE *pima ;
+       short           *sptr ;
+       int                     k, bufferlen, writecount, count ;
+       sf_count_t      total = 0 ;
+       double          normfact ;
+
+       if (! psf->fdata)
+               return 0 ;
+       pima = (IMA_ADPCM_PRIVATE*) psf->fdata ;
+
+       normfact = (psf->norm_double == SF_TRUE) ? (1.0 * 0x7FFF) : 1.0 ;
+
+       sptr = psf->u.sbuf ;
+       bufferlen = ARRAY_LEN (psf->u.sbuf) ;
+       while (len > 0)
+       {       writecount = (len >= bufferlen) ? bufferlen : (int) len ;
+               for (k = 0 ; k < writecount ; k++)
+                       sptr [k] = lrint (normfact * ptr [total + k]) ;
+               count = ima_write_block (psf, pima, sptr, writecount) ;
+               total += count ;
+               len -= writecount ;
+               if (count != writecount)
+                       break ;
+               } ;
+
+       return total ;
+} /* ima_write_d */
+
+
+/*
+** Do not edit or modify anything in this comment block.
+** The arch-tag line is a file identity tag for the GNU Arch 
+** revision control system.
+**
+** arch-tag: 75a54b82-ad18-4758-9933-64e00a7f24e0
+*/
diff --git a/libs/libsndfile/src/interleave.c b/libs/libsndfile/src/interleave.c
new file mode 100644 (file)
index 0000000..7c18bd4
--- /dev/null
@@ -0,0 +1,306 @@
+/*
+** Copyright (C) 2002-2004 Erik de Castro Lopo <erikd@mega-nerd.com>
+**
+** This program is free software; you can redistribute it and/or modify
+** it under the terms of the GNU Lesser General Public License as published by
+** the Free Software Foundation; either version 2.1 of the License, or
+** (at your option) any later version.
+**
+** This program is distributed in the hope that it will be useful,
+** but WITHOUT ANY WARRANTY; without even the implied warranty of
+** MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+** GNU Lesser General Public License for more details.
+**
+** You should have received a copy of the GNU Lesser General Public License
+** along with this program; if not, write to the Free Software
+** Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA.
+*/
+
+#include       "sfendian.h"
+
+#include       <stdlib.h>
+
+#include       "sndfile.h"
+#include       "common.h"
+
+#define                INTERLEAVE_CHANNELS             6
+
+typedef struct
+{      double  buffer [SF_BUFFER_LEN / sizeof (double)] ;
+
+       sf_count_t              channel_len ;
+
+       sf_count_t              (*read_short)   (SF_PRIVATE*, short *ptr, sf_count_t len) ;
+       sf_count_t              (*read_int)     (SF_PRIVATE*, int *ptr, sf_count_t len) ;
+       sf_count_t              (*read_float)   (SF_PRIVATE*, float *ptr, sf_count_t len) ;
+       sf_count_t              (*read_double)  (SF_PRIVATE*, double *ptr, sf_count_t len) ;
+
+} INTERLEAVE_DATA ;
+
+
+
+static sf_count_t      interleave_read_short   (SF_PRIVATE *psf, short *ptr, sf_count_t len) ;
+static sf_count_t      interleave_read_int     (SF_PRIVATE *psf, int *ptr, sf_count_t len) ;
+static sf_count_t      interleave_read_float   (SF_PRIVATE *psf, float *ptr, sf_count_t len) ;
+static sf_count_t      interleave_read_double  (SF_PRIVATE *psf, double *ptr, sf_count_t len) ;
+
+static sf_count_t      interleave_seek (SF_PRIVATE*, int mode, sf_count_t samples_from_start) ;
+
+
+
+
+int
+interleave_init        (SF_PRIVATE *psf)
+{      INTERLEAVE_DATA *pdata ;
+
+       if (psf->mode != SFM_READ)
+               return SFE_INTERLEAVE_MODE ;
+
+       if (psf->interleave)
+       {       psf_log_printf (psf, "*** Weird, already have interleave.\n") ;
+               return 666 ;
+               } ;
+
+       /* Free this in sf_close() function. */
+       if (! (pdata = malloc (sizeof (INTERLEAVE_DATA))))
+               return SFE_MALLOC_FAILED ;
+
+puts ("interleave_init") ;
+
+       psf->interleave = pdata ;
+
+       /* Save the existing methods. */
+       pdata->read_short       = psf->read_short ;
+       pdata->read_int         = psf->read_int ;
+       pdata->read_float       = psf->read_float ;
+       pdata->read_double      = psf->read_double ;
+
+       pdata->channel_len = psf->sf.frames * psf->bytewidth ;
+
+       /* Insert our new methods. */
+       psf->read_short         = interleave_read_short ;
+       psf->read_int           = interleave_read_int ;
+       psf->read_float         = interleave_read_float ;
+       psf->read_double        = interleave_read_double ;
+
+       psf->seek = interleave_seek ;
+
+       return 0 ;
+} /* pcm_interleave_init */
+
+/*------------------------------------------------------------------------------
+*/
+
+static sf_count_t
+interleave_read_short  (SF_PRIVATE *psf, short *ptr, sf_count_t len)
+{      INTERLEAVE_DATA *pdata ;
+       sf_count_t      offset, templen ;
+       int                     chan, count, k ;
+       short           *inptr, *outptr ;
+
+       if (! (pdata = psf->interleave))
+               return 0 ;
+
+       inptr = (short*) pdata->buffer ;
+
+       for (chan = 0 ; chan < psf->sf.channels ; chan++)
+       {       outptr = ptr + chan ;
+
+               offset = psf->dataoffset + chan * psf->bytewidth * psf->read_current ;
+
+               if (psf_fseek (psf, offset, SEEK_SET) != offset)
+               {       psf->error = SFE_INTERLEAVE_SEEK ;
+                       return 0 ;
+                       } ;
+
+               templen = len / psf->sf.channels ;
+
+               while (templen > 0)
+               {       if (templen > SIGNED_SIZEOF (pdata->buffer) / SIGNED_SIZEOF (short))
+                               count = SIGNED_SIZEOF (pdata->buffer) / SIGNED_SIZEOF (short) ;
+                       else
+                               count = (int) templen ;
+
+                       if (pdata->read_short (psf, inptr, count) != count)
+                       {       psf->error = SFE_INTERLEAVE_READ ;
+                               return 0 ;
+                               } ;
+
+                       for (k = 0 ; k < count ; k++)
+                       {       *outptr = inptr [k] ;
+                               outptr += psf->sf.channels ;
+                               } ;
+
+                       templen -= count ;
+                       } ;
+               } ;
+
+       return len ;
+} /* interleave_read_short */
+
+static sf_count_t
+interleave_read_int    (SF_PRIVATE *psf, int *ptr, sf_count_t len)
+{      INTERLEAVE_DATA *pdata ;
+       sf_count_t      offset, templen ;
+       int                     chan, count, k ;
+       int             *inptr, *outptr ;
+
+       if (! (pdata = psf->interleave))
+               return 0 ;
+
+       inptr = (int*) pdata->buffer ;
+
+       for (chan = 0 ; chan < psf->sf.channels ; chan++)
+       {       outptr = ptr + chan ;
+
+               offset = psf->dataoffset + chan * psf->bytewidth * psf->read_current ;
+
+               if (psf_fseek (psf, offset, SEEK_SET) != offset)
+               {       psf->error = SFE_INTERLEAVE_SEEK ;
+                       return 0 ;
+                       } ;
+
+               templen = len / psf->sf.channels ;
+
+               while (templen > 0)
+               {       if (templen > SIGNED_SIZEOF (pdata->buffer) / SIGNED_SIZEOF (int))
+                               count = SIGNED_SIZEOF (pdata->buffer) / SIGNED_SIZEOF (int) ;
+                       else
+                               count = (int) templen ;
+
+                       if (pdata->read_int (psf, inptr, count) != count)
+                       {       psf->error = SFE_INTERLEAVE_READ ;
+                               return 0 ;
+                               } ;
+
+                       for (k = 0 ; k < count ; k++)
+                       {       *outptr = inptr [k] ;
+                               outptr += psf->sf.channels ;
+                               } ;
+
+                       templen -= count ;
+                       } ;
+               } ;
+
+       return len ;
+} /* interleave_read_int */
+
+static sf_count_t
+interleave_read_float  (SF_PRIVATE *psf, float *ptr, sf_count_t len)
+{      INTERLEAVE_DATA *pdata ;
+       sf_count_t      offset, templen ;
+       int                     chan, count, k ;
+       float           *inptr, *outptr ;
+
+       if (! (pdata = psf->interleave))
+               return 0 ;
+
+       inptr = (float*) pdata->buffer ;
+
+       for (chan = 0 ; chan < psf->sf.channels ; chan++)
+       {       outptr = ptr + chan ;
+
+               offset = psf->dataoffset + pdata->channel_len * chan + psf->read_current * psf->bytewidth ;
+
+/*-printf ("chan : %d     read_current : %6lld    offset : %6lld\n", chan, psf->read_current, offset) ;-*/
+
+               if (psf_fseek (psf, offset, SEEK_SET) != offset)
+               {       psf->error = SFE_INTERLEAVE_SEEK ;
+/*-puts ("interleave_seek error") ; exit (1) ;-*/
+                       return 0 ;
+                       } ;
+
+               templen = len / psf->sf.channels ;
+
+               while (templen > 0)
+               {       if (templen > SIGNED_SIZEOF (pdata->buffer) / SIGNED_SIZEOF (float))
+                               count = SIGNED_SIZEOF (pdata->buffer) / SIGNED_SIZEOF (float) ;
+                       else
+                               count = (int) templen ;
+
+                       if (pdata->read_float (psf, inptr, count) != count)
+                       {       psf->error = SFE_INTERLEAVE_READ ;
+/*-puts ("interleave_read error") ; exit (1) ;-*/
+                               return 0 ;
+                               } ;
+
+                       for (k = 0 ; k < count ; k++)
+                       {       *outptr = inptr [k] ;
+                               outptr += psf->sf.channels ;
+                               } ;
+
+                       templen -= count ;
+                       } ;
+               } ;
+
+       return len ;
+} /* interleave_read_float */
+
+static sf_count_t
+interleave_read_double (SF_PRIVATE *psf, double *ptr, sf_count_t len)
+{      INTERLEAVE_DATA *pdata ;
+       sf_count_t      offset, templen ;
+       int                     chan, count, k ;
+       double          *inptr, *outptr ;
+
+       if (! (pdata = psf->interleave))
+               return 0 ;
+
+       inptr = (double*) pdata->buffer ;
+
+       for (chan = 0 ; chan < psf->sf.channels ; chan++)
+       {       outptr = ptr + chan ;
+
+               offset = psf->dataoffset + chan * psf->bytewidth * psf->read_current ;
+
+               if (psf_fseek (psf, offset, SEEK_SET) != offset)
+               {       psf->error = SFE_INTERLEAVE_SEEK ;
+                       return 0 ;
+                       } ;
+
+               templen = len / psf->sf.channels ;
+
+               while (templen > 0)
+               {       if (templen > SIGNED_SIZEOF (pdata->buffer) / SIGNED_SIZEOF (double))
+                               count = SIGNED_SIZEOF (pdata->buffer) / SIGNED_SIZEOF (double) ;
+                       else
+                               count = (int) templen ;
+
+                       if (pdata->read_double (psf, inptr, count) != count)
+                       {       psf->error = SFE_INTERLEAVE_READ ;
+                               return 0 ;
+                               } ;
+
+                       for (k = 0 ; k < count ; k++)
+                       {       *outptr = inptr [k] ;
+                               outptr += psf->sf.channels ;
+                               } ;
+
+                       templen -= count ;
+                       } ;
+               } ;
+
+       return len ;
+} /* interleave_read_double */
+
+/*------------------------------------------------------------------------------
+*/
+
+static sf_count_t
+interleave_seek        (SF_PRIVATE *psf, int mode, sf_count_t samples_from_start)
+{      psf = psf ;     mode = mode ;
+
+       /*
+       ** Do nothing here. This is a place holder to prevent the default
+       ** seek function from being called.
+       */
+
+       return samples_from_start ;
+} /* interleave_seek */
+/*
+** Do not edit or modify anything in this comment block.
+** The arch-tag line is a file identity tag for the GNU Arch 
+** revision control system.
+**
+** arch-tag: 82314e13-0225-4408-a2f2-e6dab3f38904
+*/
diff --git a/libs/libsndfile/src/ircam.c b/libs/libsndfile/src/ircam.c
new file mode 100644 (file)
index 0000000..003809f
--- /dev/null
@@ -0,0 +1,331 @@
+/*
+** Copyright (C) 2001-2004 Erik de Castro Lopo <erikd@mega-nerd.com>
+**
+** This program is free software; you can redistribute it and/or modify
+** it under the terms of the GNU Lesser General Public License as published by
+** the Free Software Foundation; either version 2.1 of the License, or
+** (at your option) any later version.
+**
+** This program is distributed in the hope that it will be useful,
+** but WITHOUT ANY WARRANTY; without even the implied warranty of
+** MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+** GNU Lesser General Public License for more details.
+**
+** You should have received a copy of the GNU Lesser General Public License
+** along with this program; if not, write to the Free Software
+** Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA.
+*/
+
+#include       "sfconfig.h"
+
+#include       <stdio.h>
+#include       <fcntl.h>
+#include       <string.h>
+#include       <ctype.h>
+
+#include       "sndfile.h"
+#include       "sfendian.h"
+#include       "common.h"
+
+/*------------------------------------------------------------------------------
+** Macros to handle big/little endian issues.
+*/
+
+/* The IRCAM magic number is weird in that one byte in the number can have
+** values of 0x1, 0x2, 0x03 or 0x04. Hence the need for a marker and a mask.
+*/
+
+#define IRCAM_BE_MASK          (MAKE_MARKER (0xFF, 0xFF, 0x00, 0xFF))
+#define IRCAM_BE_MARKER                (MAKE_MARKER (0x64, 0xA3, 0x00, 0x00))
+
+#define IRCAM_LE_MASK          (MAKE_MARKER (0xFF, 0x00, 0xFF, 0xFF))
+#define IRCAM_LE_MARKER                (MAKE_MARKER (0x00, 0x00, 0xA3, 0x64))
+
+#define IRCAM_02B_MARKER       (MAKE_MARKER (0x64, 0xA3, 0x02, 0x00))
+#define IRCAM_03L_MARKER       (MAKE_MARKER (0x64, 0xA3, 0x03, 0x00))
+
+#define IRCAM_DATA_OFFSET      (1024)
+
+/*------------------------------------------------------------------------------
+** Typedefs.
+*/
+
+enum
+{      IRCAM_PCM_16    = 0x00002,
+       IRCAM_FLOAT             = 0x00004,
+       IRCAM_ALAW              = 0x10001,
+       IRCAM_ULAW              = 0x20001,
+       IRCAM_PCM_32    = 0x40004
+} ;
+
+
+/*------------------------------------------------------------------------------
+** Private static functions.
+*/
+
+static int             ircam_close                     (SF_PRIVATE *psf) ;
+static int             ircam_write_header      (SF_PRIVATE *psf, int calc_length) ;
+static int             ircam_read_header       (SF_PRIVATE *psf) ;
+
+static int             get_encoding (int subformat) ;
+
+static const char*     get_encoding_str (int encoding) ;
+
+/*------------------------------------------------------------------------------
+** Public function.
+*/
+
+int
+ircam_open     (SF_PRIVATE *psf)
+{      int             subformat ;
+       int             error = SFE_NO_ERROR ;
+
+       if (psf->mode == SFM_READ || (psf->mode == SFM_RDWR && psf->filelength > 0))
+       {       if ((error = ircam_read_header (psf)))
+                       return error ;
+               } ;
+
+       subformat = psf->sf.format & SF_FORMAT_SUBMASK ;
+
+       if (psf->mode == SFM_WRITE || psf->mode == SFM_RDWR)
+       {       if ((psf->sf.format & SF_FORMAT_TYPEMASK) != SF_FORMAT_IRCAM)
+                       return  SFE_BAD_OPEN_FORMAT ;
+
+               psf->endian = psf->sf.format & SF_FORMAT_ENDMASK ;
+               if (psf->endian == 0 || psf->endian == SF_ENDIAN_CPU)
+                       psf->endian = (CPU_IS_BIG_ENDIAN) ? SF_ENDIAN_BIG : SF_ENDIAN_LITTLE ;
+
+               psf->dataoffset = IRCAM_DATA_OFFSET ;
+
+               if ((error = ircam_write_header (psf, SF_FALSE)))
+                       return error ;
+
+               psf->write_header = ircam_write_header ;
+               } ;
+
+       psf->container_close = ircam_close ;
+
+       switch (subformat)
+       {       case SF_FORMAT_ULAW :           /* 8-bit Ulaw encoding. */
+                               error = ulaw_init (psf) ;
+                               break ;
+
+               case SF_FORMAT_ALAW :           /* 8-bit Alaw encoding. */
+                               error = alaw_init (psf) ;
+                               break ;
+
+               case SF_FORMAT_PCM_16 : /* 16-bit linear PCM. */
+               case SF_FORMAT_PCM_32 : /* 32-bit linear PCM. */
+                               error = pcm_init (psf) ;
+                               break ;
+
+               case SF_FORMAT_FLOAT :  /* 32-bit linear PCM. */
+                               error = float32_init (psf) ;
+                               break ;
+
+               default : break ;
+               } ;
+
+       return error ;
+} /* ircam_open */
+
+/*------------------------------------------------------------------------------
+*/
+
+static int
+ircam_read_header      (SF_PRIVATE *psf)
+{      unsigned int    marker, encoding ;
+       float                   samplerate ;
+       int                             error = SFE_NO_ERROR ;
+
+       psf_binheader_readf (psf, "epmf44", 0, &marker, &samplerate, &(psf->sf.channels), &encoding) ;
+
+       if (((marker & IRCAM_BE_MASK) != IRCAM_BE_MARKER) && ((marker & IRCAM_LE_MASK) != IRCAM_LE_MARKER))
+       {       psf_log_printf (psf, "marker: 0x%X\n", marker) ;
+               return SFE_IRCAM_NO_MARKER ;
+               } ;
+
+       psf->endian = SF_ENDIAN_LITTLE ;
+
+       if (psf->sf.channels > 256)
+       {       psf_binheader_readf (psf, "Epmf44", 0, &marker, &samplerate, &(psf->sf.channels), &encoding) ;
+
+               /* Sanity checking for endian-ness detection. */
+               if (psf->sf.channels > 256)
+               {       psf_log_printf (psf, "marker: 0x%X\n", marker) ;
+                       return SFE_IRCAM_BAD_CHANNELS ;
+                       } ;
+
+               psf->endian = SF_ENDIAN_BIG ;
+               } ;
+
+       psf_log_printf (psf, "marker: 0x%X\n", marker) ;
+
+       psf->sf.samplerate = (int) samplerate ;
+
+       psf_log_printf (psf, "  Sample Rate : %d\n"
+                                                "  Channels    : %d\n"
+                                                "  Encoding    : %X => %s\n", psf->sf.samplerate, psf->sf.channels, encoding, get_encoding_str (encoding)) ;
+
+       switch (encoding)
+       {       case IRCAM_PCM_16 :
+                               psf->bytewidth = 2 ;
+                               psf->blockwidth = psf->sf.channels * psf->bytewidth ;
+
+                               psf->sf.format = SF_FORMAT_IRCAM | SF_FORMAT_PCM_16 ;
+                               break ;
+
+               case IRCAM_PCM_32 :
+                               psf->bytewidth = 4 ;
+                               psf->blockwidth = psf->sf.channels * psf->bytewidth ;
+
+                               psf->sf.format = SF_FORMAT_IRCAM | SF_FORMAT_PCM_32 ;
+                               break ;
+
+               case IRCAM_FLOAT :
+                               psf->bytewidth = 4 ;
+                               psf->blockwidth = psf->sf.channels * psf->bytewidth ;
+
+                               psf->sf.format = SF_FORMAT_IRCAM | SF_FORMAT_FLOAT ;
+                               break ;
+
+               case IRCAM_ALAW :
+                               psf->bytewidth = 1 ;
+                               psf->blockwidth = psf->sf.channels * psf->bytewidth ;
+
+                               psf->sf.format = SF_FORMAT_IRCAM | SF_FORMAT_ALAW ;
+                               break ;
+
+               case IRCAM_ULAW :
+                               psf->bytewidth = 1 ;
+                               psf->blockwidth = psf->sf.channels * psf->bytewidth ;
+
+                               psf->sf.format = SF_FORMAT_IRCAM | SF_FORMAT_ULAW ;
+                               break ;
+
+               default :
+                               error = SFE_IRCAM_UNKNOWN_FORMAT ;
+                               break ;
+               } ;
+
+       if (psf->endian == SF_ENDIAN_BIG)
+               psf->sf.format |= SF_ENDIAN_BIG ;
+       else
+               psf->sf.format |= SF_ENDIAN_LITTLE ;
+
+       if (error)
+               return error ;
+
+       psf->dataoffset = IRCAM_DATA_OFFSET ;
+       psf->datalength = psf->filelength - psf->dataoffset ;
+
+       if (psf->sf.frames == 0 && psf->blockwidth)
+               psf->sf.frames = psf->datalength / psf->blockwidth ;
+
+       psf_log_printf (psf, "  Samples     : %d\n", psf->sf.frames) ;
+
+       psf_binheader_readf (psf, "p", IRCAM_DATA_OFFSET) ;
+
+       return 0 ;
+} /* ircam_read_header */
+
+static int
+ircam_close    (SF_PRIVATE *psf)
+{
+       psf_log_printf (psf, "close\n") ;
+
+       return 0 ;
+} /* ircam_close */
+
+static int
+ircam_write_header (SF_PRIVATE *psf, int calc_length)
+{      int                     encoding ;
+       float           samplerate ;
+       sf_count_t      current ;
+
+       if (psf->pipeoffset > 0)
+               return 0 ;
+
+       current = psf_ftell (psf) ;
+
+       calc_length = calc_length ;
+
+       /* This also sets psf->endian. */
+       encoding = get_encoding (psf->sf.format & SF_FORMAT_SUBMASK) ;
+
+       if (encoding == 0)
+               return SFE_BAD_OPEN_FORMAT ;
+
+       /* Reset the current header length to zero. */
+       psf->header [0] = 0 ;
+       psf->headindex = 0 ;
+
+       if (psf->is_pipe == SF_FALSE)
+               psf_fseek (psf, 0, SEEK_SET) ;
+
+       samplerate = psf->sf.samplerate ;
+
+       switch (psf->endian)
+       {       case SF_ENDIAN_BIG :
+                       psf_binheader_writef (psf, "Emf", IRCAM_02B_MARKER, samplerate) ;
+                       psf_binheader_writef (psf, "E44", psf->sf.channels, encoding) ;
+                       break ;
+
+               case SF_ENDIAN_LITTLE :
+                       psf_binheader_writef (psf, "emf", IRCAM_03L_MARKER, samplerate) ;
+                       psf_binheader_writef (psf, "e44", psf->sf.channels, encoding) ;
+                       break ;
+
+               default : return SFE_BAD_OPEN_FORMAT ;
+               } ;
+
+       psf_binheader_writef (psf, "z", (size_t) (IRCAM_DATA_OFFSET - psf->headindex)) ;
+
+       /* Header construction complete so write it out. */
+       psf_fwrite (psf->header, psf->headindex, 1, psf) ;
+
+       if (psf->error)
+               return psf->error ;
+
+       if (current > 0)
+               psf_fseek (psf, current, SEEK_SET) ;
+
+       return psf->error ;
+} /* ircam_write_header */
+
+static int
+get_encoding (int subformat)
+{      switch (subformat)
+       {       case SF_FORMAT_PCM_16 : return IRCAM_PCM_16 ;
+               case SF_FORMAT_PCM_32 : return IRCAM_PCM_32 ;
+
+               case SF_FORMAT_FLOAT :  return IRCAM_FLOAT ;
+
+               case SF_FORMAT_ULAW :   return IRCAM_ULAW ;
+               case SF_FORMAT_ALAW :   return IRCAM_ALAW ;
+
+               default : break ;
+               } ;
+
+       return 0 ;
+} /* get_encoding */
+
+static const char*
+get_encoding_str (int encoding)
+{      switch (encoding)
+       {       case IRCAM_PCM_16       : return "16 bit PCM" ;
+               case IRCAM_FLOAT        : return "32 bit float" ;
+               case IRCAM_ALAW         : return "A law" ;
+               case IRCAM_ULAW         : return "u law" ;
+               case IRCAM_PCM_32       : return "32 bit PCM" ;
+               } ;
+       return "Unknown encoding" ;
+} /* get_encoding_str */
+
+/*
+** Do not edit or modify anything in this comment block.
+** The arch-tag line is a file identity tag for the GNU Arch 
+** revision control system.
+**
+** arch-tag: f2714ab8-f286-4c94-9740-edaf673a1c71
+*/
diff --git a/libs/libsndfile/src/libsndfile.def b/libs/libsndfile/src/libsndfile.def
new file mode 100644 (file)
index 0000000..7b14453
--- /dev/null
@@ -0,0 +1,39 @@
+; Auto-generated by create_symbols_file.py
+
+LIBRARY libsndfile-1.dll
+EXPORTS
+
+sf_command           @1
+sf_open              @2
+sf_close             @3
+sf_seek              @4
+sf_error             @7
+sf_perror            @8
+sf_error_str         @9
+sf_error_number      @10
+sf_format_check      @11
+sf_read_raw          @16
+sf_readf_short       @17
+sf_readf_int         @18
+sf_readf_float       @19
+sf_readf_double      @20
+sf_read_short        @21
+sf_read_int          @22
+sf_read_float        @23
+sf_read_double       @24
+sf_write_raw         @32
+sf_writef_short      @33
+sf_writef_int        @34
+sf_writef_float      @35
+sf_writef_double     @36
+sf_write_short       @37
+sf_write_int         @38
+sf_write_float       @39
+sf_write_double      @40
+sf_strerror          @50
+sf_get_string        @60
+sf_set_string        @61
+sf_open_fd           @70
+sf_open_virtual      @80
+sf_write_sync        @90
+
diff --git a/libs/libsndfile/src/macbinary3.c b/libs/libsndfile/src/macbinary3.c
new file mode 100644 (file)
index 0000000..32a1059
--- /dev/null
@@ -0,0 +1,58 @@
+/*
+** Copyright (C) 2003-2005 Erik de Castro Lopo <erikd@mega-nerd.com>
+**
+** This program is free software; you can redistribute it and/or modify
+** it under the terms of the GNU Lesser General Public License as published by
+** the Free Software Foundation; either version 2.1 of the License, or
+** (at your option) any later version.
+**
+** This program is distributed in the hope that it will be useful,
+** but WITHOUT ANY WARRANTY; without even the implied warranty of
+** MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+** GNU Lesser General Public License for more details.
+**
+** You should have received a copy of the GNU Lesser General Public License
+** along with this program; if not, write to the Free Software
+** Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA.
+*/
+
+#include       "sfconfig.h"
+
+#include       <stdlib.h>
+#include       <string.h>
+
+#include       "sndfile.h"
+#include       "sfendian.h"
+#include       "common.h"
+
+#if (OS_IS_MACOSX == 1)
+
+#include       <CoreServices/CoreServices.h>
+
+int
+macbinary3_open (SF_PRIVATE *psf)
+{
+       if (psf)
+               return 0 ;
+
+       return 0 ;
+} /* macbinary3_open */
+
+#else
+
+int
+macbinary3_open (SF_PRIVATE *psf)
+{
+       psf = psf ;
+       return 0 ;
+} /* macbinary3_open */
+
+#endif /* OS_IS_MACOSX */
+
+/*
+** Do not edit or modify anything in this comment block.
+** The arch-tag line is a file identity tag for the GNU Arch 
+** revision control system.
+**
+** arch-tag: c397a7d7-1a31-4349-9684-bd29ef06211e
+*/
diff --git a/libs/libsndfile/src/macos.c b/libs/libsndfile/src/macos.c
new file mode 100644 (file)
index 0000000..bb5543a
--- /dev/null
@@ -0,0 +1,63 @@
+/*
+** Copyright (C) 2003-2005 Erik de Castro Lopo <erikd@mega-nerd.com>
+**
+** This program is free software; you can redistribute it and/or modify
+** it under the terms of the GNU Lesser General Public License as published by
+** the Free Software Foundation; either version 2.1 of the License, or
+** (at your option) any later version.
+**
+** This program is distributed in the hope that it will be useful,
+** but WITHOUT ANY WARRANTY; without even the implied warranty of
+** MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+** GNU Lesser General Public License for more details.
+**
+** You should have received a copy of the GNU Lesser General Public License
+** along with this program; if not, write to the Free Software
+** Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA.
+*/
+
+#include       "sfconfig.h"
+
+#include       <stdlib.h>
+#include       <string.h>
+#include       <sys/stat.h>
+
+#include       "sndfile.h"
+#include       "sfendian.h"
+#include       "common.h"
+
+#define        STR_MARKER      MAKE_MARKER ('S', 'T', 'R', ' ')
+
+int
+macos_guess_file_type (SF_PRIVATE *psf, const char *filename)
+{      static char rsrc_name [1024] ;
+       struct stat statbuf ;
+       int format ;
+
+       psf = psf ;
+
+       snprintf (rsrc_name, sizeof (rsrc_name), "%s/rsrc", filename) ;
+
+       /* If there is no resource fork, just return. */
+       if (stat (rsrc_name, &statbuf) != 0)
+       {       psf_log_printf (psf, "No resource fork.\n") ;
+               return 0 ;
+               } ;
+
+       if (statbuf.st_size == 0)
+       {       psf_log_printf (psf, "Have zero size resource fork.\n") ;
+               return 0 ;
+               } ;
+
+       format = 0 ;
+
+       return format ;
+} /* macos_guess_file_type */
+
+/*
+** Do not edit or modify anything in this comment block.
+** The arch-tag line is a file identity tag for the GNU Arch 
+** revision control system.
+**
+** arch-tag: 5fbf66d7-9547-442a-9c73-92fd164f3a95
+*/
diff --git a/libs/libsndfile/src/mat4.c b/libs/libsndfile/src/mat4.c
new file mode 100644 (file)
index 0000000..fcc6111
--- /dev/null
@@ -0,0 +1,394 @@
+/*
+** Copyright (C) 2002-2004 Erik de Castro Lopo <erikd@mega-nerd.com>
+**
+** This program is free software; you can redistribute it and/or modify
+** it under the terms of the GNU Lesser General Public License as published by
+** the Free Software Foundation; either version 2.1 of the License, or
+** (at your option) any later version.
+**
+** This program is distributed in the hope that it will be useful,
+** but WITHOUT ANY WARRANTY; without even the implied warranty of
+** MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+** GNU Lesser General Public License for more details.
+**
+** You should have received a copy of the GNU Lesser General Public License
+** along with this program; if not, write to the Free Software
+** Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA.
+*/
+
+#include       "sfconfig.h"
+
+#include       <stdio.h>
+#include       <fcntl.h>
+#include       <string.h>
+#include       <ctype.h>
+
+#include       "sndfile.h"
+#include       "sfendian.h"
+#include       "common.h"
+#include       "float_cast.h"
+
+/*------------------------------------------------------------------------------
+** Information on how to decode and encode this file was obtained in a PDF
+** file which I found on http://www.wotsit.org/.
+** Also did a lot of testing with GNU Octave but do not have access to
+** Matlab (tm) and so could not test it there.
+*/
+
+/*------------------------------------------------------------------------------
+** Macros to handle big/little endian issues.
+*/
+
+#define MAT4_BE_DOUBLE (MAKE_MARKER (0, 0, 0x03, 0xE8))
+#define MAT4_LE_DOUBLE (MAKE_MARKER (0, 0, 0, 0))
+
+#define MAT4_BE_FLOAT  (MAKE_MARKER (0, 0, 0x03, 0xF2))
+#define MAT4_LE_FLOAT  (MAKE_MARKER (0x0A, 0, 0, 0))
+
+#define MAT4_BE_PCM_32 (MAKE_MARKER (0, 0, 0x03, 0xFC))
+#define MAT4_LE_PCM_32 (MAKE_MARKER (0x14, 0, 0, 0))
+
+#define MAT4_BE_PCM_16 (MAKE_MARKER (0, 0, 0x04, 0x06))
+#define MAT4_LE_PCM_16 (MAKE_MARKER (0x1E, 0, 0, 0))
+
+/* Can't see any reason to ever implement this. */
+#define MAT4_BE_PCM_U8 (MAKE_MARKER (0, 0, 0x04, 0x1A))
+#define MAT4_LE_PCM_U8 (MAKE_MARKER (0x32, 0, 0, 0))
+
+/*------------------------------------------------------------------------------
+** Private static functions.
+*/
+
+static int             mat4_close              (SF_PRIVATE *psf) ;
+
+static int     mat4_format_to_encoding (int format, int endian) ;
+
+static int             mat4_write_header (SF_PRIVATE *psf, int calc_length) ;
+static int             mat4_read_header (SF_PRIVATE *psf) ;
+
+static const char * mat4_marker_to_str (int marker) ;
+
+/*------------------------------------------------------------------------------
+** Public function.
+*/
+
+int
+mat4_open      (SF_PRIVATE *psf)
+{      int             subformat, error = 0 ;
+
+       if (psf->mode == SFM_READ || (psf->mode == SFM_RDWR && psf->filelength > 0))
+       {       if ((error = mat4_read_header (psf)))
+                       return error ;
+               } ;
+
+       if ((psf->sf.format & SF_FORMAT_TYPEMASK) != SF_FORMAT_MAT4)
+               return  SFE_BAD_OPEN_FORMAT ;
+
+       subformat = psf->sf.format & SF_FORMAT_SUBMASK ;
+
+       if (psf->mode == SFM_WRITE || psf->mode == SFM_RDWR)
+       {       if (psf->is_pipe)
+                       return SFE_NO_PIPE_WRITE ;
+
+               psf->endian = psf->sf.format & SF_FORMAT_ENDMASK ;
+               if (CPU_IS_LITTLE_ENDIAN && (psf->endian == SF_ENDIAN_CPU || psf->endian == 0))
+                       psf->endian = SF_ENDIAN_LITTLE ;
+               else if (CPU_IS_BIG_ENDIAN && (psf->endian == SF_ENDIAN_CPU || psf->endian == 0))
+                       psf->endian = SF_ENDIAN_BIG ;
+
+               if ((error = mat4_write_header (psf, SF_FALSE)))
+                       return error ;
+
+               psf->write_header = mat4_write_header ;
+               } ;
+
+       psf->container_close = mat4_close ;
+
+       psf->blockwidth = psf->bytewidth * psf->sf.channels ;
+
+       switch (subformat)
+       {       case SF_FORMAT_PCM_16 :
+               case SF_FORMAT_PCM_32 :
+                               error = pcm_init (psf) ;
+                               break ;
+
+               case SF_FORMAT_FLOAT :
+                               error = float32_init (psf) ;
+                               break ;
+
+               case SF_FORMAT_DOUBLE :
+                               error = double64_init (psf) ;
+                               break ;
+
+               default : break ;
+               } ;
+
+       if (error)
+               return error ;
+
+       return error ;
+} /* mat4_open */
+
+/*------------------------------------------------------------------------------
+*/
+
+static int
+mat4_close     (SF_PRIVATE *psf)
+{
+       if (psf->mode == SFM_WRITE || psf->mode == SFM_RDWR)
+               mat4_write_header (psf, SF_TRUE) ;
+
+       return 0 ;
+} /* mat4_close */
+
+/*------------------------------------------------------------------------------
+*/
+
+static int
+mat4_write_header (SF_PRIVATE *psf, int calc_length)
+{      sf_count_t      current ;
+       int                     encoding ;
+       double          samplerate ;
+
+       current = psf_ftell (psf) ;
+
+       if (calc_length)
+       {       psf->filelength = psf_get_filelen (psf) ;
+
+               psf->datalength = psf->filelength - psf->dataoffset ;
+               if (psf->dataend)
+                       psf->datalength -= psf->filelength - psf->dataend ;
+
+               psf->sf.frames = psf->datalength / (psf->bytewidth * psf->sf.channels) ;
+               } ;
+
+       encoding = mat4_format_to_encoding (psf->sf.format & SF_FORMAT_SUBMASK, psf->endian) ;
+
+       if (encoding == -1)
+               return SFE_BAD_OPEN_FORMAT ;
+
+       /* Reset the current header length to zero. */
+       psf->header [0] = 0 ;
+       psf->headindex = 0 ;
+       psf_fseek (psf, 0, SEEK_SET) ;
+
+       /* Need sample rate as a double for writing to the header. */
+       samplerate = psf->sf.samplerate ;
+
+       if (psf->endian == SF_ENDIAN_BIG)
+       {       psf_binheader_writef (psf, "Em444", MAT4_BE_DOUBLE, 1, 1, 0) ;
+               psf_binheader_writef (psf, "E4bd", 11, "samplerate", 11, samplerate) ;
+               psf_binheader_writef (psf, "tEm484", encoding, psf->sf.channels, psf->sf.frames, 0) ;
+               psf_binheader_writef (psf, "E4b", 9, "wavedata", 9) ;
+               }
+       else if (psf->endian == SF_ENDIAN_LITTLE)
+       {       psf_binheader_writef (psf, "em444", MAT4_LE_DOUBLE, 1, 1, 0) ;
+               psf_binheader_writef (psf, "e4bd", 11, "samplerate", 11, samplerate) ;
+               psf_binheader_writef (psf, "tem484", encoding, psf->sf.channels, psf->sf.frames, 0) ;
+               psf_binheader_writef (psf, "e4b", 9, "wavedata", 9) ;
+               }
+       else
+               return SFE_BAD_OPEN_FORMAT ;
+
+       /* Header construction complete so write it out. */
+       psf_fwrite (psf->header, psf->headindex, 1, psf) ;
+
+       if (psf->error)
+               return psf->error ;
+
+       psf->dataoffset = psf->headindex ;
+
+       if (current > 0)
+               psf_fseek (psf, current, SEEK_SET) ;
+
+       return psf->error ;
+} /* mat4_write_header */
+
+static int
+mat4_read_header (SF_PRIVATE *psf)
+{      int             marker, namesize, rows, cols, imag ;
+       double  value ;
+       const char *marker_str ;
+       char    name [64] ;
+
+       psf_binheader_readf (psf, "pm", 0, &marker) ;
+
+       /* MAT4 file must start with a double for the samplerate. */
+       if (marker == MAT4_BE_DOUBLE)
+       {       psf->endian = psf->rwf_endian = SF_ENDIAN_BIG ;
+               marker_str = "big endian double" ;
+               }
+       else if (marker == MAT4_LE_DOUBLE)
+       {       psf->endian = psf->rwf_endian = SF_ENDIAN_LITTLE ;
+               marker_str = "little endian double" ;
+               }
+       else
+               return SFE_UNIMPLEMENTED ;
+
+       psf_log_printf (psf, "GNU Octave 2.0 / MATLAB v4.2 format\nMarker : %s\n", marker_str) ;
+
+       psf_binheader_readf (psf, "444", &rows, &cols, &imag) ;
+
+       psf_log_printf (psf, " Rows  : %d\n Cols  : %d\n Imag  : %s\n", rows, cols, imag ? "True" : "False") ;
+
+       psf_binheader_readf (psf, "4", &namesize) ;
+
+       if (namesize >= SIGNED_SIZEOF (name))
+               return SFE_MAT4_BAD_NAME ;
+
+       psf_binheader_readf (psf, "b", name, namesize) ;
+       name [namesize] = 0 ;
+
+       psf_log_printf (psf, " Name  : %s\n", name) ;
+
+       psf_binheader_readf (psf, "d", &value) ;
+
+       LSF_SNPRINTF (psf->u.cbuf, sizeof (psf->u.cbuf), " Value : %f\n", value) ;
+       psf_log_printf (psf, psf->u.cbuf) ;
+
+       if ((rows != 1) || (cols != 1))
+               return SFE_MAT4_NO_SAMPLERATE ;
+
+       psf->sf.samplerate = lrint (value) ;
+
+       /* Now write out the audio data. */
+
+       psf_binheader_readf (psf, "m", &marker) ;
+
+       psf_log_printf (psf, "Marker : %s\n", mat4_marker_to_str (marker)) ;
+
+       psf_binheader_readf (psf, "444", &rows, &cols, &imag) ;
+
+       psf_log_printf (psf, " Rows  : %d\n Cols  : %d\n Imag  : %s\n", rows, cols, imag ? "True" : "False") ;
+
+       psf_binheader_readf (psf, "4", &namesize) ;
+
+       if (namesize >= SIGNED_SIZEOF (name))
+               return SFE_MAT4_BAD_NAME ;
+
+       psf_binheader_readf (psf, "b", name, namesize) ;
+       name [namesize] = 0 ;
+
+       psf_log_printf (psf, " Name  : %s\n", name) ;
+
+       psf->dataoffset = psf_ftell (psf) ;
+
+       if (rows == 0 && cols == 0)
+       {       psf_log_printf (psf, "*** Error : zero channel count.\n") ;
+               return SFE_MAT4_ZERO_CHANNELS ;
+               } ;
+
+       psf->sf.channels        = rows ;
+       psf->sf.frames          = cols ;
+
+       psf->sf.format = psf->endian | SF_FORMAT_MAT4 ;
+       switch (marker)
+       {       case MAT4_BE_DOUBLE :
+               case MAT4_LE_DOUBLE :
+                               psf->sf.format |= SF_FORMAT_DOUBLE ;
+                               psf->bytewidth = 8 ;
+                               break ;
+
+               case MAT4_BE_FLOAT :
+               case MAT4_LE_FLOAT :
+                               psf->sf.format |= SF_FORMAT_FLOAT ;
+                               psf->bytewidth = 4 ;
+                               break ;
+
+               case MAT4_BE_PCM_32     :
+               case MAT4_LE_PCM_32     :
+                               psf->sf.format |= SF_FORMAT_PCM_32 ;
+                               psf->bytewidth = 4 ;
+                               break ;
+
+               case MAT4_BE_PCM_16     :
+               case MAT4_LE_PCM_16     :
+                               psf->sf.format |= SF_FORMAT_PCM_16 ;
+                               psf->bytewidth = 2 ;
+                               break ;
+
+               default :
+                               psf_log_printf (psf, "*** Error : Bad marker %08X\n", marker) ;
+                               return SFE_UNIMPLEMENTED ;
+               } ;
+
+       if ((psf->filelength - psf->dataoffset) < psf->sf.channels * psf->sf.frames * psf->bytewidth)
+       {       psf_log_printf (psf, "*** File seems to be truncated. %D <--> %D\n",
+                               psf->filelength - psf->dataoffset, psf->sf.channels * psf->sf.frames * psf->bytewidth) ;
+               }
+       else if ((psf->filelength - psf->dataoffset) > psf->sf.channels * psf->sf.frames * psf->bytewidth)
+               psf->dataend = psf->dataoffset + rows * cols * psf->bytewidth ;
+
+       psf->datalength = psf->filelength - psf->dataoffset - psf->dataend ;
+
+       psf->sf.sections = 1 ;
+
+       return 0 ;
+} /* mat4_read_header */
+
+static int
+mat4_format_to_encoding (int format, int endian)
+{
+       switch (format | endian)
+       {       case (SF_FORMAT_PCM_16 | SF_ENDIAN_BIG) :
+                               return MAT4_BE_PCM_16 ;
+
+               case (SF_FORMAT_PCM_16 | SF_ENDIAN_LITTLE) :
+                               return MAT4_LE_PCM_16 ;
+
+               case (SF_FORMAT_PCM_32 | SF_ENDIAN_BIG) :
+                               return MAT4_BE_PCM_32 ;
+
+               case (SF_FORMAT_PCM_32 | SF_ENDIAN_LITTLE) :
+                               return MAT4_LE_PCM_32 ;
+
+               case (SF_FORMAT_FLOAT | SF_ENDIAN_BIG) :
+                               return MAT4_BE_FLOAT ;
+
+               case (SF_FORMAT_FLOAT | SF_ENDIAN_LITTLE) :
+                               return MAT4_LE_FLOAT ;
+
+               case (SF_FORMAT_DOUBLE | SF_ENDIAN_BIG) :
+                               return MAT4_BE_DOUBLE ;
+
+               case (SF_FORMAT_DOUBLE | SF_ENDIAN_LITTLE) :
+                               return MAT4_LE_DOUBLE ;
+
+               default : break ;
+               } ;
+
+       return -1 ;
+} /* mat4_format_to_encoding */
+
+static const char *
+mat4_marker_to_str (int marker)
+{      static char str [32] ;
+
+       switch (marker)
+       {
+               case MAT4_BE_PCM_16     :       return "big endian 16 bit PCM" ;
+               case MAT4_LE_PCM_16     :       return "little endian 16 bit PCM" ;
+
+               case MAT4_BE_PCM_32     :       return "big endian 32 bit PCM" ;
+               case MAT4_LE_PCM_32     :       return "little endian 32 bit PCM" ;
+
+
+               case MAT4_BE_FLOAT :    return "big endian float" ;
+               case MAT4_LE_FLOAT :    return "big endian float" ;
+
+               case MAT4_BE_DOUBLE     :       return "big endian double" ;
+               case MAT4_LE_DOUBLE     :       return "little endian double" ;
+               } ;
+
+       /* This is a little unsafe but is really only for debugging. */
+       str [sizeof (str) - 1] = 0 ;
+       LSF_SNPRINTF (str, sizeof (str) - 1, "%08X", marker) ;
+       return str ;
+} /* mat4_marker_to_str */
+/*
+** Do not edit or modify anything in this comment block.
+** The arch-tag line is a file identity tag for the GNU Arch 
+** revision control system.
+**
+** arch-tag: f7e5f5d6-fc39-452e-bc4a-59627116ff59
+*/
diff --git a/libs/libsndfile/src/mat5.c b/libs/libsndfile/src/mat5.c
new file mode 100644 (file)
index 0000000..dfef7b5
--- /dev/null
@@ -0,0 +1,507 @@
+/*
+** Copyright (C) 2002-2004 Erik de Castro Lopo <erikd@mega-nerd.com>
+**
+** This program is free software; you can redistribute it and/or modify
+** it under the terms of the GNU Lesser General Public License as published by
+** the Free Software Foundation; either version 2.1 of the License, or
+** (at your option) any later version.
+**
+** This program is distributed in the hope that it will be useful,
+** but WITHOUT ANY WARRANTY; without even the implied warranty of
+** MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+** GNU Lesser General Public License for more details.
+**
+** You should have received a copy of the GNU Lesser General Public License
+** along with this program; if not, write to the Free Software
+** Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA.
+*/
+
+#include       "sfconfig.h"
+
+#include       <stdio.h>
+#include       <fcntl.h>
+#include       <string.h>
+#include       <ctype.h>
+
+#include       "sndfile.h"
+#include       "sfendian.h"
+#include       "common.h"
+#include       "float_cast.h"
+
+/*------------------------------------------------------------------------------
+** Information on how to decode and encode this file was obtained in a PDF
+** file which I found on http://www.wotsit.org/.
+** Also did a lot of testing with GNU Octave but do not have access to
+** Matlab (tm) and so could not test it there.
+*/
+
+/*------------------------------------------------------------------------------
+** Macros to handle big/little endian issues.
+*/
+
+#define MATL_MARKER    (MAKE_MARKER ('M', 'A', 'T', 'L'))
+
+#define IM_MARKER      (('I' << 8) + 'M')
+#define MI_MARKER      (('M' << 8) + 'I')
+
+/*------------------------------------------------------------------------------
+** Enums and typedefs.
+*/
+
+enum
+{      MAT5_TYPE_SCHAR                 = 0x1,
+       MAT5_TYPE_UCHAR                 = 0x2,
+       MAT5_TYPE_INT16                 = 0x3,
+       MAT5_TYPE_UINT16                = 0x4,
+       MAT5_TYPE_INT32                 = 0x5,
+       MAT5_TYPE_UINT32                = 0x6,
+       MAT5_TYPE_FLOAT                 = 0x7,
+       MAT5_TYPE_DOUBLE                = 0x9,
+       MAT5_TYPE_ARRAY                 = 0xE,
+
+       MAT5_TYPE_COMP_USHORT   = 0x00020004,
+       MAT5_TYPE_COMP_UINT             = 0x00040006
+} ;
+
+typedef struct
+{      sf_count_t      size ;
+       int                     rows, cols ;
+       char            name [32] ;
+} MAT5_MATRIX ;
+
+/*------------------------------------------------------------------------------
+** Private static functions.
+*/
+
+static int             mat5_close              (SF_PRIVATE *psf) ;
+
+static int             mat5_write_header (SF_PRIVATE *psf, int calc_length) ;
+static int             mat5_read_header (SF_PRIVATE *psf) ;
+
+/*------------------------------------------------------------------------------
+** Public function.
+*/
+
+int
+mat5_open      (SF_PRIVATE *psf)
+{      int             subformat, error = 0 ;
+
+       if (psf->mode == SFM_READ || (psf->mode == SFM_RDWR && psf->filelength > 0))
+       {       if ((error = mat5_read_header (psf)))
+                       return error ;
+               } ;
+
+       if ((psf->sf.format & SF_FORMAT_TYPEMASK) != SF_FORMAT_MAT5)
+               return  SFE_BAD_OPEN_FORMAT ;
+
+       subformat = psf->sf.format & SF_FORMAT_SUBMASK ;
+
+       if (psf->mode == SFM_WRITE || psf->mode == SFM_RDWR)
+       {       if (psf->is_pipe)
+                       return SFE_NO_PIPE_WRITE ;
+
+               psf->endian = psf->sf.format & SF_FORMAT_ENDMASK ;
+               if (CPU_IS_LITTLE_ENDIAN && (psf->endian == SF_ENDIAN_CPU || psf->endian == 0))
+                       psf->endian = SF_ENDIAN_LITTLE ;
+               else if (CPU_IS_BIG_ENDIAN && (psf->endian == SF_ENDIAN_CPU || psf->endian == 0))
+                       psf->endian = SF_ENDIAN_BIG ;
+
+               if ((error = mat5_write_header (psf, SF_FALSE)))
+                       return error ;
+
+               psf->write_header = mat5_write_header ;
+               } ;
+
+       psf->container_close = mat5_close ;
+
+       psf->blockwidth = psf->bytewidth * psf->sf.channels ;
+
+       switch (subformat)
+       {       case SF_FORMAT_PCM_U8 :
+               case SF_FORMAT_PCM_16 :
+               case SF_FORMAT_PCM_32 :
+                               error = pcm_init (psf) ;
+                               break ;
+
+               case SF_FORMAT_FLOAT :
+                               error = float32_init (psf) ;
+                               break ;
+
+               case SF_FORMAT_DOUBLE :
+                               error = double64_init (psf) ;
+                               break ;
+
+               default : break ;
+               } ;
+
+       return error ;
+} /* mat5_open */
+
+/*------------------------------------------------------------------------------
+*/
+
+static int
+mat5_close     (SF_PRIVATE *psf)
+{
+       if (psf->mode == SFM_WRITE || psf->mode == SFM_RDWR)
+               mat5_write_header (psf, SF_TRUE) ;
+
+       return 0 ;
+} /* mat5_close */
+
+/*------------------------------------------------------------------------------
+*/
+
+static int
+mat5_write_header (SF_PRIVATE *psf, int calc_length)
+{      static const char       *filename = "MATLAB 5.0 MAT-file, written by " PACKAGE "-" VERSION ", " ;
+       static const char       *sr_name = "samplerate\0\0\0\0\0\0\0\0\0\0\0" ;
+       static const char       *wd_name = "wavedata\0" ;
+       sf_count_t      current, datasize ;
+       int                     encoding ;
+
+       current = psf_ftell (psf) ;
+
+       if (calc_length)
+       {       psf_fseek (psf, 0, SEEK_END) ;
+               psf->filelength = psf_ftell (psf) ;
+               psf_fseek (psf, 0, SEEK_SET) ;
+
+               psf->datalength = psf->filelength - psf->dataoffset ;
+               if (psf->dataend)
+                       psf->datalength -= psf->filelength - psf->dataend ;
+
+               psf->sf.frames = psf->datalength / (psf->bytewidth * psf->sf.channels) ;
+               } ;
+
+       switch (psf->sf.format & SF_FORMAT_SUBMASK)
+       {       case SF_FORMAT_PCM_U8 :
+                               encoding = MAT5_TYPE_UCHAR ;
+                               break ;
+
+               case SF_FORMAT_PCM_16 :
+                               encoding = MAT5_TYPE_INT16 ;
+                               break ;
+
+               case SF_FORMAT_PCM_32 :
+                               encoding = MAT5_TYPE_INT32 ;
+                               break ;
+
+               case SF_FORMAT_FLOAT :
+                               encoding = MAT5_TYPE_FLOAT ;
+                               break ;
+
+               case SF_FORMAT_DOUBLE :
+                               encoding = MAT5_TYPE_DOUBLE ;
+                               break ;
+
+               default :
+                               return SFE_BAD_OPEN_FORMAT ;
+               } ;
+
+       /* Reset the current header length to zero. */
+       psf->header [0] = 0 ;
+       psf->headindex = 0 ;
+       psf_fseek (psf, 0, SEEK_SET) ;
+
+       psf_get_date_str (psf->u.cbuf, sizeof (psf->u.scbuf)) ;
+       psf_binheader_writef (psf, "bb", filename, strlen (filename), psf->u.cbuf, strlen (psf->u.cbuf) + 1) ;
+
+       memset (psf->u.scbuf, ' ', 124 - psf->headindex) ;
+       psf_binheader_writef (psf, "b", psf->u.scbuf, 124 - psf->headindex) ;
+
+       psf->rwf_endian = psf->endian ;
+
+       if (psf->rwf_endian == SF_ENDIAN_BIG)
+               psf_binheader_writef (psf, "2b", 0x0100, "MI", 2) ;
+       else
+               psf_binheader_writef (psf, "2b", 0x0100, "IM", 2) ;
+
+       psf_binheader_writef (psf, "444444", MAT5_TYPE_ARRAY, 64, MAT5_TYPE_UINT32, 8, 6, 0) ;
+       psf_binheader_writef (psf, "4444", MAT5_TYPE_INT32, 8, 1, 1) ;
+       psf_binheader_writef (psf, "44b", MAT5_TYPE_SCHAR, strlen (sr_name), sr_name, 16) ;
+
+       if (psf->sf.samplerate > 0xFFFF)
+               psf_binheader_writef (psf, "44", MAT5_TYPE_COMP_UINT, psf->sf.samplerate) ;
+       else
+       {       unsigned short samplerate = psf->sf.samplerate ;
+
+               psf_binheader_writef (psf, "422", MAT5_TYPE_COMP_USHORT, samplerate, 0) ;
+               } ;
+
+       datasize = psf->sf.frames * psf->sf.channels * psf->bytewidth ;
+
+       psf_binheader_writef (psf, "t484444", MAT5_TYPE_ARRAY, datasize + 64, MAT5_TYPE_UINT32, 8, 6, 0) ;
+       psf_binheader_writef (psf, "t4448", MAT5_TYPE_INT32, 8, psf->sf.channels, psf->sf.frames) ;
+       psf_binheader_writef (psf, "44b", MAT5_TYPE_SCHAR, strlen (wd_name), wd_name, strlen (wd_name)) ;
+
+       datasize = psf->sf.frames * psf->sf.channels * psf->bytewidth ;
+       if (datasize > 0x7FFFFFFF)
+               datasize = 0x7FFFFFFF ;
+
+       psf_binheader_writef (psf, "t48", encoding, datasize) ;
+
+       /* Header construction complete so write it out. */
+       psf_fwrite (psf->header, psf->headindex, 1, psf) ;
+
+       if (psf->error)
+               return psf->error ;
+
+       psf->dataoffset = psf->headindex ;
+
+       if (current > 0)
+               psf_fseek (psf, current, SEEK_SET) ;
+
+       return psf->error ;
+} /* mat5_write_header */
+
+static int
+mat5_read_header (SF_PRIVATE *psf)
+{      char    name [32] ;
+       short   version, endian ;
+       int             type, size, flags1, flags2, rows, cols ;
+
+       psf_binheader_readf (psf, "pb", 0, psf->u.cbuf, 124) ;
+
+       psf->u.scbuf [125] = 0 ;
+
+       if (strlen (psf->u.cbuf) >= 124)
+               return SFE_UNIMPLEMENTED ;
+
+       if (strstr (psf->u.cbuf, "MATLAB 5.0 MAT-file") == psf->u.cbuf)
+               psf_log_printf (psf, "%s\n", psf->u.scbuf) ;
+
+
+       psf_binheader_readf (psf, "E22", &version, &endian) ;
+
+       if (endian == MI_MARKER)
+       {       psf->endian = psf->rwf_endian = SF_ENDIAN_BIG ;
+               if (CPU_IS_LITTLE_ENDIAN) version = ENDSWAP_SHORT (version) ;
+               }
+       else if (endian == IM_MARKER)
+       {       psf->endian = psf->rwf_endian = SF_ENDIAN_LITTLE ;
+               if (CPU_IS_BIG_ENDIAN) version = ENDSWAP_SHORT (version) ;
+               }
+       else
+               return SFE_MAT5_BAD_ENDIAN ;
+
+       if ((CPU_IS_LITTLE_ENDIAN && endian == IM_MARKER) ||
+                       (CPU_IS_BIG_ENDIAN && endian == MI_MARKER))
+               version = ENDSWAP_SHORT (version) ;
+
+       psf_log_printf (psf, "Version : 0x%04X\n", version) ;
+       psf_log_printf (psf, "Endian  : 0x%04X => %s\n", endian,
+                               (psf->endian == SF_ENDIAN_LITTLE) ? "Little" : "Big") ;
+
+       /*========================================================*/
+       psf_binheader_readf (psf, "44", &type, &size) ;
+       psf_log_printf (psf, "Block\n Type : %X    Size : %d\n", type, size) ;
+
+       if (type != MAT5_TYPE_ARRAY)
+               return SFE_MAT5_NO_BLOCK ;
+
+       psf_binheader_readf (psf, "44", &type, &size) ;
+       psf_log_printf (psf, "    Type : %X    Size : %d\n", type, size) ;
+
+       if (type != MAT5_TYPE_UINT32)
+               return SFE_MAT5_NO_BLOCK ;
+
+       psf_binheader_readf (psf, "44", &flags1, &flags2) ;
+       psf_log_printf (psf, "    Flg1 : %X    Flg2 : %d\n", flags1, flags2) ;
+
+       psf_binheader_readf (psf, "44", &type, &size) ;
+       psf_log_printf (psf, "    Type : %X    Size : %d\n", type, size) ;
+
+       if (type != MAT5_TYPE_INT32)
+               return SFE_MAT5_NO_BLOCK ;
+
+       psf_binheader_readf (psf, "44", &rows, &cols) ;
+       psf_log_printf (psf, "    Rows : %X    Cols : %d\n", rows, cols) ;
+
+       if (rows != 1 || cols != 1)
+               return SFE_MAT5_SAMPLE_RATE ;
+
+       psf_binheader_readf (psf, "4", &type) ;
+
+       if (type == MAT5_TYPE_SCHAR)
+       {       psf_binheader_readf (psf, "4", &size) ;
+               psf_log_printf (psf, "    Type : %X    Size : %d\n", type, size) ;
+               if (size > SIGNED_SIZEOF (name) - 1)
+               {       psf_log_printf (psf, "Error : Bad name length.\n") ;
+                       return SFE_MAT5_NO_BLOCK ;
+                       } ;
+
+               psf_binheader_readf (psf, "bj", name, size, (8 - (size % 8)) % 8) ;
+               name [size] = 0 ;
+               }
+       else if ((type & 0xFFFF) == MAT5_TYPE_SCHAR)
+       {       size = type >> 16 ;
+               if (size > 4)
+               {       psf_log_printf (psf, "Error : Bad name length.\n") ;
+                       return SFE_MAT5_NO_BLOCK ;
+                       } ;
+
+               psf_log_printf (psf, "    Type : %X\n", type) ;
+               psf_binheader_readf (psf, "4", &name) ;
+               name [size] = 0 ;
+               }
+       else
+               return SFE_MAT5_NO_BLOCK ;
+
+       psf_log_printf (psf, "    Name : %s\n", name) ;
+
+       /*-----------------------------------------*/
+
+       psf_binheader_readf (psf, "44", &type, &size) ;
+
+       switch (type)
+       {       case MAT5_TYPE_DOUBLE :
+                               {       double  samplerate ;
+
+                                       psf_binheader_readf (psf, "d", &samplerate) ;
+                                       LSF_SNPRINTF (name, sizeof (name), "%f\n", samplerate) ;
+                                       psf_log_printf (psf, "    Val  : %s\n", name) ;
+
+                                       psf->sf.samplerate = lrint (samplerate) ;
+                                       } ;
+                               break ;
+
+               case MAT5_TYPE_COMP_USHORT :
+                               {       unsigned short samplerate ;
+
+                                       psf_binheader_readf (psf, "j2j", -4, &samplerate, 2) ;
+                                       psf_log_printf (psf, "    Val  : %u\n", samplerate) ;
+                                       psf->sf.samplerate = samplerate ;
+                                       }
+                               break ;
+
+               case MAT5_TYPE_COMP_UINT :
+                               psf_log_printf (psf, "    Val  : %u\n", size) ;
+                               psf->sf.samplerate = size ;
+                               break ;
+
+               default :
+                       psf_log_printf (psf, "    Type : %X    Size : %d  ***\n", type, size) ;
+                       return SFE_MAT5_SAMPLE_RATE ;
+               } ;
+
+       /*-----------------------------------------*/
+
+
+       psf_binheader_readf (psf, "44", &type, &size) ;
+       psf_log_printf (psf, " Type : %X    Size : %d\n", type, size) ;
+
+       if (type != MAT5_TYPE_ARRAY)
+               return SFE_MAT5_NO_BLOCK ;
+
+       psf_binheader_readf (psf, "44", &type, &size) ;
+       psf_log_printf (psf, "    Type : %X    Size : %d\n", type, size) ;
+
+       if (type != MAT5_TYPE_UINT32)
+               return SFE_MAT5_NO_BLOCK ;
+
+       psf_binheader_readf (psf, "44", &flags1, &flags2) ;
+       psf_log_printf (psf, "    Flg1 : %X    Flg2 : %d\n", flags1, flags2) ;
+
+       psf_binheader_readf (psf, "44", &type, &size) ;
+       psf_log_printf (psf, "    Type : %X    Size : %d\n", type, size) ;
+
+       if (type != MAT5_TYPE_INT32)
+               return SFE_MAT5_NO_BLOCK ;
+
+       psf_binheader_readf (psf, "44", &rows, &cols) ;
+       psf_log_printf (psf, "    Rows : %X    Cols : %d\n", rows, cols) ;
+
+       psf_binheader_readf (psf, "4", &type) ;
+
+       if (type == MAT5_TYPE_SCHAR)
+       {       psf_binheader_readf (psf, "4", &size) ;
+               psf_log_printf (psf, "    Type : %X    Size : %d\n", type, size) ;
+               if (size > SIGNED_SIZEOF (name) - 1)
+               {       psf_log_printf (psf, "Error : Bad name length.\n") ;
+                       return SFE_MAT5_NO_BLOCK ;
+                       } ;
+
+               psf_binheader_readf (psf, "bj", name, size, (8 - (size % 8)) % 8) ;
+               name [size] = 0 ;
+               }
+       else if ((type & 0xFFFF) == MAT5_TYPE_SCHAR)
+       {       size = type >> 16 ;
+               if (size > 4)
+               {       psf_log_printf (psf, "Error : Bad name length.\n") ;
+                       return SFE_MAT5_NO_BLOCK ;
+                       } ;
+
+               psf_log_printf (psf, "    Type : %X\n", type) ;
+               psf_binheader_readf (psf, "4", &name) ;
+               name [size] = 0 ;
+               }
+       else
+               return SFE_MAT5_NO_BLOCK ;
+
+       psf_log_printf (psf, "    Name : %s\n", name) ;
+
+       psf_binheader_readf (psf, "44", &type, &size) ;
+       psf_log_printf (psf, "    Type : %X    Size : %d\n", type, size) ;
+
+       /*++++++++++++++++++++++++++++++++++++++++++++++++++*/
+
+       if (rows == 0 && cols == 0)
+       {       psf_log_printf (psf, "*** Error : zero channel count.\n") ;
+               return SFE_MAT5_ZERO_CHANNELS ;
+               } ;
+
+       psf->sf.channels        = rows ;
+       psf->sf.frames          = cols ;
+
+       psf->sf.format = psf->endian | SF_FORMAT_MAT5 ;
+
+       switch (type)
+       {       case MAT5_TYPE_DOUBLE :
+                               psf_log_printf (psf, "Data type : double\n") ;
+                               psf->sf.format |= SF_FORMAT_DOUBLE ;
+                               psf->bytewidth = 8 ;
+                               break ;
+
+               case MAT5_TYPE_FLOAT :
+                               psf_log_printf (psf, "Data type : float\n") ;
+                               psf->sf.format |= SF_FORMAT_FLOAT ;
+                               psf->bytewidth = 4 ;
+                               break ;
+
+               case MAT5_TYPE_INT32 :
+                               psf_log_printf (psf, "Data type : 32 bit PCM\n") ;
+                               psf->sf.format |= SF_FORMAT_PCM_32 ;
+                               psf->bytewidth = 4 ;
+                               break ;
+
+               case MAT5_TYPE_INT16 :
+                               psf_log_printf (psf, "Data type : 16 bit PCM\n") ;
+                               psf->sf.format |= SF_FORMAT_PCM_16 ;
+                               psf->bytewidth = 2 ;
+                               break ;
+
+               case MAT5_TYPE_UCHAR :
+                               psf_log_printf (psf, "Data type : unsigned 8 bit PCM\n") ;
+                               psf->sf.format |= SF_FORMAT_PCM_U8 ;
+                               psf->bytewidth = 1 ;
+                               break ;
+
+               default :
+                               psf_log_printf (psf, "*** Error : Bad marker %08X\n", type) ;
+                               return SFE_UNIMPLEMENTED ;
+               } ;
+
+       psf->dataoffset = psf_ftell (psf) ;
+       psf->datalength = psf->filelength - psf->dataoffset ;
+
+       return 0 ;
+} /* mat5_read_header */
+
+/*
+** Do not edit or modify anything in this comment block.
+** The arch-tag line is a file identity tag for the GNU Arch 
+** revision control system.
+**
+** arch-tag: dfdb6742-b2be-4be8-b390-d0c674e8bc8e
+*/
diff --git a/libs/libsndfile/src/ms_adpcm.c b/libs/libsndfile/src/ms_adpcm.c
new file mode 100644 (file)
index 0000000..bb774fa
--- /dev/null
@@ -0,0 +1,834 @@
+/*
+** Copyright (C) 1999-2005 Erik de Castro Lopo <erikd@mega-nerd.com>
+**
+** This program is free software; you can redistribute it and/or modify
+** it under the terms of the GNU Lesser General Public License as published by
+** the Free Software Foundation; either version 2.1 of the License, or
+** (at your option) any later version.
+**
+** This program is distributed in the hope that it will be useful,
+** but WITHOUT ANY WARRANTY; without even the implied warranty of
+** MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+** GNU Lesser General Public License for more details.
+**
+** You should have received a copy of the GNU Lesser General Public License
+** along with this program; if not, write to the Free Software
+** Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA.
+*/
+
+#include       "sfconfig.h"
+
+#include       <stdio.h>
+#include       <stdlib.h>
+#include       <string.h>
+
+#include       "sndfile.h"
+#include       "sfendian.h"
+#include       "float_cast.h"
+#include       "common.h"
+#include       "wav_w64.h"
+
+/* These required here because we write the header in this file. */
+
+#define RIFF_MARKER    (MAKE_MARKER ('R', 'I', 'F', 'F'))
+#define WAVE_MARKER    (MAKE_MARKER ('W', 'A', 'V', 'E'))
+#define fmt_MARKER     (MAKE_MARKER ('f', 'm', 't', ' '))
+#define fact_MARKER    (MAKE_MARKER ('f', 'a', 'c', 't'))
+#define data_MARKER    (MAKE_MARKER ('d', 'a', 't', 'a'))
+
+#define WAVE_FORMAT_MS_ADPCM   0x0002
+
+typedef struct
+{      int                             channels, blocksize, samplesperblock, blocks, dataremaining ;
+       int                             blockcount ;
+       sf_count_t              samplecount ;
+       short                   *samples ;
+       unsigned char   *block ;
+#if HAVE_FLEXIBLE_ARRAY
+       short                   dummydata [] ; /* ISO C99 struct flexible array. */
+#else
+       short                   dummydata [0] ; /* This is a hack an might not work. */
+#endif
+} MSADPCM_PRIVATE ;
+
+/*============================================================================================
+** MS ADPCM static data and functions.
+*/
+
+static int AdaptationTable [] =
+{      230, 230, 230, 230, 307, 409, 512, 614,
+       768, 614, 512, 409, 307, 230, 230, 230
+} ;
+
+/* TODO : The first 7 coef's are are always hardcode and must
+   appear in the actual WAVE file.  They should be read in
+   in case a sound program added extras to the list. */
+
+static int AdaptCoeff1 [MSADPCM_ADAPT_COEFF_COUNT] =
+{      256, 512, 0, 192, 240, 460, 392
+} ;
+
+static int AdaptCoeff2 [MSADPCM_ADAPT_COEFF_COUNT] =
+{      0, -256, 0, 64, 0, -208, -232
+} ;
+
+/*============================================================================================
+**     MS ADPCM Block Layout.
+**     ======================
+**     Block is usually 256, 512 or 1024 bytes depending on sample rate.
+**     For a mono file, the block is laid out as follows:
+**             byte    purpose
+**             0               block predictor [0..6]
+**             1,2             initial idelta (positive)
+**             3,4             sample 1
+**             5,6             sample 0
+**             7..n    packed bytecodes
+**
+**     For a stereo file, the block is laid out as follows:
+**             byte    purpose
+**             0               block predictor [0..6] for left channel
+**             1               block predictor [0..6] for right channel
+**             2,3             initial idelta (positive) for left channel
+**             4,5             initial idelta (positive) for right channel
+**             6,7             sample 1 for left channel
+**             8,9             sample 1 for right channel
+**             10,11   sample 0 for left channel
+**             12,13   sample 0 for right channel
+**             14..n   packed bytecodes
+*/
+
+/*============================================================================================
+** Static functions.
+*/
+
+static int     msadpcm_decode_block    (SF_PRIVATE *psf, MSADPCM_PRIVATE *pms) ;
+static sf_count_t msadpcm_read_block   (SF_PRIVATE *psf, MSADPCM_PRIVATE *pms, short *ptr, int len) ;
+
+static int     msadpcm_encode_block    (SF_PRIVATE *psf, MSADPCM_PRIVATE *pms) ;
+static sf_count_t msadpcm_write_block  (SF_PRIVATE *psf, MSADPCM_PRIVATE *pms, const short *ptr, int len) ;
+
+static sf_count_t      msadpcm_read_s  (SF_PRIVATE *psf, short *ptr, sf_count_t len) ;
+static sf_count_t      msadpcm_read_i  (SF_PRIVATE *psf, int *ptr, sf_count_t len) ;
+static sf_count_t      msadpcm_read_f  (SF_PRIVATE *psf, float *ptr, sf_count_t len) ;
+static sf_count_t      msadpcm_read_d  (SF_PRIVATE *psf, double *ptr, sf_count_t len) ;
+
+static sf_count_t      msadpcm_write_s (SF_PRIVATE *psf, const short *ptr, sf_count_t len) ;
+static sf_count_t      msadpcm_write_i (SF_PRIVATE *psf, const int *ptr, sf_count_t len) ;
+static sf_count_t      msadpcm_write_f (SF_PRIVATE *psf, const float *ptr, sf_count_t len) ;
+static sf_count_t      msadpcm_write_d (SF_PRIVATE *psf, const double *ptr, sf_count_t len) ;
+
+static sf_count_t msadpcm_seek (SF_PRIVATE *psf, int mode, sf_count_t offset) ;
+static int     msadpcm_close   (SF_PRIVATE *psf) ;
+
+static void    choose_predictor (unsigned int channels, short *data, int *bpred, int *idelta) ;
+
+/*============================================================================================
+** MS ADPCM Read Functions.
+*/
+
+int
+wav_w64_msadpcm_init   (SF_PRIVATE *psf, int blockalign, int samplesperblock)
+{      MSADPCM_PRIVATE *pms ;
+       unsigned int    pmssize ;
+       int                             count ;
+
+       if (psf->fdata != NULL)
+       {       psf_log_printf (psf, "*** psf->fdata is not NULL.\n") ;
+               return SFE_INTERNAL ;
+               } ;
+
+       if (psf->mode == SFM_WRITE)
+               samplesperblock = 2 + 2 * (blockalign - 7 * psf->sf.channels) / psf->sf.channels ;
+
+       pmssize = sizeof (MSADPCM_PRIVATE) + blockalign + 3 * psf->sf.channels * samplesperblock ;
+
+       if (! (psf->fdata = malloc (pmssize)))
+               return SFE_MALLOC_FAILED ;
+       pms = (MSADPCM_PRIVATE*) psf->fdata ;
+       memset (pms, 0, pmssize) ;
+
+       pms->samples    = pms->dummydata ;
+       pms->block              = (unsigned char*) (pms->dummydata + psf->sf.channels * samplesperblock) ;
+
+       pms->channels   = psf->sf.channels ;
+       pms->blocksize  = blockalign ;
+       pms->samplesperblock = samplesperblock ;
+
+       if (psf->mode == SFM_READ)
+       {       pms->dataremaining       = psf->datalength ;
+
+               if (psf->datalength % pms->blocksize)
+                       pms->blocks = psf->datalength / pms->blocksize + 1 ;
+               else
+                       pms->blocks = psf->datalength / pms->blocksize ;
+
+               count = 2 * (pms->blocksize - 6 * pms->channels) / pms->channels ;
+               if (pms->samplesperblock != count)
+                       psf_log_printf (psf, "*** Warning : samplesperblock shoud be %d.\n", count) ;
+
+               psf->sf.frames = (psf->datalength / pms->blocksize) * pms->samplesperblock ;
+
+               psf_log_printf (psf, " bpred   idelta\n") ;
+
+               msadpcm_decode_block (psf, pms) ;
+
+               psf->read_short         = msadpcm_read_s ;
+               psf->read_int           = msadpcm_read_i ;
+               psf->read_float         = msadpcm_read_f ;
+               psf->read_double        = msadpcm_read_d ;
+               } ;
+
+       if (psf->mode == SFM_WRITE)
+       {       pms->samples = pms->dummydata ;
+
+               pms->samplecount = 0 ;
+
+               psf->write_short        = msadpcm_write_s ;
+               psf->write_int          = msadpcm_write_i ;
+               psf->write_float        = msadpcm_write_f ;
+               psf->write_double       = msadpcm_write_d ;
+               } ;
+
+       psf->codec_close = msadpcm_close ;
+       psf->seek = msadpcm_seek ;
+
+       return 0 ;
+} /* wav_w64_msadpcm_init */
+
+static int
+msadpcm_decode_block   (SF_PRIVATE *psf, MSADPCM_PRIVATE *pms)
+{      int             chan, k, blockindx, sampleindx ;
+       short   bytecode, bpred [2], chan_idelta [2] ;
+
+    int predict ;
+    int current ;
+    int idelta ;
+
+       pms->blockcount ++ ;
+       pms->samplecount = 0 ;
+
+       if (pms->blockcount > pms->blocks)
+       {       memset (pms->samples, 0, pms->samplesperblock * pms->channels) ;
+               return 1 ;
+               } ;
+
+       if ((k = psf_fread (pms->block, 1, pms->blocksize, psf)) != pms->blocksize)
+               psf_log_printf (psf, "*** Warning : short read (%d != %d).\n", k, pms->blocksize) ;
+
+       /* Read and check the block header. */
+
+       if (pms->channels == 1)
+       {       bpred [0] = pms->block [0] ;
+
+               if (bpred [0] >= 7)
+                       psf_log_printf (psf, "MS ADPCM synchronisation error (%d).\n", bpred [0]) ;
+
+               chan_idelta [0] = pms->block [1] | (pms->block [2] << 8) ;
+               chan_idelta [1] = 0 ;
+
+               psf_log_printf (psf, "(%d) (%d)\n", bpred [0], chan_idelta [0]) ;
+
+               pms->samples [1] = pms->block [3] | (pms->block [4] << 8) ;
+               pms->samples [0] = pms->block [5] | (pms->block [6] << 8) ;
+               blockindx = 7 ;
+               }
+       else
+       {       bpred [0] = pms->block [0] ;
+               bpred [1] = pms->block [1] ;
+
+               if (bpred [0] >= 7 || bpred [1] >= 7)
+                       psf_log_printf (psf, "MS ADPCM synchronisation error (%d %d).\n", bpred [0], bpred [1]) ;
+
+               chan_idelta [0] = pms->block [2] | (pms->block [3] << 8) ;
+               chan_idelta [1] = pms->block [4] | (pms->block [5] << 8) ;
+
+               psf_log_printf (psf, "(%d, %d) (%d, %d)\n", bpred [0], bpred [1], chan_idelta [0], chan_idelta [1]) ;
+
+               pms->samples [2] = pms->block [6] | (pms->block [7] << 8) ;
+               pms->samples [3] = pms->block [8] | (pms->block [9] << 8) ;
+
+               pms->samples [0] = pms->block [10] | (pms->block [11] << 8) ;
+               pms->samples [1] = pms->block [12] | (pms->block [13] << 8) ;
+
+               blockindx = 14 ;
+               } ;
+
+       /*--------------------------------------------------------
+       This was left over from a time when calculations were done
+       as ints rather than shorts. Keep this around as a reminder
+       in case I ever find a file which decodes incorrectly.
+
+    if (chan_idelta [0] & 0x8000)
+               chan_idelta [0] -= 0x10000 ;
+    if (chan_idelta [1] & 0x8000)
+               chan_idelta [1] -= 0x10000 ;
+       --------------------------------------------------------*/
+
+       /* Pull apart the packed 4 bit samples and store them in their
+       ** correct sample positions.
+       */
+
+       sampleindx = 2 * pms->channels ;
+       while (blockindx < pms->blocksize)
+       {       bytecode = pms->block [blockindx++] ;
+               pms->samples [sampleindx++] = (bytecode >> 4) & 0x0F ;
+               pms->samples [sampleindx++] = bytecode & 0x0F ;
+               } ;
+
+       /* Decode the encoded 4 bit samples. */
+
+       for (k = 2 * pms->channels ; k < (pms->samplesperblock * pms->channels) ; k ++)
+       {       chan = (pms->channels > 1) ? (k % 2) : 0 ;
+
+               bytecode = pms->samples [k] & 0xF ;
+
+               /* Compute next Adaptive Scale Factor (ASF) */
+               idelta = chan_idelta [chan] ;
+               chan_idelta [chan] = (AdaptationTable [bytecode] * idelta) >> 8 ;       /* => / 256 => FIXED_POINT_ADAPTATION_BASE == 256 */
+               if (chan_idelta [chan] < 16)
+                       chan_idelta [chan] = 16 ;
+               if (bytecode & 0x8)
+                       bytecode -= 0x10 ;
+
+       predict = ((pms->samples [k - pms->channels] * AdaptCoeff1 [bpred [chan]])
+                                       + (pms->samples [k - 2 * pms->channels] * AdaptCoeff2 [bpred [chan]])) >> 8 ; /* => / 256 => FIXED_POINT_COEFF_BASE == 256 */
+               current = (bytecode * idelta) + predict ;
+
+               if (current > 32767)
+                       current = 32767 ;
+               else if (current < -32768)
+                       current = -32768 ;
+
+               pms->samples [k] = current ;
+               } ;
+
+       return 1 ;
+} /* msadpcm_decode_block */
+
+static sf_count_t
+msadpcm_read_block     (SF_PRIVATE *psf, MSADPCM_PRIVATE *pms, short *ptr, int len)
+{      int     count, total = 0, indx = 0 ;
+
+       while (indx < len)
+       {       if (pms->blockcount >= pms->blocks && pms->samplecount >= pms->samplesperblock)
+               {       memset (&(ptr [indx]), 0, (size_t) ((len - indx) * sizeof (short))) ;
+                       return total ;
+                       } ;
+
+               if (pms->samplecount >= pms->samplesperblock)
+                       msadpcm_decode_block (psf, pms) ;
+
+               count = (pms->samplesperblock - pms->samplecount) * pms->channels ;
+               count = (len - indx > count) ? count : len - indx ;
+
+               memcpy (&(ptr [indx]), &(pms->samples [pms->samplecount * pms->channels]), count * sizeof (short)) ;
+               indx += count ;
+               pms->samplecount += count / pms->channels ;
+               total = indx ;
+               } ;
+
+       return total ;
+} /* msadpcm_read_block */
+
+static sf_count_t
+msadpcm_read_s (SF_PRIVATE *psf, short *ptr, sf_count_t len)
+{      MSADPCM_PRIVATE         *pms ;
+       int                     readcount, count ;
+       sf_count_t      total = 0 ;
+
+       if (! psf->fdata)
+               return 0 ;
+       pms = (MSADPCM_PRIVATE*) psf->fdata ;
+
+       while (len > 0)
+       {       readcount = (len > 0x10000000) ? 0x10000000 : (int) len ;
+
+               count = msadpcm_read_block (psf, pms, ptr, readcount) ;
+
+               total += count ;
+               len -= count ;
+               if (count != readcount)
+                       break ;
+               } ;
+
+       return total ;
+} /* msadpcm_read_s */
+
+static sf_count_t
+msadpcm_read_i (SF_PRIVATE *psf, int *ptr, sf_count_t len)
+{      MSADPCM_PRIVATE *pms ;
+       short           *sptr ;
+       int                     k, bufferlen, readcount = 0, count ;
+       sf_count_t      total = 0 ;
+
+       if (! psf->fdata)
+               return 0 ;
+       pms = (MSADPCM_PRIVATE*) psf->fdata ;
+
+       sptr = psf->u.sbuf ;
+       bufferlen = ARRAY_LEN (psf->u.sbuf) ;
+       while (len > 0)
+       {       readcount = (len >= bufferlen) ? bufferlen : len ;
+               count = msadpcm_read_block (psf, pms, sptr, readcount) ;
+               for (k = 0 ; k < readcount ; k++)
+                       ptr [total + k] = sptr [k] << 16 ;
+               total += count ;
+               len -= readcount ;
+               if (count != readcount)
+                       break ;
+               } ;
+       return total ;
+} /* msadpcm_read_i */
+
+static sf_count_t
+msadpcm_read_f (SF_PRIVATE *psf, float *ptr, sf_count_t len)
+{      MSADPCM_PRIVATE *pms ;
+       short           *sptr ;
+       int                     k, bufferlen, readcount = 0, count ;
+       sf_count_t      total = 0 ;
+       float           normfact ;
+
+       if (! psf->fdata)
+               return 0 ;
+       pms = (MSADPCM_PRIVATE*) psf->fdata ;
+
+       normfact = (psf->norm_float == SF_TRUE) ? 1.0 / ((float) 0x8000) : 1.0 ;
+       sptr = psf->u.sbuf ;
+       bufferlen = ARRAY_LEN (psf->u.sbuf) ;
+       while (len > 0)
+       {       readcount = (len >= bufferlen) ? bufferlen : len ;
+               count = msadpcm_read_block (psf, pms, sptr, readcount) ;
+               for (k = 0 ; k < readcount ; k++)
+                       ptr [total + k] = normfact * (float) (sptr [k]) ;
+               total += count ;
+               len -= readcount ;
+               if (count != readcount)
+                       break ;
+               } ;
+       return total ;
+} /* msadpcm_read_f */
+
+static sf_count_t
+msadpcm_read_d (SF_PRIVATE *psf, double *ptr, sf_count_t len)
+{      MSADPCM_PRIVATE *pms ;
+       short           *sptr ;
+       int                     k, bufferlen, readcount = 0, count ;
+       sf_count_t      total = 0 ;
+       double          normfact ;
+
+       normfact = (psf->norm_double == SF_TRUE) ? 1.0 / ((double) 0x8000) : 1.0 ;
+
+       if (! psf->fdata)
+               return 0 ;
+       pms = (MSADPCM_PRIVATE*) psf->fdata ;
+
+       sptr = psf->u.sbuf ;
+       bufferlen = ARRAY_LEN (psf->u.sbuf) ;
+       while (len > 0)
+       {       readcount = (len >= bufferlen) ? bufferlen : len ;
+               count = msadpcm_read_block (psf, pms, sptr, readcount) ;
+               for (k = 0 ; k < readcount ; k++)
+                       ptr [total + k] = normfact * (double) (sptr [k]) ;
+               total += count ;
+               len -= readcount ;
+               if (count != readcount)
+                       break ;
+               } ;
+       return total ;
+} /* msadpcm_read_d */
+
+static sf_count_t
+msadpcm_seek   (SF_PRIVATE *psf, int mode, sf_count_t offset)
+{      MSADPCM_PRIVATE *pms ;
+       int                     newblock, newsample ;
+
+       if (! psf->fdata)
+               return 0 ;
+       pms = (MSADPCM_PRIVATE*) psf->fdata ;
+
+       if (psf->datalength < 0 || psf->dataoffset < 0)
+       {       psf->error = SFE_BAD_SEEK ;
+               return  PSF_SEEK_ERROR ;
+               } ;
+
+       if (offset == 0)
+       {       psf_fseek (psf, psf->dataoffset, SEEK_SET) ;
+               pms->blockcount = 0 ;
+               msadpcm_decode_block (psf, pms) ;
+               pms->samplecount = 0 ;
+               return 0 ;
+               } ;
+
+       if (offset < 0 || offset > pms->blocks * pms->samplesperblock)
+       {       psf->error = SFE_BAD_SEEK ;
+               return  PSF_SEEK_ERROR ;
+               } ;
+
+       newblock        = offset / pms->samplesperblock ;
+       newsample       = offset % pms->samplesperblock ;
+
+       if (mode == SFM_READ)
+       {       psf_fseek (psf, psf->dataoffset + newblock * pms->blocksize, SEEK_SET) ;
+               pms->blockcount = newblock ;
+               msadpcm_decode_block (psf, pms) ;
+               pms->samplecount = newsample ;
+               }
+       else
+       {       /* What to do about write??? */
+               psf->error = SFE_BAD_SEEK ;
+               return  PSF_SEEK_ERROR ;
+               } ;
+
+       return newblock * pms->samplesperblock + newsample ;
+} /* msadpcm_seek */
+
+/*==========================================================================================
+** MS ADPCM Write Functions.
+*/
+
+void
+msadpcm_write_adapt_coeffs     (SF_PRIVATE *psf)
+{      int k ;
+
+       for (k = 0 ; k < MSADPCM_ADAPT_COEFF_COUNT ; k++)
+               psf_binheader_writef (psf, "22", AdaptCoeff1 [k], AdaptCoeff2 [k]) ;
+} /* msadpcm_write_adapt_coeffs */
+
+/*==========================================================================================
+*/
+
+static int
+msadpcm_encode_block   (SF_PRIVATE *psf, MSADPCM_PRIVATE *pms)
+{      unsigned int    blockindx ;
+       unsigned char   byte ;
+       int                             chan, k, predict, bpred [2], idelta [2], errordelta, newsamp ;
+
+       choose_predictor (pms->channels, pms->samples, bpred, idelta) ;
+
+       /* Write the block header. */
+
+       if (pms->channels == 1)
+       {       pms->block [0]  = bpred [0] ;
+               pms->block [1]  = idelta [0] & 0xFF ;
+               pms->block [2]  = idelta [0] >> 8 ;
+               pms->block [3]  = pms->samples [1] & 0xFF ;
+               pms->block [4]  = pms->samples [1] >> 8 ;
+               pms->block [5]  = pms->samples [0] & 0xFF ;
+               pms->block [6]  = pms->samples [0] >> 8 ;
+
+               blockindx = 7 ;
+               byte = 0 ;
+
+               /* Encode the samples as 4 bit. */
+
+               for (k = 2 ; k < pms->samplesperblock ; k++)
+               {       predict = (pms->samples [k-1] * AdaptCoeff1 [bpred [0]] + pms->samples [k-2] * AdaptCoeff2 [bpred [0]]) >> 8 ;
+                       errordelta = (pms->samples [k] - predict) / idelta [0] ;
+                       if (errordelta < -8)
+                               errordelta = -8 ;
+                       else if (errordelta > 7)
+                               errordelta = 7 ;
+                       newsamp = predict + (idelta [0] * errordelta) ;
+                       if (newsamp > 32767)
+                               newsamp = 32767 ;
+                       else if (newsamp < -32768)
+                               newsamp = -32768 ;
+                       if (errordelta < 0)
+                               errordelta += 0x10 ;
+
+                       byte = (byte << 4) | (errordelta & 0xF) ;
+                       if (k % 2)
+                       {       pms->block [blockindx++] = byte ;
+                               byte = 0 ;
+                               } ;
+
+                       idelta [0] = (idelta [0] * AdaptationTable [errordelta]) >> 8 ;
+                       if (idelta [0] < 16)
+                               idelta [0] = 16 ;
+                       pms->samples [k] = newsamp ;
+                       } ;
+               }
+       else
+       {       /* Stereo file. */
+               pms->block [0]  = bpred [0] ;
+               pms->block [1]  = bpred [1] ;
+
+               pms->block [2]  = idelta [0] & 0xFF ;
+               pms->block [3]  = idelta [0] >> 8 ;
+               pms->block [4]  = idelta [1] & 0xFF ;
+               pms->block [5]  = idelta [1] >> 8 ;
+
+               pms->block [6]  = pms->samples [2] & 0xFF ;
+               pms->block [7]  = pms->samples [2] >> 8 ;
+               pms->block [8]  = pms->samples [3] & 0xFF ;
+               pms->block [9]  = pms->samples [3] >> 8 ;
+
+               pms->block [10] = pms->samples [0] & 0xFF ;
+               pms->block [11] = pms->samples [0] >> 8 ;
+               pms->block [12] = pms->samples [1] & 0xFF ;
+               pms->block [13] = pms->samples [1] >> 8 ;
+
+               blockindx = 14 ;
+               byte = 0 ;
+               chan = 1 ;
+
+               for (k = 4 ; k < 2 * pms->samplesperblock ; k++)
+               {       chan = k & 1 ;
+
+                       predict = (pms->samples [k-2] * AdaptCoeff1 [bpred [chan]] + pms->samples [k-4] * AdaptCoeff2 [bpred [chan]]) >> 8 ;
+                       errordelta = (pms->samples [k] - predict) / idelta [chan] ;
+
+
+                       if (errordelta < -8)
+                               errordelta = -8 ;
+                       else if (errordelta > 7)
+                               errordelta = 7 ;
+                       newsamp = predict + (idelta [chan] * errordelta) ;
+                       if (newsamp > 32767)
+                               newsamp = 32767 ;
+                       else if (newsamp < -32768)
+                               newsamp = -32768 ;
+                       if (errordelta < 0)
+                               errordelta += 0x10 ;
+
+                       byte = (byte << 4) | (errordelta & 0xF) ;
+
+                       if (chan)
+                       {       pms->block [blockindx++] = byte ;
+                               byte = 0 ;
+                               } ;
+
+                       idelta [chan] = (idelta [chan] * AdaptationTable [errordelta]) >> 8 ;
+                       if (idelta [chan] < 16)
+                               idelta [chan] = 16 ;
+                       pms->samples [k] = newsamp ;
+                       } ;
+               } ;
+
+       /* Write the block to disk. */
+
+       if ((k = psf_fwrite (pms->block, 1, pms->blocksize, psf)) != pms->blocksize)
+               psf_log_printf (psf, "*** Warning : short write (%d != %d).\n", k, pms->blocksize) ;
+
+       memset (pms->samples, 0, pms->samplesperblock * sizeof (short)) ;
+
+       pms->blockcount ++ ;
+       pms->samplecount = 0 ;
+
+       return 1 ;
+} /* msadpcm_encode_block */
+
+static sf_count_t
+msadpcm_write_block    (SF_PRIVATE *psf, MSADPCM_PRIVATE *pms, const short *ptr, int len)
+{      int             count, total = 0, indx = 0 ;
+
+       while (indx < len)
+       {       count = (pms->samplesperblock - pms->samplecount) * pms->channels ;
+
+               if (count > len - indx)
+                       count = len - indx ;
+
+               memcpy (&(pms->samples [pms->samplecount * pms->channels]), &(ptr [total]), count * sizeof (short)) ;
+               indx += count ;
+               pms->samplecount += count / pms->channels ;
+               total = indx ;
+
+               if (pms->samplecount >= pms->samplesperblock)
+                       msadpcm_encode_block (psf, pms) ;
+               } ;
+
+       return total ;
+} /* msadpcm_write_block */
+
+static sf_count_t
+msadpcm_write_s        (SF_PRIVATE *psf, const short *ptr, sf_count_t len)
+{      MSADPCM_PRIVATE *pms ;
+       int                     writecount, count ;
+       sf_count_t      total = 0 ;
+
+       if (! psf->fdata)
+               return 0 ;
+       pms = (MSADPCM_PRIVATE*) psf->fdata ;
+
+       while (len > 0)
+       {       writecount = (len > 0x10000000) ? 0x10000000 : (int) len ;
+
+               count = msadpcm_write_block (psf, pms, ptr, writecount) ;
+
+               total += count ;
+               len -= count ;
+               if (count != writecount)
+                       break ;
+               } ;
+
+       return total ;
+} /* msadpcm_write_s */
+
+static sf_count_t
+msadpcm_write_i        (SF_PRIVATE *psf, const int *ptr, sf_count_t len)
+{      MSADPCM_PRIVATE *pms ;
+       short           *sptr ;
+       int                     k, bufferlen, writecount, count ;
+       sf_count_t      total = 0 ;
+
+       if (! psf->fdata)
+               return 0 ;
+       pms = (MSADPCM_PRIVATE*) psf->fdata ;
+
+       sptr = psf->u.sbuf ;
+       bufferlen = ARRAY_LEN (psf->u.sbuf) ;
+       while (len > 0)
+       {       writecount = (len >= bufferlen) ? bufferlen : len ;
+               for (k = 0 ; k < writecount ; k++)
+                       sptr [k] = ptr [total + k] >> 16 ;
+               count = msadpcm_write_block (psf, pms, sptr, writecount) ;
+               total += count ;
+               len -= writecount ;
+               if (count != writecount)
+                       break ;
+               } ;
+       return total ;
+} /* msadpcm_write_i */
+
+static sf_count_t
+msadpcm_write_f        (SF_PRIVATE *psf, const float *ptr, sf_count_t len)
+{      MSADPCM_PRIVATE *pms ;
+       short           *sptr ;
+       int                     k, bufferlen, writecount, count ;
+       sf_count_t      total = 0 ;
+       float           normfact ;
+
+       if (! psf->fdata)
+               return 0 ;
+       pms = (MSADPCM_PRIVATE*) psf->fdata ;
+
+       normfact = (psf->norm_float == SF_TRUE) ? (1.0 * 0x7FFF) : 1.0 ;
+
+       sptr = psf->u.sbuf ;
+       bufferlen = ARRAY_LEN (psf->u.sbuf) ;
+       while (len > 0)
+       {       writecount = (len >= bufferlen) ? bufferlen : len ;
+               for (k = 0 ; k < writecount ; k++)
+                       sptr [k] = lrintf (normfact * ptr [total + k]) ;
+               count = msadpcm_write_block (psf, pms, sptr, writecount) ;
+               total += count ;
+               len -= writecount ;
+               if (count != writecount)
+                       break ;
+               } ;
+       return total ;
+} /* msadpcm_write_f */
+
+static sf_count_t
+msadpcm_write_d        (SF_PRIVATE *psf, const double *ptr, sf_count_t len)
+{      MSADPCM_PRIVATE *pms ;
+       short           *sptr ;
+       int                     k, bufferlen, writecount, count ;
+       sf_count_t      total = 0 ;
+       double          normfact ;
+
+       normfact = (psf->norm_double == SF_TRUE) ? (1.0 * 0x7FFF) : 1.0 ;
+
+       if (! psf->fdata)
+               return 0 ;
+       pms = (MSADPCM_PRIVATE*) psf->fdata ;
+
+       sptr = psf->u.sbuf ;
+       bufferlen = ARRAY_LEN (psf->u.sbuf) ;
+       while (len > 0)
+       {       writecount = (len >= bufferlen) ? bufferlen : len ;
+               for (k = 0 ; k < writecount ; k++)
+                       sptr [k] = lrint (normfact * ptr [total + k]) ;
+               count = msadpcm_write_block (psf, pms, sptr, writecount) ;
+               total += count ;
+               len -= writecount ;
+               if (count != writecount)
+                       break ;
+               } ;
+       return total ;
+} /* msadpcm_write_d */
+
+/*========================================================================================
+*/
+
+static int
+msadpcm_close  (SF_PRIVATE *psf)
+{      MSADPCM_PRIVATE *pms ;
+
+       pms = (MSADPCM_PRIVATE*) psf->fdata ;
+
+       if (psf->mode == SFM_WRITE)
+       {       /*  Now we know static int for certain the length of the file we can
+               **  re-write the header.
+               */
+
+               if (pms->samplecount && pms->samplecount < pms->samplesperblock)
+                       msadpcm_encode_block (psf, pms) ;
+               } ;
+
+       return 0 ;
+} /* msadpcm_close */
+
+/*========================================================================================
+** Static functions.
+*/
+
+/*----------------------------------------------------------------------------------------
+**     Choosing the block predictor.
+**     Each block requires a predictor and an idelta for each channel.
+**     The predictor is in the range [0..6] which is an indx into the  two AdaptCoeff tables.
+**     The predictor is chosen by trying all of the possible predictors on a small set of
+**     samples at the beginning of the block. The predictor with the smallest average
+**     abs (idelta) is chosen as the best predictor for this block.
+**     The value of idelta is chosen to to give a 4 bit code value of +/- 4 (approx. half the
+**     max. code value). If the average abs (idelta) is zero, the sixth predictor is chosen.
+**     If the value of idelta is less then 16 it is set to 16.
+**
+**     Microsoft uses an IDELTA_COUNT (number of sample pairs used to choose best predictor)
+**     value of 3. The best possible results would be obtained by using all the samples to
+**     choose the predictor.
+*/
+
+#define                IDELTA_COUNT    3
+
+static void
+choose_predictor (unsigned int channels, short *data, int *block_pred, int *idelta)
+{      unsigned int    chan, k, bpred, idelta_sum, best_bpred, best_idelta ;
+
+       for (chan = 0 ; chan < channels ; chan++)
+       {       best_bpred = best_idelta = 0 ;
+
+               for (bpred = 0 ; bpred < 7 ; bpred++)
+               {       idelta_sum = 0 ;
+                       for (k = 2 ; k < 2 + IDELTA_COUNT ; k++)
+                               idelta_sum += abs (data [k * channels] - ((data [(k - 1) * channels] * AdaptCoeff1 [bpred] + data [(k - 2) * channels] * AdaptCoeff2 [bpred]) >> 8)) ;
+                       idelta_sum /= (4 * IDELTA_COUNT) ;
+
+                       if (bpred == 0 || idelta_sum < best_idelta)
+                       {       best_bpred = bpred ;
+                               best_idelta = idelta_sum ;
+                               } ;
+
+                       if (! idelta_sum)
+                       {       best_bpred = bpred ;
+                               best_idelta = 16 ;
+                               break ;
+                               } ;
+
+                       } ; /* for bpred ... */
+               if (best_idelta < 16)
+                       best_idelta = 16 ;
+
+               block_pred [chan]       = best_bpred ;
+               idelta [chan]           = best_idelta ;
+               } ;
+
+       return ;
+} /* choose_predictor */
+/*
+** Do not edit or modify anything in this comment block.
+** The arch-tag line is a file identity tag for the GNU Arch 
+** revision control system.
+**
+** arch-tag: a98908a3-5305-4935-872b-77d6a86c330f
+*/
diff --git a/libs/libsndfile/src/nist.c b/libs/libsndfile/src/nist.c
new file mode 100644 (file)
index 0000000..2ab20db
--- /dev/null
@@ -0,0 +1,367 @@
+/*
+** Copyright (C) 1999-2004 Erik de Castro Lopo <erikd@mega-nerd.com>
+**
+** This program is free software; you can redistribute it and/or modify
+** it under the terms of the GNU Lesser General Public License as published by
+** the Free Software Foundation; either version 2.1 of the License, or
+** (at your option) any later version.
+**
+** This program is distributed in the hope that it will be useful,
+** but WITHOUT ANY WARRANTY; without even the implied warranty of
+** MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+** GNU Lesser General Public License for more details.
+**
+** You should have received a copy of the GNU Lesser General Public License
+** along with this program; if not, write to the Free Software
+** Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA.
+*/
+
+/*
+**     Some of the information used to read NIST files was gleaned from
+**     reading the code of Bill Schottstaedt's sndlib library
+**             ftp://ccrma-ftp.stanford.edu/pub/Lisp/sndlib.tar.gz
+**     However, no code from that package was used.
+*/
+
+#include       "sfconfig.h"
+
+#include       <stdio.h>
+#include       <fcntl.h>
+#include       <string.h>
+#include       <ctype.h>
+
+#include       "sndfile.h"
+#include       "sfendian.h"
+#include       "common.h"
+
+/*------------------------------------------------------------------------------
+*/
+
+#define        NIST_HEADER_LENGTH      1024
+
+/*------------------------------------------------------------------------------
+** Private static functions.
+*/
+
+static int     nist_close      (SF_PRIVATE *psf) ;
+static int nist_write_header   (SF_PRIVATE *psf, int calc_length) ;
+static int nist_read_header    (SF_PRIVATE *psf) ;
+
+/*------------------------------------------------------------------------------
+*/
+
+int
+nist_open      (SF_PRIVATE *psf)
+{      int error ;
+
+       if (psf->mode == SFM_READ || (psf->mode == SFM_RDWR && psf->filelength > 0))
+       {       if ((error = nist_read_header (psf)))
+                       return error ;
+               } ;
+
+       if (psf->mode == SFM_WRITE || psf->mode == SFM_RDWR)
+       {       if (psf->is_pipe)
+                       return SFE_NO_PIPE_WRITE ;
+
+               if ((psf->sf.format & SF_FORMAT_TYPEMASK) != SF_FORMAT_NIST)
+                       return  SFE_BAD_OPEN_FORMAT ;
+
+               psf->endian = psf->sf.format & SF_FORMAT_ENDMASK ;
+               if (psf->endian == 0 || psf->endian == SF_ENDIAN_CPU)
+                       psf->endian = (CPU_IS_BIG_ENDIAN) ? SF_ENDIAN_BIG : SF_ENDIAN_LITTLE ;
+
+               psf->blockwidth = psf->bytewidth * psf->sf.channels ;
+               psf->sf.frames = 0 ;
+
+               if ((error = nist_write_header (psf, SF_FALSE)))
+                       return error ;
+
+               psf->write_header = nist_write_header ;
+               } ;
+
+       psf->container_close = nist_close ;
+
+       switch (psf->sf.format & SF_FORMAT_SUBMASK)
+       {       case SF_FORMAT_PCM_S8 :
+                               error = pcm_init (psf) ;
+                               break ;
+
+               case SF_FORMAT_PCM_16 :
+               case SF_FORMAT_PCM_24 :
+               case SF_FORMAT_PCM_32 :
+                               error = pcm_init (psf) ;
+                               break ;
+
+               case SF_FORMAT_ULAW :
+                               error = ulaw_init (psf) ;
+                               break ;
+
+               case SF_FORMAT_ALAW :
+                               error = alaw_init (psf) ;
+                               break ;
+
+               default : error = SFE_UNIMPLEMENTED ;
+                               break ;
+               } ;
+
+       return error ;
+} /* nist_open */
+
+/*------------------------------------------------------------------------------
+*/
+
+static char bad_header [] =
+{      'N', 'I', 'S', 'T', '_', '1', 'A', 0x0d, 0x0a,
+       ' ', ' ', ' ', '1', '0', '2', '4', 0x0d, 0x0a,
+       0
+} ;
+
+       static int
+nist_read_header (SF_PRIVATE *psf)
+{      char    *psf_header ;
+       int             bitwidth = 0, bytes = 0, count, encoding ;
+       char    str [64], *cptr ;
+       long    samples ;
+
+       psf->sf.format = SF_FORMAT_NIST ;
+
+       psf_header = psf->u.cbuf ;
+
+       if (sizeof (psf->header) <= NIST_HEADER_LENGTH)
+               return SFE_INTERNAL ;
+
+       /* Go to start of file and read in the whole header. */
+       psf_binheader_readf (psf, "pb", 0, psf_header, NIST_HEADER_LENGTH) ;
+
+       /* Header is a string, so make sure it is null terminated. */
+       psf_header [NIST_HEADER_LENGTH] = 0 ;
+
+       /* Now trim the header after the end marker. */
+       if ((cptr = strstr (psf_header, "end_head")))
+       {       cptr += strlen ("end_head") + 1 ;
+               cptr [0] = 0 ;
+               } ;
+
+       if (strstr (psf_header, bad_header) == psf_header)
+               return SFE_NIST_CRLF_CONVERISON ;
+
+       /* Make sure its a NIST file. */
+       if (strstr (psf_header, "NIST_1A\n") != psf_header)
+       {       psf_log_printf (psf, "Not a NIST file.\n") ;
+               return SFE_NIST_BAD_HEADER ;
+               } ;
+
+       if (sscanf (psf_header, "NIST_1A\n%d\n", &count) == 1)
+               psf->dataoffset = count ;
+       else
+       {       psf_log_printf (psf, "*** Suspicious header length.\n") ;
+               psf->dataoffset = NIST_HEADER_LENGTH ;
+               } ;
+
+       /* Determine sample encoding, start by assuming PCM. */
+       encoding = SF_FORMAT_PCM_U8 ;
+       if ((cptr = strstr (psf_header, "sample_coding -s")))
+       {       sscanf (cptr, "sample_coding -s%d %63s", &count, str) ;
+
+               if (strcmp (str, "pcm") == 0)
+                       encoding = SF_FORMAT_PCM_U8 ;
+               else if (strcmp (str, "alaw") == 0)
+                       encoding = SF_FORMAT_ALAW ;
+               else if ((strcmp (str, "ulaw") == 0) || (strcmp (str, "mu-law") == 0))
+                       encoding = SF_FORMAT_ULAW ;
+               else
+               {       psf_log_printf (psf, "*** Unknown encoding : %s\n", str) ;
+                       encoding = 0 ;
+                       } ;
+               } ;
+
+       if ((cptr = strstr (psf_header, "channel_count -i ")))
+               sscanf (cptr, "channel_count -i %d", &(psf->sf.channels)) ;
+
+       if ((cptr = strstr (psf_header, "sample_rate -i ")))
+               sscanf (cptr, "sample_rate -i %d", &(psf->sf.samplerate)) ;
+
+       if ((cptr = strstr (psf_header, "sample_count -i ")))
+       {       sscanf (psf_header, "sample_count -i %ld", &samples) ;
+               psf->sf.frames = samples ;
+               } ;
+
+       if ((cptr = strstr (psf_header, "sample_n_bytes -i ")))
+               sscanf (cptr, "sample_n_bytes -i %d", &(psf->bytewidth)) ;
+
+       /* Default endian-ness (for 8 bit, u-law, A-law. */
+       psf->endian = (CPU_IS_BIG_ENDIAN) ? SF_ENDIAN_BIG : SF_ENDIAN_LITTLE ;
+
+       /* This is where we figure out endian-ness. */
+       if ((cptr = strstr (psf_header, "sample_byte_format -s")))
+       {       sscanf (cptr, "sample_byte_format -s%d %8s", &bytes, str) ;
+               if (bytes > 1)
+               {       if (psf->bytewidth == 0)
+                               psf->bytewidth = bytes ;
+                       else if (psf->bytewidth != bytes)
+                       {       psf_log_printf (psf, "psf->bytewidth (%d) != bytes (%d)\n", psf->bytewidth, bytes) ;
+                               return SFE_NIST_BAD_ENCODING ;
+                               } ;
+
+                       if (strstr (str, "01") == str)
+                               psf->endian = SF_ENDIAN_LITTLE ;
+                       else if (strstr (str, "10"))
+                               psf->endian = SF_ENDIAN_BIG ;
+                       else
+                       {       psf_log_printf (psf, "Weird endian-ness : %s\n", str) ;
+                               return SFE_NIST_BAD_ENCODING ;
+                               } ;
+                       } ;
+
+               psf->sf.format |= psf->endian ;
+               } ;
+
+       if ((cptr = strstr (psf_header, "sample_sig_bits -i ")))
+               sscanf (cptr, "sample_sig_bits -i %d", &bitwidth) ;
+
+       if (strstr (psf_header, "channels_interleaved -s5 FALSE"))
+       {       psf_log_printf (psf, "Non-interleaved data unsupported.\n", str) ;
+               return SFE_NIST_BAD_ENCODING ;
+               } ;
+
+       psf->blockwidth = psf->sf.channels * psf->bytewidth ;
+       psf->datalength = psf->filelength - psf->dataoffset ;
+
+       psf_fseek (psf, psf->dataoffset, SEEK_SET) ;
+
+       if (encoding == SF_FORMAT_PCM_U8)
+       {       switch (psf->bytewidth)
+               {       case 1 :
+                                       psf->sf.format |= SF_FORMAT_PCM_S8 ;
+                                       break ;
+
+                       case 2 :
+                                       psf->sf.format |= SF_FORMAT_PCM_16 ;
+                                       break ;
+
+                       case 3 :
+                                       psf->sf.format |= SF_FORMAT_PCM_24 ;
+                                       break ;
+
+                       case 4 :
+                                       psf->sf.format |= SF_FORMAT_PCM_32 ;
+                                       break ;
+
+                       default : break ;
+                       } ;
+               }
+       else if (encoding != 0)
+               psf->sf.format |= encoding ;
+       else
+               return SFE_UNIMPLEMENTED ;
+
+       return 0 ;
+} /* nist_read_header */
+
+static int
+nist_close     (SF_PRIVATE *psf)
+{
+       if (psf->mode == SFM_WRITE || psf->mode == SFM_RDWR)
+               nist_write_header (psf, SF_TRUE) ;
+
+       return 0 ;
+} /* nist_close */
+
+/*=========================================================================
+*/
+
+static int
+nist_write_header (SF_PRIVATE *psf, int calc_length)
+{      const char      *end_str ;
+       long            samples ;
+       sf_count_t      current ;
+
+       current = psf_ftell (psf) ;
+
+       if (calc_length)
+       {       psf->filelength = psf_get_filelen (psf) ;
+
+               psf->datalength = psf->filelength - psf->dataoffset ;
+
+               if (psf->dataend)
+                       psf->datalength -= psf->filelength - psf->dataend ;
+
+               if (psf->bytewidth > 0)
+                       psf->sf.frames = psf->datalength / (psf->bytewidth * psf->sf.channels) ;
+               } ;
+
+       if (psf->endian == SF_ENDIAN_BIG)
+               end_str = "10" ;
+       else if (psf->endian == SF_ENDIAN_LITTLE)
+               end_str = "01" ;
+       else
+               end_str = "error" ;
+
+       /* Clear the whole header. */
+       memset (psf->header, 0, sizeof (psf->header)) ;
+       psf->headindex = 0 ;
+
+       psf_fseek (psf, 0, SEEK_SET) ;
+
+       psf_asciiheader_printf (psf, "NIST_1A\n   1024\n") ;
+       psf_asciiheader_printf (psf, "channel_count -i %d\n", psf->sf.channels) ;
+       psf_asciiheader_printf (psf, "sample_rate -i %d\n", psf->sf.samplerate) ;
+
+       switch (psf->sf.format & SF_FORMAT_SUBMASK)
+       {       case SF_FORMAT_PCM_S8 :
+                               psf_asciiheader_printf (psf, "sample_coding -s3 pcm\n") ;
+                               psf_asciiheader_printf (psf, "sample_n_bytes -i 1\n"
+                                                                                       "sample_sig_bits -i 8\n") ;
+                               break ;
+
+               case SF_FORMAT_PCM_16 :
+               case SF_FORMAT_PCM_24 :
+               case SF_FORMAT_PCM_32 :
+                               psf_asciiheader_printf (psf, "sample_n_bytes -i %d\n", psf->bytewidth) ;
+                               psf_asciiheader_printf (psf, "sample_sig_bits -i %d\n", psf->bytewidth * 8) ;
+                               psf_asciiheader_printf (psf, "sample_coding -s3 pcm\n"
+                                                               "sample_byte_format -s%d %s\n", psf->bytewidth, end_str) ;
+                               break ;
+
+               case SF_FORMAT_ALAW :
+                               psf_asciiheader_printf (psf, "sample_coding -s4 alaw\n") ;
+                               psf_asciiheader_printf (psf, "sample_n_bytes -s1 1\n") ;
+                               break ;
+
+               case SF_FORMAT_ULAW :
+                               psf_asciiheader_printf (psf, "sample_coding -s4 ulaw\n") ;
+                               psf_asciiheader_printf (psf, "sample_n_bytes -s1 1\n") ;
+                               break ;
+
+               default : return SFE_UNIMPLEMENTED ;
+               } ;
+
+       psf->dataoffset = NIST_HEADER_LENGTH ;
+
+       /* Fix this */
+       samples = psf->sf.frames ;
+       psf_asciiheader_printf (psf, "sample_count -i %ld\n", samples) ;
+       psf_asciiheader_printf (psf, "end_head\n") ;
+
+       /* Zero fill to dataoffset. */
+       psf_binheader_writef (psf, "z", (size_t) (NIST_HEADER_LENGTH - psf->headindex)) ;
+
+       psf_fwrite (psf->header, psf->headindex, 1, psf) ;
+
+       if (psf->error)
+               return psf->error ;
+
+       if (current > 0)
+               psf_fseek (psf, current, SEEK_SET) ;
+
+       return psf->error ;
+} /* nist_write_header */
+
+
+/*
+** Do not edit or modify anything in this comment block.
+** The arch-tag line is a file identity tag for the GNU Arch 
+** revision control system.
+**
+** arch-tag: b45ed85d-9e22-4ad9-b78c-4b58b67152a8
+*/
diff --git a/libs/libsndfile/src/ogg.c b/libs/libsndfile/src/ogg.c
new file mode 100644 (file)
index 0000000..869baa9
--- /dev/null
@@ -0,0 +1,44 @@
+/*
+** Copyright (C) 2002-2004 Erik de Castro Lopo <erikd@mega-nerd.com>
+**
+** This program is free software ; you can redistribute it and/or modify
+** it under the terms of the GNU Lesser General Public License as published by
+** the Free Software Foundation ; either version 2.1 of the License, or
+** (at your option) any later version.
+**
+** This program is distributed in the hope that it will be useful,
+** but WITHOUT ANY WARRANTY ; without even the implied warranty of
+** MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+** GNU Lesser General Public License for more details.
+**
+** You should have received a copy of the GNU Lesser General Public License
+** along with this program ; if not, write to the Free Software
+** Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA.
+*/
+
+#include "sfconfig.h"
+
+#include <stdio.h>
+#include <fcntl.h>
+#include <string.h>
+#include <ctype.h>
+
+#include "sndfile.h"
+#include "sfendian.h"
+#include "common.h"
+
+int
+ogg_open       (SF_PRIVATE *psf)
+{      if (psf)
+               return SFE_UNIMPLEMENTED ;
+       return (psf && 0) ;
+} /* ogg_open */
+
+
+/*
+** Do not edit or modify anything in this comment block.
+** The arch-tag line is a file identity tag for the GNU Arch
+** revision control system.
+**
+** arch-tag: 9ff1fe9c-629e-4e9c-9ef5-3d0eb1e427a0
+*/
diff --git a/libs/libsndfile/src/paf.c b/libs/libsndfile/src/paf.c
new file mode 100644 (file)
index 0000000..6114dac
--- /dev/null
@@ -0,0 +1,843 @@
+/*
+** Copyright (C) 1999-2005 Erik de Castro Lopo <erikd@mega-nerd.com>
+**
+** This program is free software; you can redistribute it and/or modify
+** it under the terms of the GNU Lesser General Public License as published by
+** the Free Software Foundation; either version 2.1 of the License, or
+** (at your option) any later version.
+**
+** This program is distributed in the hope that it will be useful,
+** but WITHOUT ANY WARRANTY; without even the implied warranty of
+** MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+** GNU Lesser General Public License for more details.
+**
+** You should have received a copy of the GNU Lesser General Public License
+** along with this program; if not, write to the Free Software
+** Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA.
+*/
+
+#include "sfconfig.h"
+
+#include <stdio.h>
+#include <stdlib.h>
+#include <fcntl.h>
+#include <string.h>
+#include <ctype.h>
+
+#include "sndfile.h"
+#include "sfendian.h"
+#include "float_cast.h"
+#include "common.h"
+
+/*------------------------------------------------------------------------------
+** Macros to handle big/little endian issues.
+*/
+
+#define FAP_MARKER     (MAKE_MARKER ('f', 'a', 'p', ' '))
+#define PAF_MARKER     (MAKE_MARKER (' ', 'p', 'a', 'f'))
+
+/*------------------------------------------------------------------------------
+** Other defines.
+*/
+
+#define        PAF_HEADER_LENGTH                       2048
+
+#define        PAF24_SAMPLES_PER_BLOCK         10
+#define        PAF24_BLOCK_SIZE                        32
+
+/*------------------------------------------------------------------------------
+** Typedefs.
+*/
+
+typedef        struct
+{      int     version ;
+       int     endianness ;
+    int        samplerate ;
+    int        format ;
+       int     channels ;
+       int     source ;
+} PAF_FMT ;
+
+typedef struct
+{      int                             max_blocks, channels, samplesperblock, blocksize ;
+       int                             read_block, write_block, read_count, write_count ;
+       sf_count_t              sample_count ;
+       int                             *samples ;
+       unsigned char   *block ;
+#if HAVE_FLEXIBLE_ARRAY
+       int                             data [] ; /* ISO C99 struct flexible array. */
+#else
+       int                             data [1] ; /* This is a hack and may not work. */
+#endif
+} PAF24_PRIVATE ;
+
+/*------------------------------------------------------------------------------
+** Private static functions.
+*/
+
+static int paf24_init (SF_PRIVATE *psf) ;
+
+static int     paf_read_header (SF_PRIVATE *psf) ;
+static int     paf_write_header (SF_PRIVATE *psf, int calc_length) ;
+
+static sf_count_t paf24_read_s (SF_PRIVATE *psf, short *ptr, sf_count_t len) ;
+static sf_count_t paf24_read_i (SF_PRIVATE *psf, int *ptr, sf_count_t len) ;
+static sf_count_t paf24_read_f (SF_PRIVATE *psf, float *ptr, sf_count_t len) ;
+static sf_count_t paf24_read_d (SF_PRIVATE *psf, double *ptr, sf_count_t len) ;
+
+static sf_count_t paf24_write_s (SF_PRIVATE *psf, const short *ptr, sf_count_t len) ;
+static sf_count_t paf24_write_i (SF_PRIVATE *psf, const int *ptr, sf_count_t len) ;
+static sf_count_t paf24_write_f (SF_PRIVATE *psf, const float *ptr, sf_count_t len) ;
+static sf_count_t paf24_write_d (SF_PRIVATE *psf, const double *ptr, sf_count_t len) ;
+
+static sf_count_t paf24_seek (SF_PRIVATE *psf, int mode, sf_count_t offset) ;
+
+enum
+{      PAF_PCM_16 = 0,
+       PAF_PCM_24 = 1,
+       PAF_PCM_S8 = 2
+} ;
+
+/*------------------------------------------------------------------------------
+** Public function.
+*/
+
+int
+paf_open       (SF_PRIVATE *psf)
+{      int             subformat, error, endian ;
+
+       psf->dataoffset = PAF_HEADER_LENGTH ;
+
+       if (psf->mode == SFM_READ || (psf->mode == SFM_RDWR && psf->filelength > 0))
+       {       if ((error = paf_read_header (psf)))
+                       return error ;
+               } ;
+
+       subformat = psf->sf.format & SF_FORMAT_SUBMASK ;
+
+       if (psf->mode == SFM_WRITE || psf->mode == SFM_RDWR)
+       {       if ((psf->sf.format & SF_FORMAT_TYPEMASK) != SF_FORMAT_PAF)
+                       return  SFE_BAD_OPEN_FORMAT ;
+
+               endian = psf->sf.format & SF_FORMAT_ENDMASK ;
+
+               /* PAF is by default big endian. */
+               psf->endian = SF_ENDIAN_BIG ;
+
+               if (endian == SF_ENDIAN_LITTLE || (CPU_IS_LITTLE_ENDIAN && (endian == SF_ENDIAN_CPU)))
+                       psf->endian = SF_ENDIAN_LITTLE ;
+
+               if ((error = paf_write_header (psf, SF_FALSE)))
+                       return error ;
+
+               psf->write_header = paf_write_header ;
+               } ;
+
+       switch (subformat)
+       {       case SF_FORMAT_PCM_S8 :
+                                       psf->bytewidth = 1 ;
+                                       error = pcm_init (psf) ;
+                                       break ;
+
+               case SF_FORMAT_PCM_16 :
+                                       psf->bytewidth = 2 ;
+                                       error = pcm_init (psf) ;
+                                       break ;
+
+               case SF_FORMAT_PCM_24 :
+                                       /* No bytewidth because of whacky 24 bit encoding. */
+                                       error = paf24_init (psf) ;
+                                       break ;
+
+               default : return SFE_PAF_UNKNOWN_FORMAT ;
+               } ;
+
+       return error ;
+} /* paf_open */
+
+/*------------------------------------------------------------------------------
+*/
+
+static int
+paf_read_header        (SF_PRIVATE *psf)
+{      PAF_FMT         paf_fmt ;
+       int                     marker ;
+
+       memset (&paf_fmt, 0, sizeof (paf_fmt)) ;
+       psf_binheader_readf (psf, "pm", 0, &marker) ;
+
+       psf_log_printf (psf, "Signature   : '%M'\n", marker) ;
+
+       if (marker == PAF_MARKER)
+       {       psf_binheader_readf (psf, "E444444", &(paf_fmt.version), &(paf_fmt.endianness),
+                       &(paf_fmt.samplerate), &(paf_fmt.format), &(paf_fmt.channels), &(paf_fmt.source)) ;
+               }
+       else if (marker == FAP_MARKER)
+       {       psf_binheader_readf (psf, "e444444", &(paf_fmt.version), &(paf_fmt.endianness),
+                       &(paf_fmt.samplerate), &(paf_fmt.format), &(paf_fmt.channels), &(paf_fmt.source)) ;
+               }
+       else
+               return SFE_PAF_NO_MARKER ;
+
+       psf_log_printf (psf, "Version     : %d\n", paf_fmt.version) ;
+
+       if (paf_fmt.version != 0)
+       {       psf_log_printf (psf, "*** Bad version number. should be zero.\n") ;
+               return SFE_PAF_VERSION ;
+               } ;
+
+       psf_log_printf (psf, "Sample Rate : %d\n", paf_fmt.samplerate) ;
+       psf_log_printf (psf, "Channels    : %d\n", paf_fmt.channels) ;
+
+       psf_log_printf (psf, "Endianness  : %d => ", paf_fmt.endianness) ;
+       if (paf_fmt.endianness)
+       {       psf_log_printf (psf, "Little\n", paf_fmt.endianness) ;
+               psf->endian = SF_ENDIAN_LITTLE ;
+               }
+       else
+       {       psf_log_printf (psf, "Big\n", paf_fmt.endianness) ;
+               psf->endian = SF_ENDIAN_BIG ;
+               } ;
+
+       if (psf->filelength < PAF_HEADER_LENGTH)
+               return SFE_PAF_SHORT_HEADER ;
+
+       psf->datalength = psf->filelength - psf->dataoffset ;
+
+       psf_binheader_readf (psf, "p", (int) psf->dataoffset) ;
+
+       psf->sf.samplerate      = paf_fmt.samplerate ;
+       psf->sf.channels        = paf_fmt.channels ;
+
+       /* Only fill in type major. */
+       psf->sf.format = SF_FORMAT_PAF ;
+
+       psf_log_printf (psf, "Format      : %d => ", paf_fmt.format) ;
+
+       /* PAF is by default big endian. */
+       psf->sf.format |= paf_fmt.endianness ? SF_ENDIAN_LITTLE : SF_ENDIAN_BIG ;
+
+       switch (paf_fmt.format)
+       {       case PAF_PCM_S8 :
+                                       psf_log_printf (psf, "8 bit linear PCM\n") ;
+                                       psf->bytewidth = 1 ;
+
+                                       psf->sf.format |= SF_FORMAT_PCM_S8 ;
+
+                                       psf->blockwidth = psf->bytewidth * psf->sf.channels ;
+                                       psf->sf.frames = psf->datalength / psf->blockwidth ;
+                                       break ;
+
+               case PAF_PCM_16 :
+                                       psf_log_printf (psf, "16 bit linear PCM\n") ;
+                                       psf->bytewidth = 2 ;
+
+                                       psf->sf.format |= SF_FORMAT_PCM_16 ;
+
+                                       psf->blockwidth = psf->bytewidth * psf->sf.channels ;
+                                       psf->sf.frames = psf->datalength / psf->blockwidth ;
+                                       break ;
+
+               case PAF_PCM_24 :
+                                       psf_log_printf (psf, "24 bit linear PCM\n") ;
+                                       psf->bytewidth = 3 ;
+
+                                       psf->sf.format |= SF_FORMAT_PCM_24 ;
+
+                                       psf->blockwidth = 0 ;
+                                       psf->sf.frames = PAF24_SAMPLES_PER_BLOCK * psf->datalength /
+                                                                                       (PAF24_BLOCK_SIZE * psf->sf.channels) ;
+                                       break ;
+
+               default :       psf_log_printf (psf, "Unknown\n") ;
+                                       return SFE_PAF_UNKNOWN_FORMAT ;
+                                       break ;
+               } ;
+
+       psf_log_printf (psf, "Source      : %d => ", paf_fmt.source) ;
+
+       switch (paf_fmt.source)
+       {       case 1 : psf_log_printf (psf, "Analog Recording\n") ;
+                                       break ;
+               case 2 : psf_log_printf (psf, "Digital Transfer\n") ;
+                                       break ;
+               case 3 : psf_log_printf (psf, "Multi-track Mixdown\n") ;
+                                       break ;
+               case 5 : psf_log_printf (psf, "Audio Resulting From DSP Processing\n") ;
+                                       break ;
+               default : psf_log_printf (psf, "Unknown\n") ;
+                                       break ;
+               } ;
+
+       return 0 ;
+} /* paf_read_header */
+
+static int
+paf_write_header (SF_PRIVATE *psf, int calc_length)
+{      int                     paf_format ;
+
+       /* PAF header already written so no need to re-write. */
+       if (psf_ftell (psf) >= PAF_HEADER_LENGTH)
+               return 0 ;
+
+       psf->dataoffset = PAF_HEADER_LENGTH ;
+
+       psf->dataoffset = PAF_HEADER_LENGTH ;
+
+       /* Prevent compiler warning. */
+       calc_length = calc_length ;
+
+       switch (psf->sf.format & SF_FORMAT_SUBMASK)
+       {       case SF_FORMAT_PCM_S8 :
+                                       paf_format = PAF_PCM_S8 ;
+                                       break ;
+
+               case SF_FORMAT_PCM_16 :
+                                       paf_format = PAF_PCM_16 ;
+                                       break ;
+
+               case SF_FORMAT_PCM_24 :
+                                       paf_format = PAF_PCM_24 ;
+                                       break ;
+
+               default : return SFE_PAF_UNKNOWN_FORMAT ;
+               } ;
+
+       /* Reset the current header length to zero. */
+       psf->header [0] = 0 ;
+       psf->headindex = 0 ;
+
+       if (psf->endian == SF_ENDIAN_BIG)
+       {       /* Marker, version, endianness, samplerate */
+               psf_binheader_writef (psf, "Em444", PAF_MARKER, 0, 0, psf->sf.samplerate) ;
+               /* format, channels, source */
+               psf_binheader_writef (psf, "E444", paf_format, psf->sf.channels, 0) ;
+               }
+       else if (psf->endian == SF_ENDIAN_LITTLE)
+       {       /* Marker, version, endianness, samplerate */
+               psf_binheader_writef (psf, "em444", FAP_MARKER, 0, 1, psf->sf.samplerate) ;
+               /* format, channels, source */
+               psf_binheader_writef (psf, "e444", paf_format, psf->sf.channels, 0) ;
+               } ;
+
+       /* Zero fill to dataoffset. */
+       psf_binheader_writef (psf, "z", (size_t) (psf->dataoffset - psf->headindex)) ;
+
+       psf_fwrite (psf->header, psf->headindex, 1, psf) ;
+
+       return psf->error ;
+} /* paf_write_header */
+
+/*===============================================================================
+**     24 bit PAF files have a really weird encoding.
+**  For a mono file, 10 samples (each being 3 bytes) are packed into a 32 byte
+**     block. The 8 ints in this 32 byte block are then endian swapped (as ints)
+**     if necessary before being written to disk.
+**  For a stereo file, blocks of 10 samples from the same channel are encoded
+**  into 32 bytes as for the mono case. The 32 byte blocks are then interleaved
+**     on disk.
+**     Reading has to reverse the above process :-).
+**     Weird!!!
+**
+**     The code below attempts to gain efficiency while maintaining readability.
+*/
+
+static int paf24_read_block (SF_PRIVATE *psf, PAF24_PRIVATE *ppaf24) ;
+static int paf24_write_block (SF_PRIVATE *psf, PAF24_PRIVATE *ppaf24) ;
+static int paf24_close (SF_PRIVATE *psf) ;
+
+
+static int
+paf24_init (SF_PRIVATE *psf)
+{      PAF24_PRIVATE   *ppaf24 ;
+       int     paf24size ;
+
+       paf24size = sizeof (PAF24_PRIVATE) + psf->sf.channels *
+                                       (PAF24_BLOCK_SIZE + PAF24_SAMPLES_PER_BLOCK * sizeof (int)) ;
+
+       /*
+       **      Not exatly sure why this needs to be here but the tests
+       **      fail without it.
+       */
+       psf->last_op = 0 ;
+
+       if (! (psf->fdata = malloc (paf24size)))
+               return SFE_MALLOC_FAILED ;
+
+       ppaf24 = (PAF24_PRIVATE*) psf->fdata ;
+       memset (ppaf24, 0, paf24size) ;
+
+       ppaf24->channels        = psf->sf.channels ;
+       ppaf24->samples         = ppaf24->data ;
+       ppaf24->block           = (unsigned char*) (ppaf24->data + PAF24_SAMPLES_PER_BLOCK * ppaf24->channels) ;
+
+       ppaf24->blocksize = PAF24_BLOCK_SIZE * ppaf24->channels ;
+       ppaf24->samplesperblock = PAF24_SAMPLES_PER_BLOCK ;
+
+       if (psf->mode == SFM_READ || psf->mode == SFM_RDWR)
+       {       paf24_read_block (psf, ppaf24) ;        /* Read first block. */
+
+               psf->read_short         = paf24_read_s ;
+               psf->read_int           = paf24_read_i ;
+               psf->read_float         = paf24_read_f ;
+               psf->read_double        = paf24_read_d ;
+               } ;
+
+       if (psf->mode == SFM_WRITE || psf->mode == SFM_RDWR)
+       {       psf->write_short        = paf24_write_s ;
+               psf->write_int          = paf24_write_i ;
+               psf->write_float        = paf24_write_f ;
+               psf->write_double       = paf24_write_d ;
+               } ;
+
+       psf->seek       = paf24_seek ;
+       psf->container_close    = paf24_close ;
+
+       psf->filelength = psf_get_filelen (psf) ;
+       psf->datalength = psf->filelength - psf->dataoffset ;
+
+       if (psf->datalength % PAF24_BLOCK_SIZE)
+       {       if (psf->mode == SFM_READ)
+                       psf_log_printf (psf, "*** Warning : file seems to be truncated.\n") ;
+               ppaf24->max_blocks = psf->datalength / ppaf24->blocksize + 1 ;
+               }
+       else
+               ppaf24->max_blocks = psf->datalength / ppaf24->blocksize ;
+
+       ppaf24->read_block = 0 ;
+       if (psf->mode == SFM_RDWR)
+               ppaf24->write_block = ppaf24->max_blocks ;
+       else
+               ppaf24->write_block = 0 ;
+
+       psf->sf.frames = ppaf24->samplesperblock * ppaf24->max_blocks ;
+       ppaf24->sample_count = psf->sf.frames ;
+
+       return 0 ;
+} /* paf24_init */
+
+static sf_count_t
+paf24_seek (SF_PRIVATE *psf, int mode, sf_count_t offset)
+{      PAF24_PRIVATE   *ppaf24 ;
+       int                             newblock, newsample ;
+
+       if (psf->fdata == NULL)
+       {       psf->error = SFE_INTERNAL ;
+               return PSF_SEEK_ERROR ;
+               } ;
+
+       ppaf24 = (PAF24_PRIVATE*) psf->fdata ;
+
+       if (mode == SFM_READ && ppaf24->write_count > 0)
+               paf24_write_block (psf, ppaf24) ;
+
+       newblock        = offset / ppaf24->samplesperblock ;
+       newsample       = offset % ppaf24->samplesperblock ;
+
+       switch (mode)
+       {       case SFM_READ :
+                               if (psf->last_op == SFM_WRITE && ppaf24->write_count)
+                                       paf24_write_block (psf, ppaf24) ;
+
+                               psf_fseek (psf, psf->dataoffset + newblock * ppaf24->blocksize, SEEK_SET) ;
+                               ppaf24->read_block = newblock ;
+                               paf24_read_block (psf, ppaf24) ;
+                               ppaf24->read_count = newsample ;
+                               break ;
+
+               case SFM_WRITE :
+                               if (offset > ppaf24->sample_count)
+                               {       psf->error = SFE_BAD_SEEK ;
+                                       return PSF_SEEK_ERROR ;
+                                       } ;
+
+                               if (psf->last_op == SFM_WRITE && ppaf24->write_count)
+                                       paf24_write_block (psf, ppaf24) ;
+
+                               psf_fseek (psf, psf->dataoffset + newblock * ppaf24->blocksize, SEEK_SET) ;
+                               ppaf24->write_block = newblock ;
+                               paf24_read_block (psf, ppaf24) ;
+                               ppaf24->write_count = newsample ;
+                               break ;
+
+               default :
+                               psf->error = SFE_BAD_SEEK ;
+                               return PSF_SEEK_ERROR ;
+               } ;
+
+       return newblock * ppaf24->samplesperblock + newsample ;
+} /* paf24_seek */
+
+static int
+paf24_close (SF_PRIVATE *psf)
+{      PAF24_PRIVATE *ppaf24 ;
+
+       if (psf->fdata == NULL)
+               return 0 ;
+
+       ppaf24 = (PAF24_PRIVATE*) psf->fdata ;
+
+       if (psf->mode == SFM_WRITE || psf->mode == SFM_RDWR)
+       {       if (ppaf24->write_count > 0)
+                       paf24_write_block (psf, ppaf24) ;
+               } ;
+
+       return 0 ;
+} /* paf24_close */
+
+/*---------------------------------------------------------------------------
+*/
+static int
+paf24_read_block (SF_PRIVATE *psf, PAF24_PRIVATE *ppaf24)
+{      int                             k, channel ;
+       unsigned char   *cptr ;
+
+       ppaf24->read_block ++ ;
+       ppaf24->read_count = 0 ;
+
+       if (ppaf24->read_block * ppaf24->samplesperblock > ppaf24->sample_count)
+       {       memset (ppaf24->samples, 0, ppaf24->samplesperblock * ppaf24->channels) ;
+               return 1 ;
+               } ;
+
+       /* Read the block. */
+       if ((k = psf_fread (ppaf24->block, 1, ppaf24->blocksize, psf)) != ppaf24->blocksize)
+               psf_log_printf (psf, "*** Warning : short read (%d != %d).\n", k, ppaf24->blocksize) ;
+
+
+       if (CPU_IS_LITTLE_ENDIAN)
+       {       /* Do endian swapping if necessary. */
+               if (psf->endian == SF_ENDIAN_BIG)
+                       endswap_int_array       (ppaf24->data, 8 * ppaf24->channels) ;
+
+               /* Unpack block. */
+               for (k = 0 ; k < PAF24_SAMPLES_PER_BLOCK * ppaf24->channels ; k++)
+               {       channel = k % ppaf24->channels ;
+                       cptr = ppaf24->block + PAF24_BLOCK_SIZE * channel + 3 * (k / ppaf24->channels) ;
+                       ppaf24->samples [k] = (cptr [0] << 8) | (cptr [1] << 16) | (cptr [2] << 24) ;
+                       } ;
+               }
+       else
+       {       /* Do endian swapping if necessary. */
+               if (psf->endian == SF_ENDIAN_BIG)
+                       endswap_int_array       (ppaf24->data, 8 * ppaf24->channels) ;
+
+               /* Unpack block. */
+               for (k = 0 ; k < PAF24_SAMPLES_PER_BLOCK * ppaf24->channels ; k++)
+               {       channel = k % ppaf24->channels ;
+                       cptr = ppaf24->block + PAF24_BLOCK_SIZE * channel + 3 * (k / ppaf24->channels) ;
+                       ppaf24->samples [k] = (cptr [0] << 8) | (cptr [1] << 16) | (cptr [2] << 24) ;
+                       } ;
+               } ;
+
+       return 1 ;
+} /* paf24_read_block */
+
+static int
+paf24_read (SF_PRIVATE *psf, PAF24_PRIVATE *ppaf24, int *ptr, int len)
+{      int     count, total = 0 ;
+
+       while (total < len)
+       {       if (ppaf24->read_block * ppaf24->samplesperblock >= ppaf24->sample_count)
+               {       memset (&(ptr [total]), 0, (len - total) * sizeof (int)) ;
+                       return total ;
+                       } ;
+
+               if (ppaf24->read_count >= ppaf24->samplesperblock)
+                       paf24_read_block (psf, ppaf24) ;
+
+               count = (ppaf24->samplesperblock - ppaf24->read_count) * ppaf24->channels ;
+               count = (len - total > count) ? count : len - total ;
+
+               memcpy (&(ptr [total]), &(ppaf24->samples [ppaf24->read_count * ppaf24->channels]), count * sizeof (int)) ;
+               total += count ;
+               ppaf24->read_count += count / ppaf24->channels ;
+               } ;
+
+       return total ;
+} /* paf24_read */
+
+static sf_count_t
+paf24_read_s (SF_PRIVATE *psf, short *ptr, sf_count_t len)
+{      PAF24_PRIVATE   *ppaf24 ;
+       int                             *iptr ;
+       int                             k, bufferlen, readcount, count ;
+       sf_count_t              total = 0 ;
+
+       if (psf->fdata == NULL)
+               return 0 ;
+       ppaf24 = (PAF24_PRIVATE*) psf->fdata ;
+
+       iptr = psf->u.ibuf ;
+       bufferlen = ARRAY_LEN (psf->u.ibuf) ;
+       while (len > 0)
+       {       readcount = (len >= bufferlen) ? bufferlen : len ;
+               count = paf24_read (psf, ppaf24, iptr, readcount) ;
+               for (k = 0 ; k < readcount ; k++)
+                       ptr [total + k] = iptr [k] >> 16 ;
+               total += count ;
+               len -= readcount ;
+               } ;
+       return total ;
+} /* paf24_read_s */
+
+static sf_count_t
+paf24_read_i (SF_PRIVATE *psf, int *ptr, sf_count_t len)
+{      PAF24_PRIVATE *ppaf24 ;
+       int                             total ;
+
+       if (psf->fdata == NULL)
+               return 0 ;
+       ppaf24 = (PAF24_PRIVATE*) psf->fdata ;
+
+       total = paf24_read (psf, ppaf24, ptr, len) ;
+
+       return total ;
+} /* paf24_read_i */
+
+static sf_count_t
+paf24_read_f (SF_PRIVATE *psf, float *ptr, sf_count_t len)
+{      PAF24_PRIVATE   *ppaf24 ;
+       int                             *iptr ;
+       int                             k, bufferlen, readcount, count ;
+       sf_count_t              total = 0 ;
+       float                   normfact ;
+
+       if (psf->fdata == NULL)
+               return 0 ;
+       ppaf24 = (PAF24_PRIVATE*) psf->fdata ;
+
+       normfact = (psf->norm_float == SF_TRUE) ? (1.0 / 0x80000000) : (1.0 / 0x100) ;
+
+       iptr = psf->u.ibuf ;
+       bufferlen = ARRAY_LEN (psf->u.ibuf) ;
+       while (len > 0)
+       {       readcount = (len >= bufferlen) ? bufferlen : len ;
+               count = paf24_read (psf, ppaf24, iptr, readcount) ;
+               for (k = 0 ; k < readcount ; k++)
+                       ptr [total + k] = normfact * iptr [k] ;
+               total += count ;
+               len -= readcount ;
+               } ;
+       return total ;
+} /* paf24_read_f */
+
+static sf_count_t
+paf24_read_d (SF_PRIVATE *psf, double *ptr, sf_count_t len)
+{      PAF24_PRIVATE   *ppaf24 ;
+       int                             *iptr ;
+       int                             k, bufferlen, readcount, count ;
+       sf_count_t              total = 0 ;
+       double                  normfact ;
+
+       if (psf->fdata == NULL)
+               return 0 ;
+       ppaf24 = (PAF24_PRIVATE*) psf->fdata ;
+
+       normfact = (psf->norm_double == SF_TRUE) ? (1.0 / 0x80000000) : (1.0 / 0x100) ;
+
+       iptr = psf->u.ibuf ;
+       bufferlen = ARRAY_LEN (psf->u.ibuf) ;
+       while (len > 0)
+       {       readcount = (len >= bufferlen) ? bufferlen : len ;
+               count = paf24_read (psf, ppaf24, iptr, readcount) ;
+               for (k = 0 ; k < readcount ; k++)
+                       ptr [total + k] = normfact * iptr [k] ;
+               total += count ;
+               len -= readcount ;
+               } ;
+       return total ;
+} /* paf24_read_d */
+
+/*---------------------------------------------------------------------------
+*/
+
+static int
+paf24_write_block (SF_PRIVATE *psf, PAF24_PRIVATE *ppaf24)
+{      int                             k, nextsample, channel ;
+       unsigned char   *cptr ;
+
+       /* First pack block. */
+
+       if (CPU_IS_LITTLE_ENDIAN)
+       {       for (k = 0 ; k < PAF24_SAMPLES_PER_BLOCK * ppaf24->channels ; k++)
+               {       channel = k % ppaf24->channels ;
+                       cptr = ppaf24->block + PAF24_BLOCK_SIZE * channel + 3 * (k / ppaf24->channels) ;
+                       nextsample = ppaf24->samples [k] >> 8 ;
+                       cptr [0] = nextsample ;
+                       cptr [1] = nextsample >> 8 ;
+                       cptr [2] = nextsample >> 16 ;
+                       } ;
+
+               /* Do endian swapping if necessary. */
+               if (psf->endian == SF_ENDIAN_BIG)
+                       endswap_int_array (ppaf24->data, 8 * ppaf24->channels) ;
+               }
+       else if (CPU_IS_BIG_ENDIAN)
+       {       /* This is correct. */
+               for (k = 0 ; k < PAF24_SAMPLES_PER_BLOCK * ppaf24->channels ; k++)
+               {       channel = k % ppaf24->channels ;
+                       cptr = ppaf24->block + PAF24_BLOCK_SIZE * channel + 3 * (k / ppaf24->channels) ;
+                       nextsample = ppaf24->samples [k] >> 8 ;
+                       cptr [0] = nextsample ;
+                       cptr [1] = nextsample >> 8 ;
+                       cptr [2] = nextsample >> 16 ;
+                       } ;
+               if (psf->endian == SF_ENDIAN_BIG)
+                       endswap_int_array (ppaf24->data, 8 * ppaf24->channels) ;
+               } ;
+
+       /* Write block to disk. */
+       if ((k = psf_fwrite (ppaf24->block, 1, ppaf24->blocksize, psf)) != ppaf24->blocksize)
+               psf_log_printf (psf, "*** Warning : short write (%d != %d).\n", k, ppaf24->blocksize) ;
+
+       if (ppaf24->sample_count < ppaf24->write_block * ppaf24->samplesperblock + ppaf24->write_count)
+               ppaf24->sample_count = ppaf24->write_block * ppaf24->samplesperblock + ppaf24->write_count ;
+
+       if (ppaf24->write_count == ppaf24->samplesperblock)
+       {       ppaf24->write_block ++ ;
+               ppaf24->write_count = 0 ;
+               } ;
+
+       return 1 ;
+} /* paf24_write_block */
+
+static int
+paf24_write (SF_PRIVATE *psf, PAF24_PRIVATE *ppaf24, const int *ptr, int len)
+{      int             count, total = 0 ;
+
+       while (total < len)
+       {       count = (ppaf24->samplesperblock - ppaf24->write_count) * ppaf24->channels ;
+
+               if (count > len - total)
+                       count = len - total ;
+
+               memcpy (&(ppaf24->samples [ppaf24->write_count * ppaf24->channels]), &(ptr [total]), count * sizeof (int)) ;
+               total += count ;
+               ppaf24->write_count += count / ppaf24->channels ;
+
+               if (ppaf24->write_count >= ppaf24->samplesperblock)
+                       paf24_write_block (psf, ppaf24) ;
+               } ;
+
+       return total ;
+} /* paf24_write */
+
+static sf_count_t
+paf24_write_s (SF_PRIVATE *psf, const short *ptr, sf_count_t len)
+{      PAF24_PRIVATE   *ppaf24 ;
+       int                             *iptr ;
+       int                             k, bufferlen, writecount = 0, count ;
+       sf_count_t              total = 0 ;
+
+       if (psf->fdata == NULL)
+               return 0 ;
+       ppaf24 = (PAF24_PRIVATE*) psf->fdata ;
+
+       iptr = psf->u.ibuf ;
+       bufferlen = ARRAY_LEN (psf->u.ibuf) ;
+       while (len > 0)
+       {       writecount = (len >= bufferlen) ? bufferlen : len ;
+               for (k = 0 ; k < writecount ; k++)
+                       iptr [k] = ptr [total + k] << 16 ;
+               count = paf24_write (psf, ppaf24, iptr, writecount) ;
+               total += count ;
+               len -= writecount ;
+               if (count != writecount)
+                       break ;
+               } ;
+       return total ;
+} /* paf24_write_s */
+
+static sf_count_t
+paf24_write_i (SF_PRIVATE *psf, const int *ptr, sf_count_t len)
+{      PAF24_PRIVATE   *ppaf24 ;
+       int                             writecount, count ;
+       sf_count_t              total = 0 ;
+
+       if (psf->fdata == NULL)
+               return 0 ;
+       ppaf24 = (PAF24_PRIVATE*) psf->fdata ;
+
+       while (len > 0)
+       {       writecount = (len > 0x10000000) ? 0x10000000 : (int) len ;
+
+               count = paf24_write (psf, ppaf24, ptr, writecount) ;
+
+               total += count ;
+               len -= count ;
+               if (count != writecount)
+                       break ;
+               } ;
+
+       return total ;
+} /* paf24_write_i */
+
+static sf_count_t
+paf24_write_f (SF_PRIVATE *psf, const float *ptr, sf_count_t len)
+{      PAF24_PRIVATE   *ppaf24 ;
+       int                             *iptr ;
+       int                             k, bufferlen, writecount = 0, count ;
+       sf_count_t              total = 0 ;
+       float                   normfact ;
+
+       if (psf->fdata == NULL)
+               return 0 ;
+       ppaf24 = (PAF24_PRIVATE*) psf->fdata ;
+
+       normfact = (psf->norm_float == SF_TRUE) ? (1.0 * 0x7FFFFFFF) : (1.0 / 0x100) ;
+
+       iptr = psf->u.ibuf ;
+       bufferlen = ARRAY_LEN (psf->u.ibuf) ;
+       while (len > 0)
+       {       writecount = (len >= bufferlen) ? bufferlen : len ;
+               for (k = 0 ; k < writecount ; k++)
+                       iptr [k] = lrintf (normfact * ptr [total + k]) ;
+               count = paf24_write (psf, ppaf24, iptr, writecount) ;
+               total += count ;
+               len -= writecount ;
+               if (count != writecount)
+                       break ;
+               } ;
+
+       return total ;
+} /* paf24_write_f */
+
+static sf_count_t
+paf24_write_d (SF_PRIVATE *psf, const double *ptr, sf_count_t len)
+{      PAF24_PRIVATE   *ppaf24 ;
+       int                             *iptr ;
+       int                             k, bufferlen, writecount = 0, count ;
+       sf_count_t              total = 0 ;
+       double                  normfact ;
+
+       if (psf->fdata == NULL)
+               return 0 ;
+       ppaf24 = (PAF24_PRIVATE*) psf->fdata ;
+
+       normfact = (psf->norm_double == SF_TRUE) ? (1.0 * 0x7FFFFFFF) : (1.0 / 0x100) ;
+
+       iptr = psf->u.ibuf ;
+       bufferlen = ARRAY_LEN (psf->u.ibuf) ;
+       while (len > 0)
+       {       writecount = (len >= bufferlen) ? bufferlen : len ;
+               for (k = 0 ; k < writecount ; k++)
+                       iptr [k] = lrint (normfact * ptr [total+k]) ;
+               count = paf24_write (psf, ppaf24, iptr, writecount) ;
+               total += count ;
+               len -= writecount ;
+               if (count != writecount)
+                       break ;
+               } ;
+
+       return total ;
+} /* paf24_write_d */
+
+
+/*
+** Do not edit or modify anything in this comment block.
+** The arch-tag line is a file identity tag for the GNU Arch 
+** revision control system.
+**
+** arch-tag: 477a5308-451e-4bbd-bab4-fab6caa4e884
+*/
diff --git a/libs/libsndfile/src/pcm.c b/libs/libsndfile/src/pcm.c
new file mode 100644 (file)
index 0000000..bad607c
--- /dev/null
@@ -0,0 +1,2899 @@
+/*
+** Copyright (C) 1999-2005 Erik de Castro Lopo <erikd@mega-nerd.com>
+**
+** This program is free software; you can redistribute it and/or modify
+** it under the terms of the GNU Lesser General Public License as published by
+** the Free Software Foundation; either version 2.1 of the License, or
+** (at your option) any later version.
+**
+** This program is distributed in the hope that it will be useful,
+** but WITHOUT ANY WARRANTY; without even the implied warranty of
+** MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+** GNU Lesser General Public License for more details.
+**
+** You should have received a copy of the GNU Lesser General Public License
+** along with this program; if not, write to the Free Software
+** Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA.
+*/
+
+#include       "sfconfig.h"
+
+#include       "sndfile.h"
+#include       "sfendian.h"
+#include       "float_cast.h"
+#include       "common.h"
+
+/* Need to be able to handle 3 byte (24 bit) integers. So defined a
+** type and use SIZEOF_TRIBYTE instead of (tribyte).
+*/
+
+typedef        void    tribyte ;
+
+#define        SIZEOF_TRIBYTE  3
+
+static sf_count_t      pcm_read_sc2s   (SF_PRIVATE *psf, short *ptr, sf_count_t len) ;
+static sf_count_t      pcm_read_uc2s   (SF_PRIVATE *psf, short *ptr, sf_count_t len) ;
+static sf_count_t      pcm_read_bes2s  (SF_PRIVATE *psf, short *ptr, sf_count_t len) ;
+static sf_count_t      pcm_read_les2s  (SF_PRIVATE *psf, short *ptr, sf_count_t len) ;
+static sf_count_t      pcm_read_bet2s  (SF_PRIVATE *psf, short *ptr, sf_count_t len) ;
+static sf_count_t      pcm_read_let2s  (SF_PRIVATE *psf, short *ptr, sf_count_t len) ;
+static sf_count_t      pcm_read_bei2s  (SF_PRIVATE *psf, short *ptr, sf_count_t len) ;
+static sf_count_t      pcm_read_lei2s  (SF_PRIVATE *psf, short *ptr, sf_count_t len) ;
+
+static sf_count_t      pcm_read_sc2i   (SF_PRIVATE *psf, int *ptr, sf_count_t len) ;
+static sf_count_t      pcm_read_uc2i   (SF_PRIVATE *psf, int *ptr, sf_count_t len) ;
+static sf_count_t      pcm_read_bes2i  (SF_PRIVATE *psf, int *ptr, sf_count_t len) ;
+static sf_count_t      pcm_read_les2i  (SF_PRIVATE *psf, int *ptr, sf_count_t len) ;
+static sf_count_t      pcm_read_bet2i  (SF_PRIVATE *psf, int *ptr, sf_count_t len) ;
+static sf_count_t      pcm_read_let2i  (SF_PRIVATE *psf, int *ptr, sf_count_t len) ;
+static sf_count_t      pcm_read_bei2i  (SF_PRIVATE *psf, int *ptr, sf_count_t len) ;
+static sf_count_t      pcm_read_lei2i  (SF_PRIVATE *psf, int *ptr, sf_count_t len) ;
+
+static sf_count_t      pcm_read_sc2f   (SF_PRIVATE *psf, float *ptr, sf_count_t len) ;
+static sf_count_t      pcm_read_uc2f   (SF_PRIVATE *psf, float *ptr, sf_count_t len) ;
+static sf_count_t      pcm_read_bes2f  (SF_PRIVATE *psf, float *ptr, sf_count_t len) ;
+static sf_count_t      pcm_read_les2f  (SF_PRIVATE *psf, float *ptr, sf_count_t len) ;
+static sf_count_t      pcm_read_bet2f  (SF_PRIVATE *psf, float *ptr, sf_count_t len) ;
+static sf_count_t      pcm_read_let2f  (SF_PRIVATE *psf, float *ptr, sf_count_t len) ;
+static sf_count_t      pcm_read_bei2f  (SF_PRIVATE *psf, float *ptr, sf_count_t len) ;
+static sf_count_t      pcm_read_lei2f  (SF_PRIVATE *psf, float *ptr, sf_count_t len) ;
+
+static sf_count_t      pcm_read_sc2d   (SF_PRIVATE *psf, double *ptr, sf_count_t len) ;
+static sf_count_t      pcm_read_uc2d   (SF_PRIVATE *psf, double *ptr, sf_count_t len) ;
+static sf_count_t      pcm_read_bes2d  (SF_PRIVATE *psf, double *ptr, sf_count_t len) ;
+static sf_count_t      pcm_read_les2d  (SF_PRIVATE *psf, double *ptr, sf_count_t len) ;
+static sf_count_t      pcm_read_bet2d  (SF_PRIVATE *psf, double *ptr, sf_count_t len) ;
+static sf_count_t      pcm_read_let2d  (SF_PRIVATE *psf, double *ptr, sf_count_t len) ;
+static sf_count_t      pcm_read_bei2d  (SF_PRIVATE *psf, double *ptr, sf_count_t len) ;
+static sf_count_t      pcm_read_lei2d  (SF_PRIVATE *psf, double *ptr, sf_count_t len) ;
+
+static sf_count_t      pcm_write_s2sc  (SF_PRIVATE *psf, const short *ptr, sf_count_t len) ;
+static sf_count_t      pcm_write_s2uc  (SF_PRIVATE *psf, const short *ptr, sf_count_t len) ;
+static sf_count_t      pcm_write_s2bes (SF_PRIVATE *psf, const short *ptr, sf_count_t len) ;
+static sf_count_t      pcm_write_s2les (SF_PRIVATE *psf, const short *ptr, sf_count_t len) ;
+static sf_count_t      pcm_write_s2bet (SF_PRIVATE *psf, const short *ptr, sf_count_t len) ;
+static sf_count_t      pcm_write_s2let (SF_PRIVATE *psf, const short *ptr, sf_count_t len) ;
+static sf_count_t      pcm_write_s2bei (SF_PRIVATE *psf, const short *ptr, sf_count_t len) ;
+static sf_count_t      pcm_write_s2lei (SF_PRIVATE *psf, const short *ptr, sf_count_t len) ;
+
+static sf_count_t      pcm_write_i2sc  (SF_PRIVATE *psf, const int *ptr, sf_count_t len) ;
+static sf_count_t      pcm_write_i2uc  (SF_PRIVATE *psf, const int *ptr, sf_count_t len) ;
+static sf_count_t      pcm_write_i2bes (SF_PRIVATE *psf, const int *ptr, sf_count_t len) ;
+static sf_count_t      pcm_write_i2les (SF_PRIVATE *psf, const int *ptr, sf_count_t len) ;
+static sf_count_t      pcm_write_i2bet (SF_PRIVATE *psf, const int *ptr, sf_count_t len) ;
+static sf_count_t      pcm_write_i2let (SF_PRIVATE *psf, const int *ptr, sf_count_t len) ;
+static sf_count_t      pcm_write_i2bei (SF_PRIVATE *psf, const int *ptr, sf_count_t len) ;
+static sf_count_t      pcm_write_i2lei (SF_PRIVATE *psf, const int *ptr, sf_count_t len) ;
+
+static sf_count_t      pcm_write_f2sc  (SF_PRIVATE *psf, const float *ptr, sf_count_t len) ;
+static sf_count_t      pcm_write_f2uc  (SF_PRIVATE *psf, const float *ptr, sf_count_t len) ;
+static sf_count_t      pcm_write_f2bes (SF_PRIVATE *psf, const float *ptr, sf_count_t len) ;
+static sf_count_t      pcm_write_f2les (SF_PRIVATE *psf, const float *ptr, sf_count_t len) ;
+static sf_count_t      pcm_write_f2bet (SF_PRIVATE *psf, const float *ptr, sf_count_t len) ;
+static sf_count_t      pcm_write_f2let (SF_PRIVATE *psf, const float *ptr, sf_count_t len) ;
+static sf_count_t      pcm_write_f2bei (SF_PRIVATE *psf, const float *ptr, sf_count_t len) ;
+static sf_count_t      pcm_write_f2lei (SF_PRIVATE *psf, const float *ptr, sf_count_t len) ;
+
+static sf_count_t      pcm_write_d2sc  (SF_PRIVATE *psf, const double *ptr, sf_count_t len) ;
+static sf_count_t      pcm_write_d2uc  (SF_PRIVATE *psf, const double *ptr, sf_count_t len) ;
+static sf_count_t      pcm_write_d2bes (SF_PRIVATE *psf, const double *ptr, sf_count_t len) ;
+static sf_count_t      pcm_write_d2les (SF_PRIVATE *psf, const double *ptr, sf_count_t len) ;
+static sf_count_t      pcm_write_d2bet (SF_PRIVATE *psf, const double *ptr, sf_count_t len) ;
+static sf_count_t      pcm_write_d2let (SF_PRIVATE *psf, const double *ptr, sf_count_t len) ;
+static sf_count_t      pcm_write_d2bei (SF_PRIVATE *psf, const double *ptr, sf_count_t len) ;
+static sf_count_t      pcm_write_d2lei (SF_PRIVATE *psf, const double *ptr, sf_count_t len) ;
+
+/*-----------------------------------------------------------------------------------------------
+*/
+
+enum
+{      /* Char type for 8 bit files. */
+       SF_CHARS_SIGNED         = 200,
+       SF_CHARS_UNSIGNED       = 201
+} ;
+
+/*-----------------------------------------------------------------------------------------------
+*/
+
+int
+pcm_init (SF_PRIVATE *psf)
+{      int chars = 0 ;
+
+       if (psf->bytewidth == 0 || psf->sf.channels == 0)
+               return SFE_INTERNAL ;
+
+       psf->blockwidth = psf->bytewidth * psf->sf.channels ;
+
+       if ((psf->sf.format & SF_FORMAT_SUBMASK) == SF_FORMAT_PCM_S8)
+               chars = SF_CHARS_SIGNED ;
+       else if ((psf->sf.format & SF_FORMAT_SUBMASK) == SF_FORMAT_PCM_U8)
+               chars = SF_CHARS_UNSIGNED ;
+
+       if (psf->mode == SFM_READ || psf->mode == SFM_RDWR)
+       {       switch (psf->bytewidth * 0x10000 + psf->endian + chars)
+               {       case (0x10000 + SF_ENDIAN_BIG + SF_CHARS_SIGNED) :
+                       case (0x10000 + SF_ENDIAN_LITTLE + SF_CHARS_SIGNED) :
+                                       psf->read_short         = pcm_read_sc2s ;
+                                       psf->read_int           = pcm_read_sc2i ;
+                                       psf->read_float         = pcm_read_sc2f ;
+                                       psf->read_double        = pcm_read_sc2d ;
+                                       break ;
+                       case (0x10000 + SF_ENDIAN_BIG + SF_CHARS_UNSIGNED) :
+                       case (0x10000 + SF_ENDIAN_LITTLE + SF_CHARS_UNSIGNED) :
+                                       psf->read_short         = pcm_read_uc2s ;
+                                       psf->read_int           = pcm_read_uc2i ;
+                                       psf->read_float         = pcm_read_uc2f ;
+                                       psf->read_double        = pcm_read_uc2d ;
+                                       break ;
+
+                       case (2 * 0x10000 + SF_ENDIAN_BIG) :
+                                       psf->read_short         = pcm_read_bes2s ;
+                                       psf->read_int           = pcm_read_bes2i ;
+                                       psf->read_float         = pcm_read_bes2f ;
+                                       psf->read_double        = pcm_read_bes2d ;
+                                       break ;
+                       case (3 * 0x10000 + SF_ENDIAN_BIG) :
+                                       psf->read_short         = pcm_read_bet2s ;
+                                       psf->read_int           = pcm_read_bet2i ;
+                                       psf->read_float         = pcm_read_bet2f ;
+                                       psf->read_double        = pcm_read_bet2d ;
+                                       break ;
+                       case (4 * 0x10000 + SF_ENDIAN_BIG) :
+                                       psf->read_short         = pcm_read_bei2s ;
+                                       psf->read_int           = pcm_read_bei2i ;
+                                       psf->read_float         = pcm_read_bei2f ;
+                                       psf->read_double        = pcm_read_bei2d ;
+                                       break ;
+
+                       case (2 * 0x10000 + SF_ENDIAN_LITTLE) :
+                                       psf->read_short         = pcm_read_les2s ;
+                                       psf->read_int           = pcm_read_les2i ;
+                                       psf->read_float         = pcm_read_les2f ;
+                                       psf->read_double        = pcm_read_les2d ;
+                                       break ;
+                       case (3 * 0x10000 + SF_ENDIAN_LITTLE) :
+                                       psf->read_short         = pcm_read_let2s ;
+                                       psf->read_int           = pcm_read_let2i ;
+                                       psf->read_float         = pcm_read_let2f ;
+                                       psf->read_double        = pcm_read_let2d ;
+                                       break ;
+                       case (4 * 0x10000 + SF_ENDIAN_LITTLE) :
+                                       psf->read_short         = pcm_read_lei2s ;
+                                       psf->read_int           = pcm_read_lei2i ;
+                                       psf->read_float         = pcm_read_lei2f ;
+                                       psf->read_double        = pcm_read_lei2d ;
+                                       break ;
+                       default :
+                               psf_log_printf (psf, "pcm.c returning SFE_UNIMPLEMENTED\n") ;
+                               return SFE_UNIMPLEMENTED ;
+                       } ;
+               } ;
+
+       if (psf->mode == SFM_WRITE || psf->mode == SFM_RDWR)
+       {       switch (psf->bytewidth * 0x10000 + psf->endian + chars)
+               {       case (0x10000 + SF_ENDIAN_BIG + SF_CHARS_SIGNED) :
+                       case (0x10000 + SF_ENDIAN_LITTLE + SF_CHARS_SIGNED) :
+                                       psf->write_short        = pcm_write_s2sc ;
+                                       psf->write_int          = pcm_write_i2sc ;
+                                       psf->write_float        = pcm_write_f2sc ;
+                                       psf->write_double       = pcm_write_d2sc ;
+                                       break ;
+                       case (0x10000 + SF_ENDIAN_BIG + SF_CHARS_UNSIGNED) :
+                       case (0x10000 + SF_ENDIAN_LITTLE + SF_CHARS_UNSIGNED) :
+                                       psf->write_short        = pcm_write_s2uc ;
+                                       psf->write_int          = pcm_write_i2uc ;
+                                       psf->write_float        = pcm_write_f2uc ;
+                                       psf->write_double       = pcm_write_d2uc ;
+                                       break ;
+
+                       case (2 * 0x10000 + SF_ENDIAN_BIG) :
+                                       psf->write_short        = pcm_write_s2bes ;
+                                       psf->write_int          = pcm_write_i2bes ;
+                                       psf->write_float        = pcm_write_f2bes ;
+                                       psf->write_double       = pcm_write_d2bes ;
+                                       break ;
+
+                       case (3 * 0x10000 + SF_ENDIAN_BIG) :
+                                       psf->write_short        = pcm_write_s2bet ;
+                                       psf->write_int          = pcm_write_i2bet ;
+                                       psf->write_float        = pcm_write_f2bet ;
+                                       psf->write_double       = pcm_write_d2bet ;
+                                       break ;
+
+                       case (4 * 0x10000 + SF_ENDIAN_BIG) :
+                                       psf->write_short        = pcm_write_s2bei ;
+                                       psf->write_int          = pcm_write_i2bei ;
+                                       psf->write_float        = pcm_write_f2bei ;
+                                       psf->write_double       = pcm_write_d2bei ;
+                                       break ;
+
+                       case (2 * 0x10000 + SF_ENDIAN_LITTLE) :
+                                       psf->write_short        = pcm_write_s2les ;
+                                       psf->write_int          = pcm_write_i2les ;
+                                       psf->write_float        = pcm_write_f2les ;
+                                       psf->write_double       = pcm_write_d2les ;
+                                       break ;
+
+                       case (3 * 0x10000 + SF_ENDIAN_LITTLE) :
+                                       psf->write_short        = pcm_write_s2let ;
+                                       psf->write_int          = pcm_write_i2let ;
+                                       psf->write_float        = pcm_write_f2let ;
+                                       psf->write_double       = pcm_write_d2let ;
+                                       break ;
+
+                       case (4 * 0x10000 + SF_ENDIAN_LITTLE) :
+                                       psf->write_short        = pcm_write_s2lei ;
+                                       psf->write_int          = pcm_write_i2lei ;
+                                       psf->write_float        = pcm_write_f2lei ;
+                                       psf->write_double       = pcm_write_d2lei ;
+                                       break ;
+
+                       default :
+                               psf_log_printf (psf, "pcm.c returning SFE_UNIMPLEMENTED\n") ;
+                               return SFE_UNIMPLEMENTED ;
+                       } ;
+
+               } ;
+
+       if (psf->filelength > psf->dataoffset)
+       {       psf->datalength = (psf->dataend > 0) ? psf->dataend - psf->dataoffset :
+                                                       psf->filelength - psf->dataoffset ;
+               }
+       else
+               psf->datalength = 0 ;
+
+       psf->sf.frames = psf->datalength / psf->blockwidth ;
+
+       return 0 ;
+} /* pcm_init */
+
+/*==============================================================================
+*/
+
+static inline void
+sc2s_array     (signed char *src, int count, short *dest)
+{      while (--count >= 0)
+       {       dest [count] = src [count] << 8 ;
+               } ;
+} /* sc2s_array */
+
+static inline void
+uc2s_array     (unsigned char *src, int count, short *dest)
+{      while (--count >= 0)
+       {       dest [count] = (((short) src [count]) - 0x80) << 8 ;
+               } ;
+} /* uc2s_array */
+
+static inline void
+let2s_array (tribyte *src, int count, short *dest)
+{      unsigned char   *ucptr ;
+
+       ucptr = ((unsigned char*) src) + 3 * count ;
+       while (--count >= 0)
+       {       ucptr -= 3 ;
+               dest [count] = LET2H_SHORT_PTR (ucptr) ;
+               } ;
+} /* let2s_array */
+
+static inline void
+bet2s_array (tribyte *src, int count, short *dest)
+{      unsigned char   *ucptr ;
+
+       ucptr = ((unsigned char*) src) + 3 * count ;
+       while (--count >= 0)
+       {       ucptr -= 3 ;
+               dest [count] = BET2H_SHORT_PTR (ucptr) ;
+                       } ;
+} /* bet2s_array */
+
+static inline void
+lei2s_array (int *src, int count, short *dest)
+{      int value ;
+
+       while (--count >= 0)
+       {       value = LEI2H_INT (src [count]) ;
+               dest [count] = value >> 16 ;
+               } ;
+} /* lei2s_array */
+
+static inline void
+bei2s_array (int *src, int count, short *dest)
+{      int value ;
+
+       while (--count >= 0)
+       {       value = BEI2H_INT (src [count]) ;
+               dest [count] = value >> 16 ;
+               } ;
+} /* bei2s_array */
+
+/*--------------------------------------------------------------------------
+*/
+
+static inline void
+sc2i_array     (signed char *src, int count, int *dest)
+{      while (--count >= 0)
+       {       dest [count] = ((int) src [count]) << 24 ;
+               } ;
+} /* sc2i_array */
+
+static inline void
+uc2i_array     (unsigned char *src, int count, int *dest)
+{      while (--count >= 0)
+       {       dest [count] = (((int) src [count]) - 128) << 24 ;
+               } ;
+} /* uc2i_array */
+
+static inline void
+bes2i_array (short *src, int count, int *dest)
+{      short value ;
+
+       while (--count >= 0)
+       {       value = BES2H_SHORT (src [count]) ;
+               dest [count] = value << 16 ;
+               } ;
+} /* bes2i_array */
+
+static inline void
+les2i_array (short *src, int count, int *dest)
+{      short value ;
+
+       while (--count >= 0)
+       {       value = LES2H_SHORT (src [count]) ;
+               dest [count] = value << 16 ;
+               } ;
+} /* les2i_array */
+
+static inline void
+bet2i_array (tribyte *src, int count, int *dest)
+{      unsigned char   *ucptr ;
+
+       ucptr = ((unsigned char*) src) + 3 * count ;
+       while (--count >= 0)
+       {       ucptr -= 3 ;
+               dest [count] = BET2H_INT_PTR (ucptr) ;
+                       } ;
+} /* bet2i_array */
+
+static inline void
+let2i_array (tribyte *src, int count, int *dest)
+{      unsigned char   *ucptr ;
+
+       ucptr = ((unsigned char*) src) + 3 * count ;
+       while (--count >= 0)
+       {       ucptr -= 3 ;
+               dest [count] = LET2H_INT_PTR (ucptr) ;
+               } ;
+} /* let2i_array */
+
+/*--------------------------------------------------------------------------
+*/
+
+static inline void
+sc2f_array     (signed char *src, int count, float *dest, float normfact)
+{      while (--count >= 0)
+               dest [count] = ((float) src [count]) * normfact ;
+} /* sc2f_array */
+
+static inline void
+uc2f_array     (unsigned char *src, int count, float *dest, float normfact)
+{      while (--count >= 0)
+               dest [count] = (((int) src [count]) - 128) * normfact ;
+} /* uc2f_array */
+
+static inline void
+les2f_array (short *src, int count, float *dest, float normfact)
+{      short   value ;
+
+       while (--count >= 0)
+       {       value = src [count] ;
+               value = LES2H_SHORT (value) ;
+               dest [count] = ((float) value) * normfact ;
+               } ;
+} /* les2f_array */
+
+static inline void
+bes2f_array (short *src, int count, float *dest, float normfact)
+{      short                   value ;
+
+       while (--count >= 0)
+       {       value = src [count] ;
+               value = BES2H_SHORT (value) ;
+               dest [count] = ((float) value) * normfact ;
+               } ;
+} /* bes2f_array */
+
+static inline void
+let2f_array (tribyte *src, int count, float *dest, float normfact)
+{      unsigned char   *ucptr ;
+       int                     value ;
+
+       ucptr = ((unsigned char*) src) + 3 * count ;
+       while (--count >= 0)
+       {       ucptr -= 3 ;
+               value = LET2H_INT_PTR (ucptr) ;
+               dest [count] = ((float) value) * normfact ;
+               } ;
+} /* let2f_array */
+
+static inline void
+bet2f_array (tribyte *src, int count, float *dest, float normfact)
+{      unsigned char   *ucptr ;
+       int                             value ;
+
+       ucptr = ((unsigned char*) src) + 3 * count ;
+       while (--count >= 0)
+       {       ucptr -= 3 ;
+               value = BET2H_INT_PTR (ucptr) ;
+               dest [count] = ((float) value) * normfact ;
+                       } ;
+} /* bet2f_array */
+
+static inline void
+lei2f_array (int *src, int count, float *dest, float normfact)
+{      int                     value ;
+
+       while (--count >= 0)
+       {       value = src [count] ;
+               value = LEI2H_INT (value) ;
+               dest [count] = ((float) value) * normfact ;
+               } ;
+} /* lei2f_array */
+
+static inline void
+bei2f_array (int *src, int count, float *dest, float normfact)
+{      int                     value ;
+
+       while (--count >= 0)
+       {       value = src [count] ;
+               value = BEI2H_INT (value) ;
+               dest [count] = ((float) value) * normfact ;
+               } ;
+} /* bei2f_array */
+
+/*--------------------------------------------------------------------------
+*/
+
+static inline void
+sc2d_array     (signed char *src, int count, double *dest, double normfact)
+{      while (--count >= 0)
+               dest [count] = ((double) src [count]) * normfact ;
+} /* sc2d_array */
+
+static inline void
+uc2d_array     (unsigned char *src, int count, double *dest, double normfact)
+{      while (--count >= 0)
+               dest [count] = (((int) src [count]) - 128) * normfact ;
+} /* uc2d_array */
+
+static inline void
+les2d_array (short *src, int count, double *dest, double normfact)
+{      short   value ;
+
+       while (--count >= 0)
+       {       value = src [count] ;
+               value = LES2H_SHORT (value) ;
+               dest [count] = ((double) value) * normfact ;
+               } ;
+} /* les2d_array */
+
+static inline void
+bes2d_array (short *src, int count, double *dest, double normfact)
+{      short   value ;
+
+       while (--count >= 0)
+       {       value = src [count] ;
+               value = BES2H_SHORT (value) ;
+               dest [count] = ((double) value) * normfact ;
+               } ;
+} /* bes2d_array */
+
+static inline void
+let2d_array (tribyte *src, int count, double *dest, double normfact)
+{      unsigned char   *ucptr ;
+       int                             value ;
+
+       ucptr = ((unsigned char*) src) + 3 * count ;
+       while (--count >= 0)
+       {       ucptr -= 3 ;
+               value = LET2H_INT_PTR (ucptr) ;
+               dest [count] = ((double) value) * normfact ;
+               } ;
+} /* let2d_array */
+
+static inline void
+bet2d_array (tribyte *src, int count, double *dest, double normfact)
+{      unsigned char   *ucptr ;
+       int                             value ;
+
+       ucptr = ((unsigned char*) src) + 3 * count ;
+       while (--count >= 0)
+       {       ucptr -= 3 ;
+               value = (ucptr [0] << 24) | (ucptr [1] << 16) | (ucptr [2] << 8) ;
+               dest [count] = ((double) value) * normfact ;
+               } ;
+} /* bet2d_array */
+
+static inline void
+lei2d_array (int *src, int count, double *dest, double normfact)
+{      int     value ;
+
+       while (--count >= 0)
+       {       value = src [count] ;
+               value = LEI2H_INT (value) ;
+               dest [count] = ((double) value) * normfact ;
+               } ;
+} /* lei2d_array */
+
+static inline void
+bei2d_array (int *src, int count, double *dest, double normfact)
+{      int     value ;
+
+       while (--count >= 0)
+       {       value = src [count] ;
+               value = BEI2H_INT (value) ;
+               dest [count] = ((double) value) * normfact ;
+               } ;
+} /* bei2d_array */
+
+/*--------------------------------------------------------------------------
+*/
+
+static inline void
+s2sc_array     (const short *src, signed char *dest, int count)
+{      while (--count >= 0)
+               dest [count] = src [count] >> 8 ;
+} /* s2sc_array */
+
+static inline void
+s2uc_array     (const short *src, unsigned char *dest, int count)
+{      while (--count >= 0)
+               dest [count] = (src [count] >> 8) + 0x80 ;
+} /* s2uc_array */
+
+static inline void
+s2let_array (const short *src, tribyte *dest, int count)
+{      unsigned char   *ucptr ;
+
+       ucptr = ((unsigned char*) dest) + 3 * count ;
+       while (--count >= 0)
+       {       ucptr -= 3 ;
+               ucptr [0] = 0 ;
+               ucptr [1] = src [count] ;
+               ucptr [2] = src [count] >> 8 ;
+               } ;
+} /* s2let_array */
+
+static inline void
+s2bet_array (const short *src, tribyte *dest, int count)
+{      unsigned char   *ucptr ;
+
+       ucptr = ((unsigned char*) dest) + 3 * count ;
+       while (--count >= 0)
+       {       ucptr -= 3 ;
+               ucptr [2] = 0 ;
+               ucptr [1] = src [count] ;
+               ucptr [0] = src [count] >> 8 ;
+               } ;
+} /* s2bet_array */
+
+static inline void
+s2lei_array (const short *src, int *dest, int count)
+{      unsigned char   *ucptr ;
+
+       ucptr = ((unsigned char*) dest) + 4 * count ;
+       while (--count >= 0)
+       {       ucptr -= 4 ;
+               ucptr [0] = 0 ;
+               ucptr [1] = 0 ;
+               ucptr [2] = src [count] ;
+               ucptr [3] = src [count] >> 8 ;
+               } ;
+} /* s2lei_array */
+
+static inline void
+s2bei_array (const short *src, int *dest, int count)
+{      unsigned char   *ucptr ;
+
+       ucptr = ((unsigned char*) dest) + 4 * count ;
+       while (--count >= 0)
+       {       ucptr -= 4 ;
+               ucptr [0] = src [count] >> 8 ;
+               ucptr [1] = src [count] ;
+               ucptr [2] = 0 ;
+               ucptr [3] = 0 ;
+               } ;
+} /* s2bei_array */
+
+/*--------------------------------------------------------------------------
+*/
+
+static inline void
+i2sc_array     (const int *src, signed char *dest, int count)
+{      while (--count >= 0)
+               dest [count] = (src [count] >> 24) ;
+} /* i2sc_array */
+
+static inline void
+i2uc_array     (const int *src, unsigned char *dest, int count)
+{      while (--count >= 0)
+               dest [count] = ((src [count] >> 24) + 128) ;
+} /* i2uc_array */
+
+static inline void
+i2bes_array (const int *src, short *dest, int count)
+{      unsigned char   *ucptr ;
+
+       ucptr = ((unsigned char*) dest) + 2 * count ;
+       while (--count >= 0)
+       {       ucptr -= 2 ;
+               ucptr [0] = src [count] >> 24 ;
+               ucptr [1] = src [count] >> 16 ;
+               } ;
+} /* i2bes_array */
+
+static inline void
+i2les_array (const int *src, short *dest, int count)
+{      unsigned char   *ucptr ;
+
+       ucptr = ((unsigned char*) dest) + 2 * count ;
+       while (--count >= 0)
+       {       ucptr -= 2 ;
+               ucptr [0] = src [count] >> 16 ;
+               ucptr [1] = src [count] >> 24 ;
+               } ;
+} /* i2les_array */
+
+static inline void
+i2let_array (const int *src, tribyte *dest, int count)
+{      unsigned char   *ucptr ;
+       int                             value ;
+
+       ucptr = ((unsigned char*) dest) + 3 * count ;
+       while (--count >= 0)
+       {       ucptr -= 3 ;
+               value = src [count] >> 8 ;
+               ucptr [0] = value ;
+               ucptr [1] = value >> 8 ;
+               ucptr [2] = value >> 16 ;
+               } ;
+} /* i2let_array */
+
+static inline void
+i2bet_array (const int *src, tribyte *dest, int count)
+{      unsigned char   *ucptr ;
+       int                             value ;
+
+       ucptr = ((unsigned char*) dest) + 3 * count ;
+       while (--count >= 0)
+       {       ucptr -= 3 ;
+               value = src [count] >> 8 ;
+               ucptr [2] = value ;
+               ucptr [1] = value >> 8 ;
+               ucptr [0] = value >> 16 ;
+               } ;
+} /* i2bet_array */
+
+/*===============================================================================================
+*/
+
+static sf_count_t
+pcm_read_sc2s (SF_PRIVATE *psf, short *ptr, sf_count_t len)
+{      int                     bufferlen, readcount ;
+       sf_count_t      total = 0 ;
+
+       bufferlen = ARRAY_LEN (psf->u.scbuf) ;
+
+       while (len > 0)
+       {       if (len < bufferlen)
+                       bufferlen = (int) len ;
+               readcount = psf_fread (psf->u.scbuf, sizeof (signed char), bufferlen, psf) ;
+               sc2s_array (psf->u.scbuf, readcount, ptr + total) ;
+               total += readcount ;
+               if (readcount < bufferlen)
+                       break ;
+               len -= readcount ;
+               } ;
+
+       return total ;
+} /* pcm_read_sc2s */
+
+static sf_count_t
+pcm_read_uc2s (SF_PRIVATE *psf, short *ptr, sf_count_t len)
+{      int                     bufferlen, readcount ;
+       sf_count_t      total = 0 ;
+
+       bufferlen = ARRAY_LEN (psf->u.ucbuf) ;
+
+       while (len > 0)
+       {       if (len < bufferlen)
+                       bufferlen = (int) len ;
+               readcount = psf_fread (psf->u.ucbuf, sizeof (unsigned char), bufferlen, psf) ;
+               uc2s_array (psf->u.ucbuf, readcount, ptr + total) ;
+               total += readcount ;
+               if (readcount < bufferlen)
+                       break ;
+               len -= readcount ;
+               } ;
+
+       return total ;
+} /* pcm_read_uc2s */
+
+static sf_count_t
+pcm_read_bes2s (SF_PRIVATE *psf, short *ptr, sf_count_t len)
+{      int             total ;
+
+       total = psf_fread (ptr, sizeof (short), len, psf) ;
+       if (CPU_IS_LITTLE_ENDIAN)
+               endswap_short_array (ptr, len) ;
+
+       return total ;
+} /* pcm_read_bes2s */
+
+static sf_count_t
+pcm_read_les2s (SF_PRIVATE *psf, short *ptr, sf_count_t len)
+{      int             total ;
+
+       total = psf_fread (ptr, sizeof (short), len, psf) ;
+       if (CPU_IS_BIG_ENDIAN)
+               endswap_short_array (ptr, len) ;
+
+       return total ;
+} /* pcm_read_les2s */
+
+static sf_count_t
+pcm_read_bet2s (SF_PRIVATE *psf, short *ptr, sf_count_t len)
+{      int                     bufferlen, readcount ;
+       sf_count_t      total = 0 ;
+
+       bufferlen = sizeof (psf->u.ucbuf) / SIZEOF_TRIBYTE ;
+
+       while (len > 0)
+       {       if (len < bufferlen)
+                       bufferlen = (int) len ;
+               readcount = psf_fread (psf->u.ucbuf, SIZEOF_TRIBYTE, bufferlen, psf) ;
+               bet2s_array ((tribyte*) (psf->u.ucbuf), readcount, ptr + total) ;
+               total += readcount ;
+               if (readcount < bufferlen)
+                       break ;
+               len -= readcount ;
+               } ;
+
+       return total ;
+} /* pcm_read_bet2s */
+
+static sf_count_t
+pcm_read_let2s (SF_PRIVATE *psf, short *ptr, sf_count_t len)
+{      int                     bufferlen, readcount ;
+       sf_count_t      total = 0 ;
+
+       bufferlen = sizeof (psf->u.ucbuf) / SIZEOF_TRIBYTE ;
+
+       while (len > 0)
+       {       if (len < bufferlen)
+                       bufferlen = (int) len ;
+               readcount = psf_fread (psf->u.ucbuf, SIZEOF_TRIBYTE, bufferlen, psf) ;
+               let2s_array ((tribyte*) (psf->u.ucbuf), readcount, ptr + total) ;
+               total += readcount ;
+               if (readcount < bufferlen)
+                       break ;
+               len -= readcount ;
+               } ;
+
+       return total ;
+} /* pcm_read_let2s */
+
+static sf_count_t
+pcm_read_bei2s (SF_PRIVATE *psf, short *ptr, sf_count_t len)
+{      int                     bufferlen, readcount ;
+       sf_count_t      total = 0 ;
+
+       bufferlen = ARRAY_LEN (psf->u.ibuf) ;
+
+       while (len > 0)
+       {       if (len < bufferlen)
+                       bufferlen = (int) len ;
+               readcount = psf_fread (psf->u.ibuf, sizeof (int), bufferlen, psf) ;
+               bei2s_array (psf->u.ibuf, readcount, ptr + total) ;
+               total += readcount ;
+               if (readcount < bufferlen)
+                       break ;
+               len -= readcount ;
+               } ;
+
+       return total ;
+} /* pcm_read_bei2s */
+
+static sf_count_t
+pcm_read_lei2s (SF_PRIVATE *psf, short *ptr, sf_count_t len)
+{      int                     bufferlen, readcount ;
+       sf_count_t      total = 0 ;
+
+       bufferlen = ARRAY_LEN (psf->u.ibuf) ;
+
+       while (len > 0)
+       {       if (len < bufferlen)
+                       bufferlen = (int) len ;
+               readcount = psf_fread (psf->u.ibuf, sizeof (int), bufferlen, psf) ;
+               lei2s_array (psf->u.ibuf, readcount, ptr + total) ;
+               total += readcount ;
+               if (readcount < bufferlen)
+                       break ;
+               len -= readcount ;
+               } ;
+
+       return total ;
+} /* pcm_read_lei2s */
+
+/*-----------------------------------------------------------------------------------------------
+*/
+
+static sf_count_t
+pcm_read_sc2i (SF_PRIVATE *psf, int *ptr, sf_count_t len)
+{      int                     bufferlen, readcount ;
+       sf_count_t      total = 0 ;
+
+       bufferlen = ARRAY_LEN (psf->u.scbuf) ;
+
+       while (len > 0)
+       {       if (len < bufferlen)
+                       bufferlen = (int) len ;
+               readcount = psf_fread (psf->u.scbuf, sizeof (signed char), bufferlen, psf) ;
+               sc2i_array (psf->u.scbuf, readcount, ptr + total) ;
+               total += readcount ;
+               if (readcount < bufferlen)
+                       break ;
+               len -= readcount ;
+               } ;
+
+       return total ;
+} /* pcm_read_sc2i */
+
+static sf_count_t
+pcm_read_uc2i (SF_PRIVATE *psf, int *ptr, sf_count_t len)
+{      int                     bufferlen, readcount ;
+       sf_count_t      total = 0 ;
+
+       bufferlen = ARRAY_LEN (psf->u.ucbuf) ;
+
+       while (len > 0)
+       {       if (len < bufferlen)
+                       bufferlen = (int) len ;
+               readcount = psf_fread (psf->u.ucbuf, sizeof (unsigned char), bufferlen, psf) ;
+               uc2i_array (psf->u.ucbuf, readcount, ptr + total) ;
+               total += readcount ;
+               if (readcount < bufferlen)
+                       break ;
+               len -= readcount ;
+               } ;
+
+       return total ;
+} /* pcm_read_uc2i */
+
+static sf_count_t
+pcm_read_bes2i (SF_PRIVATE *psf, int *ptr, sf_count_t len)
+{      int                     bufferlen, readcount ;
+       sf_count_t      total = 0 ;
+
+       bufferlen = ARRAY_LEN (psf->u.sbuf) ;
+
+       while (len > 0)
+       {       if (len < bufferlen)
+                       bufferlen = (int) len ;
+               readcount = psf_fread (psf->u.sbuf, sizeof (short), bufferlen, psf) ;
+               bes2i_array (psf->u.sbuf, readcount, ptr + total) ;
+               total += readcount ;
+               if (readcount < bufferlen)
+                       break ;
+               len -= readcount ;
+               } ;
+
+       return total ;
+} /* pcm_read_bes2i */
+
+static sf_count_t
+pcm_read_les2i (SF_PRIVATE *psf, int *ptr, sf_count_t len)
+{      int                     bufferlen, readcount ;
+       sf_count_t      total = 0 ;
+
+       bufferlen = ARRAY_LEN (psf->u.sbuf) ;
+
+       while (len > 0)
+       {       if (len < bufferlen)
+                       bufferlen = (int) len ;
+               readcount = psf_fread (psf->u.sbuf, sizeof (short), bufferlen, psf) ;
+               les2i_array (psf->u.sbuf, readcount, ptr + total) ;
+               total += readcount ;
+               if (readcount < bufferlen)
+                       break ;
+               len -= readcount ;
+               } ;
+
+       return total ;
+} /* pcm_read_les2i */
+
+static sf_count_t
+pcm_read_bet2i (SF_PRIVATE *psf, int *ptr, sf_count_t len)
+{      int                     bufferlen, readcount ;
+       sf_count_t      total = 0 ;
+
+       bufferlen = sizeof (psf->u.ucbuf) / SIZEOF_TRIBYTE ;
+
+       while (len > 0)
+       {       if (len < bufferlen)
+                       bufferlen = (int) len ;
+               readcount = psf_fread (psf->u.ucbuf, SIZEOF_TRIBYTE, bufferlen, psf) ;
+               bet2i_array ((tribyte*) (psf->u.ucbuf), readcount, ptr + total) ;
+               total += readcount ;
+               if (readcount < bufferlen)
+                       break ;
+               len -= readcount ;
+               } ;
+
+       return total ;
+} /* pcm_read_bet2i */
+
+static sf_count_t
+pcm_read_let2i (SF_PRIVATE *psf, int *ptr, sf_count_t len)
+{      int                     bufferlen, readcount ;
+       sf_count_t      total = 0 ;
+
+       bufferlen = sizeof (psf->u.ucbuf) / SIZEOF_TRIBYTE ;
+
+       while (len > 0)
+       {       if (len < bufferlen)
+                       bufferlen = (int) len ;
+               readcount = psf_fread (psf->u.ucbuf, SIZEOF_TRIBYTE, bufferlen, psf) ;
+               let2i_array ((tribyte*) (psf->u.ucbuf), readcount, ptr + total) ;
+               total += readcount ;
+               if (readcount < bufferlen)
+                       break ;
+               len -= readcount ;
+               } ;
+
+       return total ;
+} /* pcm_read_let2i */
+
+static sf_count_t
+pcm_read_bei2i (SF_PRIVATE *psf, int *ptr, sf_count_t len)
+{      int             total ;
+
+       total = psf_fread (ptr, sizeof (int), len, psf) ;
+       if (CPU_IS_LITTLE_ENDIAN)
+               endswap_int_array       (ptr, len) ;
+
+       return total ;
+} /* pcm_read_bei2i */
+
+static sf_count_t
+pcm_read_lei2i (SF_PRIVATE *psf, int *ptr, sf_count_t len)
+{      int             total ;
+
+       total = psf_fread (ptr, sizeof (int), len, psf) ;
+       if (CPU_IS_BIG_ENDIAN)
+               endswap_int_array       (ptr, len) ;
+
+       return total ;
+} /* pcm_read_lei2i */
+
+/*-----------------------------------------------------------------------------------------------
+*/
+
+static sf_count_t
+pcm_read_sc2f (SF_PRIVATE *psf, float *ptr, sf_count_t len)
+{      int                     bufferlen, readcount ;
+       sf_count_t      total = 0 ;
+       float   normfact ;
+
+       normfact = (psf->norm_float == SF_TRUE) ? 1.0 / ((float) 0x80) : 1.0 ;
+
+       bufferlen = ARRAY_LEN (psf->u.scbuf) ;
+
+       while (len > 0)
+       {       if (len < bufferlen)
+                       bufferlen = (int) len ;
+               readcount = psf_fread (psf->u.scbuf, sizeof (signed char), bufferlen, psf) ;
+               sc2f_array (psf->u.scbuf, readcount, ptr + total, normfact) ;
+               total += readcount ;
+               if (readcount < bufferlen)
+                       break ;
+               len -= readcount ;
+               } ;
+
+       return total ;
+} /* pcm_read_sc2f */
+
+static sf_count_t
+pcm_read_uc2f (SF_PRIVATE *psf, float *ptr, sf_count_t len)
+{      int                     bufferlen, readcount ;
+       sf_count_t      total = 0 ;
+       float   normfact ;
+
+       normfact = (psf->norm_float == SF_TRUE) ? 1.0 / ((float) 0x80) : 1.0 ;
+
+       bufferlen = ARRAY_LEN (psf->u.ucbuf) ;
+
+       while (len > 0)
+       {       if (len < bufferlen)
+                       bufferlen = (int) len ;
+               readcount = psf_fread (psf->u.ucbuf, sizeof (unsigned char), bufferlen, psf) ;
+               uc2f_array (psf->u.ucbuf, readcount, ptr + total, normfact) ;
+               total += readcount ;
+               if (readcount < bufferlen)
+                       break ;
+               len -= readcount ;
+               } ;
+
+       return total ;
+} /* pcm_read_uc2f */
+
+static sf_count_t
+pcm_read_bes2f (SF_PRIVATE *psf, float *ptr, sf_count_t len)
+{      int                     bufferlen, readcount ;
+       sf_count_t      total = 0 ;
+       float   normfact ;
+
+       normfact = (psf->norm_float == SF_TRUE) ? 1.0 / ((float) 0x8000) : 1.0 ;
+
+       bufferlen = ARRAY_LEN (psf->u.sbuf) ;
+
+       while (len > 0)
+       {       if (len < bufferlen)
+                       bufferlen = (int) len ;
+               readcount = psf_fread (psf->u.sbuf, sizeof (short), bufferlen, psf) ;
+               bes2f_array (psf->u.sbuf, readcount, ptr + total, normfact) ;
+               total += readcount ;
+               if (readcount < bufferlen)
+                       break ;
+               len -= readcount ;
+               } ;
+
+       return total ;
+} /* pcm_read_bes2f */
+
+static sf_count_t
+pcm_read_les2f (SF_PRIVATE *psf, float *ptr, sf_count_t len)
+{      int                     bufferlen, readcount ;
+       sf_count_t      total = 0 ;
+       float   normfact ;
+
+       normfact = (psf->norm_float == SF_TRUE) ? 1.0 / ((float) 0x8000) : 1.0 ;
+
+       bufferlen = ARRAY_LEN (psf->u.sbuf) ;
+
+       while (len > 0)
+       {       if (len < bufferlen)
+                       bufferlen = (int) len ;
+               readcount = psf_fread (psf->u.sbuf, sizeof (short), bufferlen, psf) ;
+               les2f_array (psf->u.sbuf, readcount, ptr + total, normfact) ;
+               total += readcount ;
+               if (readcount < bufferlen)
+                       break ;
+               len -= readcount ;
+               } ;
+
+       return total ;
+} /* pcm_read_les2f */
+
+static sf_count_t
+pcm_read_bet2f (SF_PRIVATE *psf, float *ptr, sf_count_t len)
+{      int                     bufferlen, readcount ;
+       sf_count_t      total = 0 ;
+       float   normfact ;
+
+       /* Special normfactor because tribyte value is read into an int. */
+       normfact = (psf->norm_float == SF_TRUE) ? 1.0 / ((float) 0x80000000) : 1.0 / 256.0 ;
+
+       bufferlen = sizeof (psf->u.ucbuf) / SIZEOF_TRIBYTE ;
+
+       while (len > 0)
+       {       if (len < bufferlen)
+                       bufferlen = (int) len ;
+               readcount = psf_fread (psf->u.ucbuf, SIZEOF_TRIBYTE, bufferlen, psf) ;
+               bet2f_array ((tribyte*) (psf->u.ucbuf), readcount, ptr + total, normfact) ;
+               total += readcount ;
+               if (readcount < bufferlen)
+                       break ;
+               len -= readcount ;
+               } ;
+
+       return total ;
+} /* pcm_read_bet2f */
+
+static sf_count_t
+pcm_read_let2f (SF_PRIVATE *psf, float *ptr, sf_count_t len)
+{      int                     bufferlen, readcount ;
+       sf_count_t      total = 0 ;
+       float   normfact ;
+
+       /* Special normfactor because tribyte value is read into an int. */
+       normfact = (psf->norm_float == SF_TRUE) ? 1.0 / ((float) 0x80000000) : 1.0 / 256.0 ;
+
+       bufferlen = sizeof (psf->u.ucbuf) / SIZEOF_TRIBYTE ;
+
+       while (len > 0)
+       {       if (len < bufferlen)
+                       bufferlen = (int) len ;
+               readcount = psf_fread (psf->u.ucbuf, SIZEOF_TRIBYTE, bufferlen, psf) ;
+               let2f_array ((tribyte*) (psf->u.ucbuf), readcount, ptr + total, normfact) ;
+               total += readcount ;
+               if (readcount < bufferlen)
+                       break ;
+               len -= readcount ;
+               } ;
+
+       return total ;
+} /* pcm_read_let2f */
+
+static sf_count_t
+pcm_read_bei2f (SF_PRIVATE *psf, float *ptr, sf_count_t len)
+{      int                     bufferlen, readcount ;
+       sf_count_t      total = 0 ;
+       float   normfact ;
+
+       normfact = (psf->norm_float == SF_TRUE) ? 1.0 / ((float) 0x80000000) : 1.0 ;
+
+       bufferlen = ARRAY_LEN (psf->u.ibuf) ;
+
+       while (len > 0)
+       {       if (len < bufferlen)
+                       bufferlen = (int) len ;
+               readcount = psf_fread (psf->u.ibuf, sizeof (int), bufferlen, psf) ;
+               bei2f_array (psf->u.ibuf, readcount, ptr + total, normfact) ;
+               total += readcount ;
+               if (readcount < bufferlen)
+                       break ;
+               len -= readcount ;
+               } ;
+
+       return total ;
+} /* pcm_read_bei2f */
+
+static sf_count_t
+pcm_read_lei2f (SF_PRIVATE *psf, float *ptr, sf_count_t len)
+{      int                     bufferlen, readcount ;
+       sf_count_t      total = 0 ;
+       float   normfact ;
+
+       normfact = (psf->norm_float == SF_TRUE) ? 1.0 / ((float) 0x80000000) : 1.0 ;
+
+       bufferlen = ARRAY_LEN (psf->u.ibuf) ;
+
+       while (len > 0)
+       {       if (len < bufferlen)
+                       bufferlen = (int) len ;
+               readcount = psf_fread (psf->u.ibuf, sizeof (int), bufferlen, psf) ;
+               lei2f_array (psf->u.ibuf, readcount, ptr + total, normfact) ;
+               total += readcount ;
+               if (readcount < bufferlen)
+                       break ;
+               len -= readcount ;
+               } ;
+
+       return total ;
+} /* pcm_read_lei2f */
+
+/*-----------------------------------------------------------------------------------------------
+*/
+
+static sf_count_t
+pcm_read_sc2d (SF_PRIVATE *psf, double *ptr, sf_count_t len)
+{      int                     bufferlen, readcount ;
+       sf_count_t      total = 0 ;
+       double          normfact ;
+
+       normfact = (psf->norm_double == SF_TRUE) ? 1.0 / ((double) 0x80) : 1.0 ;
+
+       bufferlen = ARRAY_LEN (psf->u.scbuf) ;
+
+       while (len > 0)
+       {       if (len < bufferlen)
+                       bufferlen = (int) len ;
+               readcount = psf_fread (psf->u.scbuf, sizeof (signed char), bufferlen, psf) ;
+               sc2d_array (psf->u.scbuf, readcount, ptr + total, normfact) ;
+               total += readcount ;
+               if (readcount < bufferlen)
+                       break ;
+               len -= readcount ;
+               } ;
+
+       return total ;
+} /* pcm_read_sc2d */
+
+static sf_count_t
+pcm_read_uc2d (SF_PRIVATE *psf, double *ptr, sf_count_t len)
+{      int                     bufferlen, readcount ;
+       sf_count_t      total = 0 ;
+       double          normfact ;
+
+       normfact = (psf->norm_double == SF_TRUE) ? 1.0 / ((double) 0x80) : 1.0 ;
+
+       bufferlen = ARRAY_LEN (psf->u.ucbuf) ;
+
+       while (len > 0)
+       {       if (len < bufferlen)
+                       bufferlen = (int) len ;
+               readcount = psf_fread (psf->u.ucbuf, sizeof (unsigned char), bufferlen, psf) ;
+               uc2d_array (psf->u.ucbuf, readcount, ptr + total, normfact) ;
+               total += readcount ;
+               if (readcount < bufferlen)
+                       break ;
+               len -= readcount ;
+               } ;
+
+       return total ;
+} /* pcm_read_uc2d */
+
+static sf_count_t
+pcm_read_bes2d (SF_PRIVATE *psf, double *ptr, sf_count_t len)
+{      int                     bufferlen, readcount ;
+       sf_count_t      total = 0 ;
+       double          normfact ;
+
+       normfact = (psf->norm_double == SF_TRUE) ? 1.0 / ((double) 0x8000) : 1.0 ;
+
+       bufferlen = ARRAY_LEN (psf->u.sbuf) ;
+
+       while (len > 0)
+       {       if (len < bufferlen)
+                       bufferlen = (int) len ;
+               readcount = psf_fread (psf->u.sbuf, sizeof (short), bufferlen, psf) ;
+               bes2d_array (psf->u.sbuf, readcount, ptr + total, normfact) ;
+               total += readcount ;
+               if (readcount < bufferlen)
+                       break ;
+               len -= readcount ;
+               } ;
+
+       return total ;
+} /* pcm_read_bes2d */
+
+static sf_count_t
+pcm_read_les2d (SF_PRIVATE *psf, double *ptr, sf_count_t len)
+{      int                     bufferlen, readcount ;
+       sf_count_t      total = 0 ;
+       double          normfact ;
+
+       normfact = (psf->norm_double == SF_TRUE) ? 1.0 / ((double) 0x8000) : 1.0 ;
+
+       bufferlen = ARRAY_LEN (psf->u.sbuf) ;
+
+       while (len > 0)
+       {       if (len < bufferlen)
+                       bufferlen = (int) len ;
+               readcount = psf_fread (psf->u.sbuf, sizeof (short), bufferlen, psf) ;
+               les2d_array (psf->u.sbuf, readcount, ptr + total, normfact) ;
+               total += readcount ;
+               if (readcount < bufferlen)
+                       break ;
+               len -= readcount ;
+               } ;
+
+       return total ;
+} /* pcm_read_les2d */
+
+static sf_count_t
+pcm_read_bet2d (SF_PRIVATE *psf, double *ptr, sf_count_t len)
+{      int                     bufferlen, readcount ;
+       sf_count_t      total = 0 ;
+       double          normfact ;
+
+       normfact = (psf->norm_double == SF_TRUE) ? 1.0 / ((double) 0x80000000) : 1.0 / 256.0 ;
+
+       bufferlen = sizeof (psf->u.ucbuf) / SIZEOF_TRIBYTE ;
+
+       while (len > 0)
+       {       if (len < bufferlen)
+                       bufferlen = (int) len ;
+               readcount = psf_fread (psf->u.ucbuf, SIZEOF_TRIBYTE, bufferlen, psf) ;
+               bet2d_array ((tribyte*) (psf->u.ucbuf), readcount, ptr + total, normfact) ;
+               total += readcount ;
+               if (readcount < bufferlen)
+                       break ;
+               len -= readcount ;
+               } ;
+
+       return total ;
+} /* pcm_read_bet2d */
+
+static sf_count_t
+pcm_read_let2d (SF_PRIVATE *psf, double *ptr, sf_count_t len)
+{      int                     bufferlen, readcount ;
+       sf_count_t      total = 0 ;
+       double          normfact ;
+
+       /* Special normfactor because tribyte value is read into an int. */
+       normfact = (psf->norm_double == SF_TRUE) ? 1.0 / ((double) 0x80000000) : 1.0 / 256.0 ;
+
+       bufferlen = sizeof (psf->u.ucbuf) / SIZEOF_TRIBYTE ;
+
+       while (len > 0)
+       {       if (len < bufferlen)
+                       bufferlen = (int) len ;
+               readcount = psf_fread (psf->u.ucbuf, SIZEOF_TRIBYTE, bufferlen, psf) ;
+               let2d_array ((tribyte*) (psf->u.ucbuf), readcount, ptr + total, normfact) ;
+               total += readcount ;
+               if (readcount < bufferlen)
+                       break ;
+               len -= readcount ;
+               } ;
+
+       return total ;
+} /* pcm_read_let2d */
+
+static sf_count_t
+pcm_read_bei2d (SF_PRIVATE *psf, double *ptr, sf_count_t len)
+{      int                     bufferlen, readcount ;
+       sf_count_t      total = 0 ;
+       double          normfact ;
+
+       normfact = (psf->norm_double == SF_TRUE) ? 1.0 / ((double) 0x80000000) : 1.0 ;
+
+       bufferlen = ARRAY_LEN (psf->u.ibuf) ;
+
+       while (len > 0)
+       {       if (len < bufferlen)
+                       bufferlen = (int) len ;
+               readcount = psf_fread (psf->u.ibuf, sizeof (int), bufferlen, psf) ;
+               bei2d_array (psf->u.ibuf, readcount, ptr + total, normfact) ;
+               total += readcount ;
+               if (readcount < bufferlen)
+                       break ;
+               len -= readcount ;
+               } ;
+
+       return total ;
+} /* pcm_read_bei2d */
+
+static sf_count_t
+pcm_read_lei2d (SF_PRIVATE *psf, double *ptr, sf_count_t len)
+{      int                     bufferlen, readcount ;
+       sf_count_t      total = 0 ;
+       double          normfact ;
+
+       normfact = (psf->norm_double == SF_TRUE) ? 1.0 / ((double) 0x80000000) : 1.0 ;
+
+       bufferlen = ARRAY_LEN (psf->u.ibuf) ;
+
+       while (len > 0)
+       {       if (len < bufferlen)
+                       bufferlen = (int) len ;
+               readcount = psf_fread (psf->u.ibuf, sizeof (int), bufferlen, psf) ;
+               lei2d_array (psf->u.ibuf, readcount, ptr + total, normfact) ;
+               total += readcount ;
+               if (readcount < bufferlen)
+                       break ;
+               len -= readcount ;
+               } ;
+
+       return total ;
+} /* pcm_read_lei2d */
+
+/*===============================================================================================
+**-----------------------------------------------------------------------------------------------
+**===============================================================================================
+*/
+
+static sf_count_t
+pcm_write_s2sc (SF_PRIVATE *psf, const short *ptr, sf_count_t len)
+{      int                     bufferlen, writecount ;
+       sf_count_t      total = 0 ;
+
+       bufferlen = ARRAY_LEN (psf->u.scbuf) ;
+
+       while (len > 0)
+       {       if (len < bufferlen)
+                       bufferlen = (int) len ;
+               s2sc_array (ptr + total, psf->u.scbuf, bufferlen) ;
+               writecount = psf_fwrite (psf->u.scbuf, sizeof (signed char), bufferlen, psf) ;
+               total += writecount ;
+               if (writecount < bufferlen)
+                       break ;
+               len -= writecount ;
+               } ;
+
+       return total ;
+} /* pcm_write_s2sc */
+
+static sf_count_t
+pcm_write_s2uc (SF_PRIVATE *psf, const short *ptr, sf_count_t len)
+{      int                     bufferlen, writecount ;
+       sf_count_t      total = 0 ;
+
+       bufferlen = ARRAY_LEN (psf->u.ucbuf) ;
+
+       while (len > 0)
+       {       if (len < bufferlen)
+                       bufferlen = (int) len ;
+               s2uc_array (ptr + total, psf->u.ucbuf, bufferlen) ;
+               writecount = psf_fwrite (psf->u.ucbuf, sizeof (unsigned char), bufferlen, psf) ;
+               total += writecount ;
+               if (writecount < bufferlen)
+                       break ;
+               len -= writecount ;
+               } ;
+
+       return total ;
+} /* pcm_write_s2uc */
+
+static sf_count_t
+pcm_write_s2bes        (SF_PRIVATE *psf, const short *ptr, sf_count_t len)
+{      int                     bufferlen, writecount ;
+       sf_count_t      total = 0 ;
+
+       if (CPU_IS_BIG_ENDIAN)
+               return psf_fwrite (ptr, sizeof (short), len, psf) ;
+       else
+
+       bufferlen = ARRAY_LEN (psf->u.sbuf) ;
+
+       while (len > 0)
+       {       if (len < bufferlen)
+                       bufferlen = (int) len ;
+               endswap_short_copy (psf->u.sbuf, ptr + total, bufferlen) ;
+               writecount = psf_fwrite (psf->u.sbuf, sizeof (short), bufferlen, psf) ;
+               total += writecount ;
+               if (writecount < bufferlen)
+                       break ;
+               len -= writecount ;
+               } ;
+
+       return total ;
+} /* pcm_write_s2bes */
+
+static sf_count_t
+pcm_write_s2les        (SF_PRIVATE *psf, const short *ptr, sf_count_t len)
+{      int                     bufferlen, writecount ;
+       sf_count_t      total = 0 ;
+
+       if (CPU_IS_LITTLE_ENDIAN)
+               return psf_fwrite (ptr, sizeof (short), len, psf) ;
+
+       bufferlen = ARRAY_LEN (psf->u.sbuf) ;
+
+       while (len > 0)
+       {       if (len < bufferlen)
+                       bufferlen = (int) len ;
+               endswap_short_copy (psf->u.sbuf, ptr + total, bufferlen) ;
+               writecount = psf_fwrite (psf->u.sbuf, sizeof (short), bufferlen, psf) ;
+               total += writecount ;
+               if (writecount < bufferlen)
+                       break ;
+               len -= writecount ;
+               } ;
+
+       return total ;
+} /* pcm_write_s2les */
+
+static sf_count_t
+pcm_write_s2bet        (SF_PRIVATE *psf, const short *ptr, sf_count_t len)
+{      int                     bufferlen, writecount ;
+       sf_count_t      total = 0 ;
+
+       bufferlen = sizeof (psf->u.ucbuf) / SIZEOF_TRIBYTE ;
+
+       while (len > 0)
+       {       if (len < bufferlen)
+                       bufferlen = (int) len ;
+               s2bet_array (ptr + total, (tribyte*) (psf->u.ucbuf), bufferlen) ;
+               writecount = psf_fwrite (psf->u.ucbuf, SIZEOF_TRIBYTE, bufferlen, psf) ;
+               total += writecount ;
+               if (writecount < bufferlen)
+                       break ;
+               len -= writecount ;
+               } ;
+
+       return total ;
+} /* pcm_write_s2bet */
+
+static sf_count_t
+pcm_write_s2let        (SF_PRIVATE *psf, const short *ptr, sf_count_t len)
+{      int                     bufferlen, writecount ;
+       sf_count_t      total = 0 ;
+
+       bufferlen = sizeof (psf->u.ucbuf) / SIZEOF_TRIBYTE ;
+
+       while (len > 0)
+       {       if (len < bufferlen)
+                       bufferlen = (int) len ;
+               s2let_array (ptr + total, (tribyte*) (psf->u.ucbuf), bufferlen) ;
+               writecount = psf_fwrite (psf->u.ucbuf, SIZEOF_TRIBYTE, bufferlen, psf) ;
+               total += writecount ;
+               if (writecount < bufferlen)
+                       break ;
+               len -= writecount ;
+               } ;
+
+       return total ;
+} /* pcm_write_s2let */
+
+static sf_count_t
+pcm_write_s2bei        (SF_PRIVATE *psf, const short *ptr, sf_count_t len)
+{      int                     bufferlen, writecount ;
+       sf_count_t      total = 0 ;
+
+       bufferlen = ARRAY_LEN (psf->u.ibuf) ;
+
+       while (len > 0)
+       {       if (len < bufferlen)
+                       bufferlen = (int) len ;
+               s2bei_array (ptr + total, psf->u.ibuf, bufferlen) ;
+               writecount = psf_fwrite (psf->u.ibuf, sizeof (int), bufferlen, psf) ;
+               total += writecount ;
+               if (writecount < bufferlen)
+                       break ;
+               len -= writecount ;
+               } ;
+
+       return total ;
+} /* pcm_write_s2bei */
+
+static sf_count_t
+pcm_write_s2lei        (SF_PRIVATE *psf, const short *ptr, sf_count_t len)
+{      int                     bufferlen, writecount ;
+       sf_count_t      total = 0 ;
+
+       bufferlen = ARRAY_LEN (psf->u.ibuf) ;
+
+       while (len > 0)
+       {       if (len < bufferlen)
+                       bufferlen = (int) len ;
+               s2lei_array (ptr + total, psf->u.ibuf, bufferlen) ;
+               writecount = psf_fwrite (psf->u.ibuf, sizeof (int), bufferlen, psf) ;
+               total += writecount ;
+               if (writecount < bufferlen)
+                       break ;
+               len -= writecount ;
+               } ;
+
+       return total ;
+} /* pcm_write_s2lei */
+
+/*-----------------------------------------------------------------------------------------------
+*/
+
+static sf_count_t
+pcm_write_i2sc (SF_PRIVATE *psf, const int *ptr, sf_count_t len)
+{      int                     bufferlen, writecount ;
+       sf_count_t      total = 0 ;
+
+       bufferlen = ARRAY_LEN (psf->u.scbuf) ;
+
+       while (len > 0)
+       {       if (len < bufferlen)
+                       bufferlen = (int) len ;
+               i2sc_array (ptr + total, psf->u.scbuf, bufferlen) ;
+               writecount = psf_fwrite (psf->u.scbuf, sizeof (signed char), bufferlen, psf) ;
+               total += writecount ;
+               if (writecount < bufferlen)
+                       break ;
+               len -= writecount ;
+               } ;
+
+       return total ;
+} /* pcm_write_i2sc */
+
+static sf_count_t
+pcm_write_i2uc (SF_PRIVATE *psf, const int *ptr, sf_count_t len)
+{      int                     bufferlen, writecount ;
+       sf_count_t      total = 0 ;
+
+       bufferlen = ARRAY_LEN (psf->u.ucbuf) ;
+
+       while (len > 0)
+       {       if (len < bufferlen)
+                       bufferlen = (int) len ;
+               i2uc_array (ptr + total, psf->u.ucbuf, bufferlen) ;
+               writecount = psf_fwrite (psf->u.ucbuf, sizeof (signed char), bufferlen, psf) ;
+               total += writecount ;
+               if (writecount < bufferlen)
+                       break ;
+               len -= writecount ;
+               } ;
+
+       return total ;
+} /* pcm_write_i2uc */
+
+static sf_count_t
+pcm_write_i2bes        (SF_PRIVATE *psf, const int *ptr, sf_count_t len)
+{      int                     bufferlen, writecount ;
+       sf_count_t      total = 0 ;
+
+       bufferlen = ARRAY_LEN (psf->u.sbuf) ;
+
+       while (len > 0)
+       {       if (len < bufferlen)
+                       bufferlen = (int) len ;
+               i2bes_array (ptr + total, psf->u.sbuf, bufferlen) ;
+               writecount = psf_fwrite (psf->u.sbuf, sizeof (short), bufferlen, psf) ;
+               total += writecount ;
+               if (writecount < bufferlen)
+                       break ;
+               len -= writecount ;
+               } ;
+
+       return total ;
+} /* pcm_write_i2bes */
+
+static sf_count_t
+pcm_write_i2les        (SF_PRIVATE *psf, const int *ptr, sf_count_t len)
+{      int                     bufferlen, writecount ;
+       sf_count_t      total = 0 ;
+
+       bufferlen = ARRAY_LEN (psf->u.sbuf) ;
+
+       while (len > 0)
+       {       if (len < bufferlen)
+                       bufferlen = (int) len ;
+               i2les_array (ptr + total, psf->u.sbuf, bufferlen) ;
+               writecount = psf_fwrite (psf->u.sbuf, sizeof (short), bufferlen, psf) ;
+               total += writecount ;
+               if (writecount < bufferlen)
+                       break ;
+               len -= writecount ;
+               } ;
+
+       return total ;
+} /* pcm_write_i2les */
+
+static sf_count_t
+pcm_write_i2bet        (SF_PRIVATE *psf, const int *ptr, sf_count_t len)
+{      int                     bufferlen, writecount ;
+       sf_count_t      total = 0 ;
+
+       bufferlen = sizeof (psf->u.ucbuf) / SIZEOF_TRIBYTE ;
+
+       while (len > 0)
+       {       if (len < bufferlen)
+                       bufferlen = (int) len ;
+               i2bet_array (ptr + total, (tribyte*) (psf->u.ucbuf), bufferlen) ;
+               writecount = psf_fwrite (psf->u.ucbuf, SIZEOF_TRIBYTE, bufferlen, psf) ;
+               total += writecount ;
+               if (writecount < bufferlen)
+                       break ;
+               len -= writecount ;
+               } ;
+
+       return total ;
+} /* pcm_write_i2bet */
+
+static sf_count_t
+pcm_write_i2let        (SF_PRIVATE *psf, const int *ptr, sf_count_t len)
+{      int                     bufferlen, writecount ;
+       sf_count_t      total = 0 ;
+
+       bufferlen = sizeof (psf->u.ucbuf) / SIZEOF_TRIBYTE ;
+
+       while (len > 0)
+       {       if (len < bufferlen)
+                       bufferlen = (int) len ;
+               i2let_array (ptr + total, (tribyte*) (psf->u.ucbuf), bufferlen) ;
+               writecount = psf_fwrite (psf->u.ucbuf, SIZEOF_TRIBYTE, bufferlen, psf) ;
+               total += writecount ;
+               if (writecount < bufferlen)
+                       break ;
+               len -= writecount ;
+               } ;
+
+       return total ;
+} /* pcm_write_i2les */
+
+static sf_count_t
+pcm_write_i2bei        (SF_PRIVATE *psf, const int *ptr, sf_count_t len)
+{      int                     bufferlen, writecount ;
+       sf_count_t      total = 0 ;
+
+       if (CPU_IS_BIG_ENDIAN)
+               return psf_fwrite (ptr, sizeof (int), len, psf) ;
+
+       bufferlen = ARRAY_LEN (psf->u.ibuf) ;
+
+       while (len > 0)
+       {       if (len < bufferlen)
+                       bufferlen = (int) len ;
+               endswap_int_copy (psf->u.ibuf, ptr + total, bufferlen) ;
+               writecount = psf_fwrite (psf->u.ibuf, sizeof (int), bufferlen, psf) ;
+               total += writecount ;
+               if (writecount < bufferlen)
+                       break ;
+               len -= writecount ;
+               } ;
+
+       return total ;
+} /* pcm_write_i2bei */
+
+static sf_count_t
+pcm_write_i2lei        (SF_PRIVATE *psf, const int *ptr, sf_count_t len)
+{      int                     bufferlen, writecount ;
+       sf_count_t      total = 0 ;
+
+       if (CPU_IS_LITTLE_ENDIAN)
+               return psf_fwrite (ptr, sizeof (int), len, psf) ;
+
+       bufferlen = ARRAY_LEN (psf->u.ibuf) ;
+
+       while (len > 0)
+       {       if (len < bufferlen)
+                       bufferlen = (int) len ;
+               endswap_int_copy (psf->u.ibuf, ptr + total, bufferlen) ;
+               writecount = psf_fwrite (psf->u.ibuf, sizeof (int), bufferlen, psf) ;
+               total += writecount ;
+               if (writecount < bufferlen)
+                       break ;
+               len -= writecount ;
+               } ;
+
+       return total ;
+} /* pcm_write_i2lei */
+
+/*------------------------------------------------------------------------------
+**==============================================================================
+**------------------------------------------------------------------------------
+*/
+
+static void
+f2sc_array (const float *src, signed char *dest, int count, int normalize)
+{      float normfact ;
+
+       normfact = normalize ? (1.0 * 0x7F) : 1.0 ;
+
+       while (--count >= 0)
+       {       dest [count] = lrintf (src [count] * normfact) ;
+               } ;
+} /* f2sc_array */
+
+static void
+f2sc_clip_array (const float *src, signed char *dest, int count, int normalize)
+{      float   normfact, scaled_value ;
+
+       normfact = normalize ? (8.0 * 0x10000000) : (1.0 * 0x1000000) ;
+
+       while (--count >= 0)
+       {       scaled_value = src [count] * normfact ;
+               if (CPU_CLIPS_POSITIVE == 0 && scaled_value >= (1.0 * 0x7FFFFFFF))
+               {       dest [count] = 127 ;
+                       continue ;
+                       } ;
+               if (CPU_CLIPS_NEGATIVE == 0 && scaled_value <= (-8.0 * 0x10000000))
+               {       dest [count] = -128 ;
+                       continue ;
+                       } ;
+
+               dest [count] = lrintf (scaled_value) >> 24 ;
+               } ;
+} /* f2sc_clip_array */
+
+static sf_count_t
+pcm_write_f2sc (SF_PRIVATE *psf, const float *ptr, sf_count_t len)
+{      void            (*convert) (const float *, signed char *, int, int) ;
+       int                     bufferlen, writecount ;
+       sf_count_t      total = 0 ;
+
+       convert = (psf->add_clipping) ? f2sc_clip_array : f2sc_array ;
+       bufferlen = ARRAY_LEN (psf->u.scbuf) ;
+
+       while (len > 0)
+       {       if (len < bufferlen)
+                       bufferlen = (int) len ;
+               convert (ptr + total, psf->u.scbuf, bufferlen, psf->norm_float) ;
+               writecount = psf_fwrite (psf->u.scbuf, sizeof (signed char), bufferlen, psf) ;
+               total += writecount ;
+               if (writecount < bufferlen)
+                       break ;
+               len -= writecount ;
+               } ;
+
+       return total ;
+} /* pcm_write_f2sc */
+
+/*==============================================================================
+*/
+
+static void
+f2uc_array     (const float *src, unsigned char *dest, int count, int normalize)
+{      float normfact ;
+
+       normfact = normalize ? (1.0 * 0x7F) : 1.0 ;
+
+       while (--count >= 0)
+       {       dest [count] = lrintf (src [count] * normfact) + 128 ;
+               } ;
+} /* f2uc_array */
+
+static void
+f2uc_clip_array        (const float *src, unsigned char *dest, int count, int normalize)
+{      float   normfact, scaled_value ;
+
+       normfact = normalize ? (8.0 * 0x10000000) : (1.0 * 0x1000000) ;
+
+       while (--count >= 0)
+       {       scaled_value = src [count] * normfact ;
+               if (CPU_CLIPS_POSITIVE == 0 && scaled_value >= (1.0 * 0x7FFFFFFF))
+               {       dest [count] = 0xFF ;
+                       continue ;
+                       } ;
+               if (CPU_CLIPS_NEGATIVE == 0 && scaled_value <= (-8.0 * 0x10000000))
+               {       dest [count] = 0 ;
+                       continue ;
+                       } ;
+
+               dest [count] = (lrintf (scaled_value) >> 24) + 128 ;
+               } ;
+} /* f2uc_clip_array */
+
+static sf_count_t
+pcm_write_f2uc (SF_PRIVATE *psf, const float *ptr, sf_count_t len)
+{      void            (*convert) (const float *, unsigned char *, int, int) ;
+       int                     bufferlen, writecount ;
+       sf_count_t      total = 0 ;
+
+       convert = (psf->add_clipping) ? f2uc_clip_array : f2uc_array ;
+       bufferlen = ARRAY_LEN (psf->u.ucbuf) ;
+
+       while (len > 0)
+       {       if (len < bufferlen)
+                       bufferlen = (int) len ;
+               convert (ptr + total, psf->u.ucbuf, bufferlen, psf->norm_float) ;
+               writecount = psf_fwrite (psf->u.ucbuf, sizeof (unsigned char), bufferlen, psf) ;
+               total += writecount ;
+               if (writecount < bufferlen)
+                       break ;
+               len -= writecount ;
+               } ;
+
+       return total ;
+} /* pcm_write_f2uc */
+
+/*==============================================================================
+*/
+
+static void
+f2bes_array (const float *src, short *dest, int count, int normalize)
+{      unsigned char   *ucptr ;
+       float                   normfact ;
+       short                   value ;
+
+       normfact = normalize ? (1.0 * 0x7FFF) : 1.0 ;
+       ucptr = ((unsigned char*) dest) + 2 * count ;
+
+       while (--count >= 0)
+       {       ucptr -= 2 ;
+               value = lrintf (src [count] * normfact) ;
+               ucptr [1] = value ;
+               ucptr [0] = value >> 8 ;
+                       } ;
+} /* f2bes_array */
+
+static void
+f2bes_clip_array (const float *src, short *dest, int count, int normalize)
+{      unsigned char   *ucptr ;
+       float                   normfact, scaled_value ;
+       int                             value ;
+
+       normfact = normalize ? (8.0 * 0x10000000) : (1.0 * 0x10000) ;
+       ucptr = ((unsigned char*) dest) + 2 * count ;
+
+       while (--count >= 0)
+       {       ucptr -= 2 ;
+               scaled_value = src [count] * normfact ;
+               if (CPU_CLIPS_POSITIVE == 0 && scaled_value >= (1.0 * 0x7FFFFFFF))
+               {       ucptr [1] = 0xFF ;
+                       ucptr [0] = 0x7F ;
+                       continue ;
+               } ;
+               if (CPU_CLIPS_NEGATIVE == 0 && scaled_value <= (-8.0 * 0x10000000))
+               {       ucptr [1] = 0x00 ;
+                       ucptr [0] = 0x80 ;
+                       continue ;
+                       } ;
+
+               value = lrintf (scaled_value) ;
+               ucptr [1] = value >> 16 ;
+               ucptr [0] = value >> 24 ;
+               } ;
+} /* f2bes_clip_array */
+
+static sf_count_t
+pcm_write_f2bes        (SF_PRIVATE *psf, const float *ptr, sf_count_t len)
+{      void            (*convert) (const float *, short *t, int, int) ;
+       int                     bufferlen, writecount ;
+       sf_count_t      total = 0 ;
+
+       convert = (psf->add_clipping) ? f2bes_clip_array : f2bes_array ;
+       bufferlen = ARRAY_LEN (psf->u.sbuf) ;
+
+       while (len > 0)
+       {       if (len < bufferlen)
+                       bufferlen = (int) len ;
+               convert (ptr + total, psf->u.sbuf, bufferlen, psf->norm_float) ;
+               writecount = psf_fwrite (psf->u.sbuf, sizeof (short), bufferlen, psf) ;
+               total += writecount ;
+               if (writecount < bufferlen)
+                               break ;
+               len -= writecount ;
+               } ;
+
+       return total ;
+} /* pcm_write_f2bes */
+
+/*==============================================================================
+*/
+
+static void
+f2les_array (const float *src, short *dest, int count, int normalize)
+{      unsigned char   *ucptr ;
+       float                   normfact ;
+       int                             value ;
+
+       normfact = normalize ? (1.0 * 0x7FFF) : 1.0 ;
+       ucptr = ((unsigned char*) dest) + 2 * count ;
+
+       while (--count >= 0)
+       {       ucptr -= 2 ;
+               value = lrintf (src [count] * normfact) ;
+               ucptr [0] = value ;
+               ucptr [1] = value >> 8 ;
+               } ;
+} /* f2les_array */
+
+static void
+f2les_clip_array (const float *src, short *dest, int count, int normalize)
+{      unsigned char   *ucptr ;
+       float                   normfact, scaled_value ;
+       int                             value ;
+
+       normfact = normalize ? (8.0 * 0x10000000) : (1.0 * 0x10000) ;
+       ucptr = ((unsigned char*) dest) + 2 * count ;
+
+       while (--count >= 0)
+       {       ucptr -= 2 ;
+               scaled_value = src [count] * normfact ;
+               if (CPU_CLIPS_POSITIVE == 0 && scaled_value >= (1.0 * 0x7FFFFFFF))
+               {       ucptr [0] = 0xFF ;
+                       ucptr [1] = 0x7F ;
+                       continue ;
+                       } ;
+               if (CPU_CLIPS_NEGATIVE == 0 && scaled_value <= (-8.0 * 0x10000000))
+               {       ucptr [0] = 0x00 ;
+                       ucptr [1] = 0x80 ;
+                       continue ;
+                       } ;
+
+               value = lrintf (scaled_value) ;
+               ucptr [0] = value >> 16 ;
+               ucptr [1] = value >> 24 ;
+               } ;
+} /* f2les_clip_array */
+
+static sf_count_t
+pcm_write_f2les        (SF_PRIVATE *psf, const float *ptr, sf_count_t len)
+{      void            (*convert) (const float *, short *t, int, int) ;
+       int                     bufferlen, writecount ;
+       sf_count_t      total = 0 ;
+
+       convert = (psf->add_clipping) ? f2les_clip_array : f2les_array ;
+       bufferlen = ARRAY_LEN (psf->u.sbuf) ;
+
+       while (len > 0)
+       {       if (len < bufferlen)
+                       bufferlen = (int) len ;
+               convert (ptr + total, psf->u.sbuf, bufferlen, psf->norm_float) ;
+               writecount = psf_fwrite (psf->u.sbuf, sizeof (short), bufferlen, psf) ;
+               total += writecount ;
+               if (writecount < bufferlen)
+                       break ;
+               len -= writecount ;
+               } ;
+
+       return total ;
+} /* pcm_write_f2les */
+
+/*==============================================================================
+*/
+
+static void
+f2let_array (const float *src, tribyte *dest, int count, int normalize)
+{      unsigned char   *ucptr ;
+       float                   normfact ;
+       int                             value ;
+
+       normfact = normalize ? (1.0 * 0x7FFFFF) : 1.0 ;
+       ucptr = ((unsigned char*) dest) + 3 * count ;
+
+       while (--count >= 0)
+       {       ucptr -= 3 ;
+               value = lrintf (src [count] * normfact) ;
+               ucptr [0] = value ;
+               ucptr [1] = value >> 8 ;
+               ucptr [2] = value >> 16 ;
+               } ;
+} /* f2let_array */
+
+static void
+f2let_clip_array (const float *src, tribyte *dest, int count, int normalize)
+{      unsigned char   *ucptr ;
+       float                   normfact, scaled_value ;
+       int                             value ;
+
+       normfact = normalize ? (8.0 * 0x10000000) : (1.0 * 0x100) ;
+       ucptr = ((unsigned char*) dest) + 3 * count ;
+
+       while (--count >= 0)
+       {       ucptr -= 3 ;
+               scaled_value = src [count] * normfact ;
+               if (CPU_CLIPS_POSITIVE == 0 && scaled_value >= (1.0 * 0x7FFFFFFF))
+               {       ucptr [0] = 0xFF ;
+                       ucptr [1] = 0xFF ;
+                       ucptr [2] = 0x7F ;
+                       continue ;
+                       } ;
+               if (CPU_CLIPS_NEGATIVE == 0 && scaled_value <= (-8.0 * 0x10000000))
+               {       ucptr [0] = 0x00 ;
+                       ucptr [1] = 0x00 ;
+                       ucptr [2] = 0x80 ;
+                       continue ;
+               } ;
+
+               value = lrintf (scaled_value) ;
+               ucptr [0] = value >> 8 ;
+               ucptr [1] = value >> 16 ;
+               ucptr [2] = value >> 24 ;
+               } ;
+} /* f2let_clip_array */
+
+static sf_count_t
+pcm_write_f2let        (SF_PRIVATE *psf, const float *ptr, sf_count_t len)
+{      void            (*convert) (const float *, tribyte *, int, int) ;
+       int                     bufferlen, writecount ;
+       sf_count_t      total = 0 ;
+
+       convert = (psf->add_clipping) ? f2let_clip_array : f2let_array ;
+       bufferlen = sizeof (psf->u.ucbuf) / SIZEOF_TRIBYTE ;
+
+       while (len > 0)
+       {       if (len < bufferlen)
+                       bufferlen = (int) len ;
+               convert (ptr + total, (tribyte*) (psf->u.ucbuf), bufferlen, psf->norm_float) ;
+               writecount = psf_fwrite (psf->u.ucbuf, SIZEOF_TRIBYTE, bufferlen, psf) ;
+               total += writecount ;
+               if (writecount < bufferlen)
+                       break ;
+               len -= writecount ;
+               } ;
+
+       return total ;
+} /* pcm_write_f2let */
+
+/*==============================================================================
+*/
+
+static void
+f2bet_array (const float *src, tribyte *dest, int count, int normalize)
+{      unsigned char   *ucptr ;
+       float                   normfact ;
+       int                             value ;
+
+       normfact = normalize ? (1.0 * 0x7FFFFF) : 1.0 ;
+       ucptr = ((unsigned char*) dest) + 3 * count ;
+
+       while (--count >= 0)
+       {       ucptr -= 3 ;
+               value = lrintf (src [count] * normfact) ;
+               ucptr [0] = value >> 16 ;
+               ucptr [1] = value >> 8 ;
+               ucptr [2] = value ;
+               } ;
+} /* f2bet_array */
+
+static void
+f2bet_clip_array (const float *src, tribyte *dest, int count, int normalize)
+{      unsigned char   *ucptr ;
+       float                   normfact, scaled_value ;
+       int                             value ;
+
+       normfact = normalize ? (8.0 * 0x10000000) : (1.0 * 0x100) ;
+       ucptr = ((unsigned char*) dest) + 3 * count ;
+
+       while (--count >= 0)
+       {       ucptr -= 3 ;
+               scaled_value = src [count] * normfact ;
+               if (CPU_CLIPS_POSITIVE == 0 && scaled_value >= (1.0 * 0x7FFFFFFF))
+               {       ucptr [0] = 0x7F ;
+                       ucptr [1] = 0xFF ;
+                       ucptr [2] = 0xFF ;
+                       continue ;
+                       } ;
+               if (CPU_CLIPS_NEGATIVE == 0 && scaled_value <= (-8.0 * 0x10000000))
+               {       ucptr [0] = 0x80 ;
+                       ucptr [1] = 0x00 ;
+                       ucptr [2] = 0x00 ;
+                       continue ;
+               } ;
+
+               value = lrint (scaled_value) ;
+               ucptr [0] = value >> 24 ;
+               ucptr [1] = value >> 16 ;
+               ucptr [2] = value >> 8 ;
+               } ;
+} /* f2bet_clip_array */
+
+static sf_count_t
+pcm_write_f2bet        (SF_PRIVATE *psf, const float *ptr, sf_count_t len)
+{      void            (*convert) (const float *, tribyte *, int, int) ;
+       int                     bufferlen, writecount ;
+       sf_count_t      total = 0 ;
+
+       convert = (psf->add_clipping) ? f2bet_clip_array : f2bet_array ;
+       bufferlen = sizeof (psf->u.ucbuf) / SIZEOF_TRIBYTE ;
+
+       while (len > 0)
+       {       if (len < bufferlen)
+                       bufferlen = (int) len ;
+               convert (ptr + total, (tribyte*) (psf->u.ucbuf), bufferlen, psf->norm_float) ;
+               writecount = psf_fwrite (psf->u.ucbuf, SIZEOF_TRIBYTE, bufferlen, psf) ;
+               total += writecount ;
+               if (writecount < bufferlen)
+                       break ;
+               len -= writecount ;
+               } ;
+
+       return total ;
+} /* pcm_write_f2bet */
+
+/*==============================================================================
+*/
+
+static void
+f2bei_array (const float *src, int *dest, int count, int normalize)
+{      unsigned char   *ucptr ;
+       float                   normfact ;
+       int                             value ;
+
+       normfact = normalize ? (1.0 * 0x7FFFFFFF) : 1.0 ;
+       ucptr = ((unsigned char*) dest) + 4 * count ;
+       while (--count >= 0)
+       {       ucptr -= 4 ;
+               value = lrintf (src [count] * normfact) ;
+               ucptr [0] = value >> 24 ;
+               ucptr [1] = value >> 16 ;
+               ucptr [2] = value >> 8 ;
+               ucptr [3] = value ;
+               } ;
+} /* f2bei_array */
+
+static void
+f2bei_clip_array (const float *src, int *dest, int count, int normalize)
+{      unsigned char   *ucptr ;
+       float                   normfact, scaled_value ;
+       int                             value ;
+
+       normfact = normalize ? (8.0 * 0x10000000) : 1.0 ;
+       ucptr = ((unsigned char*) dest) + 4 * count ;
+
+       while (--count >= 0)
+       {       ucptr -= 4 ;
+               scaled_value = src [count] * normfact ;
+               if (CPU_CLIPS_POSITIVE == 0 && scaled_value >= 1.0 * 0x7FFFFFFF)
+               {       ucptr [0] = 0x7F ;
+                       ucptr [1] = 0xFF ;
+                       ucptr [2] = 0xFF ;
+                       ucptr [3] = 0xFF ;
+                       continue ;
+                       } ;
+               if (CPU_CLIPS_NEGATIVE == 0 && scaled_value <= (-8.0 * 0x10000000))
+               {       ucptr [0] = 0x80 ;
+                       ucptr [1] = 0x00 ;
+                       ucptr [2] = 0x00 ;
+                       ucptr [3] = 0x00 ;
+                       continue ;
+               } ;
+
+               value = lrintf (scaled_value) ;
+               ucptr [0] = value >> 24 ;
+               ucptr [1] = value >> 16 ;
+               ucptr [2] = value >> 8 ;
+               ucptr [3] = value ;
+               } ;
+} /* f2bei_clip_array */
+
+static sf_count_t
+pcm_write_f2bei        (SF_PRIVATE *psf, const float *ptr, sf_count_t len)
+{      void            (*convert) (const float *, int *, int, int) ;
+       int                     bufferlen, writecount ;
+       sf_count_t      total = 0 ;
+
+       convert = (psf->add_clipping) ? f2bei_clip_array : f2bei_array ;
+       bufferlen = ARRAY_LEN (psf->u.ibuf) ;
+
+       while (len > 0)
+       {       if (len < bufferlen)
+                       bufferlen = (int) len ;
+               convert (ptr + total, psf->u.ibuf, bufferlen, psf->norm_float) ;
+               writecount = psf_fwrite (psf->u.ibuf, sizeof (int), bufferlen, psf) ;
+               total += writecount ;
+               if (writecount < bufferlen)
+                       break ;
+               len -= writecount ;
+               } ;
+
+       return total ;
+} /* pcm_write_f2bei */
+
+/*==============================================================================
+*/
+
+static void
+f2lei_array (const float *src, int *dest, int count, int normalize)
+{      unsigned char   *ucptr ;
+       float                   normfact ;
+       int                             value ;
+
+       normfact = normalize ? (1.0 * 0x7FFFFFFF) : 1.0 ;
+       ucptr = ((unsigned char*) dest) + 4 * count ;
+
+       while (--count >= 0)
+       {       ucptr -= 4 ;
+               value = lrintf (src [count] * normfact) ;
+               ucptr [0] = value ;
+               ucptr [1] = value >> 8 ;
+               ucptr [2] = value >> 16 ;
+               ucptr [3] = value >> 24 ;
+               } ;
+} /* f2lei_array */
+
+static void
+f2lei_clip_array (const float *src, int *dest, int count, int normalize)
+{      unsigned char   *ucptr ;
+       float                   normfact, scaled_value ;
+       int                             value ;
+
+       normfact = normalize ? (8.0 * 0x10000000) : 1.0 ;
+       ucptr = ((unsigned char*) dest) + 4 * count ;
+
+       while (--count >= 0)
+       {       ucptr -= 4 ;
+               scaled_value = src [count] * normfact ;
+               if (CPU_CLIPS_POSITIVE == 0 && scaled_value >= (1.0 * 0x7FFFFFFF))
+               {       ucptr [0] = 0xFF ;
+                       ucptr [1] = 0xFF ;
+                       ucptr [2] = 0xFF ;
+                       ucptr [3] = 0x7F ;
+                       continue ;
+                       } ;
+               if (CPU_CLIPS_NEGATIVE == 0 && scaled_value <= (-8.0 * 0x10000000))
+               {       ucptr [0] = 0x00 ;
+                       ucptr [1] = 0x00 ;
+                       ucptr [2] = 0x00 ;
+                       ucptr [3] = 0x80 ;
+                       continue ;
+                       } ;
+
+               value = lrintf (scaled_value) ;
+               ucptr [0] = value ;
+               ucptr [1] = value >> 8 ;
+               ucptr [2] = value >> 16 ;
+               ucptr [3] = value >> 24 ;
+               } ;
+} /* f2lei_clip_array */
+
+static sf_count_t
+pcm_write_f2lei        (SF_PRIVATE *psf, const float *ptr, sf_count_t len)
+{      void            (*convert) (const float *, int *, int, int) ;
+       int                     bufferlen, writecount ;
+       sf_count_t      total = 0 ;
+
+       convert = (psf->add_clipping) ? f2lei_clip_array : f2lei_array ;
+       bufferlen = ARRAY_LEN (psf->u.ibuf) ;
+
+       while (len > 0)
+       {       if (len < bufferlen)
+                       bufferlen = (int) len ;
+               convert (ptr + total, psf->u.ibuf, bufferlen, psf->norm_float) ;
+               writecount = psf_fwrite (psf->u.ibuf, sizeof (int), bufferlen, psf) ;
+               total += writecount ;
+               if (writecount < bufferlen)
+                       break ;
+               len -= writecount ;
+               } ;
+
+       return total ;
+} /* pcm_write_f2lei */
+
+/*==============================================================================
+*/
+
+static void
+d2sc_array     (const double *src, signed char *dest, int count, int normalize)
+{      double  normfact ;
+
+       normfact = normalize ? (1.0 * 0x7F) : 1.0 ;
+
+       while (--count >= 0)
+       {       dest [count] = lrint (src [count] * normfact) ;
+               } ;
+} /* d2sc_array */
+
+static void
+d2sc_clip_array        (const double *src, signed char *dest, int count, int normalize)
+{      double  normfact, scaled_value ;
+
+       normfact = normalize ? (8.0 * 0x10000000) : (1.0 * 0x1000000) ;
+
+       while (--count >= 0)
+       {       scaled_value = src [count] * normfact ;
+               if (CPU_CLIPS_POSITIVE == 0 && scaled_value >= (1.0 * 0x7FFFFFFF))
+               {       dest [count] = 127 ;
+                       continue ;
+                       } ;
+               if (CPU_CLIPS_NEGATIVE == 0 && scaled_value <= (-8.0 * 0x10000000))
+               {       dest [count] = -128 ;
+                       continue ;
+                       } ;
+
+               dest [count] = lrintf (scaled_value) >> 24 ;
+               } ;
+} /* d2sc_clip_array */
+
+static sf_count_t
+pcm_write_d2sc (SF_PRIVATE *psf, const double *ptr, sf_count_t len)
+{      void            (*convert) (const double *, signed char *, int, int) ;
+       int                     bufferlen, writecount ;
+       sf_count_t      total = 0 ;
+
+       convert = (psf->add_clipping) ? d2sc_clip_array : d2sc_array ;
+       bufferlen = ARRAY_LEN (psf->u.scbuf) ;
+
+       while (len > 0)
+       {       if (len < bufferlen)
+                       bufferlen = (int) len ;
+               convert (ptr + total, psf->u.scbuf, bufferlen, psf->norm_double) ;
+               writecount = psf_fwrite (psf->u.scbuf, sizeof (signed char), bufferlen, psf) ;
+               total += writecount ;
+               if (writecount < bufferlen)
+                       break ;
+               len -= writecount ;
+               } ;
+
+       return total ;
+} /* pcm_write_d2sc */
+
+/*==============================================================================
+*/
+
+static void
+d2uc_array     (const double *src, unsigned char *dest, int count, int normalize)
+{      double normfact ;
+
+       normfact = normalize ? (1.0 * 0x7F) : 1.0 ;
+
+       while (--count >= 0)
+       {       dest [count] = lrint (src [count] * normfact) + 128 ;
+               } ;
+} /* d2uc_array */
+
+static void
+d2uc_clip_array        (const double *src, unsigned char *dest, int count, int normalize)
+{      double  normfact, scaled_value ;
+
+       normfact = normalize ? (8.0 * 0x10000000) : (1.0 * 0x1000000) ;
+
+       while (--count >= 0)
+       {       scaled_value = src [count] * normfact ;
+               if (CPU_CLIPS_POSITIVE == 0 && scaled_value >= (1.0 * 0x7FFFFFFF))
+               {       dest [count] = 255 ;
+                       continue ;
+                       } ;
+               if (CPU_CLIPS_NEGATIVE == 0 && scaled_value <= (-8.0 * 0x10000000))
+               {       dest [count] = 0 ;
+                       continue ;
+                       } ;
+
+               dest [count] = (lrint (src [count] * normfact) >> 24) + 128 ;
+               } ;
+} /* d2uc_clip_array */
+
+static sf_count_t
+pcm_write_d2uc (SF_PRIVATE *psf, const double *ptr, sf_count_t len)
+{      void            (*convert) (const double *, unsigned char *, int, int) ;
+       int                     bufferlen, writecount ;
+       sf_count_t      total = 0 ;
+
+       convert = (psf->add_clipping) ? d2uc_clip_array : d2uc_array ;
+       bufferlen = ARRAY_LEN (psf->u.ucbuf) ;
+
+       while (len > 0)
+       {       if (len < bufferlen)
+                       bufferlen = (int) len ;
+               convert (ptr + total, psf->u.ucbuf, bufferlen, psf->norm_double) ;
+               writecount = psf_fwrite (psf->u.ucbuf, sizeof (unsigned char), bufferlen, psf) ;
+               total += writecount ;
+               if (writecount < bufferlen)
+                       break ;
+               len -= writecount ;
+               } ;
+
+       return total ;
+} /* pcm_write_d2uc */
+
+/*==============================================================================
+*/
+
+static void
+d2bes_array (const double *src, short *dest, int count, int normalize)
+{      unsigned char   *ucptr ;
+       short                   value ;
+       double                  normfact ;
+
+       normfact = normalize ? (1.0 * 0x7FFF) : 1.0 ;
+       ucptr = ((unsigned char*) dest) + 2 * count ;
+
+       while (--count >= 0)
+       {       ucptr -= 2 ;
+               value = lrint (src [count] * normfact) ;
+               ucptr [1] = value ;
+               ucptr [0] = value >> 8 ;
+               } ;
+} /* d2bes_array */
+
+static void
+d2bes_clip_array (const double *src, short *dest, int count, int normalize)
+{      unsigned char   *ucptr ;
+       double                  normfact, scaled_value ;
+       int                             value ;
+
+       normfact = normalize ? (8.0 * 0x10000000) : (1.0 * 0x10000) ;
+       ucptr = ((unsigned char*) dest) + 2 * count ;
+
+       while (--count >= 0)
+       {       ucptr -= 2 ;
+               scaled_value = src [count] * normfact ;
+               if (CPU_CLIPS_POSITIVE == 0 && scaled_value >= (1.0 * 0x7FFFFFFF))
+               {       ucptr [1] = 0xFF ;
+                       ucptr [0] = 0x7F ;
+                       continue ;
+                       } ;
+               if (CPU_CLIPS_NEGATIVE == 0 && scaled_value <= (-8.0 * 0x10000000))
+               {       ucptr [1] = 0x00 ;
+                       ucptr [0] = 0x80 ;
+                       continue ;
+                       } ;
+
+               value = lrint (scaled_value) ;
+               ucptr [1] = value >> 16 ;
+               ucptr [0] = value >> 24 ;
+               } ;
+} /* d2bes_clip_array */
+
+static sf_count_t
+pcm_write_d2bes        (SF_PRIVATE *psf, const double *ptr, sf_count_t len)
+{      void            (*convert) (const double *, short *, int, int) ;
+       int                     bufferlen, writecount ;
+       sf_count_t      total = 0 ;
+
+       convert = (psf->add_clipping) ? d2bes_clip_array : d2bes_array ;
+       bufferlen = ARRAY_LEN (psf->u.sbuf) ;
+
+       while (len > 0)
+       {       if (len < bufferlen)
+                       bufferlen = (int) len ;
+               convert (ptr + total, psf->u.sbuf, bufferlen, psf->norm_double) ;
+               writecount = psf_fwrite (psf->u.sbuf, sizeof (short), bufferlen, psf) ;
+               total += writecount ;
+               if (writecount < bufferlen)
+                       break ;
+               len -= writecount ;
+               } ;
+
+       return total ;
+} /* pcm_write_d2bes */
+
+/*==============================================================================
+*/
+
+static void
+d2les_array (const double *src, short *dest, int count, int normalize)
+{      unsigned char   *ucptr ;
+       short                   value ;
+       double                  normfact ;
+
+       normfact = normalize ? (1.0 * 0x7FFF) : 1.0 ;
+       ucptr = ((unsigned char*) dest) + 2 * count ;
+
+       while (--count >= 0)
+       {       ucptr -= 2 ;
+               value = lrint (src [count] * normfact) ;
+               ucptr [0] = value ;
+               ucptr [1] = value >> 8 ;
+               } ;
+} /* d2les_array */
+
+static void
+d2les_clip_array (const double *src, short *dest, int count, int normalize)
+{      unsigned char   *ucptr ;
+       int                             value ;
+       double                  normfact, scaled_value ;
+
+       normfact = normalize ? (8.0 * 0x10000000) : (1.0 * 0x10000) ;
+       ucptr = ((unsigned char*) dest) + 2 * count ;
+
+       while (--count >= 0)
+       {       ucptr -= 2 ;
+               scaled_value = src [count] * normfact ;
+               if (CPU_CLIPS_POSITIVE == 0 && scaled_value >= (1.0 * 0x7FFFFFFF))
+               {       ucptr [0] = 0xFF ;
+                       ucptr [1] = 0x7F ;
+                       continue ;
+                       } ;
+               if (CPU_CLIPS_NEGATIVE == 0 && scaled_value <= (-8.0 * 0x10000000))
+               {       ucptr [0] = 0x00 ;
+                       ucptr [1] = 0x80 ;
+                       continue ;
+                       } ;
+
+               value = lrint (scaled_value) ;
+               ucptr [0] = value >> 16 ;
+               ucptr [1] = value >> 24 ;
+               } ;
+} /* d2les_clip_array */
+
+static sf_count_t
+pcm_write_d2les        (SF_PRIVATE *psf, const double *ptr, sf_count_t len)
+{      void            (*convert) (const double *, short *, int, int) ;
+       int                     bufferlen, writecount ;
+       sf_count_t      total = 0 ;
+
+       convert = (psf->add_clipping) ? d2les_clip_array : d2les_array ;
+       bufferlen = ARRAY_LEN (psf->u.sbuf) ;
+
+       while (len > 0)
+       {       if (len < bufferlen)
+                       bufferlen = (int) len ;
+               convert (ptr + total, psf->u.sbuf, bufferlen, psf->norm_double) ;
+               writecount = psf_fwrite (psf->u.sbuf, sizeof (short), bufferlen, psf) ;
+               total += writecount ;
+               if (writecount < bufferlen)
+                       break ;
+               len -= writecount ;
+               } ;
+
+       return total ;
+} /* pcm_write_d2les */
+
+/*==============================================================================
+*/
+
+static void
+d2let_array (const double *src, tribyte *dest, int count, int normalize)
+{      unsigned char   *ucptr ;
+       int                             value ;
+       double                  normfact ;
+
+       normfact = normalize ? (1.0 * 0x7FFFFF) : 1.0 ;
+       ucptr = ((unsigned char*) dest) + 3 * count ;
+
+       while (--count >= 0)
+       {       ucptr -= 3 ;
+               value = lrint (src [count] * normfact) ;
+               ucptr [0] = value ;
+               ucptr [1] = value >> 8 ;
+               ucptr [2] = value >> 16 ;
+               } ;
+} /* d2let_array */
+
+static void
+d2let_clip_array (const double *src, tribyte *dest, int count, int normalize)
+{      unsigned char   *ucptr ;
+       int                             value ;
+       double                  normfact, scaled_value ;
+
+       normfact = normalize ? (8.0 * 0x10000000) : (1.0 * 0x100) ;
+       ucptr = ((unsigned char*) dest) + 3 * count ;
+
+       while (--count >= 0)
+       {       ucptr -= 3 ;
+               scaled_value = src [count] * normfact ;
+               if (CPU_CLIPS_POSITIVE == 0 && scaled_value >= (1.0 * 0x7FFFFFFF))
+               {       ucptr [0] = 0xFF ;
+                       ucptr [1] = 0xFF ;
+                       ucptr [2] = 0x7F ;
+                       continue ;
+                       } ;
+               if (CPU_CLIPS_NEGATIVE == 0 && scaled_value <= (-8.0 * 0x10000000))
+               {       ucptr [0] = 0x00 ;
+                       ucptr [1] = 0x00 ;
+                       ucptr [2] = 0x80 ;
+                       continue ;
+                       } ;
+
+               value = lrint (scaled_value) ;
+               ucptr [0] = value >> 8 ;
+               ucptr [1] = value >> 16 ;
+               ucptr [2] = value >> 24 ;
+               } ;
+} /* d2let_clip_array */
+
+static sf_count_t
+pcm_write_d2let        (SF_PRIVATE *psf, const double *ptr, sf_count_t len)
+{      void            (*convert) (const double *, tribyte *, int, int) ;
+       int                     bufferlen, writecount ;
+       sf_count_t      total = 0 ;
+
+       convert = (psf->add_clipping) ? d2let_clip_array : d2let_array ;
+       bufferlen = sizeof (psf->u.ucbuf) / SIZEOF_TRIBYTE ;
+
+       while (len > 0)
+       {       if (len < bufferlen)
+                       bufferlen = (int) len ;
+               convert (ptr + total, (tribyte*) (psf->u.ucbuf), bufferlen, psf->norm_double) ;
+               writecount = psf_fwrite (psf->u.ucbuf, SIZEOF_TRIBYTE, bufferlen, psf) ;
+               total += writecount ;
+               if (writecount < bufferlen)
+                       break ;
+               len -= writecount ;
+               } ;
+
+       return total ;
+} /* pcm_write_d2let */
+
+/*==============================================================================
+*/
+
+static void
+d2bet_array (const double *src, tribyte *dest, int count, int normalize)
+{      unsigned char   *ucptr ;
+       int                             value ;
+       double                  normfact ;
+
+       normfact = normalize ? (1.0 * 0x7FFFFF) : 1.0 ;
+       ucptr = ((unsigned char*) dest) + 3 * count ;
+
+       while (--count >= 0)
+       {       ucptr -= 3 ;
+               value = lrint (src [count] * normfact) ;
+               ucptr [2] = value ;
+               ucptr [1] = value >> 8 ;
+               ucptr [0] = value >> 16 ;
+               } ;
+} /* d2bet_array */
+
+static void
+d2bet_clip_array (const double *src, tribyte *dest, int count, int normalize)
+{      unsigned char   *ucptr ;
+       int                             value ;
+       double                  normfact, scaled_value ;
+
+       normfact = normalize ? (8.0 * 0x10000000) : (1.0 * 0x100) ;
+       ucptr = ((unsigned char*) dest) + 3 * count ;
+
+       while (--count >= 0)
+       {       ucptr -= 3 ;
+               scaled_value = src [count] * normfact ;
+               if (CPU_CLIPS_POSITIVE == 0 && scaled_value >= (1.0 * 0x7FFFFFFF))
+               {       ucptr [2] = 0xFF ;
+                       ucptr [1] = 0xFF ;
+                       ucptr [0] = 0x7F ;
+                       continue ;
+                       } ;
+               if (CPU_CLIPS_NEGATIVE == 0 && scaled_value <= (-8.0 * 0x10000000))
+               {       ucptr [2] = 0x00 ;
+                       ucptr [1] = 0x00 ;
+                       ucptr [0] = 0x80 ;
+                       continue ;
+                       } ;
+
+               value = lrint (scaled_value) ;
+               ucptr [2] = value >> 8 ;
+               ucptr [1] = value >> 16 ;
+               ucptr [0] = value >> 24 ;
+               } ;
+} /* d2bet_clip_array */
+
+static sf_count_t
+pcm_write_d2bet        (SF_PRIVATE *psf, const double *ptr, sf_count_t len)
+{      void            (*convert) (const double *, tribyte *, int, int) ;
+       int                     bufferlen, writecount ;
+       sf_count_t      total = 0 ;
+
+       convert = (psf->add_clipping) ? d2bet_clip_array : d2bet_array ;
+       bufferlen = sizeof (psf->u.ucbuf) / SIZEOF_TRIBYTE ;
+
+       while (len > 0)
+       {       if (len < bufferlen)
+                       bufferlen = (int) len ;
+               convert (ptr + total, (tribyte*) (psf->u.ucbuf), bufferlen, psf->norm_double) ;
+               writecount = psf_fwrite (psf->u.ucbuf, SIZEOF_TRIBYTE, bufferlen, psf) ;
+               total += writecount ;
+               if (writecount < bufferlen)
+                       break ;
+               len -= writecount ;
+               } ;
+
+       return total ;
+} /* pcm_write_d2bet */
+
+/*==============================================================================
+*/
+
+static void
+d2bei_array (const double *src, int *dest, int count, int normalize)
+{      unsigned char   *ucptr ;
+       int                             value ;
+       double                  normfact ;
+
+       normfact = normalize ? (1.0 * 0x7FFFFFFF) : 1.0 ;
+       ucptr = ((unsigned char*) dest) + 4 * count ;
+
+       while (--count >= 0)
+       {       ucptr -= 4 ;
+               value = lrint (src [count] * normfact) ;
+               ucptr [0] = value >> 24 ;
+               ucptr [1] = value >> 16 ;
+               ucptr [2] = value >> 8 ;
+               ucptr [3] = value ;
+               } ;
+} /* d2bei_array */
+
+static void
+d2bei_clip_array (const double *src, int *dest, int count, int normalize)
+{      unsigned char   *ucptr ;
+       int                             value ;
+       double                  normfact, scaled_value ;
+
+       normfact = normalize ? (8.0 * 0x10000000) : 1.0 ;
+       ucptr = ((unsigned char*) dest) + 4 * count ;
+
+       while (--count >= 0)
+       {       ucptr -= 4 ;
+               scaled_value = src [count] * normfact ;
+               if (CPU_CLIPS_POSITIVE == 0 && scaled_value >= (1.0 * 0x7FFFFFFF))
+               {       ucptr [3] = 0xFF ;
+                       ucptr [2] = 0xFF ;
+                       ucptr [1] = 0xFF ;
+                       ucptr [0] = 0x7F ;
+                       continue ;
+                       } ;
+               if (CPU_CLIPS_NEGATIVE == 0 && scaled_value <= (-8.0 * 0x10000000))
+               {       ucptr [3] = 0x00 ;
+                       ucptr [2] = 0x00 ;
+                       ucptr [1] = 0x00 ;
+                       ucptr [0] = 0x80 ;
+                       continue ;
+                       } ;
+
+               value = lrint (scaled_value) ;
+               ucptr [0] = value >> 24 ;
+               ucptr [1] = value >> 16 ;
+               ucptr [2] = value >> 8 ;
+               ucptr [3] = value ;
+               } ;
+} /* d2bei_clip_array */
+
+static sf_count_t
+pcm_write_d2bei        (SF_PRIVATE *psf, const double *ptr, sf_count_t len)
+{      void            (*convert) (const double *, int *, int, int) ;
+       int                     bufferlen, writecount ;
+       sf_count_t      total = 0 ;
+
+       convert = (psf->add_clipping) ? d2bei_clip_array : d2bei_array ;
+       bufferlen = ARRAY_LEN (psf->u.ibuf) ;
+
+       while (len > 0)
+       {       if (len < bufferlen)
+                       bufferlen = (int) len ;
+               convert (ptr + total, psf->u.ibuf, bufferlen, psf->norm_double) ;
+               writecount = psf_fwrite (psf->u.ibuf, sizeof (int), bufferlen, psf) ;
+               total += writecount ;
+               if (writecount < bufferlen)
+                       break ;
+               len -= writecount ;
+               } ;
+
+       return total ;
+} /* pcm_write_d2bei */
+
+/*==============================================================================
+*/
+
+static void
+d2lei_array (const double *src, int *dest, int count, int normalize)
+{      unsigned char   *ucptr ;
+       int                             value ;
+       double                  normfact ;
+
+       normfact = normalize ? (1.0 * 0x7FFFFFFF) : 1.0 ;
+       ucptr = ((unsigned char*) dest) + 4 * count ;
+
+       while (--count >= 0)
+       {       ucptr -= 4 ;
+               value = lrint (src [count] * normfact) ;
+               ucptr [0] = value ;
+               ucptr [1] = value >> 8 ;
+               ucptr [2] = value >> 16 ;
+               ucptr [3] = value >> 24 ;
+               } ;
+} /* d2lei_array */
+
+static void
+d2lei_clip_array (const double *src, int *dest, int count, int normalize)
+{      unsigned char   *ucptr ;
+       int                             value ;
+       double                  normfact, scaled_value ;
+
+       normfact = normalize ? (8.0 * 0x10000000) : 1.0 ;
+       ucptr = ((unsigned char*) dest) + 4 * count ;
+
+       while (--count >= 0)
+       {       ucptr -= 4 ;
+               scaled_value = src [count] * normfact ;
+               if (CPU_CLIPS_POSITIVE == 0 && scaled_value >= (1.0 * 0x7FFFFFFF))
+               {       ucptr [0] = 0xFF ;
+                       ucptr [1] = 0xFF ;
+                       ucptr [2] = 0xFF ;
+                       ucptr [3] = 0x7F ;
+                       continue ;
+                       } ;
+               if (CPU_CLIPS_NEGATIVE == 0 && scaled_value <= (-8.0 * 0x10000000))
+               {       ucptr [0] = 0x00 ;
+                       ucptr [1] = 0x00 ;
+                       ucptr [2] = 0x00 ;
+                       ucptr [3] = 0x80 ;
+                       continue ;
+                       } ;
+
+               value = lrint (scaled_value) ;
+               ucptr [0] = value ;
+               ucptr [1] = value >> 8 ;
+               ucptr [2] = value >> 16 ;
+               ucptr [3] = value >> 24 ;
+               } ;
+} /* d2lei_clip_array */
+
+static sf_count_t
+pcm_write_d2lei        (SF_PRIVATE *psf, const double *ptr, sf_count_t len)
+{      void            (*convert) (const double *, int *, int, int) ;
+       int                     bufferlen, writecount ;
+       sf_count_t      total = 0 ;
+
+       convert = (psf->add_clipping) ? d2lei_clip_array : d2lei_array ;
+       bufferlen = ARRAY_LEN (psf->u.ibuf) ;
+
+       while (len > 0)
+       {       if (len < bufferlen)
+                       bufferlen = (int) len ;
+               convert (ptr + total, psf->u.ibuf, bufferlen, psf->norm_double) ;
+               writecount = psf_fwrite (psf->u.ibuf, sizeof (int), bufferlen, psf) ;
+               total += writecount ;
+               if (writecount < bufferlen)
+                       break ;
+               len -= writecount ;
+               } ;
+
+       return total ;
+} /* pcm_write_d2lei */
+
+/*
+** Do not edit or modify anything in this comment block.
+** The arch-tag line is a file identity tag for the GNU Arch 
+** revision control system.
+**
+** arch-tag: d8bc7c0e-1e2f-4ff3-a28f-10ce1fbade3b
+*/
diff --git a/libs/libsndfile/src/pvf.c b/libs/libsndfile/src/pvf.c
new file mode 100644 (file)
index 0000000..1dab17c
--- /dev/null
@@ -0,0 +1,199 @@
+/*
+** Copyright (C) 2002-2004 Erik de Castro Lopo <erikd@mega-nerd.com>
+**
+** This program is free software; you can redistribute it and/or modify
+** it under the terms of the GNU Lesser General Public License as published by
+** the Free Software Foundation; either version 2.1 of the License, or
+** (at your option) any later version.
+**
+** This program is distributed in the hope that it will be useful,
+** but WITHOUT ANY WARRANTY; without even the implied warranty of
+** MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+** GNU Lesser General Public License for more details.
+**
+** You should have received a copy of the GNU Lesser General Public License
+** along with this program; if not, write to the Free Software
+** Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA.
+*/
+
+#include       "sfconfig.h"
+
+#include       <stdio.h>
+#include       <fcntl.h>
+#include       <string.h>
+#include       <ctype.h>
+
+#include       "sndfile.h"
+#include       "sfendian.h"
+#include       "common.h"
+
+/*------------------------------------------------------------------------------
+** Macros to handle big/little endian issues.
+*/
+
+#define PVF1_MARKER            (MAKE_MARKER ('P', 'V', 'F', '1'))
+
+/*------------------------------------------------------------------------------
+** Private static functions.
+*/
+
+static int             pvf_close               (SF_PRIVATE *psf) ;
+
+static int             pvf_write_header (SF_PRIVATE *psf, int calc_length) ;
+static int             pvf_read_header (SF_PRIVATE *psf) ;
+
+/*------------------------------------------------------------------------------
+** Public function.
+*/
+
+int
+pvf_open       (SF_PRIVATE *psf)
+{      int             subformat ;
+       int             error = 0 ;
+
+       if (psf->mode == SFM_READ || (psf->mode == SFM_RDWR && psf->filelength > 0))
+       {       if ((error = pvf_read_header (psf)))
+                       return error ;
+               } ;
+
+       subformat = psf->sf.format & SF_FORMAT_SUBMASK ;
+
+       if (psf->mode == SFM_WRITE || psf->mode == SFM_RDWR)
+       {       if ((psf->sf.format & SF_FORMAT_TYPEMASK) != SF_FORMAT_PVF)
+                       return  SFE_BAD_OPEN_FORMAT ;
+
+               psf->endian = SF_ENDIAN_BIG ;
+
+               if (pvf_write_header (psf, SF_FALSE))
+                       return psf->error ;
+
+               psf->write_header = pvf_write_header ;
+               } ;
+
+       psf->container_close = pvf_close ;
+
+       psf->blockwidth = psf->bytewidth * psf->sf.channels ;
+
+       switch (subformat)
+       {       case SF_FORMAT_PCM_S8 : /* 8-bit linear PCM. */
+               case SF_FORMAT_PCM_16 : /* 16-bit linear PCM. */
+               case SF_FORMAT_PCM_32 : /* 32-bit linear PCM. */
+                               error = pcm_init (psf) ;
+                               break ;
+
+               default :       break ;
+               } ;
+
+       return error ;
+} /* pvf_open */
+
+/*------------------------------------------------------------------------------
+*/
+
+static int
+pvf_close      (SF_PRIVATE *psf)
+{
+       psf = psf ;
+
+       return 0 ;
+} /* pvf_close */
+
+static int
+pvf_write_header (SF_PRIVATE *psf, int calc_length)
+{      sf_count_t      current ;
+
+       if (psf->pipeoffset > 0)
+               return 0 ;
+
+       calc_length = calc_length ; /* Avoid a compiler warning. */
+
+       current = psf_ftell (psf) ;
+
+       /* Reset the current header length to zero. */
+       psf->header [0] = 0 ;
+       psf->headindex = 0 ;
+
+       if (psf->is_pipe == SF_FALSE)
+               psf_fseek (psf, 0, SEEK_SET) ;
+
+       LSF_SNPRINTF ((char*) psf->header, sizeof (psf->header), "PVF1\n%d %d %d\n",
+               psf->sf.channels, psf->sf.samplerate, psf->bytewidth * 8) ;
+
+       psf->headindex = strlen ((char*) psf->header) ;
+
+       /* Header construction complete so write it out. */
+       psf_fwrite (psf->header, psf->headindex, 1, psf) ;
+
+       if (psf->error)
+               return psf->error ;
+
+       psf->dataoffset = psf->headindex ;
+
+       if (current > 0)
+               psf_fseek (psf, current, SEEK_SET) ;
+
+       return psf->error ;
+} /* pvf_write_header */
+
+static int
+pvf_read_header (SF_PRIVATE *psf)
+{      char    buffer [32] ;
+       int             marker, channels, samplerate, bitwidth ;
+
+       psf_binheader_readf (psf, "pmj", 0, &marker, 1) ;
+       psf_log_printf (psf, "%M\n", marker) ;
+
+       if (marker != PVF1_MARKER)
+               return SFE_PVF_NO_PVF1 ;
+
+       /* Grab characters up until a newline which is replaced by an EOS. */
+       psf_binheader_readf (psf, "G", buffer, sizeof (buffer)) ;
+
+       if (sscanf (buffer, "%d %d %d", &channels, &samplerate, &bitwidth) != 3)
+               return SFE_PVF_BAD_HEADER ;
+
+       psf_log_printf (psf, " Channels    : %d\n Sample rate : %d\n Bit width   : %d\n",
+                               channels, samplerate, bitwidth) ;
+
+       psf->sf.channels = channels ;
+       psf->sf.samplerate = samplerate ;
+
+       switch (bitwidth)
+       {       case 8 :
+                               psf->sf.format = SF_FORMAT_PVF | SF_FORMAT_PCM_S8 ;
+                               psf->bytewidth = 1 ;
+                               break ;
+
+               case 16 :
+                               psf->sf.format = SF_FORMAT_PVF | SF_FORMAT_PCM_16 ;
+                               psf->bytewidth = 2 ;
+                               break ;
+               case 32 :
+                               psf->sf.format = SF_FORMAT_PVF | SF_FORMAT_PCM_32 ;
+                               psf->bytewidth = 4 ;
+                               break ;
+
+               default :
+                               return SFE_PVF_BAD_BITWIDTH ;
+               } ;
+
+       psf->dataoffset = psf_ftell (psf) ;
+       psf_log_printf (psf, " Data Offset : %D\n", psf->dataoffset) ;
+
+       psf->endian = SF_ENDIAN_BIG ;
+
+       psf->datalength = psf->filelength - psf->dataoffset ;
+       psf->blockwidth = psf->sf.channels * psf->bytewidth ;
+
+       if (! psf->sf.frames && psf->blockwidth)
+               psf->sf.frames = (psf->filelength - psf->dataoffset) / psf->blockwidth ;
+
+       return 0 ;
+} /* pvf_read_header */
+/*
+** Do not edit or modify anything in this comment block.
+** The arch-tag line is a file identity tag for the GNU Arch 
+** revision control system.
+**
+** arch-tag: 20a26761-8bc1-41d7-b1f3-9793bf3d9864
+*/
diff --git a/libs/libsndfile/src/raw.c b/libs/libsndfile/src/raw.c
new file mode 100644 (file)
index 0000000..65be491
--- /dev/null
@@ -0,0 +1,111 @@
+/*
+** Copyright (C) 1999-2004 Erik de Castro Lopo <erikd@mega-nerd.com>
+**
+** This program is free software; you can redistribute it and/or modify
+** it under the terms of the GNU Lesser General Public License as published by
+** the Free Software Foundation; either version 2.1 of the License, or
+** (at your option) any later version.
+**
+** This program is distributed in the hope that it will be useful,
+** but WITHOUT ANY WARRANTY; without even the implied warranty of
+** MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+** GNU Lesser General Public License for more details.
+**
+** You should have received a copy of the GNU Lesser General Public License
+** along with this program; if not, write to the Free Software
+** Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA.
+*/
+
+#include       "sfconfig.h"
+
+#include       <stdio.h>
+
+#include       "sndfile.h"
+#include       "common.h"
+
+/*------------------------------------------------------------------------------
+** Public function.
+*/
+
+int
+raw_open       (SF_PRIVATE *psf)
+{      int     subformat, error = SFE_NO_ERROR ;
+
+       subformat = psf->sf.format & SF_FORMAT_SUBMASK ;
+
+       psf->endian = psf->sf.format & SF_FORMAT_ENDMASK ;
+
+       if (CPU_IS_BIG_ENDIAN && (psf->endian == 0 || psf->endian == SF_ENDIAN_CPU))
+               psf->endian = SF_ENDIAN_BIG ;
+       else if (CPU_IS_LITTLE_ENDIAN && (psf->endian == 0 || psf->endian == SF_ENDIAN_CPU))
+               psf->endian = SF_ENDIAN_LITTLE ;
+
+       psf->blockwidth = psf->bytewidth * psf->sf.channels ;
+       psf->dataoffset = 0 ;
+       psf->datalength = psf->filelength ;
+
+       switch (subformat)
+       {       case SF_FORMAT_PCM_S8 :
+                               error = pcm_init (psf) ;
+                               break ;
+
+               case SF_FORMAT_PCM_U8 :
+                               error = pcm_init (psf) ;
+                               break ;
+
+               case SF_FORMAT_PCM_16 :
+               case SF_FORMAT_PCM_24 :
+               case SF_FORMAT_PCM_32 :
+                               error = pcm_init (psf) ;
+                               break ;
+
+               case SF_FORMAT_ULAW :
+                               error = ulaw_init (psf) ;
+                               break ;
+
+               case SF_FORMAT_ALAW :
+                               error = alaw_init (psf) ;
+                               break ;
+
+               case SF_FORMAT_GSM610 :
+                               error = gsm610_init (psf) ;
+                               break ;
+
+               /* Lite remove start */
+               case SF_FORMAT_FLOAT :
+                               error = float32_init (psf) ;
+                               break ;
+
+               case SF_FORMAT_DOUBLE :
+                               error = double64_init (psf) ;
+                               break ;
+
+               case SF_FORMAT_DWVW_12 :
+                               error = dwvw_init (psf, 12) ;
+                               break ;
+
+               case SF_FORMAT_DWVW_16 :
+                               error = dwvw_init (psf, 16) ;
+                               break ;
+
+               case SF_FORMAT_DWVW_24 :
+                               error = dwvw_init (psf, 24) ;
+                               break ;
+
+               case SF_FORMAT_VOX_ADPCM :
+                               error = vox_adpcm_init (psf) ;
+                               break ;
+               /* Lite remove end */
+
+               default : return SFE_BAD_OPEN_FORMAT ;
+               } ;
+
+       return error ;
+} /* raw_open */
+/*
+** Do not edit or modify anything in this comment block.
+** The arch-tag line is a file identity tag for the GNU Arch 
+** revision control system.
+**
+** arch-tag: f0066de7-d6ce-4f36-a1e0-e475c07d4e1a
+*/
diff --git a/libs/libsndfile/src/rx2.c b/libs/libsndfile/src/rx2.c
new file mode 100644 (file)
index 0000000..d95f11f
--- /dev/null
@@ -0,0 +1,326 @@
+/*
+** Copyright (C) 2001-2004 Erik de Castro Lopo <erikd@mega-nerd.com>
+**
+** This program is free software; you can redistribute it and/or modify
+** it under the terms of the GNU Lesser General Public License as published by
+** the Free Software Foundation; either version 2.1 of the License, or
+** (at your option) any later version.
+**
+** This program is distributed in the hope that it will be useful,
+** but WITHOUT ANY WARRANTY; without even the implied warranty of
+** MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+** GNU Lesser General Public License for more details.
+**
+** You should have received a copy of the GNU Lesser General Public License
+** along with this program; if not, write to the Free Software
+** Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA.
+*/
+
+#include       "sfconfig.h"
+
+#include       <stdio.h>
+#include       <string.h>
+#include       <ctype.h>
+#include       <stdarg.h>
+
+#include       "sndfile.h"
+#include       "sfendian.h"
+#include       "common.h"
+
+#if (ENABLE_EXPERIMENTAL_CODE == 0)
+
+int
+rx2_open       (SF_PRIVATE *psf)
+{      if (psf)
+               return SFE_UNIMPLEMENTED ;
+       return (psf && 0) ;
+} /* rx2_open */
+
+#else
+
+/*------------------------------------------------------------------------------
+ * Macros to handle big/little endian issues.
+*/
+
+#define        CAT_MARKER      (MAKE_MARKER ('C', 'A', 'T', ' '))
+#define        GLOB_MARKER (MAKE_MARKER ('G', 'L', 'O', 'B'))
+
+#define        RECY_MARKER (MAKE_MARKER ('R', 'E', 'C', 'Y'))
+
+#define        SLCL_MARKER (MAKE_MARKER ('S', 'L', 'C', 'L'))
+#define        SLCE_MARKER (MAKE_MARKER ('S', 'L', 'C', 'E'))
+
+#define        DEVL_MARKER     (MAKE_MARKER ('D', 'E', 'V', 'L'))
+#define        TRSH_MARKER     (MAKE_MARKER ('T', 'R', 'S', 'H'))
+
+#define        EQ_MARKER       (MAKE_MARKER ('E', 'Q', ' ', ' '))
+#define        COMP_MARKER (MAKE_MARKER ('C', 'O', 'M', 'P'))
+
+#define        SINF_MARKER (MAKE_MARKER ('S', 'I', 'N', 'F'))
+#define        SDAT_MARKER (MAKE_MARKER ('S', 'D', 'A', 'T'))
+
+/*------------------------------------------------------------------------------
+ * Typedefs for file chunks.
+*/
+
+
+/*------------------------------------------------------------------------------
+ * Private static functions.
+*/
+static int     rx2_close       (SF_PRIVATE *psf) ;
+
+/*------------------------------------------------------------------------------
+** Public functions.
+*/
+
+int
+rx2_open       (SF_PRIVATE *psf)
+{      static const char *marker_type [4] =
+       {       "Original Enabled", "Enabled Hidden",
+               "Additional/PencilTool", "Disabled"
+               } ;
+
+       int error, marker, length, glob_offset, slce_count, frames ;
+
+       int sdat_length = 0, slce_total = 0 ;
+
+       int n_channels ;
+
+
+       /* So far only doing read. */
+
+       psf_binheader_readf (psf, "Epm4", 0, &marker, &length) ;
+
+       if (marker != CAT_MARKER)
+       {       psf_log_printf (psf, "length : %d\n", length) ;
+               return -1000 ;
+               } ;
+
+       if (length != psf->filelength - 8)
+               psf_log_printf (psf, "%M : %d (should be %d)\n", marker, length, psf->filelength - 8) ;
+       else
+               psf_log_printf (psf, "%M : %d\n", marker, length) ;
+
+       /* 'REX2' marker */
+       psf_binheader_readf (psf, "m", &marker) ;
+       psf_log_printf (psf, "%M", marker) ;
+
+       /* 'HEAD' marker */
+       psf_binheader_readf (psf, "m", &marker) ;
+       psf_log_printf (psf, "%M\n", marker) ;
+
+       /* Grab 'GLOB' offset. */
+       psf_binheader_readf (psf, "E4", &glob_offset) ;
+       glob_offset += 0x14 ;   /* Add the current file offset. */
+
+       /* Jump to offset 0x30 */
+       psf_binheader_readf (psf, "p", 0x30) ;
+
+       /* Get name length */
+       length = 0 ;
+       psf_binheader_readf (psf, "1", &length) ;
+       if (length >= SIGNED_SIZEOF (psf->u.cbuf))
+       {       psf_log_printf (psf, "  Text : %d *** Error : Too sf_count_t!\n") ;
+               return -1001 ;
+               }
+
+       memset (psf->u.cbuf, 0, sizeof (psf->u.cbuf)) ;
+       psf_binheader_readf (psf, "b", psf->u.cbuf, length) ;
+       psf_log_printf (psf, " Text : \"%s\"\n", psf->u.cbuf) ;
+
+       /* Jump to GLOB offset position. */
+       if (glob_offset & 1)
+               glob_offset ++ ;
+
+       psf_binheader_readf (psf, "p", glob_offset) ;
+
+       slce_count = 0 ;
+       /* GLOB */
+       while (1)
+       {       psf_binheader_readf (psf, "m", &marker) ;
+
+               if (marker != SLCE_MARKER && slce_count > 0)
+               {       psf_log_printf (psf, "   SLCE count : %d\n", slce_count) ;
+                       slce_count = 0 ;
+                       }
+               switch (marker)
+               {       case GLOB_MARKER:
+                                       psf_binheader_readf (psf, "E4", &length) ;
+                                       psf_log_printf (psf, " %M : %d\n", marker, length) ;
+                                       psf_binheader_readf (psf, "j", length) ;
+                                       break ;
+
+                       case RECY_MARKER:
+                                       psf_binheader_readf (psf, "E4", &length) ;
+                                       psf_log_printf (psf, " %M : %d\n", marker, length) ;
+                                       psf_binheader_readf (psf, "j", (length+1) & 0xFFFFFFFE) ; /* ?????? */
+                                       break ;
+
+                       case CAT_MARKER:
+                                       psf_binheader_readf (psf, "E4", &length) ;
+                                       psf_log_printf (psf, " %M : %d\n", marker, length) ;
+                                       /*-psf_binheader_readf (psf, "j", length) ;-*/
+                                       break ;
+
+                       case DEVL_MARKER:
+                                       psf_binheader_readf (psf, "mE4", &marker, &length) ;
+                                       psf_log_printf (psf, "  DEVL%M : %d\n", marker, length) ;
+                                       if (length & 1)
+                                               length ++ ;
+                                       psf_binheader_readf (psf, "j", length) ;
+                                       break ;
+
+                       case EQ_MARKER:
+                       case COMP_MARKER:
+                                       psf_binheader_readf (psf, "E4", &length) ;
+                                       psf_log_printf (psf, "   %M : %d\n", marker, length) ;
+                                       /* This is weird!!!! why make this (length - 1) */
+                                       if (length & 1)
+                                               length ++ ;
+                                       psf_binheader_readf (psf, "j", length) ;
+                                       break ;
+
+                       case SLCL_MARKER:
+                                       psf_log_printf (psf, "  %M\n    (Offset, Next Offset, Type)\n", marker) ;
+                                       slce_count = 0 ;
+                                       break ;
+
+                       case SLCE_MARKER:
+                                       {       int len [4], indx ;
+
+                                               psf_binheader_readf (psf, "E4444", &len [0], &len [1], &len [2], &len [3]) ;
+
+                                               indx = ((len [3] & 0x0000FFFF) >> 8) & 3 ;
+
+                                               if (len [2] == 1)
+                                               {       if (indx != 1)
+                                                               indx = 3 ;      /* 2 cases, where next slice offset = 1 -> disabled & enabled/hidden */
+
+                                                       psf_log_printf (psf, "   %M : (%6d, ?: 0x%X, %s)\n", marker, len [1], (len [3] & 0xFFFF0000) >> 16, marker_type [indx]) ;
+                                                       }
+                                               else
+                                               {       slce_total += len [2] ;
+
+                                                       psf_log_printf (psf, "   %M : (%6d, SLCE_next_ofs:%d, ?: 0x%X, %s)\n", marker, len [1], len [2], (len [3] & 0xFFFF0000) >> 16, marker_type [indx]) ;
+                                                       } ;
+
+                                               slce_count ++ ;
+                                               } ;
+                                       break ;
+
+                       case SINF_MARKER:
+                                       psf_binheader_readf (psf, "E4", &length) ;
+                                       psf_log_printf (psf, " %M : %d\n", marker, length) ;
+
+                                       psf_binheader_readf (psf, "E2", &n_channels) ;
+                                       n_channels = (n_channels & 0x0000FF00) >> 8 ;
+                                       psf_log_printf (psf, "  Channels    : %d\n", n_channels) ;
+
+                                       psf_binheader_readf (psf, "E44", &psf->sf.samplerate, &frames) ;
+                                       psf->sf.frames = frames ;
+                                       psf_log_printf (psf, "  Sample Rate : %d\n", psf->sf.samplerate) ;
+                                       psf_log_printf (psf, "  Frames      : %D\n", psf->sf.frames) ;
+
+                                       psf_binheader_readf (psf, "E4", &length) ;
+                                       psf_log_printf (psf, "  ??????????? : %d\n", length) ;
+
+                                       psf_binheader_readf (psf, "E4", &length) ;
+                                       psf_log_printf (psf, "  ??????????? : %d\n", length) ;
+                                       break ;
+
+                       case SDAT_MARKER:
+                                       psf_binheader_readf (psf, "E4", &length) ;
+
+                               sdat_length = length ;
+
+                                       /* Get the current offset. */
+                                       psf->dataoffset = psf_binheader_readf (psf, NULL) ;
+
+                                       if (psf->dataoffset + length != psf->filelength)
+                                               psf_log_printf (psf, " %M : %d (should be %d)\n", marker, length, psf->dataoffset + psf->filelength) ;
+                                       else
+                                               psf_log_printf (psf, " %M : %d\n", marker, length) ;
+                                       break ;
+
+                       default :
+                                       psf_log_printf (psf, "Unknown marker : 0x%X %M", marker, marker) ;
+                                       return -1003 ;
+                                       break ;
+                       } ;
+
+               /* SDAT always last marker in file. */
+               if (marker == SDAT_MARKER)
+                       break ;
+               } ;
+
+       puts (psf->logbuffer) ;
+       puts ("-----------------------------------") ;
+
+       printf ("SDAT length  : %d\n", sdat_length) ;
+       printf ("SLCE count   : %d\n", slce_count) ;
+
+       /* Hack for zero slice count. */
+       if (slce_count == 0 && slce_total == 1)
+               slce_total = frames ;
+
+       printf ("SLCE samples : %d\n", slce_total) ;
+
+       /* Two bytes per sample. */
+       printf ("Comp Ratio   : %f:1\n", (2.0 * slce_total * n_channels) / sdat_length) ;
+
+       puts (" ") ;
+
+       psf->logbuffer [0] = 0 ;
+
+       /* OK, have the header although not too sure what it all means. */
+
+       psf->endian = SF_ENDIAN_BIG ;
+
+       psf->datalength = psf->filelength - psf->dataoffset ;
+
+       if (psf_fseek (psf, psf->dataoffset, SEEK_SET))
+               return SFE_BAD_SEEK ;
+
+       psf->sf.format = (SF_FORMAT_REX2 | SF_FORMAT_DWVW_12) ;
+
+       psf->sf.channels        = 1 ;
+       psf->bytewidth          = 2 ;
+       psf->blockwidth         = psf->sf.channels * psf->bytewidth ;
+
+       if ((error = dwvw_init (psf, 16)))
+               return error ;
+
+       psf->container_close = rx2_close ;
+
+       if (! psf->sf.frames && psf->blockwidth)
+               psf->sf.frames = psf->datalength / psf->blockwidth ;
+
+       /* All done. */
+
+       return 0 ;
+} /* rx2_open */
+
+/*------------------------------------------------------------------------------
+*/
+
+static int
+rx2_close      (SF_PRIVATE *psf)
+{
+       if (psf->mode == SFM_WRITE)
+       {       /*  Now we know for certain the length of the file we can re-write
+               **      correct values for the FORM, 8SVX and BODY chunks.
+               */
+
+               } ;
+
+       return 0 ;
+} /* rx2_close */
+
+#endif
+/*
+** Do not edit or modify anything in this comment block.
+** The arch-tag line is a file identity tag for the GNU Arch 
+** revision control system.
+**
+** arch-tag: 7366e813-9fee-4d1f-881e-e4a691469370
+*/
diff --git a/libs/libsndfile/src/sd2.c b/libs/libsndfile/src/sd2.c
new file mode 100644 (file)
index 0000000..7ef4814
--- /dev/null
@@ -0,0 +1,613 @@
+/*
+** Copyright (C) 2001-2006 Erik de Castro Lopo <erikd@mega-nerd.com>
+** Copyright (C) 2004 Paavo Jumppanen
+**
+** This program is free software; you can redistribute it and/or modify
+** it under the terms of the GNU Lesser General Public License as published by
+** the Free Software Foundation; either version 2.1 of the License, or
+** (at your option) any later version.
+**
+** This program is distributed in the hope that it will be useful,
+** but WITHOUT ANY WARRANTY; without even the implied warranty of
+** MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+** GNU Lesser General Public License for more details.
+**
+** You should have received a copy of the GNU Lesser General Public License
+** along with this program; if not, write to the Free Software
+** Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA.
+*/
+
+/*
+** The sd2 support implemented in this file was partially sponsored
+** (financially) by Paavo Jumppanen.
+*/
+
+/*
+** Documentation on the Mac resource fork was obtained here :
+** http://developer.apple.com/documentation/mac/MoreToolbox/MoreToolbox-99.html
+*/
+
+#include       "sfconfig.h"
+
+#include       <stdio.h>
+#include       <stdlib.h>
+#include       <string.h>
+#include       <ctype.h>
+
+#include       "sndfile.h"
+#include       "sfendian.h"
+#include       "common.h"
+
+/*------------------------------------------------------------------------------
+ * Markers.
+*/
+
+#define        Sd2f_MARKER                     MAKE_MARKER ('S', 'd', '2', 'f')
+#define        Sd2a_MARKER                     MAKE_MARKER ('S', 'd', '2', 'a')
+#define        ALCH_MARKER                     MAKE_MARKER ('A', 'L', 'C', 'H')
+#define lsf1_MARKER                    MAKE_MARKER ('l', 's', 'f', '1')
+
+#define STR_MARKER                     MAKE_MARKER ('S', 'T', 'R', ' ')
+#define sdML_MARKER                    MAKE_MARKER ('s', 'd', 'M', 'L')
+
+enum
+{      RSRC_STR = 111,
+       RSRC_BIN
+} ;
+
+typedef struct
+{      unsigned char * rsrc_data ;
+       int rsrc_len ;
+
+       int data_offset, data_length ;
+       int map_offset, map_length ;
+
+       int type_count, type_offset ;
+       int item_offset ;
+
+       int str_index, str_count ;
+
+       int string_offset ;
+
+       /* All the above just to get these three. */
+       int sample_size, sample_rate, channels ;
+} SD2_RSRC ;
+
+typedef struct
+{      int type ;
+       int id ;
+       char name [32] ;
+       char value [32] ;
+       int value_len ;
+} STR_RSRC ;
+
+/*------------------------------------------------------------------------------
+ * Private static functions.
+*/
+
+static int sd2_close   (SF_PRIVATE *psf) ;
+
+static int sd2_parse_rsrc_fork (SF_PRIVATE *psf) ;
+static int parse_str_rsrc (SF_PRIVATE *psf, SD2_RSRC * rsrc) ;
+
+static int sd2_write_rsrc_fork (SF_PRIVATE *psf, int calc_length) ;
+
+/*------------------------------------------------------------------------------
+** Public functions.
+*/
+
+int
+sd2_open (SF_PRIVATE *psf)
+{      int subformat, error = 0, valid ;
+
+       /* SD2 is always big endian. */
+       psf->endian = SF_ENDIAN_BIG ;
+
+       if (psf->mode == SFM_READ || (psf->mode == SFM_RDWR && psf->rsrclength > 0))
+       {       psf_use_rsrc (psf, SF_TRUE) ;
+               valid = psf_file_valid (psf) ;
+               psf_use_rsrc (psf, SF_FALSE) ;
+               if (! valid)
+               {       psf_log_printf (psf, "sd2_open : psf->rsrcdes < 0\n") ;
+                       return SFE_SD2_BAD_RSRC ;
+                       } ;
+
+               error = sd2_parse_rsrc_fork (psf) ;
+
+               if (error)
+                       goto error_cleanup ;
+               } ;
+
+       if ((psf->sf.format & SF_FORMAT_TYPEMASK) != SF_FORMAT_SD2)
+       {       error = SFE_BAD_OPEN_FORMAT ;
+               goto error_cleanup ;
+               } ;
+
+       subformat = psf->sf.format & SF_FORMAT_SUBMASK ;
+       psf->dataoffset = 0 ;
+
+       /* Only open and write the resource in RDWR mode is its current length is zero. */
+       if (psf->mode == SFM_WRITE || (psf->mode == SFM_RDWR && psf->rsrclength == 0))
+       {       psf_open_rsrc (psf, psf->mode) ;
+
+               error = sd2_write_rsrc_fork (psf, SF_FALSE) ;
+
+               if (error)
+                       goto error_cleanup ;
+
+               /* Not needed. */
+               psf->write_header = NULL ;
+               } ;
+
+       psf->container_close = sd2_close ;
+
+       psf->blockwidth = psf->bytewidth * psf->sf.channels ;
+
+       switch (subformat)
+       {       case SF_FORMAT_PCM_S8 : /* 8-bit linear PCM. */
+               case SF_FORMAT_PCM_16 : /* 16-bit linear PCM. */
+               case SF_FORMAT_PCM_24 : /* 24-bit linear PCM */
+                               error = pcm_init (psf) ;
+                               break ;
+
+               default :
+                               error = SFE_UNIMPLEMENTED ;
+                               break ;
+               } ;
+
+       psf_fseek (psf, psf->dataoffset, SEEK_SET) ;
+
+error_cleanup:
+
+       /* Close the resource fork regardless. We won't need it again. */
+       psf_close_rsrc (psf) ;
+
+       return error ;
+} /* sd2_open */
+
+/*------------------------------------------------------------------------------
+*/
+
+static int
+sd2_close      (SF_PRIVATE *psf)
+{
+       if (psf->mode == SFM_WRITE)
+       {       /*  Now we know for certain the audio_length of the file we can re-write
+               **      correct values for the FORM, 8SVX and BODY chunks.
+               */
+
+               } ;
+
+       return 0 ;
+} /* sd2_close */
+
+/*------------------------------------------------------------------------------
+*/
+
+static inline void
+write_char (unsigned char * data, int offset, char value)
+{      data [offset] = value ;
+} /* write_char */
+
+static inline void
+write_short (unsigned char * data, int offset, short value)
+{      data [offset] = value >> 8 ;
+       data [offset + 1] = value ;
+} /* write_char */
+
+static inline void
+write_int (unsigned char * data, int offset, int value)
+{      data [offset] = value >> 24 ;
+       data [offset + 1] = value >> 16 ;
+       data [offset + 2] = value >> 8 ;
+       data [offset + 3] = value ;
+} /* write_int */
+
+static inline void
+write_marker (unsigned char * data, int offset, int value)
+{
+       if (CPU_IS_BIG_ENDIAN)
+       {       data [offset] = value >> 24 ;
+               data [offset + 1] = value >> 16 ;
+               data [offset + 2] = value >> 8 ;
+               data [offset + 3] = value ;
+               }
+       else
+       {       data [offset] = value ;
+               data [offset + 1] = value >> 8 ;
+               data [offset + 2] = value >> 16 ;
+               data [offset + 3] = value >> 24 ;
+               } ;
+} /* write_marker */
+
+static void
+write_str (unsigned char * data, int offset, char * buffer, int buffer_len)
+{      memcpy (data + offset, buffer, buffer_len) ;
+} /* write_str */
+
+static int
+sd2_write_rsrc_fork (SF_PRIVATE *psf, int UNUSED (calc_length))
+{      SD2_RSRC rsrc ;
+       STR_RSRC str_rsrc [] =
+       {       { RSRC_STR, 1000, "_sample-size", "", 0 },
+               { RSRC_STR, 1001, "_sample-rate", "", 0 },
+               { RSRC_STR, 1002, "_channels", "", 0 },
+               { RSRC_BIN, 1000, "_Markers", "", 8 }
+               } ;
+
+       int k, str_offset, data_offset, next_str ;
+
+       psf_use_rsrc (psf, SF_TRUE) ;
+
+       memset (&rsrc, 0, sizeof (rsrc)) ;
+
+       rsrc.sample_rate = psf->sf.samplerate ;
+       rsrc.sample_size = psf->bytewidth ;
+       rsrc.channels = psf->sf.channels ;
+
+       rsrc.rsrc_data = psf->header ;
+       rsrc.rsrc_len = sizeof (psf->header) ;
+       memset (rsrc.rsrc_data, 0xea, rsrc.rsrc_len) ;
+
+       LSF_SNPRINTF (str_rsrc [0].value, sizeof (str_rsrc [0].value), "_%d", rsrc.sample_size) ;
+       LSF_SNPRINTF (str_rsrc [1].value, sizeof (str_rsrc [1].value), "_%d.000000", rsrc.sample_rate) ;
+       LSF_SNPRINTF (str_rsrc [2].value, sizeof (str_rsrc [2].value), "_%d", rsrc.channels) ;
+
+       for (k = 0 ; k < ARRAY_LEN (str_rsrc) ; k++)
+       {       if (str_rsrc [k].value_len == 0)
+               {       str_rsrc [k].value_len = strlen (str_rsrc [k].value) ;
+                       str_rsrc [k].value [0] = str_rsrc [k].value_len - 1 ;
+                       } ;
+
+               /* Turn name string into a pascal string. */
+               str_rsrc [k].name [0] = strlen (str_rsrc [k].name) - 1 ;
+               } ;
+
+       rsrc.data_offset = 0x100 ;
+
+       /*
+       ** Calculate data length :
+       **              length of strings, plus the length of the sdML chunk.
+       */
+       rsrc.data_length = 0 ;
+       for (k = 0 ; k < ARRAY_LEN (str_rsrc) ; k++)
+               rsrc.data_length += str_rsrc [k].value_len + 4 ;
+
+       rsrc.map_offset = rsrc.data_offset + rsrc.data_length ;
+
+       /* Very start of resource fork. */
+       write_int (rsrc.rsrc_data, 0, rsrc.data_offset) ;
+       write_int (rsrc.rsrc_data, 4, rsrc.map_offset) ;
+       write_int (rsrc.rsrc_data, 8, rsrc.data_length) ;
+
+       write_char (rsrc.rsrc_data, 0x30, strlen (psf->filename)) ;
+       write_str (rsrc.rsrc_data, 0x31, psf->filename, strlen (psf->filename)) ;
+
+       write_short (rsrc.rsrc_data, 0x50, 0) ;
+       write_marker (rsrc.rsrc_data, 0x52, Sd2f_MARKER) ;
+       write_marker (rsrc.rsrc_data, 0x56, lsf1_MARKER) ;
+
+       /* Very start of resource map. */
+       write_int (rsrc.rsrc_data, rsrc.map_offset + 0, rsrc.data_offset) ;
+       write_int (rsrc.rsrc_data, rsrc.map_offset + 4, rsrc.map_offset) ;
+       write_int (rsrc.rsrc_data, rsrc.map_offset + 8, rsrc.data_length) ;
+
+       /* These I don't currently understand. */
+       if (1)
+       {       write_char (rsrc.rsrc_data, rsrc.map_offset+ 16, 1) ;
+               /* Next resource map. */
+               write_int (rsrc.rsrc_data, rsrc.map_offset + 17, 0x12345678) ;
+               /* File ref number. */
+               write_short (rsrc.rsrc_data, rsrc.map_offset + 21, 0xabcd) ;
+               /* Fork attributes. */
+               write_short (rsrc.rsrc_data, rsrc.map_offset + 23, 0) ;
+               } ;
+
+       /* Resource type offset. */
+       rsrc.type_offset = rsrc.map_offset + 30 ;
+       write_short (rsrc.rsrc_data, rsrc.map_offset + 24, rsrc.type_offset - rsrc.map_offset - 2) ;
+
+       /* Type index max. */
+       rsrc.type_count = 2 ;
+       write_short (rsrc.rsrc_data, rsrc.map_offset + 28, rsrc.type_count - 1) ;
+
+       rsrc.item_offset = rsrc.type_offset + rsrc.type_count * 8 ;
+
+       rsrc.str_count = ARRAY_LEN (str_rsrc) ;
+       rsrc.string_offset = rsrc.item_offset + (rsrc.str_count + 1) * 12 - rsrc.map_offset ;
+       write_short (rsrc.rsrc_data, rsrc.map_offset + 26, rsrc.string_offset) ;
+
+       /* Write 'STR ' resource type. */
+       rsrc.str_count = 3 ;
+       write_marker (rsrc.rsrc_data, rsrc.type_offset, STR_MARKER) ;
+       write_short (rsrc.rsrc_data, rsrc.type_offset + 4, rsrc.str_count - 1) ;
+       write_short (rsrc.rsrc_data, rsrc.type_offset + 6, 0x12) ;
+
+       /* Write 'sdML' resource type. */
+       write_marker (rsrc.rsrc_data, rsrc.type_offset + 8, sdML_MARKER) ;
+       write_short (rsrc.rsrc_data, rsrc.type_offset + 12, 0) ;
+       write_short (rsrc.rsrc_data, rsrc.type_offset + 14, 0x36) ;
+
+       str_offset = rsrc.map_offset + rsrc.string_offset ;
+       next_str = 0 ;
+       data_offset = rsrc.data_offset ;
+       for (k = 0 ; k < ARRAY_LEN (str_rsrc) ; k++)
+       {       write_str (rsrc.rsrc_data, str_offset, str_rsrc [k].name, strlen (str_rsrc [k].name)) ;
+
+               write_short (rsrc.rsrc_data, rsrc.item_offset + k * 12, str_rsrc [k].id) ;
+               write_short (rsrc.rsrc_data, rsrc.item_offset + k * 12 + 2, next_str) ;
+
+               str_offset += strlen (str_rsrc [k].name) ;
+               next_str += strlen (str_rsrc [k].name) ;
+
+               write_int (rsrc.rsrc_data, rsrc.item_offset + k * 12 + 4, data_offset - rsrc.data_offset) ;
+
+               write_int (rsrc.rsrc_data, data_offset, str_rsrc [k].value_len) ;
+               write_str (rsrc.rsrc_data, data_offset + 4, str_rsrc [k].value, str_rsrc [k].value_len) ;
+               data_offset += 4 + str_rsrc [k].value_len ;
+               } ;
+
+       /* Finally, calculate and set map length. */
+       rsrc.map_length = str_offset - rsrc.map_offset ;
+       write_int (rsrc.rsrc_data, 12, rsrc.map_length) ;
+       write_int (rsrc.rsrc_data, rsrc.map_offset + 12, rsrc.map_length) ;
+
+       rsrc.rsrc_len = rsrc.map_offset + rsrc.map_length ;
+
+       psf_fwrite (rsrc.rsrc_data, rsrc.rsrc_len, 1, psf) ;
+
+       psf_use_rsrc (psf, SF_FALSE) ;
+
+       if (psf->error)
+               return psf->error ;
+
+       return 0 ;
+} /* sd2_write_rsrc_fork */
+
+/*------------------------------------------------------------------------------
+*/
+
+static inline int
+read_char (const unsigned char * data, int offset)
+{      return data [offset] ;
+} /* read_char */
+
+static inline int
+read_short (const unsigned char * data, int offset)
+{      return (data [offset] << 8) + data [offset + 1] ;
+} /* read_short */
+
+static inline int
+read_int (const unsigned char * data, int offset)
+{      return (data [offset] << 24) + (data [offset + 1] << 16) + (data [offset + 2] << 8) + data [offset + 3] ;
+} /* read_int */
+
+static inline int
+read_marker (const unsigned char * data, int offset)
+{
+       if (CPU_IS_BIG_ENDIAN)
+               return (data [offset] << 24) + (data [offset + 1] << 16) + (data [offset + 2] << 8) + data [offset + 3] ;
+       else if (CPU_IS_LITTLE_ENDIAN)
+               return data [offset] + (data [offset + 1] << 8) + (data [offset + 2] << 16) + (data [offset + 3] << 24) ;
+       else
+               return 0x666 ;
+} /* read_marker */
+
+static void
+read_str (const unsigned char * data, int offset, char * buffer, int buffer_len)
+{      int k ;
+
+       memset (buffer, 0, buffer_len) ;
+
+       for (k = 0 ; k < buffer_len - 1 ; k++)
+       {       if (isprint (data [offset + k]) == 0)
+                       return ;
+               buffer [k] = data [offset + k] ;
+               } ;
+       return ;
+} /* read_str */
+
+static int
+sd2_parse_rsrc_fork (SF_PRIVATE *psf)
+{      SD2_RSRC rsrc ;
+       int k, marker, error = 0 ;
+
+       psf_use_rsrc (psf, SF_TRUE) ;
+
+       memset (&rsrc, 0, sizeof (rsrc)) ;
+
+       rsrc.rsrc_len = psf_get_filelen (psf) ;
+       psf_log_printf (psf, "Resource length : %d (0x%04X)\n", rsrc.rsrc_len, rsrc.rsrc_len) ;
+
+       if (rsrc.rsrc_len > SIGNED_SIZEOF (psf->header))
+               rsrc.rsrc_data = calloc (1, rsrc.rsrc_len) ;
+       else
+               rsrc.rsrc_data = psf->header ;
+
+       /* Read in the whole lot. */
+       psf_fread (rsrc.rsrc_data, rsrc.rsrc_len, 1, psf) ;
+
+       /* Reset the header storage because we have changed to the rsrcdes. */
+       psf->headindex = psf->headend = rsrc.rsrc_len ;
+
+       rsrc.data_offset = read_int (rsrc.rsrc_data, 0) ;
+       rsrc.map_offset = read_int (rsrc.rsrc_data, 4) ;
+       rsrc.data_length = read_int (rsrc.rsrc_data, 8) ;
+       rsrc.map_length = read_int (rsrc.rsrc_data, 12) ;
+
+       if (rsrc.data_offset == 0x51607 && rsrc.map_offset == 0x20000)
+       {       psf_log_printf (psf, "Trying offset of 0x52 bytes.\n") ;
+               rsrc.data_offset = read_int (rsrc.rsrc_data, 0x52 + 0) + 0x52 ;
+               rsrc.map_offset = read_int (rsrc.rsrc_data, 0x52 + 4) + 0x52 ;
+               rsrc.data_length = read_int (rsrc.rsrc_data, 0x52 + 8) ;
+               rsrc.map_length = read_int (rsrc.rsrc_data, 0x52 + 12) ;
+               } ;
+
+       psf_log_printf (psf, "  data offset : 0x%04X\n  map  offset : 0x%04X\n"
+                               "  data length : 0x%04X\n  map  length : 0x%04X\n",
+                               rsrc.data_offset, rsrc.map_offset, rsrc.data_length, rsrc.map_length) ;
+
+       if (rsrc.data_offset > rsrc.rsrc_len)
+       {       psf_log_printf (psf, "Error : rsrc.data_offset (%d, 0x%x) > len\n", rsrc.data_offset, rsrc.data_offset) ;
+               error = SFE_SD2_BAD_DATA_OFFSET ;
+               goto parse_rsrc_fork_cleanup ;
+               } ;
+
+       if (rsrc.map_offset > rsrc.rsrc_len)
+       {       psf_log_printf (psf, "Error : rsrc.map_offset > len\n") ;
+               error = SFE_SD2_BAD_MAP_OFFSET ;
+               goto parse_rsrc_fork_cleanup ;
+               } ;
+
+       if (rsrc.data_length > rsrc.rsrc_len)
+       {       psf_log_printf (psf, "Error : rsrc.data_length > len\n") ;
+               error = SFE_SD2_BAD_DATA_LENGTH ;
+               goto parse_rsrc_fork_cleanup ;
+               } ;
+
+       if (rsrc.map_length > rsrc.rsrc_len)
+       {       psf_log_printf (psf, "Error : rsrc.map_length > len\n") ;
+               error = SFE_SD2_BAD_MAP_LENGTH ;
+               goto parse_rsrc_fork_cleanup ;
+               } ;
+
+       if (rsrc.data_offset + rsrc.data_length != rsrc.map_offset || rsrc.map_offset + rsrc.map_length != rsrc.rsrc_len)
+       {       psf_log_printf (psf, "Error : This does not look like a MacOSX resource fork.\n") ;
+               error = SFE_SD2_BAD_RSRC ;
+               goto parse_rsrc_fork_cleanup ;
+               } ;
+
+       rsrc.string_offset = rsrc.map_offset + read_short (rsrc.rsrc_data, rsrc.map_offset + 26) ;
+       if (rsrc.string_offset > rsrc.rsrc_len)
+       {       psf_log_printf (psf, "Bad string offset (%d).\n", rsrc.string_offset) ;
+               error = SFE_SD2_BAD_RSRC ;
+               goto parse_rsrc_fork_cleanup ;
+               } ;
+
+       rsrc.type_offset = rsrc.map_offset + 30 ;
+
+       rsrc.type_count = read_short (rsrc.rsrc_data, rsrc.map_offset + 28) + 1 ;
+       if (rsrc.type_count < 1)
+       {       psf_log_printf (psf, "Bad type count.\n") ;
+               error = SFE_SD2_BAD_RSRC ;
+               goto parse_rsrc_fork_cleanup ;
+               } ;
+
+       rsrc.item_offset = rsrc.type_offset + rsrc.type_count * 8 ;
+       if (rsrc.item_offset < 0 || rsrc.item_offset > rsrc.rsrc_len)
+       {       psf_log_printf (psf, "Bad item offset (%d).\n", rsrc.item_offset) ;
+               error = SFE_SD2_BAD_RSRC ;
+               goto parse_rsrc_fork_cleanup ;
+               } ;
+
+       rsrc.str_index = -1 ;
+       for (k = 0 ; k < rsrc.type_count ; k ++)
+       {       marker = read_marker (rsrc.rsrc_data, rsrc.type_offset + k * 8) ;
+
+               if (marker == STR_MARKER)
+               {       rsrc.str_index = k ;
+                       rsrc.str_count = read_short (rsrc.rsrc_data, rsrc.type_offset + k * 8 + 4) + 1 ;
+                       error = parse_str_rsrc (psf, &rsrc) ;
+                       goto parse_rsrc_fork_cleanup ;
+                       } ;
+               } ;
+
+       psf_log_printf (psf, "No 'STR ' resource.\n") ;
+       error = SFE_SD2_BAD_RSRC ;
+
+parse_rsrc_fork_cleanup :
+
+       psf_use_rsrc (psf, SF_FALSE) ;
+
+       if ((void *) rsrc.rsrc_data < (void *) psf || (void *) rsrc.rsrc_data > (void *) (psf + 1))
+               free (rsrc.rsrc_data) ;
+
+       return error ;
+} /* sd2_parse_rsrc_fork */
+
+static int
+parse_str_rsrc (SF_PRIVATE *psf, SD2_RSRC * rsrc)
+{      char name [32], value [32] ;
+       int k, str_offset, data_offset, data_len, rsrc_id ;
+
+       psf_log_printf (psf, "Finding parameters :\n") ;
+
+       str_offset = rsrc->string_offset ;
+       for (k = 0 ; k < rsrc->str_count ; k++)
+       {       int slen ;
+
+               slen = read_char (rsrc->rsrc_data, str_offset) ;
+               read_str (rsrc->rsrc_data, str_offset + 1, name, SF_MIN (SIGNED_SIZEOF (name), slen + 1)) ;
+               str_offset += slen + 1 ;
+
+               rsrc_id = read_short (rsrc->rsrc_data, rsrc->item_offset + k * 12) ;
+
+               data_offset = rsrc->data_offset + read_int (rsrc->rsrc_data, rsrc->item_offset + k * 12 + 4) ;
+               if (data_offset < 0 || data_offset > rsrc->rsrc_len)
+               {       psf_log_printf (psf, "Bad data offset (%d)\n", data_offset) ;
+                       return SFE_SD2_BAD_DATA_OFFSET ;
+                       } ;
+
+               data_len = read_int (rsrc->rsrc_data, data_offset) ;
+               if (data_len < 0 || data_len > rsrc->rsrc_len)
+               {       psf_log_printf (psf, "Bad data length (%d).\n", data_len) ;
+                       return SFE_SD2_BAD_RSRC ;
+                       } ;
+
+               slen = read_char (rsrc->rsrc_data, data_offset + 4) ;
+               read_str (rsrc->rsrc_data, data_offset + 5, value, SF_MIN (SIGNED_SIZEOF (value), slen + 1)) ;
+
+               psf_log_printf (psf, "  %-12s   0x%04x    %4d    %2d    %2d    '%s'\n", name, data_offset, rsrc_id, data_len, slen, value) ;
+
+               if (strcmp (name, "sample-size") == 0 && rsrc->sample_size == 0)
+                       rsrc->sample_size = strtol (value, NULL, 10) ;
+               else if (strcmp (name, "sample-rate") == 0 && rsrc->sample_rate == 0)
+                       rsrc->sample_rate = strtol (value, NULL, 10) ;
+               else if (strcmp (name, "channels") == 0 && rsrc->channels == 0)
+                       rsrc->channels = strtol (value, NULL, 10) ;
+               } ;
+
+       if (rsrc->sample_rate < 0)
+       {       psf_log_printf (psf, "Bad sample rate (%d)\n", rsrc->sample_rate) ;
+               return SFE_SD2_BAD_RSRC ;
+               } ;
+
+       if (rsrc->channels < 0)
+       {       psf_log_printf (psf, "Bad channel count (%d)\n", rsrc->channels) ;
+               return SFE_SD2_BAD_RSRC ;
+               } ;
+
+       psf->sf.samplerate = rsrc->sample_rate ;
+       psf->sf.channels = rsrc->channels ;
+       psf->bytewidth = rsrc->sample_size ;
+
+       switch (rsrc->sample_size)
+       {       case 1 :
+                       psf->sf.format = SF_FORMAT_SD2 | SF_FORMAT_PCM_S8 ;
+                       break ;
+
+               case 2 :
+                       psf->sf.format = SF_FORMAT_SD2 | SF_FORMAT_PCM_16 ;
+                       break ;
+
+               case 3 :
+                       psf->sf.format = SF_FORMAT_SD2 | SF_FORMAT_PCM_24 ;
+                       break ;
+
+               default :
+                       psf_log_printf (psf, "Bad sample size (%d)\n", rsrc->sample_size) ;
+                       return SFE_SD2_BAD_SAMPLE_SIZE ;
+               } ;
+
+       psf_log_printf (psf, "ok\n") ;
+
+       return 0 ;
+} /* parse_str_rsrc */
+
+/*
+** Do not edit or modify anything in this comment block.
+** The arch-tag line is a file identity tag for the GNU Arch
+** revision control system.
+**
+** arch-tag: 1ee183e5-6b9f-4c2c-bd0a-24f35595cefc
+*/
diff --git a/libs/libsndfile/src/sds.c b/libs/libsndfile/src/sds.c
new file mode 100644 (file)
index 0000000..3769bf0
--- /dev/null
@@ -0,0 +1,993 @@
+/*
+** Copyright (C) 2002-2005 Erik de Castro Lopo <erikd@mega-nerd.com>
+**
+** This program is free software; you can redistribute it and/or modify
+** it under the terms of the GNU Lesser General Public License as published by
+** the Free Software Foundation; either version 2.1 of the License, or
+** (at your option) any later version.
+**
+** This program is distributed in the hope that it will be useful,
+** but WITHOUT ANY WARRANTY; without even the implied warranty of
+** MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+** GNU Lesser General Public License for more details.
+**
+** You should have received a copy of the GNU Lesser General Public License
+** along with this program; if not, write to the Free Software
+** Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA.
+*/
+
+#include "sfconfig.h"
+
+#include <stdio.h>
+#include <stdlib.h>
+#include <fcntl.h>
+#include <string.h>
+#include <ctype.h>
+
+#include "sndfile.h"
+#include "sfendian.h"
+#include "common.h"
+#include "float_cast.h"
+
+/*------------------------------------------------------------------------------
+*/
+
+#define        SDS_DATA_OFFSET                         0x15
+#define SDS_BLOCK_SIZE                         127
+
+#define SDS_AUDIO_BYTES_PER_BLOCK      120
+
+#define SDS_3BYTE_TO_INT_DECODE(x) (((x) & 0x7F) | (((x) & 0x7F00) >> 1) | (((x) & 0x7F0000) >> 2))
+#define SDS_INT_TO_3BYTE_ENCODE(x) (((x) & 0x7F) | (((x) << 1) & 0x7F00) | (((x) << 2) & 0x7F0000))
+
+/*------------------------------------------------------------------------------
+** Typedefs.
+*/
+
+typedef struct tag_SDS_PRIVATE
+{      int bitwidth, frames ;
+       int     samplesperblock, total_blocks ;
+
+       int (*reader) (SF_PRIVATE *psf, struct tag_SDS_PRIVATE *psds) ;
+       int (*writer) (SF_PRIVATE *psf, struct tag_SDS_PRIVATE *psds) ;
+
+       int read_block, read_count ;
+       unsigned char read_data [SDS_BLOCK_SIZE] ;
+       int     read_samples [SDS_BLOCK_SIZE / 2] ; /* Maximum samples per block */
+
+       int write_block, write_count ;
+       unsigned char write_data [SDS_BLOCK_SIZE] ;
+       int     write_samples [SDS_BLOCK_SIZE / 2] ; /* Maximum samples per block */
+} SDS_PRIVATE ;
+
+/*------------------------------------------------------------------------------
+** Private static functions.
+*/
+
+static int     sds_close       (SF_PRIVATE *psf) ;
+
+static int     sds_write_header (SF_PRIVATE *psf, int calc_length) ;
+static int     sds_read_header (SF_PRIVATE *psf, SDS_PRIVATE *psds) ;
+
+static int     sds_init (SF_PRIVATE *psf, SDS_PRIVATE *psds) ;
+
+static sf_count_t sds_read_s (SF_PRIVATE *psf, short *ptr, sf_count_t len) ;
+static sf_count_t sds_read_i (SF_PRIVATE *psf, int *ptr, sf_count_t len) ;
+static sf_count_t sds_read_f (SF_PRIVATE *psf, float *ptr, sf_count_t len) ;
+static sf_count_t sds_read_d (SF_PRIVATE *psf, double *ptr, sf_count_t len) ;
+
+static sf_count_t sds_write_s (SF_PRIVATE *psf, const short *ptr, sf_count_t len) ;
+static sf_count_t sds_write_i (SF_PRIVATE *psf, const int *ptr, sf_count_t len) ;
+static sf_count_t sds_write_f (SF_PRIVATE *psf, const float *ptr, sf_count_t len) ;
+static sf_count_t sds_write_d (SF_PRIVATE *psf, const double *ptr, sf_count_t len) ;
+
+static sf_count_t sds_seek (SF_PRIVATE *psf, int mode, sf_count_t offset) ;
+
+static int sds_2byte_read (SF_PRIVATE *psf, SDS_PRIVATE *psds) ;
+static int sds_3byte_read (SF_PRIVATE *psf, SDS_PRIVATE *psds) ;
+static int sds_4byte_read (SF_PRIVATE *psf, SDS_PRIVATE *psds) ;
+
+static int sds_read (SF_PRIVATE *psf, SDS_PRIVATE *psds, int *iptr, int readcount) ;
+
+static int sds_2byte_write (SF_PRIVATE *psf, SDS_PRIVATE *psds) ;
+static int sds_3byte_write (SF_PRIVATE *psf, SDS_PRIVATE *psds) ;
+static int sds_4byte_write (SF_PRIVATE *psf, SDS_PRIVATE *psds) ;
+
+static int sds_write (SF_PRIVATE *psf, SDS_PRIVATE *psds, const int *iptr, int writecount) ;
+
+/*------------------------------------------------------------------------------
+** Public function.
+*/
+
+int
+sds_open       (SF_PRIVATE *psf)
+{      SDS_PRIVATE     *psds ;
+       int                     error = 0 ;
+
+       /* Hmmmm, need this here to pass update_header_test. */
+       psf->sf.frames = 0 ;
+
+       if (! (psds = calloc (1, sizeof (SDS_PRIVATE))))
+               return SFE_MALLOC_FAILED ;
+       psf->fdata = psds ;
+
+       if (psf->mode == SFM_READ || (psf->mode == SFM_RDWR && psf->filelength > 0))
+       {       if ((error = sds_read_header (psf, psds)))
+                       return error ;
+               } ;
+
+       if ((psf->sf.format & SF_FORMAT_TYPEMASK) != SF_FORMAT_SDS)
+               return  SFE_BAD_OPEN_FORMAT ;
+
+       if (psf->mode == SFM_WRITE || psf->mode == SFM_RDWR)
+       {       if (sds_write_header (psf, SF_FALSE))
+                       return psf->error ;
+
+               psf->write_header = sds_write_header ;
+
+               psf_fseek (psf, SDS_DATA_OFFSET, SEEK_SET) ;
+               } ;
+
+       if ((error = sds_init (psf, psds)) != 0)
+               return error ;
+
+       psf->seek = sds_seek ;
+       psf->container_close = sds_close ;
+
+       psf->blockwidth = 0 ;
+
+       return error ;
+} /* sds_open */
+
+/*------------------------------------------------------------------------------
+*/
+
+static int
+sds_close      (SF_PRIVATE *psf)
+{
+       if (psf->mode == SFM_WRITE || psf->mode == SFM_RDWR)
+       {       SDS_PRIVATE *psds ;
+
+               if ((psds = (SDS_PRIVATE *) psf->fdata) == NULL)
+               {       psf_log_printf (psf, "*** Bad psf->fdata ptr.\n") ;
+                       return SFE_INTERNAL ;
+                       } ;
+
+               if (psds->write_count > 0)
+               {       memset (&(psds->write_data [psds->write_count]), 0, (psds->samplesperblock - psds->write_count) * sizeof (int)) ;
+                       psds->writer (psf, psds) ;
+                       } ;
+
+               sds_write_header (psf, SF_TRUE) ;
+               } ;
+
+       return 0 ;
+} /* sds_close */
+
+static int
+sds_init (SF_PRIVATE *psf, SDS_PRIVATE *psds)
+{
+       if (psds->bitwidth < 8 || psds->bitwidth > 28)
+               return (psf->error = SFE_SDS_BAD_BIT_WIDTH) ;
+
+       if (psds->bitwidth < 14)
+       {       psds->reader = sds_2byte_read ;
+               psds->writer = sds_2byte_write ;
+               psds->samplesperblock = SDS_AUDIO_BYTES_PER_BLOCK / 2 ;
+               }
+       else if (psds->bitwidth < 21)
+       {       psds->reader = sds_3byte_read ;
+               psds->writer = sds_3byte_write ;
+               psds->samplesperblock = SDS_AUDIO_BYTES_PER_BLOCK / 3 ;
+               }
+       else
+       {       psds->reader = sds_4byte_read ;
+               psds->writer = sds_4byte_write ;
+               psds->samplesperblock = SDS_AUDIO_BYTES_PER_BLOCK / 4 ;
+               } ;
+
+       if (psf->mode == SFM_READ || psf->mode == SFM_RDWR)
+       {       psf->read_short         = sds_read_s ;
+               psf->read_int           = sds_read_i ;
+               psf->read_float         = sds_read_f ;
+               psf->read_double        = sds_read_d ;
+
+               /* Read first block. */
+               psds->reader (psf, psds) ;
+               } ;
+
+       if (psf->mode == SFM_WRITE || psf->mode == SFM_RDWR)
+       {       psf->write_short        = sds_write_s ;
+               psf->write_int          = sds_write_i ;
+               psf->write_float        = sds_write_f ;
+               psf->write_double       = sds_write_d ;
+               } ;
+
+       return 0 ;
+} /* sds_init */
+
+static int
+sds_read_header (SF_PRIVATE *psf, SDS_PRIVATE *psds)
+{      unsigned char   channel, bitwidth, loop_type, byte ;
+       unsigned short  sample_no, marker ;
+       unsigned int    samp_period, data_length, sustain_loop_start, sustain_loop_end ;
+       int             bytesread, blockcount ;
+
+       /* Set position to start of file to begin reading header. */
+       bytesread = psf_binheader_readf (psf, "pE211", 0, &marker, &channel, &byte) ;
+
+       if (marker != 0xF07E || byte != 0x01)
+               return SFE_SDS_NOT_SDS ;
+
+       psf_log_printf (psf, "Midi Sample Dump Standard (.sds)\nF07E\n Midi Channel  : %d\n", channel) ;
+
+       bytesread += psf_binheader_readf (psf, "e213", &sample_no, &bitwidth, &samp_period) ;
+
+       sample_no = SDS_3BYTE_TO_INT_DECODE (sample_no) ;
+       samp_period = SDS_3BYTE_TO_INT_DECODE (samp_period) ;
+
+       psds->bitwidth = bitwidth ;
+
+       psf->sf.samplerate = 1000000000 / samp_period ;
+
+       psf_log_printf (psf,    " Sample Number : %d\n"
+                                                       " Bit Width     : %d\n"
+                                                       " Sample Rate   : %d\n",
+                       sample_no, psds->bitwidth, psf->sf.samplerate) ;
+
+       bytesread += psf_binheader_readf (psf, "e3331", &data_length, &sustain_loop_start, &sustain_loop_end, &loop_type) ;
+
+       data_length = SDS_3BYTE_TO_INT_DECODE (data_length) ;
+
+       sustain_loop_start = SDS_3BYTE_TO_INT_DECODE (sustain_loop_start) ;
+       sustain_loop_end = SDS_3BYTE_TO_INT_DECODE (sustain_loop_end) ;
+
+       psf_log_printf (psf,    " Sustain Loop\n"
+                                                       "     Start     : %d\n"
+                                                       "     End       : %d\n"
+                                                       "     Loop Type : %d\n",
+                       sustain_loop_start, sustain_loop_end, loop_type) ;
+
+       psf->dataoffset = SDS_DATA_OFFSET ;
+       psf->datalength = psf->filelength - psf->dataoffset ;
+
+       if (data_length != psf->filelength - psf->dataoffset)
+       {       psf_log_printf (psf, " Datalength     : %d (truncated data??? %d)\n", data_length, psf->filelength - psf->dataoffset) ;
+               data_length = psf->filelength - psf->dataoffset ;
+               }
+       else
+               psf_log_printf (psf, " Datalength     : %d\n", data_length) ;
+
+       bytesread += psf_binheader_readf (psf, "1", &byte) ;
+       if (byte != 0xF7)
+               psf_log_printf (psf, "bad end : %X\n", byte & 0xFF) ;
+
+       for (blockcount = 0 ; bytesread < psf->filelength ; blockcount++)
+       {
+               bytesread += psf_fread (&marker, 1, 2, psf) ;
+
+               if (marker == 0)
+                       break ;
+
+               psf_fseek (psf, SDS_BLOCK_SIZE - 2, SEEK_CUR) ;
+               bytesread += SDS_BLOCK_SIZE - 2 ;
+               } ;
+
+       psf_log_printf (psf, "\nBlocks         : %d\n", blockcount) ;
+       psds->total_blocks = blockcount ;
+
+       psds->samplesperblock = SDS_AUDIO_BYTES_PER_BLOCK / ((psds->bitwidth + 6) / 7) ;
+       psf_log_printf (psf, "Samples/Block  : %d\n", psds->samplesperblock) ;
+
+       psf_log_printf (psf, "Frames         : %d\n", blockcount * psds->samplesperblock) ;
+
+       psf->sf.frames = blockcount * psds->samplesperblock ;
+       psds->frames = blockcount * psds->samplesperblock ;
+
+       /* Always Mono */
+       psf->sf.channels = 1 ;
+       psf->sf.sections = 1 ;
+
+       /*
+       ** Lie to the user about PCM bit width. Always round up to
+       ** the next multiple of 8.
+       */
+       switch ((psds->bitwidth + 7) / 8)
+       {       case 1 :
+                       psf->sf.format = SF_FORMAT_SDS | SF_FORMAT_PCM_S8 ;
+                       break ;
+
+               case 2 :
+                       psf->sf.format = SF_FORMAT_SDS | SF_FORMAT_PCM_16 ;
+                       break ;
+
+               case 3 :
+                       psf->sf.format = SF_FORMAT_SDS | SF_FORMAT_PCM_24 ;
+                       break ;
+
+               case 4 :
+                       psf->sf.format = SF_FORMAT_SDS | SF_FORMAT_PCM_32 ;
+                       break ;
+
+               default :
+                       psf_log_printf (psf, "*** Weird byte width (%d)\n", (psds->bitwidth + 7) / 8) ;
+                       return SFE_SDS_BAD_BIT_WIDTH ;
+               } ;
+
+       psf_fseek (psf, SDS_DATA_OFFSET, SEEK_SET) ;
+
+       return 0 ;
+} /* sds_read_header */
+
+static int
+sds_write_header (SF_PRIVATE *psf, int calc_length)
+{      SDS_PRIVATE *psds ;
+       sf_count_t      current ;
+       int samp_period, data_length, sustain_loop_start, sustain_loop_end ;
+       unsigned char loop_type = 0 ;
+
+       if ((psds = (SDS_PRIVATE *) psf->fdata) == NULL)
+       {       psf_log_printf (psf, "*** Bad psf->fdata ptr.\n") ;
+               return SFE_INTERNAL ;
+               } ;
+
+       if (psf->pipeoffset > 0)
+               return 0 ;
+
+       current = psf_ftell (psf) ;
+
+       if (calc_length)
+               psf->sf.frames = psds->total_blocks * psds->samplesperblock + psds->write_count ;
+
+       if (psds->write_count > 0)
+       {       int current_count = psds->write_count ;
+               int current_block = psds->write_block ;
+
+               psds->writer (psf, psds) ;
+
+               psf_fseek (psf, -1 * SDS_BLOCK_SIZE, SEEK_CUR) ;
+
+               psds->write_count = current_count ;
+               psds->write_block = current_block ;
+               } ;
+
+       /* Reset the current header length to zero. */
+       psf->header [0] = 0 ;
+       psf->headindex = 0 ;
+
+       if (psf->is_pipe == SF_FALSE)
+               psf_fseek (psf, 0, SEEK_SET) ;
+
+       psf_binheader_writef (psf, "E211", 0xF07E, 0, 1) ;
+
+       switch (psf->sf.format & SF_FORMAT_SUBMASK)
+       {       case SF_FORMAT_PCM_S8 :
+                               psds->bitwidth = 8 ;
+                               break ;
+               case SF_FORMAT_PCM_16 :
+                               psds->bitwidth = 16 ;
+                               break ;
+               case SF_FORMAT_PCM_24 :
+                               psds->bitwidth = 24 ;
+                               break ;
+               default:
+                       return SFE_SDS_BAD_BIT_WIDTH ;
+               } ;
+
+       samp_period = SDS_INT_TO_3BYTE_ENCODE (1000000000 / psf->sf.samplerate) ;
+
+       psf_binheader_writef (psf, "e213", 0, psds->bitwidth, samp_period) ;
+
+       data_length                     = SDS_INT_TO_3BYTE_ENCODE (psds->total_blocks * SDS_BLOCK_SIZE) ;
+       sustain_loop_start      = SDS_INT_TO_3BYTE_ENCODE (0) ;
+       sustain_loop_end        = SDS_INT_TO_3BYTE_ENCODE (psf->sf.frames) ;
+
+       psf_binheader_writef (psf, "e33311", data_length, sustain_loop_start, sustain_loop_end, loop_type, 0xF7) ;
+
+       /* Header construction complete so write it out. */
+       psf_fwrite (psf->header, psf->headindex, 1, psf) ;
+
+       if (psf->error)
+               return psf->error ;
+
+       psf->dataoffset = psf->headindex ;
+       psf->datalength = psds->write_block * SDS_BLOCK_SIZE ;
+
+       if (current > 0)
+               psf_fseek (psf, current, SEEK_SET) ;
+
+       return psf->error ;
+} /* sds_write_header */
+
+
+/*------------------------------------------------------------------------------
+*/
+
+static int
+sds_2byte_read (SF_PRIVATE *psf, SDS_PRIVATE *psds)
+{      unsigned char *ucptr, checksum ;
+       unsigned int sample ;
+       int     k ;
+
+       psds->read_block ++ ;
+       psds->read_count = 0 ;
+
+       if (psds->read_block * psds->samplesperblock > psds->frames)
+       {       memset (psds->read_samples, 0, psds->samplesperblock * sizeof (int)) ;
+               return 1 ;
+               } ;
+
+       if ((k = psf_fread (psds->read_data, 1, SDS_BLOCK_SIZE, psf)) != SDS_BLOCK_SIZE)
+               psf_log_printf (psf, "*** Warning : short read (%d != %d).\n", k, SDS_BLOCK_SIZE) ;
+
+       if (psds->read_data [0] != 0xF0)
+       {       printf ("Error A : %02X\n", psds->read_data [0] & 0xFF) ;
+               } ;
+
+       checksum = psds->read_data [1] ;
+       if (checksum != 0x7E)
+       {       printf ("Error 1 : %02X\n", checksum & 0xFF) ;
+               }
+
+       for (k = 2 ; k < SDS_BLOCK_SIZE - 3 ; k ++)
+               checksum ^= psds->read_data [k] ;
+
+       checksum &= 0x7F ;
+
+       if (checksum != psds->read_data [SDS_BLOCK_SIZE - 2])
+       {       psf_log_printf (psf, "Block %d : checksum is %02X should be %02X\n", psds->read_data [4], checksum, psds->read_data [SDS_BLOCK_SIZE - 2]) ;
+               } ;
+
+       ucptr = psds->read_data + 5 ;
+       for (k = 0 ; k < 120 ; k += 2)
+       {       sample = (ucptr [k] << 25) + (ucptr [k + 1] << 18) ;
+               psds->read_samples [k / 2] = (int) (sample - 0x80000000) ;
+               } ;
+
+       return 1 ;
+} /* sds_2byte_read */
+
+static int
+sds_3byte_read (SF_PRIVATE *psf, SDS_PRIVATE *psds)
+{      unsigned char *ucptr, checksum ;
+       unsigned int sample ;
+       int     k ;
+
+       psds->read_block ++ ;
+       psds->read_count = 0 ;
+
+       if (psds->read_block * psds->samplesperblock > psds->frames)
+       {       memset (psds->read_samples, 0, psds->samplesperblock * sizeof (int)) ;
+               return 1 ;
+               } ;
+
+       if ((k = psf_fread (psds->read_data, 1, SDS_BLOCK_SIZE, psf)) != SDS_BLOCK_SIZE)
+               psf_log_printf (psf, "*** Warning : short read (%d != %d).\n", k, SDS_BLOCK_SIZE) ;
+
+       if (psds->read_data [0] != 0xF0)
+       {       printf ("Error A : %02X\n", psds->read_data [0] & 0xFF) ;
+               } ;
+
+       checksum = psds->read_data [1] ;
+       if (checksum != 0x7E)
+       {       printf ("Error 1 : %02X\n", checksum & 0xFF) ;
+               }
+
+       for (k = 2 ; k < SDS_BLOCK_SIZE - 3 ; k ++)
+               checksum ^= psds->read_data [k] ;
+
+       checksum &= 0x7F ;
+
+       if (checksum != psds->read_data [SDS_BLOCK_SIZE - 2])
+       {       psf_log_printf (psf, "Block %d : checksum is %02X should be %02X\n", psds->read_data [4], checksum, psds->read_data [SDS_BLOCK_SIZE - 2]) ;
+               } ;
+
+       ucptr = psds->read_data + 5 ;
+       for (k = 0 ; k < 120 ; k += 3)
+       {       sample = (ucptr [k] << 25) + (ucptr [k + 1] << 18) + (ucptr [k + 2] << 11) ;
+               psds->read_samples [k / 3] = (int) (sample - 0x80000000) ;
+               } ;
+
+       return 1 ;
+} /* sds_3byte_read */
+
+static int
+sds_4byte_read (SF_PRIVATE *psf, SDS_PRIVATE *psds)
+{      unsigned char *ucptr, checksum ;
+       unsigned int sample ;
+       int     k ;
+
+       psds->read_block ++ ;
+       psds->read_count = 0 ;
+
+       if (psds->read_block * psds->samplesperblock > psds->frames)
+       {       memset (psds->read_samples, 0, psds->samplesperblock * sizeof (int)) ;
+               return 1 ;
+               } ;
+
+       if ((k = psf_fread (psds->read_data, 1, SDS_BLOCK_SIZE, psf)) != SDS_BLOCK_SIZE)
+               psf_log_printf (psf, "*** Warning : short read (%d != %d).\n", k, SDS_BLOCK_SIZE) ;
+
+       if (psds->read_data [0] != 0xF0)
+       {       printf ("Error A : %02X\n", psds->read_data [0] & 0xFF) ;
+               } ;
+
+       checksum = psds->read_data [1] ;
+       if (checksum != 0x7E)
+       {       printf ("Error 1 : %02X\n", checksum & 0xFF) ;
+               }
+
+       for (k = 2 ; k < SDS_BLOCK_SIZE - 3 ; k ++)
+               checksum ^= psds->read_data [k] ;
+
+       checksum &= 0x7F ;
+
+       if (checksum != psds->read_data [SDS_BLOCK_SIZE - 2])
+       {       psf_log_printf (psf, "Block %d : checksum is %02X should be %02X\n", psds->read_data [4], checksum, psds->read_data [SDS_BLOCK_SIZE - 2]) ;
+               } ;
+
+       ucptr = psds->read_data + 5 ;
+       for (k = 0 ; k < 120 ; k += 4)
+       {       sample = (ucptr [k] << 25) + (ucptr [k + 1] << 18) + (ucptr [k + 2] << 11) + (ucptr [k + 3] << 4) ;
+               psds->read_samples [k / 4] = (int) (sample - 0x80000000) ;
+               } ;
+
+       return 1 ;
+} /* sds_4byte_read */
+
+
+static sf_count_t
+sds_read_s (SF_PRIVATE *psf, short *ptr, sf_count_t len)
+{      SDS_PRIVATE     *psds ;
+       int                     *iptr ;
+       int                     k, bufferlen, readcount, count ;
+       sf_count_t      total = 0 ;
+
+       if (psf->fdata == NULL)
+               return 0 ;
+       psds = (SDS_PRIVATE*) psf->fdata ;
+
+       iptr = psf->u.ibuf ;
+       bufferlen = ARRAY_LEN (psf->u.ibuf) ;
+       while (len > 0)
+       {       readcount = (len >= bufferlen) ? bufferlen : len ;
+               count = sds_read (psf, psds, iptr, readcount) ;
+               for (k = 0 ; k < readcount ; k++)
+                       ptr [total + k] = iptr [k] >> 16 ;
+               total += count ;
+               len -= readcount ;
+               } ;
+
+       return total ;
+} /* sds_read_s */
+
+static sf_count_t
+sds_read_i (SF_PRIVATE *psf, int *ptr, sf_count_t len)
+{      SDS_PRIVATE *psds ;
+       int                     total ;
+
+       if (psf->fdata == NULL)
+               return 0 ;
+       psds = (SDS_PRIVATE*) psf->fdata ;
+
+       total = sds_read (psf, psds, ptr, len) ;
+
+       return total ;
+} /* sds_read_i */
+
+static sf_count_t
+sds_read_f (SF_PRIVATE *psf, float *ptr, sf_count_t len)
+{      SDS_PRIVATE     *psds ;
+       int                     *iptr ;
+       int                     k, bufferlen, readcount, count ;
+       sf_count_t      total = 0 ;
+       float           normfact ;
+
+       if (psf->fdata == NULL)
+               return 0 ;
+       psds = (SDS_PRIVATE*) psf->fdata ;
+
+       if (psf->norm_float == SF_TRUE)
+               normfact = 1.0 / 0x80000000 ;
+       else
+               normfact = 1.0 / (1 << psds->bitwidth) ;
+
+       iptr = psf->u.ibuf ;
+       bufferlen = ARRAY_LEN (psf->u.ibuf) ;
+       while (len > 0)
+       {       readcount = (len >= bufferlen) ? bufferlen : len ;
+               count = sds_read (psf, psds, iptr, readcount) ;
+               for (k = 0 ; k < readcount ; k++)
+                       ptr [total + k] = normfact * iptr [k] ;
+               total += count ;
+               len -= readcount ;
+               } ;
+
+       return total ;
+} /* sds_read_f */
+
+static sf_count_t
+sds_read_d (SF_PRIVATE *psf, double *ptr, sf_count_t len)
+{      SDS_PRIVATE     *psds ;
+       int                     *iptr ;
+       int                     k, bufferlen, readcount, count ;
+       sf_count_t      total = 0 ;
+       double          normfact ;
+
+       if (psf->fdata == NULL)
+               return 0 ;
+       psds = (SDS_PRIVATE*) psf->fdata ;
+
+       if (psf->norm_double == SF_TRUE)
+               normfact = 1.0 / 0x80000000 ;
+       else
+               normfact = 1.0 / (1 << psds->bitwidth) ;
+
+       iptr = psf->u.ibuf ;
+       bufferlen = ARRAY_LEN (psf->u.ibuf) ;
+       while (len > 0)
+       {       readcount = (len >= bufferlen) ? bufferlen : len ;
+               count = sds_read (psf, psds, iptr, readcount) ;
+               for (k = 0 ; k < readcount ; k++)
+                       ptr [total + k] = normfact * iptr [k] ;
+               total += count ;
+               len -= readcount ;
+               } ;
+
+       return total ;
+} /* sds_read_d */
+
+static int
+sds_read (SF_PRIVATE *psf, SDS_PRIVATE *psds, int *ptr, int len)
+{      int     count, total = 0 ;
+
+       while (total < len)
+       {       if (psds->read_block * psds->samplesperblock >= psds->frames)
+               {       memset (&(ptr [total]), 0, (len - total) * sizeof (int)) ;
+                       return total ;
+                       } ;
+
+               if (psds->read_count >= psds->samplesperblock)
+                       psds->reader (psf, psds) ;
+
+               count = (psds->samplesperblock - psds->read_count) ;
+               count = (len - total > count) ? count : len - total ;
+
+               memcpy (&(ptr [total]), &(psds->read_samples [psds->read_count]), count * sizeof (int)) ;
+               total += count ;
+               psds->read_count += count ;
+               } ;
+
+       return total ;
+} /* sds_read */
+
+/*==============================================================================
+*/
+
+static sf_count_t
+sds_seek (SF_PRIVATE *psf, int mode, sf_count_t seek_from_start)
+{      SDS_PRIVATE     *psds ;
+       sf_count_t      file_offset ;
+       int                     newblock, newsample ;
+
+       if ((psds = psf->fdata) == NULL)
+       {       psf->error = SFE_INTERNAL ;
+               return PSF_SEEK_ERROR ;
+               } ;
+
+       if (psf->datalength < 0 || psf->dataoffset < 0)
+       {       psf->error = SFE_BAD_SEEK ;
+               return PSF_SEEK_ERROR ;
+               } ;
+
+       if (seek_from_start < 0 || seek_from_start > psf->sf.frames)
+       {       psf->error = SFE_BAD_SEEK ;
+               return PSF_SEEK_ERROR ;
+               } ;
+
+       if (mode == SFM_READ && psds->write_count > 0)
+               psds->writer (psf, psds) ;
+
+       newblock = seek_from_start / psds->samplesperblock ;
+       newsample = seek_from_start % psds->samplesperblock ;
+
+       switch (mode)
+       {       case SFM_READ :
+                       if (newblock > psds->total_blocks)
+                       {       psf->error = SFE_BAD_SEEK ;
+                               return PSF_SEEK_ERROR ;
+                               } ;
+
+                       file_offset = psf->dataoffset + newblock * SDS_BLOCK_SIZE ;
+
+                       if (psf_fseek (psf, file_offset, SEEK_SET) != file_offset)
+                       {       psf->error = SFE_SEEK_FAILED ;
+                               return PSF_SEEK_ERROR ;
+                               } ;
+
+                       psds->read_block = newblock ;
+                       psds->reader (psf, psds) ;
+                       psds->read_count = newsample ;
+                       break ;
+
+               case SFM_WRITE :
+                       if (newblock > psds->total_blocks)
+                       {       psf->error = SFE_BAD_SEEK ;
+                               return PSF_SEEK_ERROR ;
+                               } ;
+
+                       file_offset = psf->dataoffset + newblock * SDS_BLOCK_SIZE ;
+
+                       if (psf_fseek (psf, file_offset, SEEK_SET) != file_offset)
+                       {       psf->error = SFE_SEEK_FAILED ;
+                               return PSF_SEEK_ERROR ;
+                               } ;
+
+                       psds->write_block = newblock ;
+                       psds->reader (psf, psds) ;
+                       psds->write_count = newsample ;
+                       break ;
+
+               default :
+                       psf->error = SFE_BAD_SEEK ;
+                       return PSF_SEEK_ERROR ;
+                       break ;
+               } ;
+
+       return seek_from_start ;
+} /* sds_seek */
+
+/*==============================================================================
+*/
+
+static int
+sds_2byte_write (SF_PRIVATE *psf, SDS_PRIVATE *psds)
+{      unsigned char *ucptr, checksum ;
+       unsigned int sample ;
+       int     k ;
+
+       psds->write_data [0] = 0xF0 ;
+       psds->write_data [1] = 0x7E ;
+       psds->write_data [2] = 0 ;                                                      /* Channel number */
+       psds->write_data [3] = psds->write_block & 0x7F ;       /* Packet number */
+
+       ucptr = psds->write_data + 5 ;
+       for (k = 0 ; k < 120 ; k += 2)
+       {       sample = psds->write_samples [k / 2] ;
+               sample += 0x80000000 ;
+               ucptr [k] = (sample >> 25) & 0x7F ;
+               ucptr [k + 1] = (sample >> 18) & 0x7F ;
+               } ;
+
+       checksum = psds->write_data [1] ;
+       for (k = 2 ; k < SDS_BLOCK_SIZE - 3 ; k ++)
+               checksum ^= psds->write_data [k] ;
+       checksum &= 0x7F ;
+
+       psds->write_data [SDS_BLOCK_SIZE - 2] = checksum ;
+       psds->write_data [SDS_BLOCK_SIZE - 1] = 0xF7 ;
+
+       if ((k = psf_fwrite (psds->write_data, 1, SDS_BLOCK_SIZE, psf)) != SDS_BLOCK_SIZE)
+               psf_log_printf (psf, "*** Warning : psf_fwrite (%d != %d).\n", k, SDS_BLOCK_SIZE) ;
+
+       psds->write_block ++ ;
+       psds->write_count = 0 ;
+
+       if (psds->write_block > psds->total_blocks)
+               psds->total_blocks = psds->write_block ;
+       psds->frames = psds->total_blocks * psds->samplesperblock ;
+
+       return 1 ;
+} /* sds_2byte_write */
+
+static int
+sds_3byte_write (SF_PRIVATE *psf, SDS_PRIVATE *psds)
+{      unsigned char *ucptr, checksum ;
+       unsigned int sample ;
+       int     k ;
+
+       psds->write_data [0] = 0xF0 ;
+       psds->write_data [1] = 0x7E ;
+       psds->write_data [2] = 0 ;                                                      /* Channel number */
+       psds->write_data [3] = psds->write_block & 0x7F ;       /* Packet number */
+
+       ucptr = psds->write_data + 5 ;
+       for (k = 0 ; k < 120 ; k += 3)
+       {       sample = psds->write_samples [k / 3] ;
+               sample += 0x80000000 ;
+               ucptr [k] = (sample >> 25) & 0x7F ;
+               ucptr [k + 1] = (sample >> 18) & 0x7F ;
+               ucptr [k + 2] = (sample >> 11) & 0x7F ;
+               } ;
+
+       checksum = psds->write_data [1] ;
+       for (k = 2 ; k < SDS_BLOCK_SIZE - 3 ; k ++)
+               checksum ^= psds->write_data [k] ;
+       checksum &= 0x7F ;
+
+       psds->write_data [SDS_BLOCK_SIZE - 2] = checksum ;
+       psds->write_data [SDS_BLOCK_SIZE - 1] = 0xF7 ;
+
+       if ((k = psf_fwrite (psds->write_data, 1, SDS_BLOCK_SIZE, psf)) != SDS_BLOCK_SIZE)
+               psf_log_printf (psf, "*** Warning : psf_fwrite (%d != %d).\n", k, SDS_BLOCK_SIZE) ;
+
+       psds->write_block ++ ;
+       psds->write_count = 0 ;
+
+       if (psds->write_block > psds->total_blocks)
+               psds->total_blocks = psds->write_block ;
+       psds->frames = psds->total_blocks * psds->samplesperblock ;
+
+       return 1 ;
+} /* sds_3byte_write */
+
+static int
+sds_4byte_write (SF_PRIVATE *psf, SDS_PRIVATE *psds)
+{      unsigned char *ucptr, checksum ;
+       unsigned int sample ;
+       int     k ;
+
+       psds->write_data [0] = 0xF0 ;
+       psds->write_data [1] = 0x7E ;
+       psds->write_data [2] = 0 ;                                                      /* Channel number */
+       psds->write_data [3] = psds->write_block & 0x7F ;       /* Packet number */
+
+       ucptr = psds->write_data + 5 ;
+       for (k = 0 ; k < 120 ; k += 4)
+       {       sample = psds->write_samples [k / 4] ;
+               sample += 0x80000000 ;
+               ucptr [k] = (sample >> 25) & 0x7F ;
+               ucptr [k + 1] = (sample >> 18) & 0x7F ;
+               ucptr [k + 2] = (sample >> 11) & 0x7F ;
+               ucptr [k + 3] = (sample >> 4) & 0x7F ;
+               } ;
+
+       checksum = psds->write_data [1] ;
+       for (k = 2 ; k < SDS_BLOCK_SIZE - 3 ; k ++)
+               checksum ^= psds->write_data [k] ;
+       checksum &= 0x7F ;
+
+       psds->write_data [SDS_BLOCK_SIZE - 2] = checksum ;
+       psds->write_data [SDS_BLOCK_SIZE - 1] = 0xF7 ;
+
+       if ((k = psf_fwrite (psds->write_data, 1, SDS_BLOCK_SIZE, psf)) != SDS_BLOCK_SIZE)
+               psf_log_printf (psf, "*** Warning : psf_fwrite (%d != %d).\n", k, SDS_BLOCK_SIZE) ;
+
+       psds->write_block ++ ;
+       psds->write_count = 0 ;
+
+       if (psds->write_block > psds->total_blocks)
+               psds->total_blocks = psds->write_block ;
+       psds->frames = psds->total_blocks * psds->samplesperblock ;
+
+       return 1 ;
+} /* sds_4byte_write */
+
+static sf_count_t
+sds_write_s (SF_PRIVATE *psf, const short *ptr, sf_count_t len)
+{      SDS_PRIVATE     *psds ;
+       int                     *iptr ;
+       int                     k, bufferlen, writecount, count ;
+       sf_count_t      total = 0 ;
+
+       if (psf->fdata == NULL)
+               return 0 ;
+       psds = (SDS_PRIVATE*) psf->fdata ;
+
+       iptr = psf->u.ibuf ;
+       bufferlen = ARRAY_LEN (psf->u.ibuf) ;
+       while (len > 0)
+       {       writecount = (len >= bufferlen) ? bufferlen : len ;
+               for (k = 0 ; k < writecount ; k++)
+                       iptr [k] = ptr [total + k] << 16 ;
+               count = sds_write (psf, psds, iptr, writecount) ;
+               total += count ;
+               len -= writecount ;
+               } ;
+
+       return total ;
+} /* sds_write_s */
+
+static sf_count_t
+sds_write_i (SF_PRIVATE *psf, const int *ptr, sf_count_t len)
+{      SDS_PRIVATE *psds ;
+       int                     total ;
+
+       if (psf->fdata == NULL)
+               return 0 ;
+       psds = (SDS_PRIVATE*) psf->fdata ;
+
+       total = sds_write (psf, psds, ptr, len) ;
+
+       return total ;
+} /* sds_write_i */
+
+static sf_count_t
+sds_write_f (SF_PRIVATE *psf, const float *ptr, sf_count_t len)
+{      SDS_PRIVATE     *psds ;
+       int                     *iptr ;
+       int                     k, bufferlen, writecount, count ;
+       sf_count_t      total = 0 ;
+       float           normfact ;
+
+       if (psf->fdata == NULL)
+               return 0 ;
+       psds = (SDS_PRIVATE*) psf->fdata ;
+
+       if (psf->norm_float == SF_TRUE)
+               normfact = 1.0 * 0x80000000 ;
+       else
+               normfact = 1.0 * (1 << psds->bitwidth) ;
+
+       iptr = psf->u.ibuf ;
+       bufferlen = ARRAY_LEN (psf->u.ibuf) ;
+       while (len > 0)
+       {       writecount = (len >= bufferlen) ? bufferlen : len ;
+               for (k = 0 ; k < writecount ; k++)
+                       iptr [k] = normfact * ptr [total + k] ;
+               count = sds_write (psf, psds, iptr, writecount) ;
+               total += count ;
+               len -= writecount ;
+               } ;
+
+       return total ;
+} /* sds_write_f */
+
+static sf_count_t
+sds_write_d (SF_PRIVATE *psf, const double *ptr, sf_count_t len)
+{      SDS_PRIVATE     *psds ;
+       int                     *iptr ;
+       int                     k, bufferlen, writecount, count ;
+       sf_count_t      total = 0 ;
+       double          normfact ;
+
+       if (psf->fdata == NULL)
+               return 0 ;
+       psds = (SDS_PRIVATE*) psf->fdata ;
+
+       if (psf->norm_double == SF_TRUE)
+               normfact = 1.0 * 0x80000000 ;
+       else
+               normfact = 1.0 * (1 << psds->bitwidth) ;
+
+       iptr = psf->u.ibuf ;
+       bufferlen = ARRAY_LEN (psf->u.ibuf) ;
+       while (len > 0)
+       {       writecount = (len >= bufferlen) ? bufferlen : len ;
+               for (k = 0 ; k < writecount ; k++)
+                       iptr [k] = normfact * ptr [total + k] ;
+               count = sds_write (psf, psds, iptr, writecount) ;
+               total += count ;
+               len -= writecount ;
+               } ;
+
+       return total ;
+} /* sds_write_d */
+
+static int
+sds_write (SF_PRIVATE *psf, SDS_PRIVATE *psds, const int *ptr, int len)
+{      int     count, total = 0 ;
+
+       while (total < len)
+       {       count = psds->samplesperblock - psds->write_count ;
+               if (count > len - total)
+                       count = len - total ;
+
+               memcpy (&(psds->write_samples [psds->write_count]), &(ptr [total]), count * sizeof (int)) ;
+               total += count ;
+               psds->write_count += count ;
+
+               if (psds->write_count >= psds->samplesperblock)
+                       psds->writer (psf, psds) ;
+               } ;
+
+       return total ;
+} /* sds_write */
+
+/*
+** Do not edit or modify anything in this comment block.
+** The arch-tag line is a file identity tag for the GNU Arch
+** revision control system.
+**
+** arch-tag: d5d26aa3-368c-4ca6-bb85-377e5a2578cc
+*/
diff --git a/libs/libsndfile/src/sf_unistd.h b/libs/libsndfile/src/sf_unistd.h
new file mode 100644 (file)
index 0000000..f24ae67
--- /dev/null
@@ -0,0 +1,67 @@
+/*
+** Copyright (C) 2002-2004 Erik de Castro Lopo <erikd@mega-nerd.com>
+**
+** This program is free software; you can redistribute it and/or modify
+** it under the terms of the GNU Lesser General Public License as published by
+** the Free Software Foundation; either version 2.1 of the License, or
+** (at your option) any later version.
+**
+** This program is distributed in the hope that it will be useful,
+** but WITHOUT ANY WARRANTY; without even the implied warranty of
+** MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+** GNU Lesser General Public License for more details.
+**
+** You should have received a copy of the GNU Lesser General Public License
+** along with this program; if not, write to the Free Software
+** Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA.
+*/
+
+/* Some defines that microsoft 'forgot' to implement. */
+
+#ifndef S_IRWXU
+#define        S_IRWXU         0000700 /* rwx, owner */
+#endif
+
+#ifndef                S_IRUSR
+#define                S_IRUSR 0000400 /* read permission, owner */
+#endif
+
+#ifndef                S_IWUSR
+#define                S_IWUSR 0000200 /* write permission, owner */
+#endif
+
+#ifndef                S_IXUSR
+#define                S_IXUSR 0000100 /* execute/search permission, owner */
+#endif
+
+#define        S_IRWXG         0000070 /* rwx, group */
+#define                S_IRGRP 0000040 /* read permission, group */
+#define                S_IWGRP 0000020 /* write permission, grougroup */
+#define                S_IXGRP 0000010 /* execute/search permission, group */
+
+#define        S_IRWXO         0000007 /* rwx, other */
+#define                S_IROTH 0000004 /* read permission, other */
+#define                S_IWOTH 0000002 /* write permission, other */
+#define                S_IXOTH 0000001 /* execute/search permission, other */
+
+#ifndef S_ISFIFO
+#define S_ISFIFO(mode) (((mode) & _S_IFMT) == _S_IFIFO)
+#endif
+
+#ifndef S_ISREG
+#define        S_ISREG(mode)   (((mode) & _S_IFREG) == _S_IFREG)
+#endif
+
+/*
+**     Don't know if these are still needed.
+**
+**     #define _IFMT           _S_IFMT
+**     #define _IFREG          _S_IFREG
+*/
+/*
+** Do not edit or modify anything in this comment block.
+** The arch-tag line is a file identity tag for the GNU Arch 
+** revision control system.
+**
+** arch-tag: 253aea6d-6299-46fd-8d06-bc5f6224c8fe
+*/
diff --git a/libs/libsndfile/src/sfconfig.h b/libs/libsndfile/src/sfconfig.h
new file mode 100644 (file)
index 0000000..f12df6d
--- /dev/null
@@ -0,0 +1,108 @@
+/*
+** Copyright (C) 2005 Erik de Castro Lopo <erikd@mega-nerd.com>
+**
+** This program is free software; you can redistribute it and/or modify
+** it under the terms of the GNU Lesser General Public License as published by
+** the Free Software Foundation; either version 2.1 of the License, or
+** (at your option) any later version.
+**
+** This program is distributed in the hope that it will be useful,
+** but WITHOUT ANY WARRANTY; without even the implied warranty of
+** MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+** GNU Lesser General Public License for more details.
+**
+** You should have received a copy of the GNU Lesser General Public License
+** along with this program; if not, write to the Free Software
+** Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA.
+*/
+
+/*
+**     Autoconf leaves many config parameters undefined.
+**     Here we change then from being undefined to defining them to 0.
+**     This allows things like:
+**
+**             #if HAVE_CONFIG_PARAM
+**
+**     and
+**
+**             if (HAVE_CONFIG_PARAM)
+**                     do_something () ;
+*/
+
+#ifndef SFCONFIG_H
+#define SFCONFIG_H
+
+/* Include the Autoconf generated file. */
+#include "config.h"
+
+/* Now fiddle the values. */
+
+#ifndef HAVE_ALSA_ASOUNDLIB_H
+#define HAVE_ALSA_ASOUNDLIB_H 0
+#endif
+
+#ifndef HAVE_BYTESWAP_H
+#define HAVE_BYTESWAP_H 0
+#endif
+
+#ifndef HAVE_DECL_S_IRGRP
+#define        HAVE_DECL_S_IRGRP 0
+#endif
+
+#ifndef HAVE_ENDIAN_H
+#define HAVE_ENDIAN_H 0
+#endif
+
+#ifndef HAVE_FSYNC
+#define HAVE_FSYNC 0
+#endif
+
+#ifndef HAVE_LOCALE_H
+#define HAVE_LOCALE_H 0
+#endif
+
+#ifndef HAVE_LRINT
+#define HAVE_LRINT 0
+#endif
+
+#ifndef HAVE_LRINTF
+#define HAVE_LRINTF 0
+#endif
+
+#ifndef HAVE_MMAP
+#define HAVE_MMAP 0
+#endif
+
+#ifndef HAVE_PREAD
+#define HAVE_PREAD 0
+#endif
+
+#ifndef HAVE_PWRITE
+#define HAVE_PWRITE 0
+#endif
+
+#ifndef HAVE_SETLOCALE
+#define HAVE_SETLOCALE 0
+#endif
+
+#ifndef HAVE_SQLITE3
+#define HAVE_SQLITE3 0
+#endif
+
+#ifndef HAVE_STDINT_H
+#define HAVE_STDINT_H 0
+#endif
+
+#ifndef HAVE_UNISTD_H
+#define HAVE_UNISTD_H 0
+#endif
+
+#endif
+
+/*
+** Do not edit or modify anything in this comment block.
+** The arch-tag line is a file identity tag for the GNU Arch
+** revision control system.
+**
+** arch-tag: 2df2316e-8f9d-4860-bba7-f3c16c63eed3
+*/
diff --git a/libs/libsndfile/src/sfendian.h b/libs/libsndfile/src/sfendian.h
new file mode 100644 (file)
index 0000000..efc1c10
--- /dev/null
@@ -0,0 +1,256 @@
+/*
+** Copyright (C) 1999-2006 Erik de Castro Lopo <erikd@mega-nerd.com>
+**
+** This program is free software; you can redistribute it and/or modify
+** it under the terms of the GNU Lesser General Public License as published by
+** the Free Software Foundation; either version 2.1 of the License, or
+** (at your option) any later version.
+**
+** This program is distributed in the hope that it will be useful,
+** but WITHOUT ANY WARRANTY; without even the implied warranty of
+** MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+** GNU Lesser General Public License for more details.
+**
+** You should have received a copy of the GNU Lesser General Public License
+** along with this program; if not, write to the Free Software
+** Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA.
+*/
+
+#include "sfconfig.h"
+
+#if HAVE_STDINT_H
+#include <stdint.h>
+#elif HAVE_INTTYPES_H
+#include <inttypes.h>
+#endif
+
+#if (defined (SIZEOF_INT64_T) && (SIZEOF_INT64_T == 8))
+/* Good, we have int64_t. */
+#elif (defined (SIZEOF_LONG_LONG) && (SIZEOF_LONG_LONG == 8))
+typedef long long int64_t ;
+#elif (defined (SIZEOF_LONG) && (SIZEOF_LONG == 8))
+typedef long int64_t ;
+#elif (defined (WIN32) || defined (_WIN32))
+typedef __int64 int64_t ;
+#else
+#error "No 64 bit integer type."
+#endif
+
+#if HAVE_BYTESWAP_H
+
+#include <byteswap.h>
+
+#define        ENDSWAP_SHORT(x)        ((short) bswap_16 (x))
+#define        ENDSWAP_INT(x)          ((int) bswap_32 (x))
+
+#else
+
+#define        ENDSWAP_SHORT(x)        ((((x) >> 8) & 0xFF) + (((x) & 0xFF) << 8))
+#define        ENDSWAP_INT(x)          ((((x) >> 24) & 0xFF) + (((x) >> 8) & 0xFF00) + (((x) & 0xFF00) << 8) + (((x) & 0xFF) << 24))
+
+#endif
+
+/*
+** Many file types (ie WAV, AIFF) use sets of four consecutive bytes as a
+** marker indicating different sections of the file.
+** The following MAKE_MARKER macro allows th creation of integer constants
+** for these markers.
+*/
+
+#if (CPU_IS_LITTLE_ENDIAN == 1)
+       #define MAKE_MARKER(a,b,c,d)    ((a) | ((b) << 8) | ((c) << 16) | ((d) << 24))
+#elif (CPU_IS_BIG_ENDIAN == 1)
+       #define MAKE_MARKER(a,b,c,d)    (((a) << 24) | ((b) << 16) | ((c) << 8) | (d))
+#else
+       #error "Target CPU endian-ness unknown. May need to hand edit src/sfconfig.h"
+#endif
+
+/*
+** Macros to handle reading of data of a specific endian-ness into host endian
+** shorts and ints. The single input is an unsigned char* pointer to the start
+** of the object. There are two versions of each macro as we need to deal with
+** both big and little endian CPUs.
+*/
+
+#if (CPU_IS_LITTLE_ENDIAN == 1)
+       #define LES2H_SHORT(x)                  (x)
+       #define LEI2H_INT(x)                    (x)
+
+       #define BES2H_SHORT(x)                  ENDSWAP_SHORT (x)
+       #define BEI2H_INT(x)                    ENDSWAP_INT (x)
+
+       #define H2BE_SHORT(x)                   ENDSWAP_SHORT (x)
+       #define H2BE_INT(x)                             ENDSWAP_INT (x)
+
+#elif (CPU_IS_BIG_ENDIAN == 1)
+       #define LES2H_SHORT(x)                  ENDSWAP_SHORT (x)
+       #define LEI2H_INT(x)                    ENDSWAP_INT (x)
+
+       #define BES2H_SHORT(x)                  (x)
+       #define BEI2H_INT(x)                    (x)
+
+       #define H2LE_SHORT(x)                   ENDSWAP_SHORT (x)
+       #define H2LE_INT(x)                             ENDSWAP_INT (x)
+
+#else
+       #error "Target CPU endian-ness unknown. May need to hand edit src/sfconfig.h"
+#endif
+
+#define LET2H_SHORT_PTR(x)             ((x) [1] + ((x) [2] << 8))
+#define LET2H_INT_PTR(x)               (((x) [0] << 8) + ((x) [1] << 16) + ((x) [2] << 24))
+
+#define BET2H_SHORT_PTR(x)             (((x) [0] << 8) + (x) [1])
+#define BET2H_INT_PTR(x)               (((x) [0] << 24) + ((x) [1] << 16) + ((x) [2] << 8))
+
+/*-----------------------------------------------------------------------------------------------
+** Generic functions for performing endian swapping on integer arrays.
+*/
+
+static inline void
+endswap_short_array (short *ptr, int len)
+{      short   temp ;
+
+       while (--len >= 0)
+       {       temp = ptr [len] ;
+               ptr [len] = ENDSWAP_SHORT (temp) ;
+               } ;
+} /* endswap_short_array */
+
+static inline void
+endswap_short_copy (short *dest, const short *src, int len)
+{
+       while (--len >= 0)
+       {       dest [len] = ENDSWAP_SHORT (src [len]) ;
+               } ;
+} /* endswap_short_copy */
+
+static inline void
+endswap_int_array (int *ptr, int len)
+{      int temp ;
+
+       while (--len >= 0)
+       {       temp = ptr [len] ;
+               ptr [len] = ENDSWAP_INT (temp) ;
+               } ;
+} /* endswap_int_array */
+
+static inline void
+endswap_int_copy (int *dest, const int *src, int len)
+{
+       while (--len >= 0)
+       {       dest [len] = ENDSWAP_INT (src [len]) ;
+               } ;
+} /* endswap_int_copy */
+
+/*========================================================================================
+*/
+
+#if    (HAVE_BYTESWAP_H && defined (SIZEOF_INT64_T) && (SIZEOF_INT64_T == 8))
+
+static inline void
+endswap_int64_t_array (int64_t *ptr, int len)
+{      int64_t value ;
+
+       while (--len >= 0)
+       {       value = ptr [len] ;
+               ptr [len] = bswap_64 (value) ;
+               } ;
+} /* endswap_int64_t_array */
+
+static inline void
+endswap_int64_t_copy (int64_t *dest, const int64_t *src, int len)
+{      int64_t value ;
+
+       while (--len >= 0)
+       {       value = src [len] ;
+               dest [len] = bswap_64 (value) ;
+               } ;
+} /* endswap_int64_t_copy */
+
+#else
+
+static inline void
+endswap_int64_t_array (int64_t *ptr, int len)
+{      unsigned char *ucptr, temp ;
+
+       ucptr = (unsigned char *) ptr ;
+       ucptr += 8 * len ;
+       while (--len >= 0)
+       {       ucptr -= 8 ;
+
+               temp = ucptr [0] ;
+               ucptr [0] = ucptr [7] ;
+               ucptr [7] = temp ;
+
+               temp = ucptr [1] ;
+               ucptr [1] = ucptr [6] ;
+               ucptr [6] = temp ;
+
+               temp = ucptr [2] ;
+               ucptr [2] = ucptr [5] ;
+               ucptr [5] = temp ;
+
+               temp = ucptr [3] ;
+               ucptr [3] = ucptr [4] ;
+               ucptr [4] = temp ;
+               } ;
+} /* endswap_int64_t_array */
+
+static inline void
+endswap_int64_t_copy (int64_t *dest, const int64_t *src, int len)
+{      const unsigned char *psrc ;
+       unsigned char *pdest ;
+
+       if (dest == src)
+       {       endswap_int64_t_array (dest, len) ;
+               return ;
+               } ;
+
+       psrc = ((const unsigned char *) src) + 8 * len ;
+       pdest = ((unsigned char *) dest) + 8 * len ;
+       while (--len >= 0)
+       {       psrc -= 8 ;
+               pdest -= 8 ;
+
+               pdest [0] = psrc [7] ;
+               pdest [2] = psrc [5] ;
+               pdest [4] = psrc [3] ;
+               pdest [6] = psrc [1] ;
+               pdest [7] = psrc [0] ;
+               pdest [1] = psrc [6] ;
+               pdest [3] = psrc [4] ;
+               pdest [5] = psrc [2] ;
+               } ;
+} /* endswap_int64_t_copy */
+
+#endif
+
+/* A couple of wrapper functions. */
+
+static inline void
+endswap_float_array (float *ptr, int len)
+{      endswap_int_array ((void *) ptr, len) ;
+} /* endswap_float_array */
+
+static inline void
+endswap_double_array (double *ptr, int len)
+{      endswap_int64_t_array ((void *) ptr, len) ;
+} /* endswap_double_array */
+
+static inline void
+endswap_float_copy (float *dest, const float *src, int len)
+{      endswap_int_copy ((int *) dest, (const int *) src, len) ;
+} /* endswap_float_copy */
+
+static inline void
+endswap_double_copy (double *dest, const double *src, int len)
+{      endswap_int64_t_copy ((int64_t *) dest, (const int64_t *) src, len) ;
+} /* endswap_double_copy */
+
+/*
+** Do not edit or modify anything in this comment block.
+** The arch-tag line is a file identity tag for the GNU Arch
+** revision control system.
+**
+** arch-tag: f0c5cd54-42d3-4237-90ec-11fe24995de7
+*/
diff --git a/libs/libsndfile/src/sndfile.c b/libs/libsndfile/src/sndfile.c
new file mode 100644 (file)
index 0000000..c30d7b6
--- /dev/null
@@ -0,0 +1,2694 @@
+/*
+** Copyright (C) 1999-2005 Erik de Castro Lopo <erikd@mega-nerd.com>
+**
+** This program is free software; you can redistribute it and/or modify
+** it under the terms of the GNU Lesser General Public License as published by
+** the Free Software Foundation; either version 2.1 of the License, or
+** (at your option) any later version.
+**
+** This program is distributed in the hope that it will be useful,
+** but WITHOUT ANY WARRANTY; without even the implied warranty of
+** MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+** GNU Lesser General Public License for more details.
+**
+** You should have received a copy of the GNU Lesser General Public License
+** along with this program; if not, write to the Free Software
+** Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA.
+*/
+
+#include       "sfconfig.h"
+
+#include       <stdlib.h>
+#include       <string.h>
+#include       <ctype.h>
+
+#include       "sndfile.h"
+#include       "sfendian.h"
+#include       "common.h"
+
+#define                SNDFILE_MAGICK  0x1234C0DE
+
+typedef struct
+{      int             error ;
+       const char      *str ;
+} ErrorStruct ;
+
+static
+ErrorStruct SndfileErrors [] =
+{
+       /* Public error values and their associated strings. */
+       {       SF_ERR_NO_ERROR                         , "No Error." },
+       {       SF_ERR_UNRECOGNISED_FORMAT      , "File opened for read. Format not recognised." },
+       {       SF_ERR_SYSTEM                           , "System error." /* Often replaced. */         },
+       {       SF_ERR_MALFORMED_FILE           , "Supported file format but file is malformed." },
+       {       SF_ERR_UNSUPPORTED_ENCODING     , "Supported file format but unsupported encoding." },
+
+       /* Private error values and their associated strings. */
+       {       SFE_BAD_FILE                    , "File does not exist or is not a regular file (possibly a pipe?)." },
+       {       SFE_BAD_FILE_READ               , "File exists but no data could be read." },
+       {       SFE_OPEN_FAILED                 , "Could not open file." },
+       {       SFE_BAD_SNDFILE_PTR             , "Not a valid SNDFILE* pointer." },
+       {       SFE_BAD_SF_INFO_PTR             , "NULL SF_INFO pointer passed to libsndfile." },
+       {       SFE_BAD_SF_INCOMPLETE   , "SF_PRIVATE struct incomplete and end of header parsing." },
+       {       SFE_BAD_FILE_PTR                , "Bad FILE pointer." },
+       {       SFE_BAD_INT_PTR                 , "Internal error, Bad pointer." },
+       {       SFE_BAD_STAT_SIZE               , "Error : software was misconfigured at compile time (sizeof statbuf.st_size)." },
+
+       {       SFE_MALLOC_FAILED               , "Internal malloc () failed." },
+       {       SFE_UNIMPLEMENTED               , "File contains data in an unimplemented format." },
+       {       SFE_BAD_READ_ALIGN              , "Attempt to read a non-integer number of channels." },
+       {       SFE_BAD_WRITE_ALIGN     , "Attempt to write a non-integer number of channels." },
+       {       SFE_UNKNOWN_FORMAT              , "File contains data in an unknown format." },
+       {       SFE_NOT_READMODE                , "Read attempted on file currently open for write." },
+       {       SFE_NOT_WRITEMODE               , "Write attempted on file currently open for read." },
+       {       SFE_BAD_MODE_RW                 , "This file format does not support read/write mode." },
+       {       SFE_BAD_SF_INFO                 , "Internal error : SF_INFO struct incomplete." },
+       {       SFE_BAD_OFFSET                  , "Error : supplied offset beyond end of file." },
+       {       SFE_NO_EMBED_SUPPORT    , "Error : embedding not supported for this file format." },
+       {       SFE_NO_EMBEDDED_RDWR    , "Error : cannot open embedded file read/write." },
+       {       SFE_NO_PIPE_WRITE               , "Error : this file format does not support pipe write." },
+       {       SFE_BAD_RDWR_FORMAT             , "Attempted to open read only format for RDWR." },
+       {       SFE_BAD_VIRTUAL_IO              , "Error : bad pointer on SF_VIRTUAL_IO struct." },
+
+       {       SFE_INTERLEAVE_MODE             , "Attempt to write to file with non-interleaved data." },
+       {       SFE_INTERLEAVE_SEEK             , "Bad karma in seek during interleave read operation." },
+       {       SFE_INTERLEAVE_READ             , "Bad karma in read during interleave read operation." },
+
+       {       SFE_INTERNAL                    , "Unspecified internal error." },
+       {       SFE_BAD_CONTROL_CMD             , "Bad command passed to function sf_command()." },
+       {       SFE_BAD_ENDIAN                  , "Bad endian-ness. Try default endian-ness" },
+       {       SFE_CHANNEL_COUNT               , "Too many channels specified." },
+
+       {       SFE_BAD_SEEK                    , "Internal psf_fseek() failed." },
+       {       SFE_NOT_SEEKABLE                , "Seek attempted on unseekable file type." },
+       {       SFE_AMBIGUOUS_SEEK              , "Error : combination of file open mode and seek command is ambiguous." },
+       {       SFE_WRONG_SEEK                  , "Error : invalid seek parameters." },
+       {       SFE_SEEK_FAILED                 , "Error : parameters OK, but psf_seek() failed." },
+
+       {       SFE_BAD_OPEN_MODE               , "Error : bad mode parameter for file open." },
+       {       SFE_OPEN_PIPE_RDWR              , "Error : attempt toopen a pipe in read/write mode." },
+       {       SFE_RDWR_POSITION               , "Error on RDWR position (cryptic)." },
+       {       SFE_RDWR_BAD_HEADER             , "Error : Cannot open file in read/write mode due to string data in header." },
+
+       {       SFE_STR_NO_SUPPORT              , "Error : File type does not support string data." },
+       {       SFE_STR_NOT_WRITE               , "Error : Trying to set a string when file is not in write mode." },
+       {       SFE_STR_MAX_DATA                , "Error : Maximum string data storage reached." },
+       {       SFE_STR_MAX_COUNT               , "Error : Maximum string data count reached." },
+       {       SFE_STR_BAD_TYPE                , "Error : Bad string data type." },
+       {       SFE_STR_NO_ADD_END              , "Error : file type does not support strings added at end of file." },
+       {       SFE_STR_BAD_STRING              , "Error : bad string." },
+       {       SFE_STR_WEIRD                   , "Error : Weird string error." },
+
+       {       SFE_WAV_NO_RIFF                 , "Error in WAV file. No 'RIFF' chunk marker." },
+       {       SFE_WAV_NO_WAVE                 , "Error in WAV file. No 'WAVE' chunk marker." },
+       {       SFE_WAV_NO_FMT                  , "Error in WAV file. No 'fmt ' chunk marker." },
+       {       SFE_WAV_FMT_SHORT               , "Error in WAV file. Short 'fmt ' chunk." },
+
+       {       SFE_WAV_BAD_FACT                , "Error in WAV file. 'fact' chunk out of place." },
+       {       SFE_WAV_BAD_PEAK                , "Error in WAV file. Bad 'PEAK' chunk." },
+       {       SFE_WAV_PEAK_B4_FMT             , "Error in WAV file. 'PEAK' chunk found before 'fmt ' chunk." },
+
+       {       SFE_WAV_BAD_FORMAT              , "Error in WAV file. Errors in 'fmt ' chunk." },
+       {       SFE_WAV_BAD_BLOCKALIGN  , "Error in WAV file. Block alignment in 'fmt ' chunk is incorrect." },
+       {       SFE_WAV_NO_DATA                 , "Error in WAV file. No 'data' chunk marker." },
+       {       SFE_WAV_BAD_LIST                , "Error in WAV file. Malformed LIST chunk." },
+       {       SFE_WAV_UNKNOWN_CHUNK   , "Error in WAV file. File contains an unknown chunk marker." },
+       {       SFE_WAV_WVPK_DATA               , "Error in WAV file. Data is in WAVPACK format." },
+
+       {       SFE_WAV_ADPCM_NOT4BIT   , "Error in ADPCM WAV file. Invalid bit width." },
+       {       SFE_WAV_ADPCM_CHANNELS  , "Error in ADPCM WAV file. Invalid number of channels." },
+       {       SFE_WAV_GSM610_FORMAT   , "Error in GSM610 WAV file. Invalid format chunk." },
+
+       {       SFE_AIFF_NO_FORM                , "Error in AIFF file, bad 'FORM' marker." },
+       {       SFE_AIFF_AIFF_NO_FORM   , "Error in AIFF file, 'AIFF' marker without 'FORM'." },
+       {       SFE_AIFF_COMM_NO_FORM   , "Error in AIFF file, 'COMM' marker without 'FORM'." },
+       {       SFE_AIFF_SSND_NO_COMM   , "Error in AIFF file, 'SSND' marker without 'COMM'." },
+       {       SFE_AIFF_UNKNOWN_CHUNK  , "Error in AIFF file, unknown chunk." },
+       {       SFE_AIFF_COMM_CHUNK_SIZE, "Error in AIFF file, bad 'COMM' chunk size." },
+       {       SFE_AIFF_BAD_COMM_CHUNK , "Error in AIFF file, bad 'COMM' chunk." },
+       {       SFE_AIFF_PEAK_B4_COMM   , "Error in AIFF file. 'PEAK' chunk found before 'COMM' chunk." },
+       {       SFE_AIFF_BAD_PEAK               , "Error in AIFF file. Bad 'PEAK' chunk." },
+       {       SFE_AIFF_NO_SSND                , "Error in AIFF file, bad 'SSND' chunk." },
+       {       SFE_AIFF_NO_DATA                , "Error in AIFF file, no sound data." },
+       {       SFE_AIFF_RW_SSND_NOT_LAST, "Error in AIFF file, RDWR only possible if SSND chunk at end of file." },
+
+       {       SFE_AU_UNKNOWN_FORMAT   , "Error in AU file, unknown format." },
+       {       SFE_AU_NO_DOTSND                , "Error in AU file, missing '.snd' or 'dns.' marker." },
+       {       SFE_AU_EMBED_BAD_LEN    , "Embedded AU file with unknown length." },
+
+       {       SFE_RAW_READ_BAD_SPEC   , "Error while opening RAW file for read. Must specify format and channels.\n"
+                                                                       "Possibly trying to open unsupported format."
+                                                                        },
+       {       SFE_RAW_BAD_BITWIDTH    , "Error. RAW file bitwidth must be a multiple of 8." },
+       {       SFE_RAW_BAD_FORMAT              , "Error. Bad format field in SF_INFO struct when openning a RAW file for read." },
+
+       {       SFE_PAF_NO_MARKER               , "Error in PAF file, no marker." },
+       {       SFE_PAF_VERSION                 , "Error in PAF file, bad version." },
+       {       SFE_PAF_UNKNOWN_FORMAT  , "Error in PAF file, unknown format." },
+       {       SFE_PAF_SHORT_HEADER    , "Error in PAF file. File shorter than minimal header." },
+
+       {       SFE_SVX_NO_FORM                 , "Error in 8SVX / 16SV file, no 'FORM' marker." },
+       {       SFE_SVX_NO_BODY                 , "Error in 8SVX / 16SV file, no 'BODY' marker." },
+       {       SFE_SVX_NO_DATA                 , "Error in 8SVX / 16SV file, no sound data." },
+       {       SFE_SVX_BAD_COMP                , "Error in 8SVX / 16SV file, unsupported compression format." },
+       {       SFE_SVX_BAD_NAME_LENGTH , "Error in 8SVX / 16SV file, NAME chunk too long." },
+
+       {       SFE_NIST_BAD_HEADER             , "Error in NIST file, bad header." },
+       {       SFE_NIST_CRLF_CONVERISON, "Error : NIST file damaged by Windows CR -> CRLF conversion process." },
+       {       SFE_NIST_BAD_ENCODING   , "Error in NIST file, unsupported compression format." },
+
+       {       SFE_VOC_NO_CREATIVE             , "Error in VOC file, no 'Creative Voice File' marker." },
+       {       SFE_VOC_BAD_FORMAT              , "Error in VOC file, bad format." },
+       {       SFE_VOC_BAD_VERSION             , "Error in VOC file, bad version number." },
+       {       SFE_VOC_BAD_MARKER              , "Error in VOC file, bad marker in file." },
+       {       SFE_VOC_BAD_SECTIONS    , "Error in VOC file, incompatible VOC sections." },
+       {       SFE_VOC_MULTI_SAMPLERATE, "Error in VOC file, more than one sample rate defined." },
+       {       SFE_VOC_MULTI_SECTION   , "Unimplemented VOC file feature, file contains multiple sound sections." },
+       {       SFE_VOC_MULTI_PARAM             , "Error in VOC file, file contains multiple bit or channel widths." },
+       {       SFE_VOC_SECTION_COUNT   , "Error in VOC file, too many sections." },
+       {       SFE_VOC_NO_PIPE                 , "Error : not able to operate on VOC files over a pipe." },
+
+       {       SFE_IRCAM_NO_MARKER             , "Error in IRCAM file, bad IRCAM marker." },
+       {       SFE_IRCAM_BAD_CHANNELS  , "Error in IRCAM file, bad channel count." },
+       {       SFE_IRCAM_UNKNOWN_FORMAT, "Error in IRCAM file, unknow encoding format." },
+
+       {       SFE_W64_64_BIT                  , "Error in W64 file, file contains 64 bit offset." },
+
+       {       SFE_W64_NO_RIFF                 , "Error in W64 file. No 'riff' chunk marker." },
+       {       SFE_W64_NO_WAVE                 , "Error in W64 file. No 'wave' chunk marker." },
+       {       SFE_W64_NO_FMT                  , "Error in W64 file. No 'fmt ' chunk marker." },
+       {       SFE_W64_NO_DATA                 , "Error in W64 file. No 'data' chunk marker." },
+
+       {       SFE_W64_FMT_SHORT               , "Error in W64 file. Short 'fmt ' chunk." },
+       {       SFE_W64_FMT_TOO_BIG             , "Error in W64 file. 'fmt ' chunk too large." },
+
+       {       SFE_W64_ADPCM_NOT4BIT   , "Error in ADPCM W64 file. Invalid bit width." },
+       {       SFE_W64_ADPCM_CHANNELS  , "Error in ADPCM W64 file. Invalid number of channels." },
+       {       SFE_W64_GSM610_FORMAT   , "Error in GSM610 W64 file. Invalid format chunk." },
+
+       {       SFE_MAT4_BAD_NAME               , "Error in MAT4 file. No variable name." },
+       {       SFE_MAT4_NO_SAMPLERATE  , "Error in MAT4 file. No sample rate." },
+       {       SFE_MAT4_ZERO_CHANNELS  , "Error in MAT4 file. Channel count is zero." },
+
+       {       SFE_MAT5_BAD_ENDIAN             , "Error in MAT5 file. Not able to determine endian-ness." },
+       {       SFE_MAT5_NO_BLOCK               , "Error in MAT5 file. Bad block structure." },
+       {       SFE_MAT5_SAMPLE_RATE    , "Error in MAT5 file. Not able to determine sample rate." },
+       {       SFE_MAT5_ZERO_CHANNELS  , "Error in MAT5 file. Channel count is zero." },
+
+       {       SFE_PVF_NO_PVF1                 , "Error in PVF file. No PVF1 marker." },
+       {       SFE_PVF_BAD_HEADER              , "Error in PVF file. Bad header." },
+       {       SFE_PVF_BAD_BITWIDTH    , "Error in PVF file. Bad bit width." },
+
+       {       SFE_XI_BAD_HEADER               , "Error in XI file. Bad header." },
+       {       SFE_XI_EXCESS_SAMPLES   , "Error in XI file. Excess samples in file." },
+       {       SFE_XI_NO_PIPE                  , "Error : not able to operate on XI files over a pipe." },
+
+       {       SFE_HTK_NO_PIPE                 , "Error : not able to operate on HTK files over a pipe." },
+
+       {       SFE_SDS_NOT_SDS                 , "Error : not an SDS file." },
+       {       SFE_SDS_BAD_BIT_WIDTH   , "Error : bad bit width for SDS file." },
+
+       {       SFE_SD2_FD_DISALLOWED   , "Error : cannot open SD2 file without a file name." },
+       {       SFE_SD2_BAD_DATA_OFFSET , "Error : bad data offset." },
+       {       SFE_SD2_BAD_MAP_OFFSET  , "Error : bad map offset." },
+       {       SFE_SD2_BAD_DATA_LENGTH , "Error : bad data length." },
+       {       SFE_SD2_BAD_MAP_LENGTH  , "Error : bad map length." },
+       {       SFE_SD2_BAD_RSRC                , "Error : bad resource fork." },
+       {       SFE_SD2_BAD_SAMPLE_SIZE , "Error : bad sample size." },
+
+       {       SFE_FLAC_BAD_HEADER             , "Error : bad flac header." },
+       {       SFE_FLAC_NEW_DECODER    , "Error : problem while creating flac decoder." },
+       {       SFE_FLAC_INIT_DECODER   , "Error : problem while initialization of the flac decoder." },
+       {       SFE_FLAC_LOST_SYNC              , "Error : flac decoder lost sync." },
+       {       SFE_FLAC_BAD_SAMPLE_RATE, "Error : flac does not support this sample rate." },
+       {       SFE_FLAC_UNKOWN_ERROR   , "Error : unkown error in flac decoder." },
+
+       {       SFE_DWVW_BAD_BITWIDTH   , "Error : Bad bit width for DWVW encoding. Must be 12, 16 or 24." },
+       {       SFE_G72X_NOT_MONO               , "Error : G72x encoding does not support more than 1 channel." },
+
+       {       SFE_MAX_ERROR                   , "Maximum error number." },
+       {       SFE_MAX_ERROR + 1               , NULL }
+} ;
+
+/*------------------------------------------------------------------------------
+*/
+
+static int     format_from_extension (SF_PRIVATE *psf) ;
+static int     guess_file_type (SF_PRIVATE *psf) ;
+static int     validate_sfinfo (SF_INFO *sfinfo) ;
+static int     validate_psf (SF_PRIVATE *psf) ;
+static void    save_header_info (SF_PRIVATE *psf) ;
+static void    copy_filename (SF_PRIVATE *psf, const char *path) ;
+static int     psf_close (SF_PRIVATE *psf) ;
+static int     psf_open_file (SF_PRIVATE *psf, int mode, SF_INFO *sfinfo) ;
+
+static int     try_resource_fork (SF_PRIVATE * psf, int mode) ;
+
+/*------------------------------------------------------------------------------
+** Private (static) variables.
+*/
+
+static int     sf_errno = 0 ;
+static char    sf_logbuffer [SF_BUFFER_LEN] = { 0 } ;
+static char    sf_syserr [SF_SYSERR_LEN] = { 0 } ;
+
+/*------------------------------------------------------------------------------
+*/
+
+#define        VALIDATE_SNDFILE_AND_ASSIGN_PSF(a,b,c)          \
+               {       if (! (a))                                                              \
+                       {       sf_errno = SFE_BAD_SNDFILE_PTR ;        \
+                               return 0 ;                                                      \
+                               } ;                                                                     \
+                       (b) = (SF_PRIVATE*) (a) ;                               \
+                       if ((b)->virtual_io == SF_FALSE &&              \
+                               psf_file_valid (b) == 0)                        \
+                       {       (b)->error = SFE_BAD_FILE_PTR ;         \
+                               return 0 ;                                                      \
+                               } ;                                                                     \
+                       if ((b)->Magick != SNDFILE_MAGICK)              \
+                       {       (b)->error = SFE_BAD_SNDFILE_PTR ;      \
+                               return 0 ;                                                      \
+                               } ;                                                                     \
+                       if (c) (b)->error = 0 ;                                 \
+                       }
+
+/*------------------------------------------------------------------------------
+**     Public functions.
+*/
+
+SNDFILE*
+sf_open        (const char *path, int mode, SF_INFO *sfinfo)
+{      SF_PRIVATE      *psf ;
+       int                     error = 0 ;
+
+       if ((psf = calloc (1, sizeof (SF_PRIVATE))) == NULL)
+       {       sf_errno = SFE_MALLOC_FAILED ;
+               return  NULL ;
+               } ;
+
+       memset (psf, 0, sizeof (SF_PRIVATE)) ;
+       psf_init_files (psf) ;
+
+       psf_log_printf (psf, "File : %s\n", path) ;
+
+       copy_filename (psf, path) ;
+
+       if (strcmp (path, "-") == 0)
+               error = psf_set_stdio (psf, mode) ;
+       else
+               error = psf_fopen (psf, path, mode) ;
+
+       if (error == 0)
+               error = psf_open_file (psf, mode, sfinfo) ;
+
+       if (error)
+       {       sf_errno = error ;
+               if (error == SFE_SYSTEM)
+                       LSF_SNPRINTF (sf_syserr, sizeof (sf_syserr), "%s", psf->syserr) ;
+               LSF_SNPRINTF (sf_logbuffer, sizeof (sf_logbuffer), "%s", psf->logbuffer) ;
+               psf_close (psf) ;
+               return NULL ;
+               } ;
+
+       memcpy (sfinfo, &(psf->sf), sizeof (SF_INFO)) ;
+
+       return (SNDFILE*) psf ;
+} /* sf_open */
+
+SNDFILE*
+sf_open_fd     (int fd, int mode, SF_INFO *sfinfo, int close_desc)
+{      SF_PRIVATE      *psf ;
+       int                     error ;
+
+       if ((sfinfo->format & SF_FORMAT_TYPEMASK) == SF_FORMAT_SD2)
+       {       sf_errno = SFE_SD2_FD_DISALLOWED ;
+               return  NULL ;
+               } ;
+
+       if ((psf = calloc (1, sizeof (SF_PRIVATE))) == NULL)
+       {       sf_errno = SFE_MALLOC_FAILED ;
+               return  NULL ;
+               } ;
+
+       psf_init_files (psf) ;
+
+       psf_set_file (psf, fd) ;
+       psf->is_pipe = psf_is_pipe (psf) ;
+       psf->fileoffset = psf_ftell (psf) ;
+
+       if (! close_desc)
+               psf->do_not_close_descriptor = SF_TRUE ;
+
+       error = psf_open_file (psf, mode, sfinfo) ;
+
+       if (error)
+       {       sf_errno = error ;
+               if (error == SFE_SYSTEM)
+                       LSF_SNPRINTF (sf_syserr, sizeof (sf_syserr), "%s", psf->syserr) ;
+               LSF_SNPRINTF (sf_logbuffer, sizeof (sf_logbuffer), "%s", psf->logbuffer) ;
+               psf_close (psf) ;
+               return NULL ;
+               } ;
+
+       memcpy (sfinfo, &(psf->sf), sizeof (SF_INFO)) ;
+
+       return (SNDFILE*) psf ;
+} /* sf_open_fd */
+
+SNDFILE*
+sf_open_virtual        (SF_VIRTUAL_IO *sfvirtual, int mode, SF_INFO *sfinfo, void *user_data)
+{      SF_PRIVATE      *psf ;
+       int                     error = 0 ;
+
+       /* Make sure we have a valid set ot virtual pointers. */
+       if (sfvirtual->get_filelen == NULL || sfvirtual->seek == NULL || sfvirtual->tell == NULL)
+       {       sf_errno = SFE_BAD_VIRTUAL_IO ;
+               LSF_SNPRINTF (sf_logbuffer, sizeof (sf_logbuffer), "Bad vio_get_filelen / vio_seek / vio_tell in SF_VIRTUAL_IO struct.\n") ;
+               return NULL ;
+               } ;
+
+       if ((mode == SFM_READ || mode == SFM_RDWR) && sfvirtual->read == NULL)
+       {       sf_errno = SFE_BAD_VIRTUAL_IO ;
+               LSF_SNPRINTF (sf_logbuffer, sizeof (sf_logbuffer), "Bad vio_read in SF_VIRTUAL_IO struct.\n") ;
+               return NULL ;
+               } ;
+
+       if ((mode == SFM_WRITE || mode == SFM_RDWR) && sfvirtual->write == NULL)
+       {       sf_errno = SFE_BAD_VIRTUAL_IO ;
+               LSF_SNPRINTF (sf_logbuffer, sizeof (sf_logbuffer), "Bad vio_write in SF_VIRTUAL_IO struct.\n") ;
+               return NULL ;
+               } ;
+
+       if ((psf = calloc (1, sizeof (SF_PRIVATE))) == NULL)
+       {       sf_errno = SFE_MALLOC_FAILED ;
+               return  NULL ;
+               } ;
+
+       psf_init_files (psf) ;
+
+       psf->virtual_io = SF_TRUE ;
+       psf->vio = *sfvirtual ;
+       psf->vio_user_data = user_data ;
+
+       psf->mode = mode ;
+
+       error = psf_open_file (psf, mode, sfinfo) ;
+
+       if (error)
+       {       sf_errno = error ;
+               if (error == SFE_SYSTEM)
+                       LSF_SNPRINTF (sf_syserr, sizeof (sf_syserr), "%s", psf->syserr) ;
+               LSF_SNPRINTF (sf_logbuffer, sizeof (sf_logbuffer), "%s", psf->logbuffer) ;
+               psf_close (psf) ;
+               return NULL ;
+               } ;
+
+       memcpy (sfinfo, &(psf->sf), sizeof (SF_INFO)) ;
+
+       return (SNDFILE*) psf ;
+} /* sf_open_virtual */
+
+int
+sf_close       (SNDFILE *sndfile)
+{      SF_PRIVATE      *psf ;
+
+       VALIDATE_SNDFILE_AND_ASSIGN_PSF (sndfile, psf, 1) ;
+
+       return psf_close (psf) ;
+} /* sf_close */
+
+void
+sf_write_sync  (SNDFILE *sndfile)
+{      SF_PRIVATE      *psf ;
+
+       if ((psf = (SF_PRIVATE *) sndfile) == NULL)
+               return ;
+
+       psf_fsync (psf) ;
+
+       return ;
+} /* sf_write_sync */
+
+/*==============================================================================
+*/
+
+const char*
+sf_error_number        (int errnum)
+{      static const char *bad_errnum =
+               "No error defined for this error number. This is a bug in libsndfile." ;
+       int     k ;
+
+       if (errnum == SFE_MAX_ERROR)
+               return SndfileErrors [0].str ;
+
+       if (errnum < 0 || errnum > SFE_MAX_ERROR)
+       {       /* This really shouldn't happen in release versions. */
+               printf ("Not a valid error number (%d).\n", errnum) ;
+               return bad_errnum ;
+               } ;
+
+       for (k = 0 ; SndfileErrors [k].str ; k++)
+               if (errnum == SndfileErrors [k].error)
+                       return SndfileErrors [k].str ;
+
+       return bad_errnum ;
+} /* sf_error_number */
+
+const char*
+sf_strerror (SNDFILE *sndfile)
+{      SF_PRIVATE      *psf = NULL ;
+       int errnum ;
+
+       if (! sndfile)
+       {       errnum = sf_errno ;
+               if (errnum == SFE_SYSTEM && sf_syserr [0])
+                       return sf_syserr ;
+               }
+       else
+       {       psf = (SF_PRIVATE *) sndfile ;
+
+               if (psf->Magick != SNDFILE_MAGICK)
+                       return  "sf_strerror : Bad magic number." ;
+
+               errnum = psf->error ;
+
+               if (errnum == SFE_SYSTEM && psf->syserr [0])
+                       return psf->syserr ;
+               } ;
+
+       return sf_error_number (errnum) ;
+} /* sf_strerror */
+
+/*------------------------------------------------------------------------------
+*/
+
+int
+sf_error (SNDFILE *sndfile)
+{      SF_PRIVATE      *psf ;
+
+       if (! sndfile)
+       {       if (sf_error != 0)
+                       return sf_errno ;
+               return 0 ;
+               } ;
+
+       VALIDATE_SNDFILE_AND_ASSIGN_PSF (sndfile, psf, 0) ;
+
+       if (psf->error)
+               return psf->error ;
+
+       return 0 ;
+} /* sf_error */
+
+/*------------------------------------------------------------------------------
+*/
+
+int
+sf_perror (SNDFILE *sndfile)
+{      SF_PRIVATE      *psf ;
+       int             errnum ;
+
+       if (! sndfile)
+       {       errnum = sf_errno ;
+               }
+       else
+       {       VALIDATE_SNDFILE_AND_ASSIGN_PSF (sndfile, psf, 0) ;
+               errnum = psf->error ;
+               } ;
+
+       fprintf (stderr, "%s\n", sf_error_number (errnum)) ;
+       return SFE_NO_ERROR ;
+} /* sf_perror */
+
+
+/*------------------------------------------------------------------------------
+*/
+
+int
+sf_error_str (SNDFILE *sndfile, char *str, size_t maxlen)
+{      SF_PRIVATE      *psf ;
+       int             errnum ;
+
+       if (! str)
+               return SFE_INTERNAL ;
+
+       if (! sndfile)
+               errnum = sf_errno ;
+       else
+       {       VALIDATE_SNDFILE_AND_ASSIGN_PSF (sndfile, psf, 0) ;
+               errnum = psf->error ;
+               } ;
+
+       LSF_SNPRINTF (str, maxlen, "%s", sf_error_number (errnum)) ;
+
+       return SFE_NO_ERROR ;
+} /* sf_error_str */
+
+/*==============================================================================
+*/
+
+int
+sf_format_check        (const SF_INFO *info)
+{      int     subformat, endian ;
+
+       subformat = info->format & SF_FORMAT_SUBMASK ;
+       endian = info->format & SF_FORMAT_ENDMASK ;
+
+       /* This is the place where each file format can check if the suppiled
+       ** SF_INFO struct is valid.
+       ** Return 0 on failure, 1 ons success.
+       */
+
+       if (info->channels < 1 || info->channels > 256)
+               return 0 ;
+
+       if (info->samplerate < 0)
+               return 0 ;
+
+       switch (info->format & SF_FORMAT_TYPEMASK)
+       {       case SF_FORMAT_WAV :
+               case SF_FORMAT_WAVEX :
+                               /* WAV now allows both endian, RIFF or RIFX (little or big respectively) */
+                               if (subformat == SF_FORMAT_PCM_U8 || subformat == SF_FORMAT_PCM_16)
+                                       return 1 ;
+                               if (subformat == SF_FORMAT_PCM_24 || subformat == SF_FORMAT_PCM_32)
+                                       return 1 ;
+                               if ((subformat == SF_FORMAT_IMA_ADPCM || subformat == SF_FORMAT_MS_ADPCM) && info->channels <= 2)
+                                       return 1 ;
+                               if (subformat == SF_FORMAT_GSM610 && info->channels == 1)
+                                       return 1 ;
+                               if (subformat == SF_FORMAT_G721_32 && info->channels == 1)
+                                       return 1 ;
+                               if (subformat == SF_FORMAT_ULAW || subformat == SF_FORMAT_ALAW)
+                                       return 1 ;
+                               if (subformat == SF_FORMAT_FLOAT || subformat == SF_FORMAT_DOUBLE)
+                                       return 1 ;
+                               break ;
+
+               case SF_FORMAT_AIFF :
+                               /* AIFF does allow both endian-nesses for PCM data.*/
+                               if (subformat == SF_FORMAT_PCM_16 || subformat == SF_FORMAT_PCM_24 || subformat == SF_FORMAT_PCM_32)
+                                       return 1 ;
+                               /* Other encodings. Check for endian-ness. */
+                               if (endian == SF_ENDIAN_LITTLE || endian == SF_ENDIAN_CPU)
+                                       return 0 ;
+                               if (subformat == SF_FORMAT_PCM_U8 || subformat == SF_FORMAT_PCM_S8)
+                                       return 1 ;
+                               if (subformat == SF_FORMAT_FLOAT || subformat == SF_FORMAT_DOUBLE)
+                                       return 1 ;
+                               if (subformat == SF_FORMAT_ULAW || subformat == SF_FORMAT_ALAW)
+                                       return 1 ;
+                               if ((subformat == SF_FORMAT_DWVW_12 || subformat == SF_FORMAT_DWVW_16 ||
+                                                       subformat == SF_FORMAT_DWVW_24) && info-> channels == 1)
+                                       return 1 ;
+                               if (subformat == SF_FORMAT_GSM610 && info->channels == 1)
+                                       return 1 ;
+                               if (subformat == SF_FORMAT_IMA_ADPCM && (info->channels == 1 || info->channels == 2))
+                                       return 1 ;
+                               break ;
+
+               case SF_FORMAT_AU :
+                               if (subformat == SF_FORMAT_PCM_S8 || subformat == SF_FORMAT_PCM_16)
+                                       return 1 ;
+                               if (subformat == SF_FORMAT_PCM_24 || subformat == SF_FORMAT_PCM_32)
+                                       return 1 ;
+                               if (subformat == SF_FORMAT_ULAW || subformat == SF_FORMAT_ALAW)
+                                       return 1 ;
+                               if (subformat == SF_FORMAT_FLOAT || subformat == SF_FORMAT_DOUBLE)
+                                       return 1 ;
+                               if (subformat == SF_FORMAT_G721_32 && info->channels == 1)
+                                       return 1 ;
+                               if (subformat == SF_FORMAT_G723_24 && info->channels == 1)
+                                       return 1 ;
+                               if (subformat == SF_FORMAT_G723_40 && info->channels == 1)
+                                       return 1 ;
+                               break ;
+
+               case SF_FORMAT_CAF :
+                               if (subformat == SF_FORMAT_PCM_S8 || subformat == SF_FORMAT_PCM_16)
+                                       return 1 ;
+                               if (subformat == SF_FORMAT_PCM_24 || subformat == SF_FORMAT_PCM_32)
+                                       return 1 ;
+                               if (subformat == SF_FORMAT_ULAW || subformat == SF_FORMAT_ALAW)
+                                       return 1 ;
+                               if (subformat == SF_FORMAT_FLOAT || subformat == SF_FORMAT_DOUBLE)
+                                       return 1 ;
+                               break ;
+
+               case SF_FORMAT_RAW :
+                               if (subformat == SF_FORMAT_PCM_U8 || subformat == SF_FORMAT_PCM_S8 || subformat == SF_FORMAT_PCM_16)
+                                       return 1 ;
+                               if (subformat == SF_FORMAT_PCM_24 || subformat == SF_FORMAT_PCM_32)
+                                       return 1 ;
+                               if (subformat == SF_FORMAT_FLOAT || subformat == SF_FORMAT_DOUBLE)
+                                       return 1 ;
+                               if (subformat == SF_FORMAT_ALAW || subformat == SF_FORMAT_ULAW)
+                                       return 1 ;
+                               if ((subformat == SF_FORMAT_DWVW_12 || subformat == SF_FORMAT_DWVW_16 ||
+                                                       subformat == SF_FORMAT_DWVW_24) && info-> channels == 1)
+                                       return 1 ;
+                               if (subformat == SF_FORMAT_GSM610 && info->channels == 1)
+                                       return 1 ;
+                               if (subformat == SF_FORMAT_VOX_ADPCM && info->channels == 1)
+                                       return 1 ;
+                               break ;
+
+               case SF_FORMAT_PAF :
+                               if (subformat == SF_FORMAT_PCM_S8 || subformat == SF_FORMAT_PCM_16)
+                                       return 1 ;
+                               if (subformat == SF_FORMAT_PCM_24 || subformat == SF_FORMAT_PCM_32)
+                                       return 1 ;
+                               break ;
+
+               case SF_FORMAT_SVX :
+                               /* SVX currently does not support more than one channel for write.
+                               ** Read will allow more than one channel but only allow one here.
+                               */
+                               if (info->channels != 1)
+                                       return 0 ;
+                               /* Always big endian. */
+                               if (endian == SF_ENDIAN_LITTLE || endian == SF_ENDIAN_CPU)
+                                       return 0 ;
+
+                               if ((subformat == SF_FORMAT_PCM_S8 || subformat == SF_FORMAT_PCM_16) && info->channels == 1)
+                                       return 1 ;
+                               break ;
+
+               case SF_FORMAT_NIST :
+                               if (subformat == SF_FORMAT_PCM_S8 || subformat == SF_FORMAT_PCM_16)
+                                       return 1 ;
+                               if (subformat == SF_FORMAT_PCM_24 || subformat == SF_FORMAT_PCM_32)
+                                       return 1 ;
+                               if (subformat == SF_FORMAT_ULAW || subformat == SF_FORMAT_ALAW)
+                                       return 1 ;
+                               break ;
+
+               case SF_FORMAT_IRCAM :
+                               if (subformat == SF_FORMAT_PCM_16 || subformat == SF_FORMAT_PCM_24 || subformat == SF_FORMAT_PCM_32)
+                                       return 1 ;
+                               if (subformat == SF_FORMAT_ULAW || subformat == SF_FORMAT_ALAW || subformat == SF_FORMAT_FLOAT)
+                                       return 1 ;
+                               break ;
+
+               case SF_FORMAT_VOC :
+                               /* VOC is strictly little endian. */
+                               if (endian == SF_ENDIAN_BIG || endian == SF_ENDIAN_CPU)
+                                       return 0 ;
+                               if (subformat == SF_FORMAT_PCM_U8 || subformat == SF_FORMAT_PCM_16)
+                                       return 1 ;
+                               if (subformat == SF_FORMAT_ULAW || subformat == SF_FORMAT_ALAW)
+                                       return 1 ;
+                               break ;
+
+               case SF_FORMAT_W64 :
+                               /* W64 is strictly little endian. */
+                               if (endian == SF_ENDIAN_BIG || endian == SF_ENDIAN_CPU)
+                                       return 0 ;
+                               if (subformat == SF_FORMAT_PCM_U8 || subformat == SF_FORMAT_PCM_16)
+                                       return 1 ;
+                               if (subformat == SF_FORMAT_PCM_24 || subformat == SF_FORMAT_PCM_32)
+                                       return 1 ;
+                               if ((subformat == SF_FORMAT_IMA_ADPCM || subformat == SF_FORMAT_MS_ADPCM) && info->channels <= 2)
+                                       return 1 ;
+                               if (subformat == SF_FORMAT_GSM610 && info->channels == 1)
+                                       return 1 ;
+                               if (subformat == SF_FORMAT_ULAW || subformat == SF_FORMAT_ALAW)
+                                       return 1 ;
+                               if (subformat == SF_FORMAT_FLOAT || subformat == SF_FORMAT_DOUBLE)
+                                       return 1 ;
+                               break ;
+
+               case SF_FORMAT_MAT4 :
+                               if (subformat == SF_FORMAT_PCM_16 || subformat == SF_FORMAT_PCM_32)
+                                       return 1 ;
+                               if (subformat == SF_FORMAT_FLOAT || subformat == SF_FORMAT_DOUBLE)
+                                       return 1 ;
+                               break ;
+
+               case SF_FORMAT_MAT5 :
+                               if (subformat == SF_FORMAT_PCM_U8 || subformat == SF_FORMAT_PCM_16 || subformat == SF_FORMAT_PCM_32)
+                                       return 1 ;
+                               if (subformat == SF_FORMAT_FLOAT || subformat == SF_FORMAT_DOUBLE)
+                                       return 1 ;
+                               break ;
+
+               case SF_FORMAT_PVF :
+                               if (subformat == SF_FORMAT_PCM_S8 || subformat == SF_FORMAT_PCM_16 || subformat == SF_FORMAT_PCM_32)
+                                       return 1 ;
+                               break ;
+
+               case SF_FORMAT_XI :
+                               if (info->channels != 1)
+                                       return 0 ;
+                               if (subformat == SF_FORMAT_DPCM_8 || subformat == SF_FORMAT_DPCM_16)
+                                       return 1 ;
+                               break ;
+
+               case SF_FORMAT_HTK :
+                               /* HTK is strictly big endian. */
+                               if (endian == SF_ENDIAN_LITTLE || endian == SF_ENDIAN_CPU)
+                                       return 0 ;
+                               if (info->channels != 1)
+                                       return 0 ;
+                               if (subformat == SF_FORMAT_PCM_16)
+                                       return 1 ;
+                               break ;
+
+               case SF_FORMAT_SDS :
+                               /* SDS is strictly big endian. */
+                               if (endian == SF_ENDIAN_LITTLE || endian == SF_ENDIAN_CPU)
+                                       return 0 ;
+                               if (info->channels != 1)
+                                       return 0 ;
+                               if (subformat == SF_FORMAT_PCM_S8 || subformat == SF_FORMAT_PCM_16 || subformat == SF_FORMAT_PCM_24)
+                                       return 1 ;
+                               break ;
+
+               case SF_FORMAT_AVR :
+                               /* SDS is strictly big endian. */
+                               if (endian == SF_ENDIAN_LITTLE || endian == SF_ENDIAN_CPU)
+                                       return 0 ;
+                               if (info->channels > 2)
+                                       return 0 ;
+                               if (subformat == SF_FORMAT_PCM_U8 || subformat == SF_FORMAT_PCM_S8 || subformat == SF_FORMAT_PCM_16)
+                                       return 1 ;
+                               break ;
+
+               case SF_FORMAT_FLAC :
+                               /* FLAC can't do more than 8 channels. */
+                               if (info->channels > 8)
+                                       return 0 ;
+                               if (subformat == SF_FORMAT_PCM_S8 || subformat == SF_FORMAT_PCM_16 || subformat == SF_FORMAT_PCM_24)
+                                       return 1 ;
+                               break ;
+
+               case SF_FORMAT_SD2 :
+                               /* SD2 is strictly big endian. */
+                               if (endian == SF_ENDIAN_LITTLE || endian == SF_ENDIAN_CPU)
+                                       return 0 ;
+                               if (subformat == SF_FORMAT_PCM_S8 || subformat == SF_FORMAT_PCM_16 || subformat == SF_FORMAT_PCM_24)
+                                       return 1 ;
+                               break ;
+
+               default : break ;
+               } ;
+
+       return 0 ;
+} /* sf_format_check */
+
+/*------------------------------------------------------------------------------
+*/
+
+int
+sf_command     (SNDFILE *sndfile, int command, void *data, int datasize)
+{      SF_PRIVATE      *psf = NULL ;
+       int old_value ;
+
+       /* This set of commands do not need the sndfile parameter. */
+       switch (command)
+       {       case SFC_GET_LIB_VERSION :
+                       if (data == NULL)
+                               return (psf->error = SFE_BAD_CONTROL_CMD) ;
+                       if (ENABLE_EXPERIMENTAL_CODE)
+                               LSF_SNPRINTF (data, datasize, "%s-%s-exp", PACKAGE_NAME, PACKAGE_VERSION) ;
+                       else
+                               LSF_SNPRINTF (data, datasize, "%s-%s", PACKAGE_NAME, PACKAGE_VERSION) ;
+                       return strlen (data) ;
+
+               case SFC_GET_SIMPLE_FORMAT_COUNT :
+                       if (data == NULL || datasize != SIGNED_SIZEOF (int))
+                               return (sf_errno = SFE_BAD_CONTROL_CMD) ;
+                       *((int*) data) = psf_get_format_simple_count () ;
+                       return 0 ;
+
+               case SFC_GET_SIMPLE_FORMAT :
+                       if (data == NULL || datasize != SIGNED_SIZEOF (SF_FORMAT_INFO))
+                               return (sf_errno = SFE_BAD_CONTROL_CMD) ;
+                       return psf_get_format_simple (data) ;
+
+               case SFC_GET_FORMAT_MAJOR_COUNT :
+                       if (data == NULL || datasize != SIGNED_SIZEOF (int))
+                               return (sf_errno = SFE_BAD_CONTROL_CMD) ;
+                       *((int*) data) = psf_get_format_major_count () ;
+                       return 0 ;
+
+               case SFC_GET_FORMAT_MAJOR :
+                       if (data == NULL || datasize != SIGNED_SIZEOF (SF_FORMAT_INFO))
+                               return (sf_errno = SFE_BAD_CONTROL_CMD) ;
+                       return psf_get_format_major (data) ;
+
+               case SFC_GET_FORMAT_SUBTYPE_COUNT :
+                       if (data == NULL || datasize != SIGNED_SIZEOF (int))
+                               return (sf_errno = SFE_BAD_CONTROL_CMD) ;
+                       *((int*) data) = psf_get_format_subtype_count () ;
+                       return 0 ;
+
+               case SFC_GET_FORMAT_SUBTYPE :
+                       if (data == NULL || datasize != SIGNED_SIZEOF (SF_FORMAT_INFO))
+                               return (sf_errno = SFE_BAD_CONTROL_CMD) ;
+                       return psf_get_format_subtype (data) ;
+
+               case SFC_GET_FORMAT_INFO :
+                       if (data == NULL || datasize != SIGNED_SIZEOF (SF_FORMAT_INFO))
+                               return (sf_errno = SFE_BAD_CONTROL_CMD) ;
+                       return psf_get_format_info (data) ;
+               } ;
+
+       if (sndfile == NULL && command == SFC_GET_LOG_INFO)
+       {       if (data == NULL)
+                       return (psf->error = SFE_BAD_CONTROL_CMD) ;
+               LSF_SNPRINTF (data, datasize, "%s", sf_logbuffer) ;
+               return strlen (data) ;
+               } ;
+
+       VALIDATE_SNDFILE_AND_ASSIGN_PSF (sndfile, psf, 1) ;
+
+       switch (command)
+       {       case SFC_SET_NORM_FLOAT :
+                       old_value = psf->norm_float ;
+                       psf->norm_float = (datasize) ? SF_TRUE : SF_FALSE ;
+                       return old_value ;
+
+               case SFC_SET_NORM_DOUBLE :
+                       old_value = psf->norm_double ;
+                       psf->norm_double = (datasize) ? SF_TRUE : SF_FALSE ;
+                       return old_value ;
+
+               case SFC_GET_NORM_FLOAT :
+                       return psf->norm_float ;
+
+               case SFC_GET_NORM_DOUBLE :
+                       return psf->norm_double ;
+
+               case SFC_SET_SCALE_FLOAT_INT_READ :
+                       old_value = psf->float_int_mult ;
+
+                       psf->float_int_mult = (datasize != 0) ? SF_TRUE : SF_FALSE ;
+                       if (psf->float_int_mult && psf->float_max < 0.0)
+                               psf->float_max = psf_calc_signal_max (psf, SF_FALSE) ;
+                       return old_value ;
+
+               case SFC_SET_ADD_PEAK_CHUNK :
+                       {       int format = psf->sf.format & SF_FORMAT_TYPEMASK ;
+
+                               /* Only WAV and AIFF support the PEAK chunk. */
+                               if (format != SF_FORMAT_WAV && format != SF_FORMAT_WAVEX && format != SF_FORMAT_AIFF)
+                                       return SF_FALSE ;
+
+                               format = psf->sf.format & SF_FORMAT_SUBMASK ;
+
+                               /* Only files containg the following data types support the PEAK chunk. */
+                               if (format != SF_FORMAT_FLOAT && format != SF_FORMAT_DOUBLE)
+                                       return SF_FALSE ;
+
+                               } ;
+                       /* Can only do this is in SFM_WRITE mode. */
+                       if (psf->mode != SFM_WRITE)
+                               return SF_FALSE ;
+                       /* If data has already been written this must fail. */
+                       if (psf->have_written)
+                               return SF_FALSE ;
+                       /* Everything seems OK, so set psf->has_peak and re-write header. */
+                       if (datasize == SF_FALSE && psf->peak_info != NULL)
+                       {       free (psf->peak_info) ;
+                               psf->peak_info = NULL ;
+                               }
+                       else if (psf->peak_info == NULL)
+                       {       psf->peak_info = peak_info_calloc (psf->sf.channels) ;
+                               psf->peak_info->peak_loc = SF_PEAK_START ;
+                               } ;
+
+                       if (psf->write_header)
+                               psf->write_header (psf, SF_TRUE) ;
+                       return datasize ;
+
+               case SFC_GET_LOG_INFO :
+                       if (data == NULL)
+                               return (psf->error = SFE_BAD_CONTROL_CMD) ;
+                       LSF_SNPRINTF (data, datasize, "%s", psf->logbuffer) ;
+                       break ;
+
+               case SFC_CALC_SIGNAL_MAX :
+                       if (data == NULL || datasize != sizeof (double))
+                               return (psf->error = SFE_BAD_CONTROL_CMD) ;
+                       *((double*) data) = psf_calc_signal_max (psf, SF_FALSE) ;
+                       break ;
+
+               case SFC_CALC_NORM_SIGNAL_MAX :
+                       if (data == NULL || datasize != sizeof (double))
+                               return (psf->error = SFE_BAD_CONTROL_CMD) ;
+                       *((double*) data) = psf_calc_signal_max (psf, SF_TRUE) ;
+                       break ;
+
+               case SFC_CALC_MAX_ALL_CHANNELS :
+                       if (data == NULL || datasize != SIGNED_SIZEOF (double) * psf->sf.channels)
+                               return (psf->error = SFE_BAD_CONTROL_CMD) ;
+                       return psf_calc_max_all_channels (psf, (double*) data, SF_FALSE) ;
+
+               case SFC_CALC_NORM_MAX_ALL_CHANNELS :
+                       if (data == NULL || datasize != SIGNED_SIZEOF (double) * psf->sf.channels)
+                               return (psf->error = SFE_BAD_CONTROL_CMD) ;
+                       return psf_calc_max_all_channels (psf, (double*) data, SF_TRUE) ;
+
+               case SFC_GET_SIGNAL_MAX :
+                       if (data == NULL || datasize != sizeof (double))
+                       {       psf->error = SFE_BAD_CONTROL_CMD ;
+                               return SF_FALSE ;
+                               } ;
+                       return psf_get_signal_max (psf, (double *) data) ;
+
+               case SFC_GET_MAX_ALL_CHANNELS :
+                       if (data == NULL || datasize != SIGNED_SIZEOF (double) * psf->sf.channels)
+                       {       psf->error = SFE_BAD_CONTROL_CMD ;
+                               return SF_FALSE ;
+                               } ;
+                       return psf_get_max_all_channels (psf, (double*) data) ;
+
+               case SFC_UPDATE_HEADER_NOW :
+                       if (psf->write_header)
+                               psf->write_header (psf, SF_TRUE) ;
+                       break ;
+
+               case SFC_SET_UPDATE_HEADER_AUTO :
+                       psf->auto_header = datasize ? SF_TRUE : SF_FALSE ;
+                       return psf->auto_header ;
+                       break ;
+
+               case SFC_SET_ADD_DITHER_ON_WRITE :
+               case SFC_SET_ADD_DITHER_ON_READ :
+                       /*
+                       ** FIXME !
+                       ** These are obsolete. Just return.
+                       ** Remove some time after version 1.0.8.
+                       */
+                       break ;
+
+               case SFC_SET_DITHER_ON_WRITE :
+                       if (data == NULL || datasize != SIGNED_SIZEOF (SF_DITHER_INFO))
+                               return (psf->error = SFE_BAD_CONTROL_CMD) ;
+                       memcpy (&psf->write_dither, data, sizeof (psf->write_dither)) ;
+                       if (psf->mode == SFM_WRITE || psf->mode == SFM_RDWR)
+                               dither_init (psf, SFM_WRITE) ;
+                       break ;
+
+               case SFC_SET_DITHER_ON_READ :
+                       if (data == NULL || datasize != SIGNED_SIZEOF (SF_DITHER_INFO))
+                               return (psf->error = SFE_BAD_CONTROL_CMD) ;
+                       memcpy (&psf->read_dither, data, sizeof (psf->read_dither)) ;
+                       if (psf->mode == SFM_READ || psf->mode == SFM_RDWR)
+                               dither_init (psf, SFM_READ) ;
+                       break ;
+
+               case SFC_FILE_TRUNCATE :
+                       if (psf->mode != SFM_WRITE && psf->mode != SFM_RDWR)
+                               return SF_TRUE ;
+                       if (datasize != sizeof (sf_count_t))
+                               return SF_TRUE ;
+                       {       sf_count_t position ;
+
+                               position = *((sf_count_t*) data) ;
+
+                               if (sf_seek (sndfile, position, SEEK_SET) != position)
+                                       return SF_TRUE ;
+
+                               psf->sf.frames = position ;
+
+                               position = psf_fseek (psf, 0, SEEK_CUR) ;
+
+                               return psf_ftruncate (psf, position) ;
+                               } ;
+                       break ;
+
+               case SFC_SET_RAW_START_OFFSET :
+                       if (data == NULL || datasize != sizeof (sf_count_t))
+                               return (psf->error = SFE_BAD_CONTROL_CMD) ;
+                       if ((psf->sf.format & SF_FORMAT_TYPEMASK) != SF_FORMAT_RAW)
+                               return (psf->error = SFE_BAD_CONTROL_CMD) ;
+
+                       psf->dataoffset = *((sf_count_t*) data) ;
+                       sf_seek (sndfile, 0, SEEK_CUR) ;
+                       break ;
+
+               case SFC_GET_EMBED_FILE_INFO :
+                       if (data == NULL || datasize != sizeof (SF_EMBED_FILE_INFO))
+                               return (psf->error = SFE_BAD_CONTROL_CMD) ;
+
+                       ((SF_EMBED_FILE_INFO*) data)->offset = psf->fileoffset ;
+                       ((SF_EMBED_FILE_INFO*) data)->length = psf->filelength ;
+                       break ;
+
+               /* Lite remove start */
+               case SFC_TEST_IEEE_FLOAT_REPLACE :
+                       psf->ieee_replace = (datasize) ? SF_TRUE : SF_FALSE ;
+                       if ((psf->sf.format & SF_FORMAT_SUBMASK) == SF_FORMAT_FLOAT)
+                               float32_init (psf) ;
+                       else if ((psf->sf.format & SF_FORMAT_SUBMASK) == SF_FORMAT_DOUBLE)
+                               double64_init (psf) ;
+                       else
+                               return (psf->error = SFE_BAD_CONTROL_CMD) ;
+                       break ;
+               /* Lite remove end */
+
+               case SFC_SET_CLIPPING :
+                       psf->add_clipping = (datasize) ? SF_TRUE : SF_FALSE ;
+                       return psf->add_clipping ;
+
+               case SFC_GET_CLIPPING :
+                       return psf->add_clipping ;
+
+               case SFC_GET_LOOP_INFO :
+                       if (datasize != sizeof (SF_LOOP_INFO) || data == NULL)
+                               return SF_FALSE ;
+                       if (psf->loop_info == NULL)
+                               return SF_FALSE ;
+                       memcpy (data, psf->loop_info, sizeof (SF_LOOP_INFO)) ;
+                       return SF_TRUE ;
+
+               case SFC_SET_BROADCAST_INFO :
+                       {       int format = psf->sf.format & SF_FORMAT_TYPEMASK ;
+
+                               /* Only WAV supports the BEXT (Broadcast) chunk. */
+                               if (format != SF_FORMAT_WAV && format != SF_FORMAT_WAVEX) 
+                                       return SF_FALSE ;
+                                } ;
+
+                       /* Can only do this is in SFM_RDWR or SFM_WRITE modes. */
+                       if (psf->mode == SFM_READ)
+                               return SF_FALSE ;
+
+                       /* If data has already been written this must fail. */
+                       if (psf->broadcast_info == NULL && psf->have_written) 
+                               return SF_FALSE ;
+
+                       if (psf->broadcast_info == NULL)
+                               psf->broadcast_info = broadcast_info_alloc () ;
+
+                       broadcast_info_copy (psf->broadcast_info, data) ;
+                       broadcast_add_coding_history (psf->broadcast_info, psf->sf.channels, psf->sf.samplerate) ;
+
+                       if (psf->write_header)
+                               psf->write_header (psf, SF_TRUE) ;
+                       return SF_TRUE ;
+
+               case SFC_GET_BROADCAST_INFO :
+                       if (datasize != sizeof (SF_BROADCAST_INFO) || data == NULL)
+                               return SF_FALSE ;
+                       if (psf->broadcast_info == NULL)
+                               return SF_FALSE ;
+                       return broadcast_info_copy (data, psf->broadcast_info) ;
+
+               case SFC_GET_INSTRUMENT :
+                       if (datasize != sizeof (SF_INSTRUMENT) || data == NULL)
+                               return SF_FALSE ;
+                       if (psf->instrument == NULL)
+                               return SF_FALSE ;
+                       memcpy (data, psf->instrument, sizeof (SF_INSTRUMENT)) ;
+                       return SF_TRUE ;
+
+               case SFC_SET_INSTRUMENT :
+                       /* If data has already been written this must fail. */
+                       if (psf->have_written)
+                               return SF_FALSE ;
+                       if (datasize != sizeof (SF_INSTRUMENT) || data == NULL)
+                               return SF_FALSE ;
+                       if (psf->instrument == NULL && (psf->instrument = psf_instrument_alloc ()) == NULL)
+                       {       psf->error = SFE_MALLOC_FAILED ;
+                               return SF_FALSE ;
+                               } ;
+                       memcpy (psf->instrument, data, sizeof (SF_INSTRUMENT)) ;
+                       return SF_TRUE ;
+
+               default :
+                       /* Must be a file specific command. Pass it on. */
+                       if (psf->command)
+                               return psf->command (psf, command, data, datasize) ;
+
+                       psf_log_printf (psf, "*** sf_command : cmd = 0x%X\n", command) ;
+                       return (psf->error = SFE_BAD_CONTROL_CMD) ;
+               } ;
+
+       return 0 ;
+} /* sf_command */
+
+/*------------------------------------------------------------------------------
+*/
+
+sf_count_t
+sf_seek        (SNDFILE *sndfile, sf_count_t offset, int whence)
+{      SF_PRIVATE      *psf ;
+       sf_count_t      seek_from_start = 0, retval ;
+
+       VALIDATE_SNDFILE_AND_ASSIGN_PSF (sndfile, psf, 1) ;
+
+       if (! psf->sf.seekable)
+       {       psf->error = SFE_NOT_SEEKABLE ;
+               return  PSF_SEEK_ERROR ;
+               } ;
+
+       /* If the whence parameter has a mode ORed in, check to see that
+       ** it makes sense.
+       */
+       if (((whence & SFM_MASK) == SFM_WRITE && psf->mode == SFM_READ) ||
+                       ((whence & SFM_MASK) == SFM_WRITE && psf->mode == SFM_WRITE))
+       {       psf->error = SFE_WRONG_SEEK ;
+               return PSF_SEEK_ERROR ;
+               } ;
+
+       /* Convert all SEEK_CUR and SEEK_END into seek_from_start to be
+       ** used with SEEK_SET.
+       */
+       switch (whence)
+       {       /* The SEEK_SET behaviour is independant of mode. */
+               case SEEK_SET :
+               case SEEK_SET | SFM_READ :
+               case SEEK_SET | SFM_WRITE :
+               case SEEK_SET | SFM_RDWR :
+                               seek_from_start = offset ;
+                               break ;
+
+               /* The SEEK_CUR is a little more tricky. */
+               case SEEK_CUR :
+                               if (offset == 0)
+                               {       if (psf->mode == SFM_READ)
+                                               return psf->read_current ;
+                                       if (psf->mode == SFM_WRITE)
+                                               return psf->write_current ;
+                                       } ;
+                               if (psf->mode == SFM_READ)
+                                       seek_from_start = psf->read_current + offset ;
+                               else if (psf->mode == SFM_WRITE || psf->mode == SFM_RDWR)
+                                       seek_from_start = psf->write_current + offset ;
+                               else
+                                       psf->error = SFE_AMBIGUOUS_SEEK ;
+                               break ;
+
+               case SEEK_CUR | SFM_READ :
+                               if (offset == 0)
+                                       return psf->read_current ;
+                               seek_from_start = psf->read_current + offset ;
+                               break ;
+
+               case SEEK_CUR | SFM_WRITE :
+                               if (offset == 0)
+                                       return psf->write_current ;
+                               seek_from_start = psf->write_current + offset ;
+                               break ;
+
+               /* The SEEK_END */
+               case SEEK_END :
+               case SEEK_END | SFM_READ :
+               case SEEK_END | SFM_WRITE :
+                               seek_from_start = psf->sf.frames + offset ;
+                               break ;
+
+               default :
+                               psf->error = SFE_BAD_SEEK ;
+                               break ;
+               } ;
+
+       if (psf->error)
+               return PSF_SEEK_ERROR ;
+
+       if (seek_from_start < 0 || seek_from_start > psf->sf.frames)
+       {       psf->error = SFE_BAD_SEEK ;
+               return PSF_SEEK_ERROR ;
+               } ;
+
+       if (psf->seek)
+       {       int new_mode = (whence & SFM_MASK) ? (whence & SFM_MASK) : psf->mode ;
+
+               retval = psf->seek (psf, new_mode, seek_from_start) ;
+
+               switch (new_mode)
+               {       case SFM_READ :
+                                       psf->read_current = retval ;
+                                       break ;
+                       case SFM_WRITE :
+                                       psf->write_current = retval ;
+                                       break ;
+                       case SFM_RDWR :
+                                       psf->read_current = retval ;
+                                       psf->write_current = retval ;
+                                       new_mode = SFM_READ ;
+                                       break ;
+                       } ;
+
+               psf->last_op = new_mode ;
+
+               return retval ;
+               } ;
+
+       psf->error = SFE_AMBIGUOUS_SEEK ;
+       return PSF_SEEK_ERROR ;
+} /* sf_seek */
+
+/*------------------------------------------------------------------------------
+*/
+
+const char*
+sf_get_string (SNDFILE *sndfile, int str_type)
+{      SF_PRIVATE      *psf ;
+
+       if ((psf = (SF_PRIVATE*) sndfile) == NULL)
+               return NULL ;
+       if (psf->Magick != SNDFILE_MAGICK)
+               return NULL ;
+
+       return psf_get_string (psf, str_type) ;
+} /* sf_get_string */
+
+int
+sf_set_string (SNDFILE *sndfile, int str_type, const char* str)
+{      SF_PRIVATE      *psf ;
+
+       VALIDATE_SNDFILE_AND_ASSIGN_PSF (sndfile, psf, 1) ;
+
+       return psf_set_string (psf, str_type, str) ;
+} /* sf_get_string */
+
+/*==============================================================================
+*/
+
+sf_count_t
+sf_read_raw            (SNDFILE *sndfile, void *ptr, sf_count_t bytes)
+{      SF_PRIVATE      *psf ;
+       sf_count_t      count ;
+       int                     bytewidth, blockwidth ;
+
+       VALIDATE_SNDFILE_AND_ASSIGN_PSF (sndfile, psf, 1) ;
+
+       bytewidth = (psf->bytewidth > 0) ? psf->bytewidth : 1 ;
+       blockwidth = (psf->blockwidth > 0) ? psf->blockwidth : 1 ;
+
+       if (psf->mode == SFM_WRITE)
+       {       psf->error = SFE_NOT_READMODE ;
+               return  0 ;
+               } ;
+
+       if (bytes < 0 || psf->read_current >= psf->datalength)
+       {       psf_memset (ptr, 0, bytes) ;
+               return 0 ;
+               } ;
+
+       if (bytes % (psf->sf.channels * bytewidth))
+       {       psf->error = SFE_BAD_READ_ALIGN ;
+               return 0 ;
+               } ;
+
+       count = psf_fread (ptr, 1, bytes, psf) ;
+
+       if (count < bytes)
+               psf_memset (((char*) ptr) + count, 0, bytes - count) ;
+
+       psf->read_current += count / blockwidth ;
+
+       psf->last_op = SFM_READ ;
+
+       return count ;
+} /* sf_read_raw */
+
+/*------------------------------------------------------------------------------
+*/
+
+sf_count_t
+sf_read_short  (SNDFILE *sndfile, short *ptr, sf_count_t len)
+{      SF_PRIVATE      *psf ;
+       sf_count_t      count, extra ;
+
+       VALIDATE_SNDFILE_AND_ASSIGN_PSF (sndfile, psf, 1) ;
+
+       if (psf->mode == SFM_WRITE)
+       {       psf->error = SFE_NOT_READMODE ;
+               return 0 ;
+               } ;
+
+       if (len % psf->sf.channels)
+       {       psf->error = SFE_BAD_READ_ALIGN ;
+               return 0 ;
+               } ;
+
+       if (len <= 0 || psf->read_current >= psf->sf.frames)
+       {       psf_memset (ptr, 0, len * sizeof (short)) ;
+               return 0 ; /* End of file. */
+               } ;
+
+       if (! psf->read_short || psf->seek == NULL)
+       {       psf->error = SFE_UNIMPLEMENTED ;
+               return  0 ;
+               } ;
+
+       if (psf->last_op != SFM_READ)
+               if (psf->seek (psf, SFM_READ, psf->read_current) < 0)
+                       return 0 ;
+
+       count = psf->read_short (psf, ptr, len) ;
+
+       if (psf->read_current + count / psf->sf.channels > psf->sf.frames)
+       {       count = (psf->sf.frames - psf->read_current) * psf->sf.channels ;
+               extra = len - count ;
+               psf_memset (ptr + count, 0, extra * sizeof (short)) ;
+               psf->read_current = psf->sf.frames ;
+               } ;
+
+       psf->read_current += count / psf->sf.channels ;
+
+       psf->last_op = SFM_READ ;
+
+       if (psf->read_current > psf->sf.frames)
+       {       count = psf->sf.channels * (psf->read_current - psf->sf.frames) ;
+               psf->read_current = psf->sf.frames ;
+               } ;
+
+       return count ;
+} /* sf_read_short */
+
+sf_count_t
+sf_readf_short         (SNDFILE *sndfile, short *ptr, sf_count_t frames)
+{      SF_PRIVATE      *psf ;
+       sf_count_t      count, extra ;
+
+       VALIDATE_SNDFILE_AND_ASSIGN_PSF (sndfile, psf, 1) ;
+
+       if (psf->mode == SFM_WRITE)
+       {       psf->error = SFE_NOT_READMODE ;
+               return 0 ;
+               } ;
+
+       if (frames <= 0 || psf->read_current >= psf->sf.frames)
+       {       psf_memset (ptr, 0, frames * psf->sf.channels * sizeof (short)) ;
+               return 0 ; /* End of file. */
+               } ;
+
+       if (! psf->read_short || psf->seek == NULL)
+       {       psf->error = SFE_UNIMPLEMENTED ;
+               return 0 ;
+               } ;
+
+       if (psf->last_op != SFM_READ)
+               if (psf->seek (psf, SFM_READ, psf->read_current) < 0)
+                       return 0 ;
+
+       count = psf->read_short (psf, ptr, frames * psf->sf.channels) ;
+
+       if (psf->read_current + count / psf->sf.channels > psf->sf.frames)
+       {       count = (psf->sf.frames - psf->read_current) * psf->sf.channels ;
+               extra = frames * psf->sf.channels - count ;
+               psf_memset (ptr + count, 0, extra * sizeof (short)) ;
+               psf->read_current = psf->sf.frames ;
+               } ;
+
+       psf->read_current += count / psf->sf.channels ;
+
+       psf->last_op = SFM_READ ;
+
+       if (psf->read_current > psf->sf.frames)
+       {       count = psf->sf.channels * (psf->read_current - psf->sf.frames) ;
+               psf->read_current = psf->sf.frames ;
+               } ;
+
+       return count / psf->sf.channels ;
+} /* sf_readf_short */
+
+/*------------------------------------------------------------------------------
+*/
+
+sf_count_t
+sf_read_int            (SNDFILE *sndfile, int *ptr, sf_count_t len)
+{      SF_PRIVATE      *psf ;
+       sf_count_t      count, extra ;
+
+       VALIDATE_SNDFILE_AND_ASSIGN_PSF (sndfile, psf, 1) ;
+
+       if (psf->mode == SFM_WRITE)
+       {       psf->error = SFE_NOT_READMODE ;
+               return 0 ;
+               } ;
+
+       if (len % psf->sf.channels)
+       {       psf->error = SFE_BAD_READ_ALIGN ;
+               return 0 ;
+               } ;
+
+       if (len <= 0 || psf->read_current >= psf->sf.frames)
+       {       psf_memset (ptr, 0, len * sizeof (int)) ;
+               return 0 ;
+               } ;
+
+       if (! psf->read_int || psf->seek == NULL)
+       {       psf->error = SFE_UNIMPLEMENTED ;
+               return 0 ;
+               } ;
+
+       if (psf->last_op != SFM_READ)
+               if (psf->seek (psf, SFM_READ, psf->read_current) < 0)
+                       return 0 ;
+
+       count = psf->read_int (psf, ptr, len) ;
+
+       if (psf->read_current + count / psf->sf.channels > psf->sf.frames)
+       {       count = (psf->sf.frames - psf->read_current) * psf->sf.channels ;
+               extra = len - count ;
+               psf_memset (ptr + count, 0, extra * sizeof (int)) ;
+               psf->read_current = psf->sf.frames ;
+               } ;
+
+       psf->read_current += count / psf->sf.channels ;
+
+       psf->last_op = SFM_READ ;
+
+       if (psf->read_current > psf->sf.frames)
+       {       count = psf->sf.channels * (psf->read_current - psf->sf.frames) ;
+               psf->read_current = psf->sf.frames ;
+               } ;
+
+       return count ;
+} /* sf_read_int */
+
+sf_count_t
+sf_readf_int   (SNDFILE *sndfile, int *ptr, sf_count_t frames)
+{      SF_PRIVATE      *psf ;
+       sf_count_t      count, extra ;
+
+       VALIDATE_SNDFILE_AND_ASSIGN_PSF (sndfile, psf, 1) ;
+
+       if (psf->mode == SFM_WRITE)
+       {       psf->error = SFE_NOT_READMODE ;
+               return 0 ;
+               } ;
+
+       if (frames <= 0 || psf->read_current >= psf->sf.frames)
+       {       psf_memset (ptr, 0, frames * psf->sf.channels * sizeof (int)) ;
+               return 0 ;
+               } ;
+
+       if (! psf->read_int || psf->seek == NULL)
+       {       psf->error = SFE_UNIMPLEMENTED ;
+               return  0 ;
+               } ;
+
+       if (psf->last_op != SFM_READ)
+               if (psf->seek (psf, SFM_READ, psf->read_current) < 0)
+                       return 0 ;
+
+       count = psf->read_int (psf, ptr, frames * psf->sf.channels) ;
+
+       if (psf->read_current + count / psf->sf.channels > psf->sf.frames)
+       {       count = (psf->sf.frames - psf->read_current) * psf->sf.channels ;
+               extra = frames * psf->sf.channels - count ;
+               psf_memset (ptr + count, 0, extra * sizeof (int)) ;
+               psf->read_current = psf->sf.frames ;
+               } ;
+
+       psf->read_current += count / psf->sf.channels ;
+
+       psf->last_op = SFM_READ ;
+
+       if (psf->read_current > psf->sf.frames)
+       {       count = psf->sf.channels * (psf->read_current - psf->sf.frames) ;
+               psf->read_current = psf->sf.frames ;
+               } ;
+
+       return count / psf->sf.channels ;
+} /* sf_readf_int */
+
+/*------------------------------------------------------------------------------
+*/
+
+sf_count_t
+sf_read_float  (SNDFILE *sndfile, float *ptr, sf_count_t len)
+{      SF_PRIVATE      *psf ;
+       sf_count_t      count, extra ;
+
+       VALIDATE_SNDFILE_AND_ASSIGN_PSF (sndfile, psf, 1) ;
+
+       if (psf->mode == SFM_WRITE)
+       {       psf->error = SFE_NOT_READMODE ;
+               return 0 ;
+               } ;
+
+       if (len % psf->sf.channels)
+       {       psf->error = SFE_BAD_READ_ALIGN ;
+               return 0 ;
+               } ;
+
+       if (len <= 0 || psf->read_current >= psf->sf.frames)
+       {       psf_memset (ptr, 0, len * sizeof (float)) ;
+               return 0 ;
+               } ;
+
+       if (! psf->read_float || psf->seek == NULL)
+       {       psf->error = SFE_UNIMPLEMENTED ;
+               return  0 ;
+               } ;
+
+       if (psf->last_op != SFM_READ)
+               if (psf->seek (psf, SFM_READ, psf->read_current) < 0)
+                       return 0 ;
+
+       count = psf->read_float (psf, ptr, len) ;
+
+       if (psf->read_current + count / psf->sf.channels > psf->sf.frames)
+       {       count = (psf->sf.frames - psf->read_current) * psf->sf.channels ;
+               extra = len - count ;
+               psf_memset (ptr + count, 0, extra * sizeof (float)) ;
+               psf->read_current = psf->sf.frames ;
+               } ;
+
+       psf->read_current += count / psf->sf.channels ;
+
+       psf->last_op = SFM_READ ;
+
+       if (psf->read_current > psf->sf.frames)
+       {       count = psf->sf.channels * (psf->read_current - psf->sf.frames) ;
+               psf->read_current = psf->sf.frames ;
+               } ;
+
+       return count ;
+} /* sf_read_float */
+
+sf_count_t
+sf_readf_float (SNDFILE *sndfile, float *ptr, sf_count_t frames)
+{      SF_PRIVATE      *psf ;
+       sf_count_t      count, extra ;
+
+       VALIDATE_SNDFILE_AND_ASSIGN_PSF (sndfile, psf, 1) ;
+
+       if (psf->mode == SFM_WRITE)
+       {       psf->error = SFE_NOT_READMODE ;
+               return 0 ;
+               } ;
+
+       if (frames <= 0 || psf->read_current >= psf->sf.frames)
+       {       psf_memset (ptr, 0, frames * psf->sf.channels * sizeof (float)) ;
+               return 0 ;
+               } ;
+
+       if (! psf->read_float || psf->seek == NULL)
+       {       psf->error = SFE_UNIMPLEMENTED ;
+               return  0 ;
+               } ;
+
+       if (psf->last_op != SFM_READ)
+               if (psf->seek (psf, SFM_READ, psf->read_current) < 0)
+                       return 0 ;
+
+       count = psf->read_float (psf, ptr, frames * psf->sf.channels) ;
+
+       if (psf->read_current + count / psf->sf.channels > psf->sf.frames)
+       {       count = (psf->sf.frames - psf->read_current) * psf->sf.channels ;
+               extra = frames * psf->sf.channels - count ;
+               psf_memset (ptr + count, 0, extra * sizeof (float)) ;
+               psf->read_current = psf->sf.frames ;
+               } ;
+
+       psf->read_current += count / psf->sf.channels ;
+
+       psf->last_op = SFM_READ ;
+
+       if (psf->read_current > psf->sf.frames)
+       {       count = psf->sf.channels * (psf->read_current - psf->sf.frames) ;
+               psf->read_current = psf->sf.frames ;
+               } ;
+
+       return count / psf->sf.channels ;
+} /* sf_readf_float */
+
+/*------------------------------------------------------------------------------
+*/
+
+sf_count_t
+sf_read_double (SNDFILE *sndfile, double *ptr, sf_count_t len)
+{      SF_PRIVATE      *psf ;
+       sf_count_t      count, extra ;
+
+       VALIDATE_SNDFILE_AND_ASSIGN_PSF (sndfile, psf, 1) ;
+
+       if (psf->mode == SFM_WRITE)
+       {       psf->error = SFE_NOT_READMODE ;
+               return 0 ;
+               } ;
+
+       if (len % psf->sf.channels)
+       {       psf->error = SFE_BAD_READ_ALIGN ;
+               return 0 ;
+               } ;
+
+       if (len <= 0 || psf->read_current >= psf->sf.frames)
+       {       psf_memset (ptr, 0, len * sizeof (double)) ;
+               return 0 ;
+               } ;
+
+       if (! psf->read_double || psf->seek == NULL)
+       {       psf->error = SFE_UNIMPLEMENTED ;
+               return  0 ;
+               } ;
+
+       if (psf->last_op != SFM_READ)
+               if (psf->seek (psf, SFM_READ, psf->read_current) < 0)
+                       return 0 ;
+
+       count = psf->read_double (psf, ptr, len) ;
+
+       if (psf->read_current + count / psf->sf.channels > psf->sf.frames)
+       {       count = (psf->sf.frames - psf->read_current) * psf->sf.channels ;
+               extra = len - count ;
+               psf_memset (ptr + count, 0, extra * sizeof (double)) ;
+               psf->read_current = psf->sf.frames ;
+               } ;
+
+       psf->read_current += count / psf->sf.channels ;
+
+       psf->last_op = SFM_READ ;
+
+       if (psf->read_current > psf->sf.frames)
+       {       count = psf->sf.channels * (psf->read_current - psf->sf.frames) ;
+               psf->read_current = psf->sf.frames ;
+               } ;
+
+       return count ;
+} /* sf_read_double */
+
+sf_count_t
+sf_readf_double        (SNDFILE *sndfile, double *ptr, sf_count_t frames)
+{      SF_PRIVATE      *psf ;
+       sf_count_t      count, extra ;
+
+       VALIDATE_SNDFILE_AND_ASSIGN_PSF (sndfile, psf, 1) ;
+
+       if (psf->mode == SFM_WRITE)
+       {       psf->error = SFE_NOT_READMODE ;
+               return 0 ;
+               } ;
+
+       if (frames <= 0 || psf->read_current >= psf->sf.frames)
+       {       psf_memset (ptr, 0, frames * psf->sf.channels * sizeof (double)) ;
+               return 0 ;
+               } ;
+
+       if (! psf->read_double || psf->seek == NULL)
+       {       psf->error = SFE_UNIMPLEMENTED ;
+               return  0 ;
+               } ;
+
+       if (psf->last_op != SFM_READ)
+               if (psf->seek (psf, SFM_READ, psf->read_current) < 0)
+                       return 0 ;
+
+       count = psf->read_double (psf, ptr, frames * psf->sf.channels) ;
+
+       if (psf->read_current + count / psf->sf.channels > psf->sf.frames)
+       {       count = (psf->sf.frames - psf->read_current) * psf->sf.channels ;
+               extra = frames * psf->sf.channels - count ;
+               psf_memset (ptr + count, 0, extra * sizeof (double)) ;
+               psf->read_current = psf->sf.frames ;
+               } ;
+
+       psf->read_current += count / psf->sf.channels ;
+
+       psf->last_op = SFM_READ ;
+
+       if (psf->read_current > psf->sf.frames)
+       {       count = psf->sf.channels * (psf->read_current - psf->sf.frames) ;
+               psf->read_current = psf->sf.frames ;
+               } ;
+
+       return count / psf->sf.channels ;
+} /* sf_readf_double */
+
+/*------------------------------------------------------------------------------
+*/
+
+sf_count_t
+sf_write_raw   (SNDFILE *sndfile, const void *ptr, sf_count_t len)
+{      SF_PRIVATE      *psf ;
+       sf_count_t      count ;
+       int                     bytewidth, blockwidth ;
+
+       VALIDATE_SNDFILE_AND_ASSIGN_PSF (sndfile, psf, 1) ;
+
+       bytewidth = (psf->bytewidth > 0) ? psf->bytewidth : 1 ;
+       blockwidth = (psf->blockwidth > 0) ? psf->blockwidth : 1 ;
+
+       if (psf->mode == SFM_READ)
+       {       psf->error = SFE_NOT_WRITEMODE ;
+               return 0 ;
+               } ;
+
+       if (len % (psf->sf.channels * bytewidth))
+       {       psf->error = SFE_BAD_WRITE_ALIGN ;
+               return 0 ;
+               } ;
+
+       if (psf->have_written == SF_FALSE && psf->write_header != NULL)
+               psf->write_header (psf, SF_FALSE) ;
+       psf->have_written = SF_TRUE ;
+
+       count = psf_fwrite (ptr, 1, len, psf) ;
+
+       psf->write_current += count / blockwidth ;
+
+       if (psf->write_current > psf->sf.frames)
+               psf->sf.frames = psf->write_current ;
+
+       psf->last_op = SFM_WRITE ;
+
+       return count ;
+} /* sf_write_raw */
+
+/*------------------------------------------------------------------------------
+*/
+
+sf_count_t
+sf_write_short (SNDFILE *sndfile, const short *ptr, sf_count_t len)
+{      SF_PRIVATE      *psf ;
+       sf_count_t      count ;
+
+       VALIDATE_SNDFILE_AND_ASSIGN_PSF (sndfile, psf, 1) ;
+
+       if (psf->mode == SFM_READ)
+       {       psf->error = SFE_NOT_WRITEMODE ;
+               return 0 ;
+               } ;
+
+       if (len % psf->sf.channels)
+       {       psf->error = SFE_BAD_WRITE_ALIGN ;
+               return 0 ;
+               } ;
+
+       if (! psf->write_short || psf->seek == NULL)
+       {       psf->error = SFE_UNIMPLEMENTED ;
+               return 0 ;
+               } ;
+
+       if (psf->last_op != SFM_WRITE)
+               if (psf->seek (psf, SFM_WRITE, psf->write_current) < 0)
+                       return 0 ;
+
+       if (psf->have_written == SF_FALSE && psf->write_header != NULL)
+               psf->write_header (psf, SF_FALSE) ;
+       psf->have_written = SF_TRUE ;
+
+       count = psf->write_short (psf, ptr, len) ;
+
+       psf->write_current += count / psf->sf.channels ;
+
+       psf->last_op = SFM_WRITE ;
+
+       if (psf->auto_header && psf->write_header != NULL)
+               psf->write_header (psf, SF_TRUE) ;
+
+       if (psf->write_current > psf->sf.frames)
+               psf->sf.frames = psf->write_current ;
+
+       return count ;
+} /* sf_write_short */
+
+sf_count_t
+sf_writef_short        (SNDFILE *sndfile, const short *ptr, sf_count_t frames)
+{      SF_PRIVATE      *psf ;
+       sf_count_t      count ;
+
+       VALIDATE_SNDFILE_AND_ASSIGN_PSF (sndfile, psf, 1) ;
+
+       if (psf->mode == SFM_READ)
+       {       psf->error = SFE_NOT_WRITEMODE ;
+               return 0 ;
+               } ;
+
+       if (! psf->write_short || psf->seek == NULL)
+       {       psf->error = SFE_UNIMPLEMENTED ;
+               return 0 ;
+               } ;
+
+       if (psf->last_op != SFM_WRITE)
+               if (psf->seek (psf, SFM_WRITE, psf->write_current) < 0)
+                       return 0 ;
+
+       if (psf->have_written == SF_FALSE && psf->write_header != NULL)
+               psf->write_header (psf, SF_FALSE) ;
+       psf->have_written = SF_TRUE ;
+
+       count = psf->write_short (psf, ptr, frames * psf->sf.channels) ;
+
+       psf->write_current += count / psf->sf.channels ;
+
+       psf->last_op = SFM_WRITE ;
+
+       if (psf->auto_header && psf->write_header != NULL)
+               psf->write_header (psf, SF_TRUE) ;
+
+       if (psf->write_current > psf->sf.frames)
+               psf->sf.frames = psf->write_current ;
+
+       return count / psf->sf.channels ;
+} /* sf_writef_short */
+
+/*------------------------------------------------------------------------------
+*/
+
+sf_count_t
+sf_write_int   (SNDFILE *sndfile, const int *ptr, sf_count_t len)
+{      SF_PRIVATE      *psf ;
+       sf_count_t      count ;
+
+       VALIDATE_SNDFILE_AND_ASSIGN_PSF (sndfile, psf, 1) ;
+
+       if (psf->mode == SFM_READ)
+       {       psf->error = SFE_NOT_WRITEMODE ;
+               return 0 ;
+               } ;
+
+       if (len % psf->sf.channels)
+       {       psf->error = SFE_BAD_WRITE_ALIGN ;
+               return 0 ;
+               } ;
+
+       if (! psf->write_int || psf->seek == NULL)
+       {       psf->error = SFE_UNIMPLEMENTED ;
+               return 0 ;
+               } ;
+
+       if (psf->last_op != SFM_WRITE)
+               if (psf->seek (psf, SFM_WRITE, psf->write_current) < 0)
+                       return 0 ;
+
+       if (psf->have_written == SF_FALSE && psf->write_header != NULL)
+               psf->write_header (psf, SF_FALSE) ;
+       psf->have_written = SF_TRUE ;
+
+       count = psf->write_int (psf, ptr, len) ;
+
+       psf->write_current += count / psf->sf.channels ;
+
+       psf->last_op = SFM_WRITE ;
+
+       if (psf->auto_header && psf->write_header != NULL)
+               psf->write_header (psf, SF_TRUE) ;
+
+       if (psf->write_current > psf->sf.frames)
+               psf->sf.frames = psf->write_current ;
+
+       return count ;
+} /* sf_write_int */
+
+sf_count_t
+sf_writef_int  (SNDFILE *sndfile, const int *ptr, sf_count_t frames)
+{      SF_PRIVATE      *psf ;
+       sf_count_t      count ;
+
+       VALIDATE_SNDFILE_AND_ASSIGN_PSF (sndfile, psf, 1) ;
+
+       if (psf->mode == SFM_READ)
+       {       psf->error = SFE_NOT_WRITEMODE ;
+               return 0 ;
+               } ;
+
+       if (! psf->write_int || psf->seek == NULL)
+       {       psf->error = SFE_UNIMPLEMENTED ;
+               return 0 ;
+               } ;
+
+       if (psf->last_op != SFM_WRITE)
+               if (psf->seek (psf, SFM_WRITE, psf->write_current) < 0)
+                       return 0 ;
+
+       if (psf->have_written == SF_FALSE && psf->write_header != NULL)
+               psf->write_header (psf, SF_FALSE) ;
+       psf->have_written = SF_TRUE ;
+
+       count = psf->write_int (psf, ptr, frames * psf->sf.channels) ;
+
+       psf->write_current += count / psf->sf.channels ;
+
+       psf->last_op = SFM_WRITE ;
+
+       if (psf->auto_header && psf->write_header != NULL)
+               psf->write_header (psf, SF_TRUE) ;
+
+       if (psf->write_current > psf->sf.frames)
+               psf->sf.frames = psf->write_current ;
+
+       return count / psf->sf.channels ;
+} /* sf_writef_int */
+
+/*------------------------------------------------------------------------------
+*/
+
+sf_count_t
+sf_write_float (SNDFILE *sndfile, const float *ptr, sf_count_t len)
+{      SF_PRIVATE      *psf ;
+       sf_count_t      count ;
+
+       VALIDATE_SNDFILE_AND_ASSIGN_PSF (sndfile, psf, 1) ;
+
+       if (psf->mode == SFM_READ)
+       {       psf->error = SFE_NOT_WRITEMODE ;
+               return 0 ;
+               } ;
+
+       if (len % psf->sf.channels)
+       {       psf->error = SFE_BAD_WRITE_ALIGN ;
+               return 0 ;
+               } ;
+
+       if (! psf->write_float || psf->seek == NULL)
+       {       psf->error = SFE_UNIMPLEMENTED ;
+               return 0 ;
+               } ;
+
+       if (psf->last_op != SFM_WRITE)
+               if (psf->seek (psf, SFM_WRITE, psf->write_current) < 0)
+                       return 0 ;
+
+       if (psf->have_written == SF_FALSE && psf->write_header != NULL)
+               psf->write_header (psf, SF_FALSE) ;
+       psf->have_written = SF_TRUE ;
+
+       count = psf->write_float (psf, ptr, len) ;
+
+       psf->write_current += count / psf->sf.channels ;
+
+       psf->last_op = SFM_WRITE ;
+
+       if (psf->auto_header && psf->write_header != NULL)
+               psf->write_header (psf, SF_TRUE) ;
+
+       if (psf->write_current > psf->sf.frames)
+               psf->sf.frames = psf->write_current ;
+
+       return count ;
+} /* sf_write_float */
+
+sf_count_t
+sf_writef_float        (SNDFILE *sndfile, const float *ptr, sf_count_t frames)
+{      SF_PRIVATE      *psf ;
+       sf_count_t      count ;
+
+       VALIDATE_SNDFILE_AND_ASSIGN_PSF (sndfile, psf, 1) ;
+
+       if (psf->mode == SFM_READ)
+       {       psf->error = SFE_NOT_WRITEMODE ;
+               return 0 ;
+               } ;
+
+       if (! psf->write_float || psf->seek == NULL)
+       {       psf->error = SFE_UNIMPLEMENTED ;
+               return 0 ;
+               } ;
+
+       if (psf->last_op != SFM_WRITE)
+               if (psf->seek (psf, SFM_WRITE, psf->write_current) < 0)
+                       return 0 ;
+
+       if (psf->have_written == SF_FALSE && psf->write_header != NULL)
+               psf->write_header (psf, SF_FALSE) ;
+       psf->have_written = SF_TRUE ;
+
+       count = psf->write_float (psf, ptr, frames * psf->sf.channels) ;
+
+       psf->write_current += count / psf->sf.channels ;
+
+       psf->last_op = SFM_WRITE ;
+
+       if (psf->auto_header && psf->write_header != NULL)
+               psf->write_header (psf, SF_TRUE) ;
+
+       if (psf->write_current > psf->sf.frames)
+               psf->sf.frames = psf->write_current ;
+
+       return count / psf->sf.channels ;
+} /* sf_writef_float */
+
+/*------------------------------------------------------------------------------
+*/
+
+sf_count_t
+sf_write_double        (SNDFILE *sndfile, const double *ptr, sf_count_t len)
+{      SF_PRIVATE      *psf ;
+       sf_count_t      count ;
+
+       VALIDATE_SNDFILE_AND_ASSIGN_PSF (sndfile, psf, 1) ;
+
+       if (psf->mode == SFM_READ)
+       {       psf->error = SFE_NOT_WRITEMODE ;
+               return 0 ;
+               } ;
+
+       if (len % psf->sf.channels)
+       {       psf->error = SFE_BAD_WRITE_ALIGN ;
+               return  0 ;
+               } ;
+
+       if (! psf->write_double || psf->seek == NULL)
+       {       psf->error = SFE_UNIMPLEMENTED ;
+               return 0 ;
+               } ;
+
+       if (psf->last_op != SFM_WRITE)
+               if (psf->seek (psf, SFM_WRITE, psf->write_current) < 0)
+                       return 0 ;
+
+       if (psf->have_written == SF_FALSE && psf->write_header != NULL)
+               psf->write_header (psf, SF_FALSE) ;
+       psf->have_written = SF_TRUE ;
+
+       count = psf->write_double (psf, ptr, len) ;
+
+       psf->write_current += count / psf->sf.channels ;
+
+       psf->last_op = SFM_WRITE ;
+
+       if (psf->auto_header && psf->write_header != NULL)
+               psf->write_header (psf, SF_TRUE) ;
+
+       if (psf->write_current > psf->sf.frames)
+               psf->sf.frames = psf->write_current ;
+
+       return count ;
+} /* sf_write_double */
+
+sf_count_t
+sf_writef_double       (SNDFILE *sndfile, const double *ptr, sf_count_t frames)
+{      SF_PRIVATE      *psf ;
+       sf_count_t      count ;
+
+       VALIDATE_SNDFILE_AND_ASSIGN_PSF (sndfile, psf, 1) ;
+
+       if (psf->mode == SFM_READ)
+       {       psf->error = SFE_NOT_WRITEMODE ;
+               return 0 ;
+               } ;
+
+       if (! psf->write_double || psf->seek == NULL)
+       {       psf->error = SFE_UNIMPLEMENTED ;
+               return 0 ;
+               } ;
+
+       if (psf->last_op != SFM_WRITE)
+               if (psf->seek (psf, SFM_WRITE, psf->write_current) < 0)
+                       return 0 ;
+
+       if (psf->have_written == SF_FALSE && psf->write_header != NULL)
+               psf->write_header (psf, SF_FALSE) ;
+       psf->have_written = SF_TRUE ;
+
+       count = psf->write_double (psf, ptr, frames * psf->sf.channels) ;
+
+       psf->write_current += count / psf->sf.channels ;
+
+       psf->last_op = SFM_WRITE ;
+
+       if (psf->auto_header && psf->write_header != NULL)
+               psf->write_header (psf, SF_TRUE) ;
+
+       if (psf->write_current > psf->sf.frames)
+               psf->sf.frames = psf->write_current ;
+
+       return count / psf->sf.channels ;
+} /* sf_writef_double */
+
+/*=========================================================================
+** Private functions.
+*/
+
+static int
+try_resource_fork (SF_PRIVATE * psf, int mode)
+{
+       if (psf_open_rsrc (psf, mode) != 0)
+               return 0 ;
+
+       /* More checking here. */
+       psf_log_printf (psf, "Resource fork : %s\n", psf->rsrcpath) ;
+
+       return SF_FORMAT_SD2 ;
+} /* try_resource_fork */
+
+static int
+format_from_extension (SF_PRIVATE *psf)
+{      char *cptr ;
+       char buffer [16] ;
+
+       if (psf->filename == NULL)
+               return 0 ;
+
+       if ((cptr = strrchr (psf->filename, '.')) == NULL)
+               return 0 ;
+
+       cptr ++ ;
+       if (strlen (cptr) > sizeof (buffer) - 1)
+               return 0 ;
+
+       strncpy (buffer, cptr, sizeof (buffer)) ;
+       buffer [sizeof (buffer) - 1] = 0 ;
+
+       /* Convert everything in the buffer to lower case. */
+       cptr = buffer ;
+       while (*cptr)
+       {       *cptr = tolower (*cptr) ;
+               cptr ++ ;
+               } ;
+
+       cptr = buffer ;
+
+       if (strcmp (cptr, "au") == 0)
+       {       psf->sf.channels = 1 ;
+               psf->sf.samplerate = 8000 ;
+               return SF_FORMAT_RAW | SF_FORMAT_ULAW ;
+               } ;
+
+       if (strcmp (cptr, "snd") == 0)
+       {       psf->sf.channels = 1 ;
+               psf->sf.samplerate = 8000 ;
+               return SF_FORMAT_RAW | SF_FORMAT_ULAW ;
+               } ;
+
+       if (strcmp (cptr, "vox") == 0)
+       {       psf->sf.channels = 1 ;
+               psf->sf.samplerate = 8000 ;
+               return SF_FORMAT_RAW | SF_FORMAT_VOX_ADPCM ;
+               } ;
+
+       if (strcmp (cptr, "gsm") == 0)
+       {       psf->sf.channels = 1 ;
+               psf->sf.samplerate = 8000 ;
+               return SF_FORMAT_RAW | SF_FORMAT_GSM610 ;
+               } ;
+
+       return 0 ;
+} /* format_from_extension */
+
+static int
+guess_file_type (SF_PRIVATE *psf)
+{      int buffer [3], format ;
+
+       if (psf_binheader_readf (psf, "b", &buffer, SIGNED_SIZEOF (buffer)) != SIGNED_SIZEOF (buffer))
+       {       psf->error = SFE_BAD_FILE_READ ;
+               return 0 ;
+               } ;
+
+       if ((buffer [0] == MAKE_MARKER ('R', 'I', 'F', 'F') || buffer [0] == MAKE_MARKER ('R', 'I', 'F', 'X'))
+                       && buffer [2] == MAKE_MARKER ('W', 'A', 'V', 'E'))
+               return SF_FORMAT_WAV ;
+
+       if (buffer [0] == MAKE_MARKER ('F', 'O', 'R', 'M'))
+       {       if (buffer [2] == MAKE_MARKER ('A', 'I', 'F', 'F') || buffer [2] == MAKE_MARKER ('A', 'I', 'F', 'C'))
+                       return SF_FORMAT_AIFF ;
+               if (buffer [2] == MAKE_MARKER ('8', 'S', 'V', 'X') || buffer [2] == MAKE_MARKER ('1', '6', 'S', 'V'))
+                       return SF_FORMAT_SVX ;
+               return 0 ;
+               } ;
+
+       if (buffer [0] == MAKE_MARKER ('.', 's', 'n', 'd') || buffer [0] == MAKE_MARKER ('d', 'n', 's', '.'))
+               return SF_FORMAT_AU ;
+
+       if ((buffer [0] == MAKE_MARKER ('f', 'a', 'p', ' ') || buffer [0] == MAKE_MARKER (' ', 'p', 'a', 'f')))
+               return SF_FORMAT_PAF ;
+
+       if (buffer [0] == MAKE_MARKER ('N', 'I', 'S', 'T'))
+               return SF_FORMAT_NIST ;
+
+       if (buffer [0] == MAKE_MARKER ('C', 'r', 'e', 'a') && buffer [1] == MAKE_MARKER ('t', 'i', 'v', 'e'))
+               return SF_FORMAT_VOC ;
+
+       if ((buffer [0] & MAKE_MARKER (0xFF, 0xFF, 0xF8, 0xFF)) == MAKE_MARKER (0x64, 0xA3, 0x00, 0x00) ||
+               (buffer [0] & MAKE_MARKER (0xFF, 0xF8, 0xFF, 0xFF)) == MAKE_MARKER (0x00, 0x00, 0xA3, 0x64))
+               return SF_FORMAT_IRCAM ;
+
+       if (buffer [0] == MAKE_MARKER ('r', 'i', 'f', 'f'))
+               return SF_FORMAT_W64 ;
+
+       if (buffer [0] == MAKE_MARKER (0, 0, 0x03, 0xE8) && buffer [1] == MAKE_MARKER (0, 0, 0, 1) &&
+                                                               buffer [2] == MAKE_MARKER (0, 0, 0, 1))
+               return SF_FORMAT_MAT4 ;
+
+       if (buffer [0] == MAKE_MARKER (0, 0, 0, 0) && buffer [1] == MAKE_MARKER (1, 0, 0, 0) &&
+                                                               buffer [2] == MAKE_MARKER (1, 0, 0, 0))
+               return SF_FORMAT_MAT4 ;
+
+       if (buffer [0] == MAKE_MARKER ('M', 'A', 'T', 'L') && buffer [1] == MAKE_MARKER ('A', 'B', ' ', '5'))
+               return SF_FORMAT_MAT5 ;
+
+       if (buffer [0] == MAKE_MARKER ('P', 'V', 'F', '1'))
+               return SF_FORMAT_PVF ;
+
+       if (buffer [0] == MAKE_MARKER ('E', 'x', 't', 'e') && buffer [1] == MAKE_MARKER ('n', 'd', 'e', 'd') &&
+                                                               buffer [2] == MAKE_MARKER (' ', 'I', 'n', 's'))
+               return SF_FORMAT_XI ;
+
+       if (buffer [0] == MAKE_MARKER ('c', 'a', 'f', 'f') && buffer [2] == MAKE_MARKER ('d', 'e', 's', 'c'))
+               return SF_FORMAT_CAF ;
+
+       if (ENABLE_EXPERIMENTAL_CODE && buffer [0] == MAKE_MARKER ('O', 'g', 'g', 'S'))
+               return SF_FORMAT_OGG ;
+
+       if (buffer [0] == MAKE_MARKER ('A', 'L', 'a', 'w') && buffer [1] == MAKE_MARKER ('S', 'o', 'u', 'n')
+                       && buffer [2] == MAKE_MARKER ('d', 'F', 'i', 'l'))
+               return SF_FORMAT_WVE ;
+
+       if (buffer [0] == MAKE_MARKER ('D', 'i', 'a', 'm') && buffer [1] == MAKE_MARKER ('o', 'n', 'd', 'W')
+                       && buffer [2] == MAKE_MARKER ('a', 'r', 'e', ' '))
+               return SF_FORMAT_DWD ;
+
+       if (buffer [0] == MAKE_MARKER ('L', 'M', '8', '9') || buffer [0] == MAKE_MARKER ('5', '3', 0, 0))
+               return SF_FORMAT_TXW ;
+
+       if ((buffer [0] & MAKE_MARKER (0xFF, 0xFF, 0x80, 0xFF)) == MAKE_MARKER (0xF0, 0x7E, 0, 0x01))
+               return SF_FORMAT_SDS ;
+
+       if (buffer [0] == MAKE_MARKER ('C', 'A', 'T', ' ') && buffer [2] == MAKE_MARKER ('R', 'E', 'X', '2'))
+               return SF_FORMAT_REX2 ;
+
+       if (buffer [0] == MAKE_MARKER (0x30, 0x26, 0xB2, 0x75) && buffer [1] == MAKE_MARKER (0x8E, 0x66, 0xCF, 0x11))
+               return 0 /*-SF_FORMAT_WMA-*/ ;
+
+       /* HMM (Hidden Markov Model) Tool Kit. */
+       if (2 * BEI2H_INT (buffer [0]) + 12 == psf->filelength && buffer [2] == MAKE_MARKER (0, 2, 0, 0))
+               return SF_FORMAT_HTK ;
+
+       if (buffer [0] == MAKE_MARKER ('f', 'L', 'a', 'C'))
+               return SF_FORMAT_FLAC ;
+
+       /* Turtle Beach SMP 16-bit */
+       if (buffer [0] == MAKE_MARKER ('S', 'O', 'U', 'N') && buffer [1] == MAKE_MARKER ('D', ' ', 'S', 'A'))
+               return 0 ;
+
+       if (buffer [0] == MAKE_MARKER ('S', 'Y', '8', '0') || buffer [0] == MAKE_MARKER ('S', 'Y', '8', '5'))
+               return 0 ;
+
+       if (buffer [0] == MAKE_MARKER ('a', 'j', 'k', 'g'))
+               return 0 /*-SF_FORMAT_SHN-*/ ;
+
+       if (buffer [0] == MAKE_MARKER ('2', 'B', 'I', 'T'))
+               return SF_FORMAT_AVR ;
+
+       /* This must be the second last one. */
+       if (psf->filelength > 0 && (format = try_resource_fork (psf, SFM_READ)) != 0)
+               return format ;
+
+       return 0 ;
+} /* guess_file_type */
+
+
+static int
+validate_sfinfo (SF_INFO *sfinfo)
+{      if (sfinfo->samplerate < 1)
+               return 0 ;
+       if (sfinfo->frames < 0)
+               return 0 ;
+       if (sfinfo->channels < 1)
+               return 0 ;
+       if ((sfinfo->format & SF_FORMAT_TYPEMASK) == 0)
+               return 0 ;
+       if ((sfinfo->format & SF_FORMAT_SUBMASK) == 0)
+               return 0 ;
+       if (sfinfo->sections < 1)
+               return 0 ;
+       return 1 ;
+} /* validate_sfinfo */
+
+static int
+validate_psf (SF_PRIVATE *psf)
+{
+       if (psf->datalength < 0)
+       {       psf_log_printf (psf, "Invalid SF_PRIVATE field : datalength == %D.\n", psf->datalength) ;
+               return 0 ;
+               } ;
+       if (psf->dataoffset < 0)
+       {       psf_log_printf (psf, "Invalid SF_PRIVATE field : dataoffset == %D.\n", psf->dataoffset) ;
+               return 0 ;
+               } ;
+       if (psf->blockwidth && psf->blockwidth != psf->sf.channels * psf->bytewidth)
+       {       psf_log_printf (psf, "Invalid SF_PRIVATE field : channels * bytewidth == %d.\n",
+                                                               psf->sf.channels * psf->bytewidth) ;
+               return 0 ;
+               } ;
+       return 1 ;
+} /* validate_psf */
+
+static void
+save_header_info (SF_PRIVATE *psf)
+{      LSF_SNPRINTF (sf_logbuffer, sizeof (sf_logbuffer), "%s", psf->logbuffer) ;
+} /* save_header_info */
+
+static void
+copy_filename (SF_PRIVATE *psf, const char *path)
+{      const char *ccptr ;
+       char *cptr ;
+
+       LSF_SNPRINTF (psf->filepath, sizeof (psf->filepath), "%s", path) ;
+       if ((ccptr = strrchr (path, '/')) || (ccptr = strrchr (path, '\\')))
+               ccptr ++ ;
+       else
+               ccptr = path ;
+
+       LSF_SNPRINTF (psf->filename, sizeof (psf->filename), "%s", ccptr) ;
+
+       /* Now grab the directory. */
+       LSF_SNPRINTF (psf->directory, sizeof (psf->directory), "%s", path) ;
+       if ((cptr = strrchr (psf->directory, '/')) || (cptr = strrchr (psf->directory, '\\')))
+               cptr [1] = 0 ;
+       else
+               psf->directory [0] = 0 ;
+
+       return ;
+} /* copy_filename */
+
+/*==============================================================================
+*/
+
+static int
+psf_close (SF_PRIVATE *psf)
+{      int     error ;
+
+       if (psf->codec_close)
+               error = psf->codec_close (psf) ;
+       if (psf->container_close)
+               error = psf->container_close (psf) ;
+
+       psf_fclose (psf) ;
+       psf_close_rsrc (psf) ;
+
+       if (psf->fdata)
+               free (psf->fdata) ;
+
+       if (psf->interleave)
+               free (psf->interleave) ;
+
+       if (psf->dither)
+               free (psf->dither) ;
+
+       if (psf->peak_info)
+               free (psf->peak_info) ;
+
+       if (psf->broadcast_info)
+               free (psf->broadcast_info) ;
+
+       if (psf->loop_info)
+               free (psf->loop_info) ;
+
+       if (psf->instrument)
+               free (psf->instrument) ;
+
+       if (psf->format_desc)
+       {       memset (psf->format_desc, 0, strlen (psf->format_desc)) ;
+               free (psf->format_desc) ;
+               } ;
+
+       memset (psf, 0, sizeof (SF_PRIVATE)) ;
+       free (psf) ;
+
+       return 0 ;
+} /* psf_close */
+
+static int
+psf_open_file (SF_PRIVATE *psf, int mode, SF_INFO *sfinfo)
+{      int             error, format ;
+
+       if (mode != SFM_READ && mode != SFM_WRITE && mode != SFM_RDWR)
+               return SFE_BAD_OPEN_MODE ;
+
+       if (sfinfo == NULL)
+               return SFE_BAD_SF_INFO_PTR ;
+
+       /* Zero out these fields. */
+       sfinfo->frames = 0 ;
+       sfinfo->sections = 0 ;
+       sfinfo->seekable = 0 ;
+
+       if (mode == SFM_READ)
+       {       if ((sfinfo->format & SF_FORMAT_TYPEMASK) == SF_FORMAT_RAW)
+               {       if (sf_format_check (sfinfo) == 0)
+                               return SFE_RAW_BAD_FORMAT ;
+                       }
+               else
+                       memset (sfinfo, 0, sizeof (SF_INFO)) ;
+               } ;
+
+       sf_errno = error = 0 ;
+       sf_logbuffer [0] = 0 ;
+
+       memcpy (&(psf->sf), sfinfo, sizeof (SF_INFO)) ;
+
+       psf->Magick             = SNDFILE_MAGICK ;
+       psf->norm_float         = SF_TRUE ;
+       psf->norm_double        = SF_TRUE ;
+       psf->mode                       = mode ;
+       psf->dataoffset         = -1 ;
+       psf->datalength         = -1 ;
+       psf->read_current       = -1 ;
+       psf->write_current      = -1 ;
+       psf->auto_header        = SF_FALSE ;
+       psf->rwf_endian         = SF_ENDIAN_LITTLE ;
+       psf->seek                       = psf_default_seek ;
+       psf->float_int_mult = 0 ;
+       psf->float_max          = -1.0 ;
+
+       psf->sf.sections = 1 ;
+
+       psf->is_pipe = psf_is_pipe (psf) ;
+
+       if (psf->is_pipe)
+       {       psf->sf.seekable = SF_FALSE ;
+               psf->filelength = SF_COUNT_MAX ;
+               }
+       else
+       {       psf->sf.seekable = SF_TRUE ;
+
+               /* File is open, so get the length. */
+               psf->filelength = psf_get_filelen (psf) ;
+               } ;
+
+       if (psf->fileoffset > 0)
+       {       switch (psf->mode)
+               {       case SFM_READ :
+                               if (psf->filelength < 44)
+                               {       psf_log_printf (psf, "Short filelength: %D (fileoffset: %D)\n", psf->filelength, psf->fileoffset) ;
+                                       return SFE_BAD_OFFSET ;
+                                       } ;
+                               break ;
+
+                       case SFM_WRITE :
+                               psf->fileoffset = 0 ;
+                               psf_fseek (psf, 0, SEEK_END) ;
+                               psf->fileoffset = psf_ftell (psf) ;
+                               break ;
+
+                       case SFM_RDWR :
+                               return SFE_NO_EMBEDDED_RDWR ;
+                       } ;
+
+               psf_log_printf (psf, "Embedded file offset : %D\n", psf->fileoffset) ;
+               } ;
+
+       if (psf->filelength == SF_COUNT_MAX)
+               psf_log_printf (psf, "Length : unknown\n") ;
+       else
+               psf_log_printf (psf, "Length : %D\n", psf->filelength) ;
+
+       if (mode == SFM_WRITE || (mode == SFM_RDWR && psf->filelength == 0))
+       {       /* If the file is being opened for write or RDWR and the file is currently
+               ** empty, then the SF_INFO struct must contain valid data.
+               */
+               if (sf_format_check (&(psf->sf)) == 0)
+                       return SFE_BAD_OPEN_FORMAT ;
+               }
+       else if ((psf->sf.format & SF_FORMAT_TYPEMASK) != SF_FORMAT_RAW)
+       {       /* If type RAW has not been specified then need to figure out file type. */
+               psf->sf.format = guess_file_type (psf) ;
+
+               if (psf->sf.format == 0)
+                       psf->sf.format = format_from_extension (psf) ;
+               } ;
+
+       /* Prevent unnecessary seeks */
+       psf->last_op = psf->mode ;
+
+       /* Set bytewidth if known. */
+       switch (psf->sf.format & SF_FORMAT_SUBMASK)
+       {       case SF_FORMAT_PCM_S8 :
+               case SF_FORMAT_PCM_U8 :
+               case SF_FORMAT_ULAW :
+               case SF_FORMAT_ALAW :
+               case SF_FORMAT_DPCM_8 :
+                               psf->bytewidth = 1 ;
+                               break ;
+
+               case SF_FORMAT_PCM_16 :
+               case SF_FORMAT_DPCM_16 :
+                               psf->bytewidth = 2 ;
+                               break ;
+
+               case SF_FORMAT_PCM_24 :
+                               psf->bytewidth = 3 ;
+                               break ;
+
+               case SF_FORMAT_PCM_32 :
+               case SF_FORMAT_FLOAT :
+                               psf->bytewidth = 4 ;
+                               break ;
+
+               case SF_FORMAT_DOUBLE :
+                               psf->bytewidth = 8 ;
+                               break ;
+               } ;
+
+       /* Call the initialisation function for the relevant file type. */
+       switch (psf->sf.format & SF_FORMAT_TYPEMASK)
+       {       case    SF_FORMAT_WAV :
+               case    SF_FORMAT_WAVEX :
+                               error = wav_open (psf) ;
+                               break ;
+
+               case    SF_FORMAT_AIFF :
+                               error = aiff_open (psf) ;
+                               break ;
+
+               case    SF_FORMAT_AU :
+                               error = au_open (psf) ;
+                               break ;
+
+               case    SF_FORMAT_RAW :
+                               error = raw_open (psf) ;
+                               break ;
+
+               case    SF_FORMAT_W64 :
+                               error = w64_open (psf) ;
+                               break ;
+
+               /* Lite remove start */
+               case    SF_FORMAT_PAF :
+                               error = paf_open (psf) ;
+                               break ;
+
+               case    SF_FORMAT_SVX :
+                               error = svx_open (psf) ;
+                               break ;
+
+               case    SF_FORMAT_NIST :
+                               error = nist_open (psf) ;
+                               break ;
+
+               case    SF_FORMAT_IRCAM :
+                               error = ircam_open (psf) ;
+                               break ;
+
+               case    SF_FORMAT_VOC :
+                               error = voc_open (psf) ;
+                               break ;
+
+               case    SF_FORMAT_SDS :
+                               error = sds_open (psf) ;
+                               break ;
+
+               case    SF_FORMAT_OGG :
+                               error = ogg_open (psf) ;
+                               break ;
+
+               case    SF_FORMAT_TXW :
+                               error = txw_open (psf) ;
+                               break ;
+
+               case    SF_FORMAT_WVE :
+                               error = wve_open (psf) ;
+                               break ;
+
+               case    SF_FORMAT_DWD :
+                               error = dwd_open (psf) ;
+                               break ;
+
+               case    SF_FORMAT_MAT4 :
+                               error = mat4_open (psf) ;
+                               break ;
+
+               case    SF_FORMAT_MAT5 :
+                               error = mat5_open (psf) ;
+                               break ;
+
+               case    SF_FORMAT_PVF :
+                               error = pvf_open (psf) ;
+                               break ;
+
+               case    SF_FORMAT_XI :
+                               error = xi_open (psf) ;
+                               break ;
+
+               case    SF_FORMAT_HTK :
+                               error = htk_open (psf) ;
+                               break ;
+
+               case    SF_FORMAT_SD2 :
+                               error = sd2_open (psf) ;
+                               break ;
+
+               case    SF_FORMAT_REX2 :
+                               error = rx2_open (psf) ;
+                               break ;
+
+               case    SF_FORMAT_AVR :
+                               error = avr_open (psf) ;
+                               break ;
+
+               case    SF_FORMAT_FLAC :
+                               error = flac_open (psf) ;
+                               break ;
+
+               case    SF_FORMAT_CAF :
+                               error = caf_open (psf) ;
+                               break ;
+
+               /* Lite remove end */
+
+               default :
+                               error = SFE_UNKNOWN_FORMAT ;
+               } ;
+
+       if (error)
+       {       if (error != SF_ERR_SYSTEM && error != SF_ERR_UNSUPPORTED_ENCODING)
+               {       psf_log_printf (psf, "Parse error : %s\n", sf_error_number (error)) ;
+                       error = SF_ERR_MALFORMED_FILE ;
+                       } ;
+
+               return error ;
+               } ;
+
+       /* For now, check whether embedding is supported. */
+       format = psf->sf.format & SF_FORMAT_TYPEMASK ;
+       if (psf->fileoffset > 0 &&
+                       (format != SF_FORMAT_WAV) && (format != SF_FORMAT_WAVEX) &&
+                       (format != SF_FORMAT_AIFF) && (format != SF_FORMAT_AU)
+                       )
+               return SFE_NO_EMBED_SUPPORT ;
+
+       if (psf->fileoffset > 0)
+               psf_log_printf (psf, "Embedded file length : %D\n", psf->filelength) ;
+
+       if (mode == SFM_RDWR && sf_format_check (&(psf->sf)) == 0)
+               return SFE_BAD_RDWR_FORMAT ;
+
+       if (validate_sfinfo (&(psf->sf)) == 0)
+       {       psf_log_SF_INFO (psf) ;
+               save_header_info (psf) ;
+               return SFE_BAD_SF_INFO ;
+               } ;
+
+       if (validate_psf (psf) == 0)
+       {       save_header_info (psf) ;
+               return SFE_INTERNAL ;
+               } ;
+
+       psf->read_current = 0 ;
+       psf->write_current = (psf->mode == SFM_RDWR) ? psf->sf.frames : 0 ;
+
+       memcpy (sfinfo, &(psf->sf), sizeof (SF_INFO)) ;
+
+       return 0 ;
+} /* psf_open_file */
+
+/*
+** Do not edit or modify anything in this comment block.
+** The arch-tag line is a file identity tag for the GNU Arch
+** revision control system.
+**
+** arch-tag: cd4f9e91-a8ec-4154-9bf6-fe4b8c69a615
+*/
diff --git a/libs/libsndfile/src/sndfile.h.in b/libs/libsndfile/src/sndfile.h.in
new file mode 100644 (file)
index 0000000..93f1d61
--- /dev/null
@@ -0,0 +1,554 @@
+/*
+** Copyright (C) 1999-2006 Erik de Castro Lopo <erikd@mega-nerd.com>
+**
+** This program is free software; you can redistribute it and/or modify
+** it under the terms of the GNU Lesser General Public License as published by
+** the Free Software Foundation; either version 2.1 of the License, or
+** (at your option) any later version.
+**
+** This program is distributed in the hope that it will be useful,
+** but WITHOUT ANY WARRANTY; without even the implied warranty of
+** MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+** GNU Lesser General Public License for more details.
+**
+** You should have received a copy of the GNU Lesser General Public License
+** along with this program; if not, write to the Free Software
+** Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA.
+*/
+
+/*
+** sndfile.h -- system-wide definitions
+**
+** API documentation is in the doc/ directory of the source code tarball
+** and at http://www.mega-nerd.com/libsndfile/api.html.
+*/
+
+#ifndef SNDFILE_H
+#define SNDFILE_H
+
+/* This is the version 1.0.X header file. */
+#define        SNDFILE_1
+
+#include <stdio.h>
+
+/* For the Metrowerks CodeWarrior Pro Compiler (mainly MacOS) */
+
+#if    (defined (__MWERKS__))
+#include       <unix.h>
+#else
+#include       <sys/types.h>
+#endif
+
+#ifdef __cplusplus
+extern "C" {
+#endif /* __cplusplus */
+
+/* The following file types can be read and written.
+** A file type would consist of a major type (ie SF_FORMAT_WAV) bitwise
+** ORed with a minor type (ie SF_FORMAT_PCM). SF_FORMAT_TYPEMASK and
+** SF_FORMAT_SUBMASK can be used to separate the major and minor file
+** types.
+*/
+
+enum
+{      /* Major formats. */
+       SF_FORMAT_WAV                   = 0x010000,             /* Microsoft WAV format (little endian default). */
+       SF_FORMAT_AIFF                  = 0x020000,             /* Apple/SGI AIFF format (big endian). */
+       SF_FORMAT_AU                    = 0x030000,             /* Sun/NeXT AU format (big endian). */
+       SF_FORMAT_RAW                   = 0x040000,             /* RAW PCM data. */
+       SF_FORMAT_PAF                   = 0x050000,             /* Ensoniq PARIS file format. */
+       SF_FORMAT_SVX                   = 0x060000,             /* Amiga IFF / SVX8 / SV16 format. */
+       SF_FORMAT_NIST                  = 0x070000,             /* Sphere NIST format. */
+       SF_FORMAT_VOC                   = 0x080000,             /* VOC files. */
+       SF_FORMAT_IRCAM                 = 0x0A0000,             /* Berkeley/IRCAM/CARL */
+       SF_FORMAT_W64                   = 0x0B0000,             /* Sonic Foundry's 64 bit RIFF/WAV */
+       SF_FORMAT_MAT4                  = 0x0C0000,             /* Matlab (tm) V4.2 / GNU Octave 2.0 */
+       SF_FORMAT_MAT5                  = 0x0D0000,             /* Matlab (tm) V5.0 / GNU Octave 2.1 */
+       SF_FORMAT_PVF                   = 0x0E0000,             /* Portable Voice Format */
+       SF_FORMAT_XI                    = 0x0F0000,             /* Fasttracker 2 Extended Instrument */
+       SF_FORMAT_HTK                   = 0x100000,             /* HMM Tool Kit format */
+       SF_FORMAT_SDS                   = 0x110000,             /* Midi Sample Dump Standard */
+       SF_FORMAT_AVR                   = 0x120000,             /* Audio Visual Research */
+       SF_FORMAT_WAVEX                 = 0x130000,             /* MS WAVE with WAVEFORMATEX */
+       SF_FORMAT_SD2                   = 0x160000,             /* Sound Designer 2 */
+       SF_FORMAT_FLAC                  = 0x170000,             /* FLAC lossless file format */
+       SF_FORMAT_CAF                   = 0x180000,             /* Core Audio File format */
+
+       /* Subtypes from here on. */
+
+       SF_FORMAT_PCM_S8                = 0x0001,               /* Signed 8 bit data */
+       SF_FORMAT_PCM_16                = 0x0002,               /* Signed 16 bit data */
+       SF_FORMAT_PCM_24                = 0x0003,               /* Signed 24 bit data */
+       SF_FORMAT_PCM_32                = 0x0004,               /* Signed 32 bit data */
+
+       SF_FORMAT_PCM_U8                = 0x0005,               /* Unsigned 8 bit data (WAV and RAW only) */
+
+       SF_FORMAT_FLOAT                 = 0x0006,               /* 32 bit float data */
+       SF_FORMAT_DOUBLE                = 0x0007,               /* 64 bit float data */
+
+       SF_FORMAT_ULAW                  = 0x0010,               /* U-Law encoded. */
+       SF_FORMAT_ALAW                  = 0x0011,               /* A-Law encoded. */
+       SF_FORMAT_IMA_ADPCM             = 0x0012,               /* IMA ADPCM. */
+       SF_FORMAT_MS_ADPCM              = 0x0013,               /* Microsoft ADPCM. */
+
+       SF_FORMAT_GSM610                = 0x0020,               /* GSM 6.10 encoding. */
+       SF_FORMAT_VOX_ADPCM             = 0x0021,               /* OKI / Dialogix ADPCM */
+
+       SF_FORMAT_G721_32               = 0x0030,               /* 32kbs G721 ADPCM encoding. */
+       SF_FORMAT_G723_24               = 0x0031,               /* 24kbs G723 ADPCM encoding. */
+       SF_FORMAT_G723_40               = 0x0032,               /* 40kbs G723 ADPCM encoding. */
+
+       SF_FORMAT_DWVW_12               = 0x0040,               /* 12 bit Delta Width Variable Word encoding. */
+       SF_FORMAT_DWVW_16               = 0x0041,               /* 16 bit Delta Width Variable Word encoding. */
+       SF_FORMAT_DWVW_24               = 0x0042,               /* 24 bit Delta Width Variable Word encoding. */
+       SF_FORMAT_DWVW_N                = 0x0043,               /* N bit Delta Width Variable Word encoding. */
+
+       SF_FORMAT_DPCM_8                = 0x0050,               /* 8 bit differential PCM (XI only) */
+       SF_FORMAT_DPCM_16               = 0x0051,               /* 16 bit differential PCM (XI only) */
+
+       /* Endian-ness options. */
+
+       SF_ENDIAN_FILE                  = 0x00000000,   /* Default file endian-ness. */
+       SF_ENDIAN_LITTLE                = 0x10000000,   /* Force little endian-ness. */
+       SF_ENDIAN_BIG                   = 0x20000000,   /* Force big endian-ness. */
+       SF_ENDIAN_CPU                   = 0x30000000,   /* Force CPU endian-ness. */
+
+       SF_FORMAT_SUBMASK               = 0x0000FFFF,
+       SF_FORMAT_TYPEMASK              = 0x0FFF0000,
+       SF_FORMAT_ENDMASK               = 0x30000000
+} ;
+
+/*
+** The following are the valid command numbers for the sf_command()
+** interface.  The use of these commands is documented in the file
+** command.html in the doc directory of the source code distribution.
+*/
+
+enum
+{      SFC_GET_LIB_VERSION                             = 0x1000,
+       SFC_GET_LOG_INFO                                = 0x1001,
+
+       SFC_GET_NORM_DOUBLE                             = 0x1010,
+       SFC_GET_NORM_FLOAT                              = 0x1011,
+       SFC_SET_NORM_DOUBLE                             = 0x1012,
+       SFC_SET_NORM_FLOAT                              = 0x1013,
+       SFC_SET_SCALE_FLOAT_INT_READ    = 0x1014,
+
+       SFC_GET_SIMPLE_FORMAT_COUNT             = 0x1020,
+       SFC_GET_SIMPLE_FORMAT                   = 0x1021,
+
+       SFC_GET_FORMAT_INFO                             = 0x1028,
+
+       SFC_GET_FORMAT_MAJOR_COUNT              = 0x1030,
+       SFC_GET_FORMAT_MAJOR                    = 0x1031,
+       SFC_GET_FORMAT_SUBTYPE_COUNT    = 0x1032,
+       SFC_GET_FORMAT_SUBTYPE                  = 0x1033,
+
+       SFC_CALC_SIGNAL_MAX                             = 0x1040,
+       SFC_CALC_NORM_SIGNAL_MAX                = 0x1041,
+       SFC_CALC_MAX_ALL_CHANNELS               = 0x1042,
+       SFC_CALC_NORM_MAX_ALL_CHANNELS  = 0x1043,
+       SFC_GET_SIGNAL_MAX                              = 0x1044,
+       SFC_GET_MAX_ALL_CHANNELS                = 0x1045,
+
+       SFC_SET_ADD_PEAK_CHUNK                  = 0x1050,
+
+       SFC_UPDATE_HEADER_NOW                   = 0x1060,
+       SFC_SET_UPDATE_HEADER_AUTO              = 0x1061,
+
+       SFC_FILE_TRUNCATE                               = 0x1080,
+
+       SFC_SET_RAW_START_OFFSET                = 0x1090,
+
+       SFC_SET_DITHER_ON_WRITE                 = 0x10A0,
+       SFC_SET_DITHER_ON_READ                  = 0x10A1,
+
+       SFC_GET_DITHER_INFO_COUNT               = 0x10A2,
+       SFC_GET_DITHER_INFO                             = 0x10A3,
+
+       SFC_GET_EMBED_FILE_INFO                 = 0x10B0,
+
+       SFC_SET_CLIPPING                                = 0x10C0,
+       SFC_GET_CLIPPING                                = 0x10C1,
+
+       SFC_GET_INSTRUMENT                              = 0x10D0,
+       SFC_SET_INSTRUMENT                              = 0x10D1,
+
+       SFC_GET_LOOP_INFO                               = 0x10E0,
+
+       SFC_GET_BROADCAST_INFO                  = 0x10F0,
+       SFC_SET_BROADCAST_INFO                  = 0x10F1,
+
+       /* Following commands for testing only. */
+       SFC_TEST_IEEE_FLOAT_REPLACE             = 0x6001,
+
+       /*
+       ** SFC_SET_ADD_* values are deprecated and will disappear at some
+       ** time in the future. They are guaranteed to be here up to and
+       ** including version 1.0.8 to avoid breakage of existng software.
+       ** They currently do nothing and will continue to do nothing.
+       */
+       SFC_SET_ADD_DITHER_ON_WRITE             = 0x1070,
+       SFC_SET_ADD_DITHER_ON_READ              = 0x1071
+} ;
+
+
+/*
+** String types that can be set and read from files. Not all file types
+** support this and even the file types which support one, may not support
+** all string types.
+*/
+
+enum
+{      SF_STR_TITLE                                    = 0x01,
+       SF_STR_COPYRIGHT                                = 0x02,
+       SF_STR_SOFTWARE                                 = 0x03,
+       SF_STR_ARTIST                                   = 0x04,
+       SF_STR_COMMENT                                  = 0x05,
+       SF_STR_DATE                                             = 0x06
+} ;
+
+/*
+** Use the following as the start and end index when doing metadata
+** transcoding.
+*/
+
+#define        SF_STR_FIRST    SF_STR_TITLE
+#define        SF_STR_LAST             SF_STR_DATE
+
+enum
+{      /* True and false */
+       SF_FALSE        = 0,
+       SF_TRUE         = 1,
+
+       /* Modes for opening files. */
+       SFM_READ        = 0x10,
+       SFM_WRITE       = 0x20,
+       SFM_RDWR        = 0x30
+} ;
+
+/* Public error values. These are guaranteed to remain unchanged for the duration
+** of the library major version number.
+** There are also a large number of private error numbers which are internal to
+** the library which can change at any time.
+*/
+
+enum
+{      SF_ERR_NO_ERROR                         = 0,
+       SF_ERR_UNRECOGNISED_FORMAT      = 1,
+       SF_ERR_SYSTEM                           = 2,
+       SF_ERR_MALFORMED_FILE           = 3,
+       SF_ERR_UNSUPPORTED_ENCODING     = 4
+} ;
+
+/* A SNDFILE* pointer can be passed around much like stdio.h's FILE* pointer. */
+
+typedef        struct SNDFILE_tag      SNDFILE ;
+
+/* The following typedef is system specific and is defined when libsndfile is.
+** compiled. sf_count_t can be one of loff_t (Linux), off_t (*BSD),
+** off64_t (Solaris), __int64_t (Win32) etc.
+*/
+
+typedef @TYPEOF_SF_COUNT_T@    sf_count_t ;
+
+#define SF_COUNT_MAX           @SF_COUNT_MAX@
+
+/* A pointer to a SF_INFO structure is passed to sf_open_read () and filled in.
+** On write, the SF_INFO structure is filled in by the user and passed into
+** sf_open_write ().
+*/
+
+struct SF_INFO
+{      sf_count_t      frames ;                /* Used to be called samples.  Changed to avoid confusion. */
+       int                     samplerate ;
+       int                     channels ;
+       int                     format ;
+       int                     sections ;
+       int                     seekable ;
+} ;
+
+typedef        struct SF_INFO SF_INFO ;
+
+/* The SF_FORMAT_INFO struct is used to retrieve information about the sound
+** file formats libsndfile supports using the sf_command () interface.
+**
+** Using this interface will allow applications to support new file formats
+** and encoding types when libsndfile is upgraded, without requiring
+** re-compilation of the application.
+**
+** Please consult the libsndfile documentation (particularly the information
+** on the sf_command () interface) for examples of its use.
+*/
+
+typedef struct
+{      int                     format ;
+       const char      *name ;
+       const char      *extension ;
+} SF_FORMAT_INFO ;
+
+/*
+** Enums and typedefs for adding dither on read and write.
+** See the html documentation for sf_command(), SFC_SET_DITHER_ON_WRITE
+** and SFC_SET_DITHER_ON_READ.
+*/
+
+enum
+{      SFD_DEFAULT_LEVEL       = 0,
+       SFD_CUSTOM_LEVEL        = 0x40000000,
+
+       SFD_NO_DITHER           = 500,
+       SFD_WHITE                       = 501,
+       SFD_TRIANGULAR_PDF      = 502
+} ;
+
+typedef struct
+{      int                     type ;
+       double          level ;
+       const char      *name ;
+} SF_DITHER_INFO ;
+
+/* Struct used to retrieve information about a file embedded within a
+** larger file. See SFC_GET_EMBED_FILE_INFO.
+*/
+
+typedef struct
+{      sf_count_t      offset ;
+       sf_count_t      length ;
+} SF_EMBED_FILE_INFO ;
+
+/*
+**     Structs used to retrieve music sample information from a file.
+*/
+
+enum
+{      /*
+       **      The loop mode field in SF_INSTRUMENT will be one of the following.
+       */
+       SF_LOOP_NONE = 800,
+       SF_LOOP_FORWARD,
+       SF_LOOP_BACKWARD,
+       SF_LOOP_ALTERNATING
+} ;
+
+typedef struct
+{      int gain ;
+       char basenote, detune ;
+       char velocity_lo, velocity_hi ;
+       char key_lo, key_hi ;
+       int loop_count ;
+
+       struct
+       {       int mode ;
+               unsigned int start ;
+               unsigned int end ;
+               unsigned int count ;
+       } loops [16] ; /* make variable in a sensible way */
+} SF_INSTRUMENT ;
+
+
+
+/* Struct used to retrieve loop information from a file.*/
+typedef struct
+{
+       short   time_sig_num ;  /* any positive integer    > 0  */
+       short   time_sig_den ;  /* any positive power of 2 > 0  */
+       int             loop_mode ;             /* see SF_LOOP enum             */
+
+       int             num_beats ;             /* this is NOT the amount of quarter notes !!!*/
+                                                       /* a full bar of 4/4 is 4 beats */
+                                                       /* a full bar of 7/8 is 7 beats */
+
+       float   bpm ;                   /* suggestion, as it can be calculated using other fields:*/
+                                                       /* file's lenght, file's sampleRate and our time_sig_den*/
+                                                       /* -> bpms are always the amount of _quarter notes_ per minute */
+
+       int     root_key ;                      /* MIDI note, or -1 for None */
+       int future [6] ;
+} SF_LOOP_INFO ;
+
+
+/*     Struct used to retrieve broadcast (EBU) information from a file. 
+**     Strongly (!) based on EBU "bext" chunk format used in Broadcast WAVE.
+*/
+typedef struct
+{      char                    description [256] ;
+       char                    originator [32] ;
+       char                    originator_reference [32] ;
+       char                    origination_date [10] ;
+       char                    origination_time [8] ;
+       int                             time_reference_low ;
+       int                             time_reference_high ;
+       short                   version ;
+       char                    umid [64] ;
+       char                    reserved [190] ;
+       unsigned int    coding_history_size ;
+       char                    coding_history [256] ;
+} SF_BROADCAST_INFO ;
+
+typedef sf_count_t             (*sf_vio_get_filelen)   (void *user_data) ;
+typedef sf_count_t             (*sf_vio_seek)          (sf_count_t offset, int whence, void *user_data) ;
+typedef sf_count_t             (*sf_vio_read)          (void *ptr, sf_count_t count, void *user_data) ;
+typedef sf_count_t             (*sf_vio_write)         (const void *ptr, sf_count_t count, void *user_data) ;
+typedef sf_count_t             (*sf_vio_tell)          (void *user_data) ;
+
+struct SF_VIRTUAL_IO
+{      sf_vio_get_filelen      get_filelen ;
+       sf_vio_seek                     seek ;
+       sf_vio_read                     read ;
+       sf_vio_write            write ;
+       sf_vio_tell                     tell ;
+} ;
+
+typedef        struct SF_VIRTUAL_IO SF_VIRTUAL_IO ;
+
+/* Open the specified file for read, write or both. On error, this will
+** return a NULL pointer. To find the error number, pass a NULL SNDFILE
+** to sf_perror () or sf_error_str ().
+** All calls to sf_open() should be matched with a call to sf_close().
+*/
+
+SNDFILE*       sf_open         (const char *path, int mode, SF_INFO *sfinfo) ;
+
+/* Use the existing file descriptor to create a SNDFILE object. If close_desc
+** is TRUE, the file descriptor will be closed when sf_close() is called. If
+** it is FALSE, the descritor will not be closed.
+** When passed a descriptor like this, the library will assume that the start
+** of file header is at the current file offset. This allows sound files within
+** larger container files to be read and/or written.
+** On error, this will return a NULL pointer. To find the error number, pass a
+** NULL SNDFILE to sf_perror () or sf_error_str ().
+** All calls to sf_open_fd() should be matched with a call to sf_close().
+
+*/
+
+SNDFILE*       sf_open_fd      (int fd, int mode, SF_INFO *sfinfo, int close_desc) ;
+
+SNDFILE*       sf_open_virtual (SF_VIRTUAL_IO *sfvirtual, int mode, SF_INFO *sfinfo, void *user_data) ;
+
+/* sf_error () returns a error number which can be translated to a text
+** string using sf_error_number().
+*/
+
+int            sf_error                (SNDFILE *sndfile) ;
+
+/* sf_strerror () returns to the caller a pointer to the current error message for
+** the given SNDFILE.
+*/
+
+const char* sf_strerror (SNDFILE *sndfile) ;
+
+/* sf_error_number () allows the retrieval of the error string for each internal
+** error number.
+**
+*/
+
+const char*    sf_error_number (int errnum) ;
+
+/* The following three error functions are deprecated but they will remain in the
+** library for the forseeable future. The function sf_strerror() should be used
+** in their place.
+*/
+
+int            sf_perror               (SNDFILE *sndfile) ;
+int            sf_error_str    (SNDFILE *sndfile, char* str, size_t len) ;
+
+
+/* Return TRUE if fields of the SF_INFO struct are a valid combination of values. */
+
+int            sf_command      (SNDFILE *sndfile, int command, void *data, int datasize) ;
+
+/* Return TRUE if fields of the SF_INFO struct are a valid combination of values. */
+
+int            sf_format_check (const SF_INFO *info) ;
+
+/* Seek within the waveform data chunk of the SNDFILE. sf_seek () uses
+** the same values for whence (SEEK_SET, SEEK_CUR and SEEK_END) as
+** stdio.h function fseek ().
+** An offset of zero with whence set to SEEK_SET will position the
+** read / write pointer to the first data sample.
+** On success sf_seek returns the current position in (multi-channel)
+** samples from the start of the file.
+** Please see the libsndfile documentation for moving the read pointer
+** separately from the write pointer on files open in mode SFM_RDWR.
+** On error all of these functions return -1.
+*/
+
+sf_count_t     sf_seek                 (SNDFILE *sndfile, sf_count_t frames, int whence) ;
+
+/* Functions for retrieving and setting string data within sound files.
+** Not all file types support this features; AIFF and WAV do. For both
+** functions, the str_type parameter must be one of the SF_STR_* values
+** defined above.
+** On error, sf_set_string() returns non-zero while sf_get_string()
+** returns NULL.
+*/
+
+int sf_set_string (SNDFILE *sndfile, int str_type, const char* str) ;
+
+const char* sf_get_string (SNDFILE *sndfile, int str_type) ;
+
+/* Functions for reading/writing the waveform data of a sound file.
+*/
+
+sf_count_t     sf_read_raw             (SNDFILE *sndfile, void *ptr, sf_count_t bytes) ;
+sf_count_t     sf_write_raw    (SNDFILE *sndfile, const void *ptr, sf_count_t bytes) ;
+
+/* Functions for reading and writing the data chunk in terms of frames.
+** The number of items actually read/written = frames * number of channels.
+**     sf_xxxx_raw             read/writes the raw data bytes from/to the file
+**     sf_xxxx_short   passes data in the native short format
+**     sf_xxxx_int             passes data in the native int format
+**     sf_xxxx_float   passes data in the native float format
+**     sf_xxxx_double  passes data in the native double format
+** All of these read/write function return number of frames read/written.
+*/
+
+sf_count_t     sf_readf_short  (SNDFILE *sndfile, short *ptr, sf_count_t frames) ;
+sf_count_t     sf_writef_short (SNDFILE *sndfile, const short *ptr, sf_count_t frames) ;
+
+sf_count_t     sf_readf_int    (SNDFILE *sndfile, int *ptr, sf_count_t frames) ;
+sf_count_t     sf_writef_int   (SNDFILE *sndfile, const int *ptr, sf_count_t frames) ;
+
+sf_count_t     sf_readf_float  (SNDFILE *sndfile, float *ptr, sf_count_t frames) ;
+sf_count_t     sf_writef_float (SNDFILE *sndfile, const float *ptr, sf_count_t frames) ;
+
+sf_count_t     sf_readf_double         (SNDFILE *sndfile, double *ptr, sf_count_t frames) ;
+sf_count_t     sf_writef_double        (SNDFILE *sndfile, const double *ptr, sf_count_t frames) ;
+
+/* Functions for reading and writing the data chunk in terms of items.
+** Otherwise similar to above.
+** All of these read/write function return number of items read/written.
+*/
+
+sf_count_t     sf_read_short   (SNDFILE *sndfile, short *ptr, sf_count_t items) ;
+sf_count_t     sf_write_short  (SNDFILE *sndfile, const short *ptr, sf_count_t items) ;
+
+sf_count_t     sf_read_int             (SNDFILE *sndfile, int *ptr, sf_count_t items) ;
+sf_count_t     sf_write_int    (SNDFILE *sndfile, const int *ptr, sf_count_t items) ;
+
+sf_count_t     sf_read_float   (SNDFILE *sndfile, float *ptr, sf_count_t items) ;
+sf_count_t     sf_write_float  (SNDFILE *sndfile, const float *ptr, sf_count_t items) ;
+
+sf_count_t     sf_read_double  (SNDFILE *sndfile, double *ptr, sf_count_t items) ;
+sf_count_t     sf_write_double (SNDFILE *sndfile, const double *ptr, sf_count_t items) ;
+
+/* Close the SNDFILE and clean up all memory allocations associated with this
+** file.
+** Returns 0 on success, or an error number.
+*/
+
+int            sf_close                (SNDFILE *sndfile) ;
+
+/* If the file is opened SFM_WRITE or SFM_RDWR, call fsync() on the file
+** to force the writing of data to disk. If the file is opened SFM_READ
+** no action is taken.
+*/
+
+void   sf_write_sync   (SNDFILE *sndfile) ;
+
+#ifdef __cplusplus
+}              /* extern "C" */
+#endif /* __cplusplus */
+
+#endif /* SNDFILE_H */
diff --git a/libs/libsndfile/src/stamp-h1 b/libs/libsndfile/src/stamp-h1
new file mode 100644 (file)
index 0000000..57ea58e
--- /dev/null
@@ -0,0 +1 @@
+timestamp for src/config.h
diff --git a/libs/libsndfile/src/strings.c b/libs/libsndfile/src/strings.c
new file mode 100644 (file)
index 0000000..2433f9b
--- /dev/null
@@ -0,0 +1,204 @@
+/*
+** Copyright (C) 2001-2004 Erik de Castro Lopo <erikd@mega-nerd.com>
+**
+** This program is free software; you can redistribute it and/or modify
+** it under the terms of the GNU Lesser General Public License as published by
+** the Free Software Foundation; either version 2.1 of the License, or
+** (at your option) any later version.
+**
+** This program is distributed in the hope that it will be useful,
+** but WITHOUT ANY WARRANTY; without even the implied warranty of
+** MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+** GNU Lesser General Public License for more details.
+**
+** You should have received a copy of the GNU Lesser General Public License
+** along with this program; if not, write to the Free Software
+** Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA.
+*/
+
+#include       "sfconfig.h"
+
+#include       <stdio.h>
+#include       <string.h>
+#include       <math.h>
+
+#include       "sndfile.h"
+#include       "common.h"
+
+#define STRINGS_DEBUG 0
+#if STRINGS_DEBUG
+static void hexdump (void *data, int len) ;
+#endif
+
+int
+psf_store_string (SF_PRIVATE *psf, int str_type, const char *str)
+{      static char lsf_name [] = PACKAGE "-" VERSION ;
+       static char bracket_name [] = " (" PACKAGE "-" VERSION ")" ;
+       int             k, str_len, len_remaining, str_flags ;
+
+       if (str == NULL)
+               return SFE_STR_BAD_STRING ;
+
+       str_len = strlen (str) ;
+
+       /* A few extra checks for write mode. */
+       if (psf->mode == SFM_WRITE || psf->mode == SFM_RDWR)
+       {       if ((psf->str_flags & SF_STR_ALLOW_START) == 0)
+                       return SFE_STR_NO_SUPPORT ;
+               if ((psf->str_flags & SF_STR_ALLOW_END) == 0)
+                       return SFE_STR_NO_SUPPORT ;
+               /* Only allow zero length strings for software. */
+               if (str_type != SF_STR_SOFTWARE && str_len == 0)
+                       return SFE_STR_BAD_STRING ;
+               } ;
+
+       /* Determine flags */
+       str_flags = SF_STR_LOCATE_START ;
+       if (psf->have_written)
+       {       if ((psf->str_flags & SF_STR_ALLOW_END) == 0)
+                       return SFE_STR_NO_ADD_END ;
+               str_flags = SF_STR_LOCATE_END ;
+               } ;
+
+       /* Find next free slot in table. */
+       for (k = 0 ; k < SF_MAX_STRINGS ; k++)
+               if (psf->strings [k].type == 0)
+                       break ;
+
+       /* More sanity checking. */
+       if (k >= SF_MAX_STRINGS)
+               return SFE_STR_MAX_COUNT ;
+
+       if (k == 0 && psf->str_end != NULL)
+       {       psf_log_printf (psf, "SFE_STR_WEIRD : k == 0 && psf->str_end != NULL\n") ;
+               return SFE_STR_WEIRD ;
+               } ;
+
+       if (k != 0 && psf->str_end == NULL)
+       {       psf_log_printf (psf, "SFE_STR_WEIRD : k != 0 && psf->str_end == NULL\n") ;
+               return SFE_STR_WEIRD ;
+               } ;
+
+       /* Special case for the first string. */
+       if (k == 0)
+               psf->str_end = psf->str_storage ;
+
+
+#if STRINGS_DEBUG
+       psf_log_printf (psf, "str_storage          : %X\n", (int) psf->str_storage) ;
+       psf_log_printf (psf, "str_end              : %X\n", (int) psf->str_end) ;
+       psf_log_printf (psf, "sizeof (str_storage) : %d\n", SIGNED_SIZEOF (psf->str_storage)) ;
+#endif
+
+       len_remaining = SIGNED_SIZEOF (psf->str_storage) - (psf->str_end - psf->str_storage) ;
+
+       if (len_remaining < str_len + 2)
+               return SFE_STR_MAX_DATA ;
+
+       switch (str_type)
+       {       case SF_STR_SOFTWARE :
+                               /* In write mode, want to append libsndfile-version to string. */
+                               if (psf->mode == SFM_WRITE || psf->mode == SFM_RDWR)
+                               {       psf->strings [k].type = str_type ;
+                                       psf->strings [k].str = psf->str_end ;
+                                       psf->strings [k].flags = str_flags ;
+
+                                       memcpy (psf->str_end, str, str_len + 1) ;
+                                       psf->str_end += str_len ;
+
+                                       /*
+                                       ** If the supplied string does not already contain a
+                                       ** libsndfile-X.Y.Z component, then add it.
+                                       */
+                                       if (strstr (str, PACKAGE) == NULL && len_remaining > (int) (strlen (bracket_name) + str_len + 2))
+                                       {       if (strlen (str) == 0)
+                                                       strncat (psf->str_end, lsf_name, len_remaining) ;
+                                               else
+                                                       strncat (psf->str_end, bracket_name, len_remaining) ;
+                                               psf->str_end += strlen (psf->str_end) ;
+                                               } ;
+
+                                       /* Plus one to catch string terminator. */
+                                       psf->str_end += 1 ;
+                                       break ;
+                                       } ;
+
+                               /* Fall though if not write mode. */
+
+               case SF_STR_TITLE :
+               case SF_STR_COPYRIGHT :
+               case SF_STR_ARTIST :
+               case SF_STR_COMMENT :
+               case SF_STR_DATE :
+                               psf->strings [k].type = str_type ;
+                               psf->strings [k].str = psf->str_end ;
+                               psf->strings [k].flags = str_flags ;
+
+                               /* Plus one to catch string terminator. */
+                               memcpy (psf->str_end, str, str_len + 1) ;
+                               psf->str_end += str_len + 1 ;
+                               break ;
+
+               default :
+                       return SFE_STR_BAD_TYPE ;
+               } ;
+
+       psf->str_flags |= (psf->have_written) ? SF_STR_LOCATE_END : SF_STR_LOCATE_START ;
+
+#if STRINGS_DEBUG
+       hexdump (psf->str_storage, 300) ;
+#endif
+
+       return 0 ;
+} /* psf_store_string */
+
+int
+psf_set_string (SF_PRIVATE *psf, int str_type, const char *str)
+{      if (psf->mode == SFM_READ)
+               return SFE_STR_NOT_WRITE ;
+
+       return psf_store_string (psf, str_type, str) ;
+} /* psf_set_string */
+
+const char*
+psf_get_string (SF_PRIVATE *psf, int str_type)
+{      int k ;
+
+       for (k = 0 ; k < SF_MAX_STRINGS ; k++)
+               if (str_type == psf->strings [k].type)
+                       return psf->strings [k].str ;
+
+       return NULL ;
+} /* psf_get_string */
+
+#if STRINGS_DEBUG
+
+#include <ctype.h>
+static void
+hexdump (void *data, int len)
+{      unsigned char *ptr ;
+       int k ;
+
+       ptr = data ;
+
+       puts ("---------------------------------------------------------") ;
+       while (len >= 16)
+       {       for (k = 0 ; k < 16 ; k++)
+                       printf ("%02X ", ptr [k] & 0xFF) ;
+               printf ("   ") ;
+               for (k = 0 ; k < 16 ; k++)
+                       printf ("%c", isprint (ptr [k]) ? ptr [k] : '.') ;
+               puts ("") ;
+               ptr += 16 ;
+               len -= 16 ;
+               } ;
+} /* hexdump */
+
+#endif
+/*
+** Do not edit or modify anything in this comment block.
+** The arch-tag line is a file identity tag for the GNU Arch 
+** revision control system.
+**
+** arch-tag: 04393aa1-9389-46fe-baf2-58a7bd544fd6
+*/
diff --git a/libs/libsndfile/src/svx.c b/libs/libsndfile/src/svx.c
new file mode 100644 (file)
index 0000000..3ef461d
--- /dev/null
@@ -0,0 +1,410 @@
+/*
+** Copyright (C) 1999-2004 Erik de Castro Lopo <erikd@mega-nerd.com>
+**
+** This program is free software; you can redistribute it and/or modify
+** it under the terms of the GNU Lesser General Public License as published by
+** the Free Software Foundation; either version 2.1 of the License, or
+** (at your option) any later version.
+**
+** This program is distributed in the hope that it will be useful,
+** but WITHOUT ANY WARRANTY; without even the implied warranty of
+** MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+** GNU Lesser General Public License for more details.
+**
+** You should have received a copy of the GNU Lesser General Public License
+** along with this program; if not, write to the Free Software
+** Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA.
+*/
+
+#include "sfconfig.h"
+
+#include <stdio.h>
+#include <string.h>
+#include <ctype.h>
+#include <stdarg.h>
+
+#include "sndfile.h"
+#include "sfendian.h"
+#include "common.h"
+
+
+/*------------------------------------------------------------------------------
+ * Macros to handle big/little endian issues.
+*/
+
+#define FORM_MARKER    (MAKE_MARKER ('F', 'O', 'R', 'M'))
+#define SVX8_MARKER    (MAKE_MARKER ('8', 'S', 'V', 'X'))
+#define SV16_MARKER    (MAKE_MARKER ('1', '6', 'S', 'V'))
+#define VHDR_MARKER    (MAKE_MARKER ('V', 'H', 'D', 'R'))
+#define BODY_MARKER    (MAKE_MARKER ('B', 'O', 'D', 'Y'))
+
+#define ATAK_MARKER    (MAKE_MARKER ('A', 'T', 'A', 'K'))
+#define RLSE_MARKER    (MAKE_MARKER ('R', 'L', 'S', 'E'))
+
+#define c_MARKER       (MAKE_MARKER ('(', 'c', ')', ' '))
+#define NAME_MARKER    (MAKE_MARKER ('N', 'A', 'M', 'E'))
+#define AUTH_MARKER    (MAKE_MARKER ('A', 'U', 'T', 'H'))
+#define ANNO_MARKER    (MAKE_MARKER ('A', 'N', 'N', 'O'))
+#define CHAN_MARKER    (MAKE_MARKER ('C', 'H', 'A', 'N'))
+
+/*------------------------------------------------------------------------------
+ * Typedefs for file chunks.
+*/
+
+typedef struct
+{      unsigned int    oneShotHiSamples, repeatHiSamples, samplesPerHiCycle ;
+       unsigned short  samplesPerSec ;
+       unsigned char   octave, compression ;
+       unsigned int    volume ;
+} VHDR_CHUNK ;
+
+enum {
+       HAVE_FORM       = 0x01,
+
+       HAVE_SVX        = 0x02,
+       HAVE_VHDR       = 0x04,
+       HAVE_BODY       = 0x08
+} ;
+
+/*------------------------------------------------------------------------------
+ * Private static functions.
+*/
+
+static int     svx_close       (SF_PRIVATE *psf) ;
+static int     svx_write_header (SF_PRIVATE *psf, int calc_length) ;
+static int     svx_read_header (SF_PRIVATE *psf) ;
+
+/*------------------------------------------------------------------------------
+** Public function.
+*/
+
+int
+svx_open       (SF_PRIVATE *psf)
+{      int error ;
+
+       if (psf->mode == SFM_READ || (psf->mode == SFM_RDWR && psf->filelength > 0))
+       {       if ((error = svx_read_header (psf)))
+                       return error ;
+
+               psf->endian = SF_ENDIAN_BIG ;                   /* All SVX files are big endian. */
+
+               psf->blockwidth = psf->sf.channels * psf->bytewidth ;
+               if (psf->blockwidth)
+                       psf->sf.frames = psf->datalength / psf->blockwidth ;
+
+               psf_fseek (psf, psf->dataoffset, SEEK_SET) ;
+               } ;
+
+       if (psf->mode == SFM_WRITE || psf->mode == SFM_RDWR)
+       {       if (psf->is_pipe)
+                       return SFE_NO_PIPE_WRITE ;
+
+               if ((psf->sf.format & SF_FORMAT_TYPEMASK) != SF_FORMAT_SVX)
+                       return  SFE_BAD_OPEN_FORMAT ;
+
+               psf->endian = psf->sf.format & SF_FORMAT_ENDMASK ;
+
+               if (psf->endian == SF_ENDIAN_LITTLE || (CPU_IS_LITTLE_ENDIAN && psf->endian == SF_ENDIAN_CPU))
+                       return SFE_BAD_ENDIAN ;
+
+               psf->endian = SF_ENDIAN_BIG ;                   /* All SVX files are big endian. */
+
+               error = svx_write_header (psf, SF_FALSE) ;
+               if (error)
+                       return error ;
+
+               psf->write_header = svx_write_header ;
+               } ;
+
+       psf->container_close = svx_close ;
+
+       if ((error = pcm_init (psf)))
+               return error ;
+
+       return 0 ;
+} /* svx_open */
+
+/*------------------------------------------------------------------------------
+*/
+
+static int
+svx_read_header        (SF_PRIVATE *psf)
+{      VHDR_CHUNK              vhdr ;
+       unsigned int    FORMsize, vhdrsize, dword, marker ;
+       int                             filetype = 0, parsestage = 0, done = 0 ;
+       int                     bytecount = 0, channels ;
+
+       memset (&vhdr, 0, sizeof (vhdr)) ;
+       psf_binheader_readf (psf, "p", 0) ;
+
+       /* Set default number of channels. Currently can't handle stereo SVX files. */
+       psf->sf.channels = 1 ;
+
+       psf->sf.format = SF_FORMAT_SVX ;
+
+       while (! done)
+       {       psf_binheader_readf (psf, "m", &marker) ;
+               switch (marker)
+               {       case FORM_MARKER :
+                                       if (parsestage)
+                                               return SFE_SVX_NO_FORM ;
+
+                                       psf_binheader_readf (psf, "E4", &FORMsize) ;
+
+                                       if (FORMsize != psf->filelength - 2 * sizeof (dword))
+                                       {       dword = psf->filelength - 2 * sizeof (dword) ;
+                                               psf_log_printf (psf, "FORM : %d (should be %d)\n", FORMsize, dword) ;
+                                               FORMsize = dword ;
+                                               }
+                                       else
+                                               psf_log_printf (psf, "FORM : %d\n", FORMsize) ;
+                                       parsestage |= HAVE_FORM ;
+                                       break ;
+
+                       case SVX8_MARKER :
+                       case SV16_MARKER :
+                                       if (! (parsestage & HAVE_FORM))
+                                               return SFE_SVX_NO_FORM ;
+                                       filetype = marker ;
+                                       psf_log_printf (psf, " %M\n", marker) ;
+                                       parsestage |= HAVE_SVX ;
+                                       break ;
+
+                       case VHDR_MARKER :
+                                       if (! (parsestage & (HAVE_FORM | HAVE_SVX)))
+                                               return SFE_SVX_NO_FORM ;
+
+                                       psf_binheader_readf (psf, "E4", &vhdrsize) ;
+
+                                       psf_log_printf (psf, " VHDR : %d\n", vhdrsize) ;
+
+                                       psf_binheader_readf (psf, "E4442114", &(vhdr.oneShotHiSamples), &(vhdr.repeatHiSamples),
+                                               &(vhdr.samplesPerHiCycle), &(vhdr.samplesPerSec), &(vhdr.octave), &(vhdr.compression),
+                                               &(vhdr.volume)) ;
+
+                                       psf_log_printf (psf, "  OneShotHiSamples  : %d\n", vhdr.oneShotHiSamples) ;
+                                       psf_log_printf (psf, "  RepeatHiSamples   : %d\n", vhdr.repeatHiSamples) ;
+                                       psf_log_printf (psf, "  samplesPerHiCycle : %d\n", vhdr.samplesPerHiCycle) ;
+                                       psf_log_printf (psf, "  Sample Rate       : %d\n", vhdr.samplesPerSec) ;
+                                       psf_log_printf (psf, "  Octave            : %d\n", vhdr.octave) ;
+
+                                       psf_log_printf (psf, "  Compression       : %d => ", vhdr.compression) ;
+
+                                       switch (vhdr.compression)
+                                       {       case 0 : psf_log_printf (psf, "None.\n") ;
+                                                               break ;
+                                               case 1 : psf_log_printf (psf, "Fibonacci delta\n") ;
+                                                               break ;
+                                               case 2 : psf_log_printf (psf, "Exponential delta\n") ;
+                                                               break ;
+                                               } ;
+
+                                       psf_log_printf (psf, "  Volume            : %d\n", vhdr.volume) ;
+
+                                       psf->sf.samplerate      = vhdr.samplesPerSec ;
+
+                                       if (filetype == SVX8_MARKER)
+                                       {       psf->sf.format |= SF_FORMAT_PCM_S8 ;
+                                               psf->bytewidth = 1 ;
+                                               }
+                                       else if (filetype == SV16_MARKER)
+                                       {       psf->sf.format |= SF_FORMAT_PCM_16 ;
+                                               psf->bytewidth = 2 ;
+                                               } ;
+
+                                       parsestage |= HAVE_VHDR ;
+                                       break ;
+
+                       case BODY_MARKER :
+                                       if (! (parsestage & HAVE_VHDR))
+                                               return SFE_SVX_NO_BODY ;
+
+                                       psf_binheader_readf (psf, "E4", &dword) ;
+                                       psf->datalength = dword ;
+
+                                       psf->dataoffset = psf_ftell (psf) ;
+
+                                       if (psf->datalength > psf->filelength - psf->dataoffset)
+                                       {       psf_log_printf (psf, " BODY : %D (should be %D)\n", psf->datalength, psf->filelength - psf->dataoffset) ;
+                                               psf->datalength = psf->filelength - psf->dataoffset ;
+                                               }
+                                       else
+                                               psf_log_printf (psf, " BODY : %D\n", psf->datalength) ;
+
+                                       parsestage |= HAVE_BODY ;
+
+                                       if (! psf->sf.seekable)
+                                               break ;
+
+                                       psf_fseek (psf, psf->datalength, SEEK_CUR) ;
+                                       break ;
+
+                       case NAME_MARKER :
+                                       if (! (parsestage & HAVE_SVX))
+                                               return SFE_SVX_NO_FORM ;
+
+                                       psf_binheader_readf (psf, "E4", &dword) ;
+
+                                       psf_log_printf (psf, " %M : %d\n", marker, dword) ;
+
+                                       if (strlen (psf->filename) != dword)
+                                       {       if (dword > sizeof (psf->filename) - 1)
+                                                       return SFE_SVX_BAD_NAME_LENGTH ;
+
+                                               psf_binheader_readf (psf, "b", psf->filename, dword) ;
+                                               psf->filename [dword] = 0 ;
+                                               }
+                                       else
+                                               psf_binheader_readf (psf, "j", dword) ;
+                                       break ;
+
+                       case ANNO_MARKER :
+                                       if (! (parsestage & HAVE_SVX))
+                                               return SFE_SVX_NO_FORM ;
+
+                                       psf_binheader_readf (psf, "E4", &dword) ;
+
+                                       psf_log_printf (psf, " %M : %d\n", marker, dword) ;
+
+                                       psf_binheader_readf (psf, "j", dword) ;
+                                       break ;
+
+                       case CHAN_MARKER :
+                                       if (! (parsestage & HAVE_SVX))
+                                               return SFE_SVX_NO_FORM ;
+
+                                       psf_binheader_readf (psf, "E4", &dword) ;
+
+                                       psf_log_printf (psf, " %M : %d\n", marker, dword) ;
+
+                                       bytecount += psf_binheader_readf (psf, "E4", &channels) ;
+                                       psf->sf.channels = channels ;
+
+                                       psf_log_printf (psf, "  Channels : %d\n", channels) ;
+
+                                       psf_binheader_readf (psf, "j", dword - bytecount) ;
+                                       break ;
+
+
+                       case AUTH_MARKER :
+                       case c_MARKER :
+                                       if (! (parsestage & HAVE_SVX))
+                                               return SFE_SVX_NO_FORM ;
+
+                                       psf_binheader_readf (psf, "E4", &dword) ;
+
+                                       psf_log_printf (psf, " %M : %d\n", marker, dword) ;
+
+                                       psf_binheader_readf (psf, "j", dword) ;
+                                       break ;
+
+                       default :
+                                       if (isprint ((marker >> 24) & 0xFF) && isprint ((marker >> 16) & 0xFF)
+                                               && isprint ((marker >> 8) & 0xFF) && isprint (marker & 0xFF))
+                                       {       psf_binheader_readf (psf, "E4", &dword) ;
+
+                                               psf_log_printf (psf, "%M : %d (unknown marker)\n", marker, dword) ;
+
+                                               psf_binheader_readf (psf, "j", dword) ;
+                                               break ;
+                                               } ;
+                                       if ((dword = psf_ftell (psf)) & 0x03)
+                                       {       psf_log_printf (psf, "  Unknown chunk marker at position %d. Resynching.\n", dword - 4) ;
+
+                                               psf_binheader_readf (psf, "j", -3) ;
+                                               break ;
+                                               } ;
+                                       psf_log_printf (psf, "*** Unknown chunk marker : %X. Exiting parser.\n", marker) ;
+                                       done = 1 ;
+                       } ;     /* switch (marker) */
+
+               if (! psf->sf.seekable && (parsestage & HAVE_BODY))
+                       break ;
+
+               if (psf_ftell (psf) >= psf->filelength - SIGNED_SIZEOF (dword))
+                       break ;
+               } ; /* while (1) */
+
+       if (vhdr.compression)
+               return SFE_SVX_BAD_COMP ;
+
+       if (psf->dataoffset <= 0)
+               return SFE_SVX_NO_DATA ;
+
+       return 0 ;
+} /* svx_read_header */
+
+static int
+svx_close (SF_PRIVATE *psf)
+{
+       if (psf->mode == SFM_WRITE || psf->mode == SFM_RDWR)
+               svx_write_header (psf, SF_TRUE) ;
+
+       return 0 ;
+} /* svx_close */
+
+static int
+svx_write_header (SF_PRIVATE *psf, int calc_length)
+{      static  char    annotation      [] = "libsndfile by Erik de Castro Lopo\0\0\0" ;
+       sf_count_t      current ;
+
+       current = psf_ftell (psf) ;
+
+       if (calc_length)
+       {       psf->filelength = psf_get_filelen (psf) ;
+
+               psf->datalength = psf->filelength - psf->dataoffset ;
+
+               if (psf->dataend)
+                       psf->datalength -= psf->filelength - psf->dataend ;
+
+               psf->sf.frames = psf->datalength / (psf->bytewidth * psf->sf.channels) ;
+               } ;
+
+       psf->header [0] = 0 ;
+       psf->headindex = 0 ;
+       psf_fseek (psf, 0, SEEK_SET) ;
+
+       /* FORM marker and FORM size. */
+       psf_binheader_writef (psf, "Etm8", FORM_MARKER, (psf->filelength < 8) ?
+                       psf->filelength * 0 : psf->filelength - 8) ;
+
+       psf_binheader_writef (psf, "m", (psf->bytewidth == 1) ? SVX8_MARKER : SV16_MARKER) ;
+
+       /* VHDR chunk. */
+       psf_binheader_writef (psf, "Em4", VHDR_MARKER, sizeof (VHDR_CHUNK)) ;
+       /* VHDR : oneShotHiSamples, repeatHiSamples, samplesPerHiCycle */
+       psf_binheader_writef (psf, "E444", psf->sf.frames, 0, 0) ;
+       /* VHDR : samplesPerSec, octave, compression */
+       psf_binheader_writef (psf, "E211", psf->sf.samplerate, 1, 0) ;
+       /* VHDR : volume */
+       psf_binheader_writef (psf, "E4", (psf->bytewidth == 1) ? 0xFF : 0xFFFF) ;
+
+       /* Filename and annotation strings. */
+       psf_binheader_writef (psf, "Emsms", NAME_MARKER, psf->filename, ANNO_MARKER, annotation) ;
+
+       /* BODY marker and size. */
+       psf_binheader_writef (psf, "Etm8", BODY_MARKER, (psf->datalength < 0) ?
+                       psf->datalength * 0 : psf->datalength) ;
+
+       psf_fwrite (psf->header, psf->headindex, 1, psf) ;
+
+       if (psf->error)
+               return psf->error ;
+
+       psf->dataoffset = psf->headindex ;
+
+       if (current > 0)
+               psf_fseek (psf, current, SEEK_SET) ;
+
+       return psf->error ;
+} /* svx_write_header */
+
+
+/*
+** Do not edit or modify anything in this comment block.
+** The arch-tag line is a file identity tag for the GNU Arch 
+** revision control system.
+**
+** arch-tag: a80ab6fb-7d75-4d32-a6b0-0061a3f05d95
+*/
diff --git a/libs/libsndfile/src/txw.c b/libs/libsndfile/src/txw.c
new file mode 100644 (file)
index 0000000..0f0add6
--- /dev/null
@@ -0,0 +1,379 @@
+/*
+** Copyright (C) 2002-2004 Erik de Castro Lopo <erikd@mega-nerd.com>
+**
+** This program is free software; you can redistribute it and/or modify
+** it under the terms of the GNU Lesser General Public License as published by
+** the Free Software Foundation; either version 2.1 of the License, or
+** (at your option) any later version.
+**
+** This program is distributed in the hope that it will be useful,
+** but WITHOUT ANY WARRANTY; without even the implied warranty of
+** MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+** GNU Lesser General Public License for more details.
+**
+** You should have received a copy of the GNU Lesser General Public License
+** along with this program; if not, write to the Free Software
+** Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA.
+*/
+
+/*===========================================================================
+** Yamaha TX16 Sampler Files.
+**
+** This header parser was written using information from the SoX source code
+** and trial and error experimentation. The code here however is all original.
+*/
+
+#include       "sfconfig.h"
+
+#include       <stdio.h>
+#include       <fcntl.h>
+#include       <string.h>
+#include       <ctype.h>
+
+#include       "sndfile.h"
+#include       "sfendian.h"
+#include       "common.h"
+
+#if (ENABLE_EXPERIMENTAL_CODE == 0)
+
+int
+txw_open       (SF_PRIVATE *psf)
+{      if (psf)
+               return SFE_UNIMPLEMENTED ;
+       return (psf && 0) ;
+} /* txw_open */
+
+#else
+
+/*------------------------------------------------------------------------------
+** Markers.
+*/
+
+#define TXW_DATA_OFFSET                32
+
+#define        TXW_LOOPED                      0x49
+#define        TXW_NO_LOOP                     0xC9
+
+/*------------------------------------------------------------------------------
+** Private static functions.
+*/
+
+static int txw_read_header (SF_PRIVATE *psf) ;
+
+static sf_count_t txw_read_s (SF_PRIVATE *psf, short *ptr, sf_count_t len) ;
+static sf_count_t txw_read_i (SF_PRIVATE *psf, int *ptr, sf_count_t len) ;
+static sf_count_t txw_read_f (SF_PRIVATE *psf, float *ptr, sf_count_t len) ;
+static sf_count_t txw_read_d (SF_PRIVATE *psf, double *ptr, sf_count_t len) ;
+
+static sf_count_t txw_seek (SF_PRIVATE *psf, int mode, sf_count_t offset) ;
+
+/*------------------------------------------------------------------------------
+** Public functions.
+*/
+
+/*
+ * ftp://ftp.t0.or.at/pub/sound/tx16w/samples.yamaha
+ * ftp://ftp.t0.or.at/pub/sound/tx16w/faq/tx16w.tec
+ * http://www.t0.or.at/~mpakesch/tx16w/
+ *
+ * from tx16w.c sox 12.15: (7-Oct-98) (Mark Lakata and Leigh Smith)
+ *  char filetype[6] "LM8953"
+ *  nulls[10],
+ *  dummy_aeg[6]
+ *  format 0x49 = looped, 0xC9 = non-looped
+ *  sample_rate 1 = 33 kHz, 2 = 50 kHz, 3 = 16 kHz
+ *  atc_length[3] if sample rate 0, [2]&0xfe = 6: 33kHz, 0x10:50, 0xf6: 16,
+ *                                     depending on [5] but to heck with it
+ *  rpt_length[3] (these are for looped samples, attack and loop lengths)
+ *  unused[2]
+ */
+
+typedef struct
+{      unsigned char   format, srate, sr2, sr3 ;
+       unsigned short  srhash ;
+       unsigned int    attacklen, repeatlen ;
+} TXW_HEADER ;
+
+#define        ERROR_666       666
+
+int
+txw_open       (SF_PRIVATE *psf)
+{      int error ;
+
+       if (psf->mode != SFM_READ)
+               return SFE_UNIMPLEMENTED ;
+
+       if ((error = txw_read_header (psf)))
+                       return error ;
+
+       if (psf_fseek (psf, psf->dataoffset, SEEK_SET) != psf->dataoffset)
+               return SFE_BAD_SEEK ;
+
+       psf->read_short         = txw_read_s ;
+       psf->read_int           = txw_read_i ;
+       psf->read_float         = txw_read_f ;
+       psf->read_double        = txw_read_d ;
+
+       psf->seek = txw_seek ;
+
+       return 0 ;
+} /* txw_open */
+
+/*------------------------------------------------------------------------------
+*/
+
+static int
+txw_read_header        (SF_PRIVATE *psf)
+{      TXW_HEADER txwh ;
+       char    *strptr ;
+
+       memset (&txwh, 0, sizeof (txwh)) ;
+       memset (psf->u.cbuf, 0, sizeof (psf->u.cbuf)) ;
+       psf_binheader_readf (psf, "pb", 0, psf->u.cbuf, 16) ;
+
+       if (memcmp (psf->u.cbuf, "LM8953\0\0\0\0\0\0\0\0\0\0", 16) != 0)
+               return ERROR_666 ;
+
+       psf_log_printf (psf, "Read only : Yamaha TX-16 Sampler (.txw)\nLM8953\n") ;
+
+       /* Jump 6 bytes (dummp_aeg), read format, read sample rate. */
+       psf_binheader_readf (psf, "j11", 6, &txwh.format, &txwh.srate) ;
+
+       /* 8 bytes (atc_length[3], rpt_length[3], unused[2]). */
+       psf_binheader_readf (psf, "e33j", &txwh.attacklen, &txwh.repeatlen, 2) ;
+       txwh.sr2 = (txwh.attacklen >> 16) & 0xFE ;
+       txwh.sr3 = (txwh.repeatlen >> 16) & 0xFE ;
+       txwh.attacklen &= 0x1FFFF ;
+       txwh.repeatlen &= 0x1FFFF ;
+
+       switch (txwh.format)
+       {       case TXW_LOOPED :
+                               strptr = "looped" ;
+                               break ;
+
+               case TXW_NO_LOOP :
+                               strptr = "non-looped" ;
+                               break ;
+
+               default :
+                               psf_log_printf (psf, " Format      : 0x%02x => ?????\n", txwh.format) ;
+                               return ERROR_666 ;
+               } ;
+
+       psf_log_printf (psf, " Format      : 0x%02X => %s\n", txwh.format, strptr) ;
+
+       strptr = NULL ;
+
+       switch (txwh.srate)
+       {       case 1 :
+                               psf->sf.samplerate = 33333 ;
+                               break ;
+
+               case 2 :
+                               psf->sf.samplerate = 50000 ;
+                               break ;
+
+               case 3 :
+                               psf->sf.samplerate = 16667 ;
+                               break ;
+
+               default :
+                       /* This is ugly and braindead. */
+                       txwh.srhash = ((txwh.sr2 & 0xFE) << 8) | (txwh.sr3 & 0xFE) ;
+                       switch (txwh.srhash)
+                       {       case ((0x6 << 8) | 0x52) :
+                                               psf->sf.samplerate = 33333 ;
+                                               break ;
+
+                               case ((0x10 << 8) | 0x52) :
+                                               psf->sf.samplerate = 50000 ;
+                                               break ;
+
+                               case ((0xF6 << 8) | 0x52) :
+                                               psf->sf.samplerate = 166667 ;
+                                               break ;
+
+                               default :
+                                               strptr = " Sample Rate : Unknown : forcing to 33333\n" ;
+                                               psf->sf.samplerate = 33333 ;
+                                               break ;
+                               } ;
+               } ;
+
+
+       if (strptr)
+               psf_log_printf (psf, strptr) ;
+       else if (txwh.srhash)
+               psf_log_printf (psf, " Sample Rate : %d (0x%X) => %d\n", txwh.srate, txwh.srhash, psf->sf.samplerate) ;
+       else
+               psf_log_printf (psf, " Sample Rate : %d => %d\n", txwh.srate, psf->sf.samplerate) ;
+
+       if (txwh.format == TXW_LOOPED)
+       {       psf_log_printf (psf, " Attack Len  : %d\n", txwh.attacklen) ;
+               psf_log_printf (psf, " Repeat Len  : %d\n", txwh.repeatlen) ;
+               } ;
+
+       psf->dataoffset = TXW_DATA_OFFSET ;
+       psf->datalength = psf->filelength - TXW_DATA_OFFSET ;
+       psf->sf.frames  = 2 * psf->datalength / 3 ;
+
+
+       if (psf->datalength % 3 == 1)
+               psf_log_printf (psf, "*** File seems to be truncated, %d extra bytes.\n",
+                       (int) (psf->datalength % 3)) ;
+
+       if (txwh.attacklen + txwh.repeatlen > psf->sf.frames)
+               psf_log_printf (psf, "*** File has been truncated.\n") ;
+
+       psf->sf.format = SF_FORMAT_TXW | SF_FORMAT_PCM_16 ;
+       psf->sf.channels = 1 ;
+       psf->sf.sections = 1 ;
+       psf->sf.seekable = SF_TRUE ;
+
+       return 0 ;
+} /* txw_read_header */
+
+static sf_count_t
+txw_read_s (SF_PRIVATE *psf, short *ptr, sf_count_t len)
+{      unsigned char   *ucptr ;
+       short                   sample ;
+       int                             k, bufferlen, readcount, count ;
+       sf_count_t              total = 0 ;
+
+       bufferlen = sizeof (psf->u.cbuf) / 3 ;
+       bufferlen -= (bufferlen & 1) ;
+       while (len > 0)
+       {       readcount = (len >= bufferlen) ? bufferlen : len ;
+               count = psf_fread (psf->u.cbuf, 3, readcount, psf) ;
+
+               ucptr = psf->u.ucbuf ;
+               for (k = 0 ; k < readcount ; k += 2)
+               {       sample = (ucptr [0] << 8) | (ucptr [1] & 0xF0) ;
+                       ptr [total + k] = sample ;
+                       sample = (ucptr [2] << 8) | ((ucptr [1] & 0xF) << 4) ;
+                       ptr [total + k + 1] = sample ;
+                       ucptr += 3 ;
+                       } ;
+
+               total += count ;
+               len -= readcount ;
+               } ;
+
+       return total ;
+} /* txw_read_s */
+
+static sf_count_t
+txw_read_i (SF_PRIVATE *psf, int *ptr, sf_count_t len)
+{      unsigned char   *ucptr ;
+       short                   sample ;
+       int                             k, bufferlen, readcount, count ;
+       sf_count_t              total = 0 ;
+
+       bufferlen = sizeof (psf->u.cbuf) / 3 ;
+       bufferlen -= (bufferlen & 1) ;
+       while (len > 0)
+       {       readcount = (len >= bufferlen) ? bufferlen : len ;
+               count = psf_fread (psf->u.cbuf, 3, readcount, psf) ;
+
+               ucptr = psf->u.ucbuf ;
+               for (k = 0 ; k < readcount ; k += 2)
+               {       sample = (ucptr [0] << 8) | (ucptr [1] & 0xF0) ;
+                       ptr [total + k] = sample << 16 ;
+                       sample = (ucptr [2] << 8) | ((ucptr [1] & 0xF) << 4) ;
+                       ptr [total + k + 1] = sample << 16 ;
+                       ucptr += 3 ;
+                       } ;
+
+               total += count ;
+               len -= readcount ;
+               } ;
+
+       return total ;
+} /* txw_read_i */
+
+static sf_count_t
+txw_read_f (SF_PRIVATE *psf, float *ptr, sf_count_t len)
+{      unsigned char   *ucptr ;
+       short                   sample ;
+       int                             k, bufferlen, readcount, count ;
+       sf_count_t              total = 0 ;
+       float                   normfact ;
+
+       if (psf->norm_float == SF_TRUE)
+               normfact = 1.0 / 0x8000 ;
+       else
+               normfact = 1.0 / 0x10 ;
+
+       bufferlen = sizeof (psf->u.cbuf) / 3 ;
+       bufferlen -= (bufferlen & 1) ;
+       while (len > 0)
+       {       readcount = (len >= bufferlen) ? bufferlen : len ;
+               count = psf_fread (psf->u.cbuf, 3, readcount, psf) ;
+
+               ucptr = psf->u.ucbuf ;
+               for (k = 0 ; k < readcount ; k += 2)
+               {       sample = (ucptr [0] << 8) | (ucptr [1] & 0xF0) ;
+                       ptr [total + k] = normfact * sample ;
+                       sample = (ucptr [2] << 8) | ((ucptr [1] & 0xF) << 4) ;
+                       ptr [total + k + 1] = normfact * sample ;
+                       ucptr += 3 ;
+                       } ;
+
+               total += count ;
+               len -= readcount ;
+               } ;
+
+       return total ;
+} /* txw_read_f */
+
+static sf_count_t
+txw_read_d (SF_PRIVATE *psf, double *ptr, sf_count_t len)
+{      unsigned char   *ucptr ;
+       short                   sample ;
+       int                             k, bufferlen, readcount, count ;
+       sf_count_t              total = 0 ;
+       double                  normfact ;
+
+       if (psf->norm_double == SF_TRUE)
+               normfact = 1.0 / 0x8000 ;
+       else
+               normfact = 1.0 / 0x10 ;
+
+       bufferlen = sizeof (psf->u.cbuf) / 3 ;
+       bufferlen -= (bufferlen & 1) ;
+       while (len > 0)
+       {       readcount = (len >= bufferlen) ? bufferlen : len ;
+               count = psf_fread (psf->u.cbuf, 3, readcount, psf) ;
+
+               ucptr = psf->u.ucbuf ;
+               for (k = 0 ; k < readcount ; k += 2)
+               {       sample = (ucptr [0] << 8) | (ucptr [1] & 0xF0) ;
+                       ptr [total + k] = normfact * sample ;
+                       sample = (ucptr [2] << 8) | ((ucptr [1] & 0xF) << 4) ;
+                       ptr [total + k + 1] = normfact * sample ;
+                       ucptr += 3 ;
+                       } ;
+
+               total += count ;
+               len -= readcount ;
+               } ;
+
+       return total ;
+} /* txw_read_d */
+
+static sf_count_t
+txw_seek (SF_PRIVATE *psf, int mode, sf_count_t offset)
+{      if (psf && mode)
+               return offset ;
+
+       return 0 ;
+} /* txw_seek */
+
+#endif
+/*
+** Do not edit or modify anything in this comment block.
+** The arch-tag line is a file identity tag for the GNU Arch 
+** revision control system.
+**
+** arch-tag: 4d0ba7af-b1c5-46b4-a900-7c6f59fd9a89
+*/
diff --git a/libs/libsndfile/src/ulaw.c b/libs/libsndfile/src/ulaw.c
new file mode 100644 (file)
index 0000000..e476c0a
--- /dev/null
@@ -0,0 +1,1047 @@
+/*
+** Copyright (C) 1999-2005 Erik de Castro Lopo <erikd@mega-nerd.com>
+**
+** This program is free software; you can redistribute it and/or modify
+** it under the terms of the GNU Lesser General Public License as published by
+** the Free Software Foundation; either version 2.1 of the License, or
+** (at your option) any later version.
+**
+** This program is distributed in the hope that it will be useful,
+** but WITHOUT ANY WARRANTY; without even the implied warranty of
+** MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+** GNU Lesser General Public License for more details.
+**
+** You should have received a copy of the GNU Lesser General Public License
+** along with this program; if not, write to the Free Software
+** Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA.
+*/
+
+#include       "sndfile.h"
+#include       "float_cast.h"
+#include       "common.h"
+
+static sf_count_t ulaw_read_ulaw2s (SF_PRIVATE *psf, short *ptr, sf_count_t len) ;
+static sf_count_t ulaw_read_ulaw2i (SF_PRIVATE *psf, int *ptr, sf_count_t len) ;
+static sf_count_t ulaw_read_ulaw2f (SF_PRIVATE *psf, float *ptr, sf_count_t len) ;
+static sf_count_t ulaw_read_ulaw2d (SF_PRIVATE *psf, double *ptr, sf_count_t len) ;
+
+static sf_count_t ulaw_write_s2ulaw (SF_PRIVATE *psf, const short *ptr, sf_count_t len) ;
+static sf_count_t ulaw_write_i2ulaw (SF_PRIVATE *psf, const int *ptr, sf_count_t len) ;
+static sf_count_t ulaw_write_f2ulaw (SF_PRIVATE *psf, const float *ptr, sf_count_t len) ;
+static sf_count_t ulaw_write_d2ulaw (SF_PRIVATE *psf, const double *ptr, sf_count_t len) ;
+
+int
+ulaw_init (SF_PRIVATE *psf)
+{
+       if (psf->mode == SFM_READ || psf->mode == SFM_RDWR)
+       {       psf->read_short         = ulaw_read_ulaw2s ;
+               psf->read_int           = ulaw_read_ulaw2i ;
+               psf->read_float         = ulaw_read_ulaw2f ;
+               psf->read_double        = ulaw_read_ulaw2d ;
+               } ;
+
+       if (psf->mode == SFM_WRITE || psf->mode == SFM_RDWR)
+       {       psf->write_short        = ulaw_write_s2ulaw ;
+               psf->write_int          = ulaw_write_i2ulaw ;
+               psf->write_float        = ulaw_write_f2ulaw ;
+               psf->write_double       = ulaw_write_d2ulaw ;
+               } ;
+
+       psf->bytewidth = 1 ;
+       psf->blockwidth = psf->sf.channels ;
+
+       if (psf->filelength > psf->dataoffset)
+               psf->datalength = (psf->dataend) ? psf->dataend - psf->dataoffset :
+                                                       psf->filelength - psf->dataoffset ;
+       else
+               psf->datalength = 0 ;
+
+       psf->sf.frames = psf->datalength / psf->blockwidth ;
+
+       return 0 ;
+} /* ulaw_init */
+
+/*==============================================================================
+*/
+
+static short ulaw_decode [256] =
+{      -32124, -31100, -30076, -29052, -28028, -27004, -25980, -24956,
+       -23932, -22908, -21884, -20860, -19836, -18812, -17788, -16764,
+       -15996, -15484, -14972, -14460, -13948, -13436, -12924, -12412,
+       -11900, -11388, -10876, -10364, -9852,  -9340,  -8828,  -8316,
+       -7932,  -7676,  -7420,  -7164,  -6908,  -6652,  -6396,  -6140,
+       -5884,  -5628,  -5372,  -5116,  -4860,  -4604,  -4348,  -4092,
+       -3900,  -3772,  -3644,  -3516,  -3388,  -3260,  -3132,  -3004,
+       -2876,  -2748,  -2620,  -2492,  -2364,  -2236,  -2108,  -1980,
+       -1884,  -1820,  -1756,  -1692,  -1628,  -1564,  -1500,  -1436,
+       -1372,  -1308,  -1244,  -1180,  -1116,  -1052,  -988,   -924,
+       -876,   -844,   -812,   -780,   -748,   -716,   -684,   -652,
+       -620,   -588,   -556,   -524,   -492,   -460,   -428,   -396,
+       -372,   -356,   -340,   -324,   -308,   -292,   -276,   -260,
+       -244,   -228,   -212,   -196,   -180,   -164,   -148,   -132,
+       -120,   -112,   -104,   -96,    -88,    -80,    -72,    -64,
+       -56,    -48,    -40,    -32,    -24,    -16,    -8,             0,
+
+       32124,  31100,  30076,  29052,  28028,  27004,  25980,  24956,
+       23932,  22908,  21884,  20860,  19836,  18812,  17788,  16764,
+       15996,  15484,  14972,  14460,  13948,  13436,  12924,  12412,
+       11900,  11388,  10876,  10364,  9852,   9340,   8828,   8316,
+       7932,   7676,   7420,   7164,   6908,   6652,   6396,   6140,
+       5884,   5628,   5372,   5116,   4860,   4604,   4348,   4092,
+       3900,   3772,   3644,   3516,   3388,   3260,   3132,   3004,
+       2876,   2748,   2620,   2492,   2364,   2236,   2108,   1980,
+       1884,   1820,   1756,   1692,   1628,   1564,   1500,   1436,
+       1372,   1308,   1244,   1180,   1116,   1052,   988,    924,
+       876,    844,    812,    780,    748,    716,    684,    652,
+       620,    588,    556,    524,    492,    460,    428,    396,
+       372,    356,    340,    324,    308,    292,    276,    260,
+       244,    228,    212,    196,    180,    164,    148,    132,
+       120,    112,    104,    96,             88,             80,             72,             64,
+       56,             48,             40,             32,             24,             16,             8,              0
+} ;
+
+static
+unsigned char ulaw_encode [8193] =
+{      0xff, 0xfe, 0xfe, 0xfd, 0xfd, 0xfc, 0xfc, 0xfb, 0xfb, 0xfa, 0xfa, 0xf9,
+       0xf9, 0xf8, 0xf8, 0xf7, 0xf7, 0xf6, 0xf6, 0xf5, 0xf5, 0xf4, 0xf4, 0xf3,
+       0xf3, 0xf2, 0xf2, 0xf1, 0xf1, 0xf0, 0xf0, 0xef, 0xef, 0xef, 0xef, 0xee,
+       0xee, 0xee, 0xee, 0xed, 0xed, 0xed, 0xed, 0xec, 0xec, 0xec, 0xec, 0xeb,
+       0xeb, 0xeb, 0xeb, 0xea, 0xea, 0xea, 0xea, 0xe9, 0xe9, 0xe9, 0xe9, 0xe8,
+       0xe8, 0xe8, 0xe8, 0xe7, 0xe7, 0xe7, 0xe7, 0xe6, 0xe6, 0xe6, 0xe6, 0xe5,
+       0xe5, 0xe5, 0xe5, 0xe4, 0xe4, 0xe4, 0xe4, 0xe3, 0xe3, 0xe3, 0xe3, 0xe2,
+       0xe2, 0xe2, 0xe2, 0xe1, 0xe1, 0xe1, 0xe1, 0xe0, 0xe0, 0xe0, 0xe0, 0xdf,
+       0xdf, 0xdf, 0xdf, 0xdf, 0xdf, 0xdf, 0xdf, 0xde, 0xde, 0xde, 0xde, 0xde,
+       0xde, 0xde, 0xde, 0xdd, 0xdd, 0xdd, 0xdd, 0xdd, 0xdd, 0xdd, 0xdd, 0xdc,
+       0xdc, 0xdc, 0xdc, 0xdc, 0xdc, 0xdc, 0xdc, 0xdb, 0xdb, 0xdb, 0xdb, 0xdb,
+       0xdb, 0xdb, 0xdb, 0xda, 0xda, 0xda, 0xda, 0xda, 0xda, 0xda, 0xda, 0xd9,
+       0xd9, 0xd9, 0xd9, 0xd9, 0xd9, 0xd9, 0xd9, 0xd8, 0xd8, 0xd8, 0xd8, 0xd8,
+       0xd8, 0xd8, 0xd8, 0xd7, 0xd7, 0xd7, 0xd7, 0xd7, 0xd7, 0xd7, 0xd7, 0xd6,
+       0xd6, 0xd6, 0xd6, 0xd6, 0xd6, 0xd6, 0xd6, 0xd5, 0xd5, 0xd5, 0xd5, 0xd5,
+       0xd5, 0xd5, 0xd5, 0xd4, 0xd4, 0xd4, 0xd4, 0xd4, 0xd4, 0xd4, 0xd4, 0xd3,
+       0xd3, 0xd3, 0xd3, 0xd3, 0xd3, 0xd3, 0xd3, 0xd2, 0xd2, 0xd2, 0xd2, 0xd2,
+       0xd2, 0xd2, 0xd2, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0xd0,
+       0xd0, 0xd0, 0xd0, 0xd0, 0xd0, 0xd0, 0xd0, 0xcf, 0xcf, 0xcf, 0xcf, 0xcf,
+       0xcf, 0xcf, 0xcf, 0xcf, 0xcf, 0xcf, 0xcf, 0xcf, 0xcf, 0xcf, 0xcf, 0xce,
+       0xce, 0xce, 0xce, 0xce, 0xce, 0xce, 0xce, 0xce, 0xce, 0xce, 0xce, 0xce,
+       0xce, 0xce, 0xce, 0xcd, 0xcd, 0xcd, 0xcd, 0xcd, 0xcd, 0xcd, 0xcd, 0xcd,
+       0xcd, 0xcd, 0xcd, 0xcd, 0xcd, 0xcd, 0xcd, 0xcc, 0xcc, 0xcc, 0xcc, 0xcc,
+       0xcc, 0xcc, 0xcc, 0xcc, 0xcc, 0xcc, 0xcc, 0xcc, 0xcc, 0xcc, 0xcc, 0xcb,
+       0xcb, 0xcb, 0xcb, 0xcb, 0xcb, 0xcb, 0xcb, 0xcb, 0xcb, 0xcb, 0xcb, 0xcb,
+       0xcb, 0xcb, 0xcb, 0xca, 0xca, 0xca, 0xca, 0xca, 0xca, 0xca, 0xca, 0xca,
+       0xca, 0xca, 0xca, 0xca, 0xca, 0xca, 0xca, 0xc9, 0xc9, 0xc9, 0xc9, 0xc9,
+       0xc9, 0xc9, 0xc9, 0xc9, 0xc9, 0xc9, 0xc9, 0xc9, 0xc9, 0xc9, 0xc9, 0xc8,
+       0xc8, 0xc8, 0xc8, 0xc8, 0xc8, 0xc8, 0xc8, 0xc8, 0xc8, 0xc8, 0xc8, 0xc8,
+       0xc8, 0xc8, 0xc8, 0xc7, 0xc7, 0xc7, 0xc7, 0xc7, 0xc7, 0xc7, 0xc7, 0xc7,
+       0xc7, 0xc7, 0xc7, 0xc7, 0xc7, 0xc7, 0xc7, 0xc6, 0xc6, 0xc6, 0xc6, 0xc6,
+       0xc6, 0xc6, 0xc6, 0xc6, 0xc6, 0xc6, 0xc6, 0xc6, 0xc6, 0xc6, 0xc6, 0xc5,
+       0xc5, 0xc5, 0xc5, 0xc5, 0xc5, 0xc5, 0xc5, 0xc5, 0xc5, 0xc5, 0xc5, 0xc5,
+       0xc5, 0xc5, 0xc5, 0xc4, 0xc4, 0xc4, 0xc4, 0xc4, 0xc4, 0xc4, 0xc4, 0xc4,
+       0xc4, 0xc4, 0xc4, 0xc4, 0xc4, 0xc4, 0xc4, 0xc3, 0xc3, 0xc3, 0xc3, 0xc3,
+       0xc3, 0xc3, 0xc3, 0xc3, 0xc3, 0xc3, 0xc3, 0xc3, 0xc3, 0xc3, 0xc3, 0xc2,
+       0xc2, 0xc2, 0xc2, 0xc2, 0xc2, 0xc2, 0xc2, 0xc2, 0xc2, 0xc2, 0xc2, 0xc2,
+       0xc2, 0xc2, 0xc2, 0xc1, 0xc1, 0xc1, 0xc1, 0xc1, 0xc1, 0xc1, 0xc1, 0xc1,
+       0xc1, 0xc1, 0xc1, 0xc1, 0xc1, 0xc1, 0xc1, 0xc0, 0xc0, 0xc0, 0xc0, 0xc0,
+       0xc0, 0xc0, 0xc0, 0xc0, 0xc0, 0xc0, 0xc0, 0xc0, 0xc0, 0xc0, 0xc0, 0xbf,
+       0xbf, 0xbf, 0xbf, 0xbf, 0xbf, 0xbf, 0xbf, 0xbf, 0xbf, 0xbf, 0xbf, 0xbf,
+       0xbf, 0xbf, 0xbf, 0xbf, 0xbf, 0xbf, 0xbf, 0xbf, 0xbf, 0xbf, 0xbf, 0xbf,
+       0xbf, 0xbf, 0xbf, 0xbf, 0xbf, 0xbf, 0xbf, 0xbe, 0xbe, 0xbe, 0xbe, 0xbe,
+       0xbe, 0xbe, 0xbe, 0xbe, 0xbe, 0xbe, 0xbe, 0xbe, 0xbe, 0xbe, 0xbe, 0xbe,
+       0xbe, 0xbe, 0xbe, 0xbe, 0xbe, 0xbe, 0xbe, 0xbe, 0xbe, 0xbe, 0xbe, 0xbe,
+       0xbe, 0xbe, 0xbe, 0xbd, 0xbd, 0xbd, 0xbd, 0xbd, 0xbd, 0xbd, 0xbd, 0xbd,
+       0xbd, 0xbd, 0xbd, 0xbd, 0xbd, 0xbd, 0xbd, 0xbd, 0xbd, 0xbd, 0xbd, 0xbd,
+       0xbd, 0xbd, 0xbd, 0xbd, 0xbd, 0xbd, 0xbd, 0xbd, 0xbd, 0xbd, 0xbd, 0xbc,
+       0xbc, 0xbc, 0xbc, 0xbc, 0xbc, 0xbc, 0xbc, 0xbc, 0xbc, 0xbc, 0xbc, 0xbc,
+       0xbc, 0xbc, 0xbc, 0xbc, 0xbc, 0xbc, 0xbc, 0xbc, 0xbc, 0xbc, 0xbc, 0xbc,
+       0xbc, 0xbc, 0xbc, 0xbc, 0xbc, 0xbc, 0xbc, 0xbb, 0xbb, 0xbb, 0xbb, 0xbb,
+       0xbb, 0xbb, 0xbb, 0xbb, 0xbb, 0xbb, 0xbb, 0xbb, 0xbb, 0xbb, 0xbb, 0xbb,
+       0xbb, 0xbb, 0xbb, 0xbb, 0xbb, 0xbb, 0xbb, 0xbb, 0xbb, 0xbb, 0xbb, 0xbb,
+       0xbb, 0xbb, 0xbb, 0xba, 0xba, 0xba, 0xba, 0xba, 0xba, 0xba, 0xba, 0xba,
+       0xba, 0xba, 0xba, 0xba, 0xba, 0xba, 0xba, 0xba, 0xba, 0xba, 0xba, 0xba,
+       0xba, 0xba, 0xba, 0xba, 0xba, 0xba, 0xba, 0xba, 0xba, 0xba, 0xba, 0xb9,
+       0xb9, 0xb9, 0xb9, 0xb9, 0xb9, 0xb9, 0xb9, 0xb9, 0xb9, 0xb9, 0xb9, 0xb9,
+       0xb9, 0xb9, 0xb9, 0xb9, 0xb9, 0xb9, 0xb9, 0xb9, 0xb9, 0xb9, 0xb9, 0xb9,
+       0xb9, 0xb9, 0xb9, 0xb9, 0xb9, 0xb9, 0xb9, 0xb8, 0xb8, 0xb8, 0xb8, 0xb8,
+       0xb8, 0xb8, 0xb8, 0xb8, 0xb8, 0xb8, 0xb8, 0xb8, 0xb8, 0xb8, 0xb8, 0xb8,
+       0xb8, 0xb8, 0xb8, 0xb8, 0xb8, 0xb8, 0xb8, 0xb8, 0xb8, 0xb8, 0xb8, 0xb8,
+       0xb8, 0xb8, 0xb8, 0xb7, 0xb7, 0xb7, 0xb7, 0xb7, 0xb7, 0xb7, 0xb7, 0xb7,
+       0xb7, 0xb7, 0xb7, 0xb7, 0xb7, 0xb7, 0xb7, 0xb7, 0xb7, 0xb7, 0xb7, 0xb7,
+       0xb7, 0xb7, 0xb7, 0xb7, 0xb7, 0xb7, 0xb7, 0xb7, 0xb7, 0xb7, 0xb7, 0xb6,
+       0xb6, 0xb6, 0xb6, 0xb6, 0xb6, 0xb6, 0xb6, 0xb6, 0xb6, 0xb6, 0xb6, 0xb6,
+       0xb6, 0xb6, 0xb6, 0xb6, 0xb6, 0xb6, 0xb6, 0xb6, 0xb6, 0xb6, 0xb6, 0xb6,
+       0xb6, 0xb6, 0xb6, 0xb6, 0xb6, 0xb6, 0xb6, 0xb5, 0xb5, 0xb5, 0xb5, 0xb5,
+       0xb5, 0xb5, 0xb5, 0xb5, 0xb5, 0xb5, 0xb5, 0xb5, 0xb5, 0xb5, 0xb5, 0xb5,
+       0xb5, 0xb5, 0xb5, 0xb5, 0xb5, 0xb5, 0xb5, 0xb5, 0xb5, 0xb5, 0xb5, 0xb5,
+       0xb5, 0xb5, 0xb5, 0xb4, 0xb4, 0xb4, 0xb4, 0xb4, 0xb4, 0xb4, 0xb4, 0xb4,
+       0xb4, 0xb4, 0xb4, 0xb4, 0xb4, 0xb4, 0xb4, 0xb4, 0xb4, 0xb4, 0xb4, 0xb4,
+       0xb4, 0xb4, 0xb4, 0xb4, 0xb4, 0xb4, 0xb4, 0xb4, 0xb4, 0xb4, 0xb4, 0xb3,
+       0xb3, 0xb3, 0xb3, 0xb3, 0xb3, 0xb3, 0xb3, 0xb3, 0xb3, 0xb3, 0xb3, 0xb3,
+       0xb3, 0xb3, 0xb3, 0xb3, 0xb3, 0xb3, 0xb3, 0xb3, 0xb3, 0xb3, 0xb3, 0xb3,
+       0xb3, 0xb3, 0xb3, 0xb3, 0xb3, 0xb3, 0xb3, 0xb2, 0xb2, 0xb2, 0xb2, 0xb2,
+       0xb2, 0xb2, 0xb2, 0xb2, 0xb2, 0xb2, 0xb2, 0xb2, 0xb2, 0xb2, 0xb2, 0xb2,
+       0xb2, 0xb2, 0xb2, 0xb2, 0xb2, 0xb2, 0xb2, 0xb2, 0xb2, 0xb2, 0xb2, 0xb2,
+       0xb2, 0xb2, 0xb2, 0xb1, 0xb1, 0xb1, 0xb1, 0xb1, 0xb1, 0xb1, 0xb1, 0xb1,
+       0xb1, 0xb1, 0xb1, 0xb1, 0xb1, 0xb1, 0xb1, 0xb1, 0xb1, 0xb1, 0xb1, 0xb1,
+       0xb1, 0xb1, 0xb1, 0xb1, 0xb1, 0xb1, 0xb1, 0xb1, 0xb1, 0xb1, 0xb1, 0xb0,
+       0xb0, 0xb0, 0xb0, 0xb0, 0xb0, 0xb0, 0xb0, 0xb0, 0xb0, 0xb0, 0xb0, 0xb0,
+       0xb0, 0xb0, 0xb0, 0xb0, 0xb0, 0xb0, 0xb0, 0xb0, 0xb0, 0xb0, 0xb0, 0xb0,
+       0xb0, 0xb0, 0xb0, 0xb0, 0xb0, 0xb0, 0xb0, 0xaf, 0xaf, 0xaf, 0xaf, 0xaf,
+       0xaf, 0xaf, 0xaf, 0xaf, 0xaf, 0xaf, 0xaf, 0xaf, 0xaf, 0xaf, 0xaf, 0xaf,
+       0xaf, 0xaf, 0xaf, 0xaf, 0xaf, 0xaf, 0xaf, 0xaf, 0xaf, 0xaf, 0xaf, 0xaf,
+       0xaf, 0xaf, 0xaf, 0xaf, 0xaf, 0xaf, 0xaf, 0xaf, 0xaf, 0xaf, 0xaf, 0xaf,
+       0xaf, 0xaf, 0xaf, 0xaf, 0xaf, 0xaf, 0xaf, 0xaf, 0xaf, 0xaf, 0xaf, 0xaf,
+       0xaf, 0xaf, 0xaf, 0xaf, 0xaf, 0xaf, 0xaf, 0xaf, 0xaf, 0xaf, 0xaf, 0xae,
+       0xae, 0xae, 0xae, 0xae, 0xae, 0xae, 0xae, 0xae, 0xae, 0xae, 0xae, 0xae,
+       0xae, 0xae, 0xae, 0xae, 0xae, 0xae, 0xae, 0xae, 0xae, 0xae, 0xae, 0xae,
+       0xae, 0xae, 0xae, 0xae, 0xae, 0xae, 0xae, 0xae, 0xae, 0xae, 0xae, 0xae,
+       0xae, 0xae, 0xae, 0xae, 0xae, 0xae, 0xae, 0xae, 0xae, 0xae, 0xae, 0xae,
+       0xae, 0xae, 0xae, 0xae, 0xae, 0xae, 0xae, 0xae, 0xae, 0xae, 0xae, 0xae,
+       0xae, 0xae, 0xae, 0xad, 0xad, 0xad, 0xad, 0xad, 0xad, 0xad, 0xad, 0xad,
+       0xad, 0xad, 0xad, 0xad, 0xad, 0xad, 0xad, 0xad, 0xad, 0xad, 0xad, 0xad,
+       0xad, 0xad, 0xad, 0xad, 0xad, 0xad, 0xad, 0xad, 0xad, 0xad, 0xad, 0xad,
+       0xad, 0xad, 0xad, 0xad, 0xad, 0xad, 0xad, 0xad, 0xad, 0xad, 0xad, 0xad,
+       0xad, 0xad, 0xad, 0xad, 0xad, 0xad, 0xad, 0xad, 0xad, 0xad, 0xad, 0xad,
+       0xad, 0xad, 0xad, 0xad, 0xad, 0xad, 0xad, 0xac, 0xac, 0xac, 0xac, 0xac,
+       0xac, 0xac, 0xac, 0xac, 0xac, 0xac, 0xac, 0xac, 0xac, 0xac, 0xac, 0xac,
+       0xac, 0xac, 0xac, 0xac, 0xac, 0xac, 0xac, 0xac, 0xac, 0xac, 0xac, 0xac,
+       0xac, 0xac, 0xac, 0xac, 0xac, 0xac, 0xac, 0xac, 0xac, 0xac, 0xac, 0xac,
+       0xac, 0xac, 0xac, 0xac, 0xac, 0xac, 0xac, 0xac, 0xac, 0xac, 0xac, 0xac,
+       0xac, 0xac, 0xac, 0xac, 0xac, 0xac, 0xac, 0xac, 0xac, 0xac, 0xac, 0xab,
+       0xab, 0xab, 0xab, 0xab, 0xab, 0xab, 0xab, 0xab, 0xab, 0xab, 0xab, 0xab,
+       0xab, 0xab, 0xab, 0xab, 0xab, 0xab, 0xab, 0xab, 0xab, 0xab, 0xab, 0xab,
+       0xab, 0xab, 0xab, 0xab, 0xab, 0xab, 0xab, 0xab, 0xab, 0xab, 0xab, 0xab,
+       0xab, 0xab, 0xab, 0xab, 0xab, 0xab, 0xab, 0xab, 0xab, 0xab, 0xab, 0xab,
+       0xab, 0xab, 0xab, 0xab, 0xab, 0xab, 0xab, 0xab, 0xab, 0xab, 0xab, 0xab,
+       0xab, 0xab, 0xab, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa,
+       0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa,
+       0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa,
+       0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa,
+       0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa,
+       0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xa9, 0xa9, 0xa9, 0xa9, 0xa9,
+       0xa9, 0xa9, 0xa9, 0xa9, 0xa9, 0xa9, 0xa9, 0xa9, 0xa9, 0xa9, 0xa9, 0xa9,
+       0xa9, 0xa9, 0xa9, 0xa9, 0xa9, 0xa9, 0xa9, 0xa9, 0xa9, 0xa9, 0xa9, 0xa9,
+       0xa9, 0xa9, 0xa9, 0xa9, 0xa9, 0xa9, 0xa9, 0xa9, 0xa9, 0xa9, 0xa9, 0xa9,
+       0xa9, 0xa9, 0xa9, 0xa9, 0xa9, 0xa9, 0xa9, 0xa9, 0xa9, 0xa9, 0xa9, 0xa9,
+       0xa9, 0xa9, 0xa9, 0xa9, 0xa9, 0xa9, 0xa9, 0xa9, 0xa9, 0xa9, 0xa9, 0xa8,
+       0xa8, 0xa8, 0xa8, 0xa8, 0xa8, 0xa8, 0xa8, 0xa8, 0xa8, 0xa8, 0xa8, 0xa8,
+       0xa8, 0xa8, 0xa8, 0xa8, 0xa8, 0xa8, 0xa8, 0xa8, 0xa8, 0xa8, 0xa8, 0xa8,
+       0xa8, 0xa8, 0xa8, 0xa8, 0xa8, 0xa8, 0xa8, 0xa8, 0xa8, 0xa8, 0xa8, 0xa8,
+       0xa8, 0xa8, 0xa8, 0xa8, 0xa8, 0xa8, 0xa8, 0xa8, 0xa8, 0xa8, 0xa8, 0xa8,
+       0xa8, 0xa8, 0xa8, 0xa8, 0xa8, 0xa8, 0xa8, 0xa8, 0xa8, 0xa8, 0xa8, 0xa8,
+       0xa8, 0xa8, 0xa8, 0xa7, 0xa7, 0xa7, 0xa7, 0xa7, 0xa7, 0xa7, 0xa7, 0xa7,
+       0xa7, 0xa7, 0xa7, 0xa7, 0xa7, 0xa7, 0xa7, 0xa7, 0xa7, 0xa7, 0xa7, 0xa7,
+       0xa7, 0xa7, 0xa7, 0xa7, 0xa7, 0xa7, 0xa7, 0xa7, 0xa7, 0xa7, 0xa7, 0xa7,
+       0xa7, 0xa7, 0xa7, 0xa7, 0xa7, 0xa7, 0xa7, 0xa7, 0xa7, 0xa7, 0xa7, 0xa7,
+       0xa7, 0xa7, 0xa7, 0xa7, 0xa7, 0xa7, 0xa7, 0xa7, 0xa7, 0xa7, 0xa7, 0xa7,
+       0xa7, 0xa7, 0xa7, 0xa7, 0xa7, 0xa7, 0xa7, 0xa6, 0xa6, 0xa6, 0xa6, 0xa6,
+       0xa6, 0xa6, 0xa6, 0xa6, 0xa6, 0xa6, 0xa6, 0xa6, 0xa6, 0xa6, 0xa6, 0xa6,
+       0xa6, 0xa6, 0xa6, 0xa6, 0xa6, 0xa6, 0xa6, 0xa6, 0xa6, 0xa6, 0xa6, 0xa6,
+       0xa6, 0xa6, 0xa6, 0xa6, 0xa6, 0xa6, 0xa6, 0xa6, 0xa6, 0xa6, 0xa6, 0xa6,
+       0xa6, 0xa6, 0xa6, 0xa6, 0xa6, 0xa6, 0xa6, 0xa6, 0xa6, 0xa6, 0xa6, 0xa6,
+       0xa6, 0xa6, 0xa6, 0xa6, 0xa6, 0xa6, 0xa6, 0xa6, 0xa6, 0xa6, 0xa6, 0xa5,
+       0xa5, 0xa5, 0xa5, 0xa5, 0xa5, 0xa5, 0xa5, 0xa5, 0xa5, 0xa5, 0xa5, 0xa5,
+       0xa5, 0xa5, 0xa5, 0xa5, 0xa5, 0xa5, 0xa5, 0xa5, 0xa5, 0xa5, 0xa5, 0xa5,
+       0xa5, 0xa5, 0xa5, 0xa5, 0xa5, 0xa5, 0xa5, 0xa5, 0xa5, 0xa5, 0xa5, 0xa5,
+       0xa5, 0xa5, 0xa5, 0xa5, 0xa5, 0xa5, 0xa5, 0xa5, 0xa5, 0xa5, 0xa5, 0xa5,
+       0xa5, 0xa5, 0xa5, 0xa5, 0xa5, 0xa5, 0xa5, 0xa5, 0xa5, 0xa5, 0xa5, 0xa5,
+       0xa5, 0xa5, 0xa5, 0xa4, 0xa4, 0xa4, 0xa4, 0xa4, 0xa4, 0xa4, 0xa4, 0xa4,
+       0xa4, 0xa4, 0xa4, 0xa4, 0xa4, 0xa4, 0xa4, 0xa4, 0xa4, 0xa4, 0xa4, 0xa4,
+       0xa4, 0xa4, 0xa4, 0xa4, 0xa4, 0xa4, 0xa4, 0xa4, 0xa4, 0xa4, 0xa4, 0xa4,
+       0xa4, 0xa4, 0xa4, 0xa4, 0xa4, 0xa4, 0xa4, 0xa4, 0xa4, 0xa4, 0xa4, 0xa4,
+       0xa4, 0xa4, 0xa4, 0xa4, 0xa4, 0xa4, 0xa4, 0xa4, 0xa4, 0xa4, 0xa4, 0xa4,
+       0xa4, 0xa4, 0xa4, 0xa4, 0xa4, 0xa4, 0xa4, 0xa3, 0xa3, 0xa3, 0xa3, 0xa3,
+       0xa3, 0xa3, 0xa3, 0xa3, 0xa3, 0xa3, 0xa3, 0xa3, 0xa3, 0xa3, 0xa3, 0xa3,
+       0xa3, 0xa3, 0xa3, 0xa3, 0xa3, 0xa3, 0xa3, 0xa3, 0xa3, 0xa3, 0xa3, 0xa3,
+       0xa3, 0xa3, 0xa3, 0xa3, 0xa3, 0xa3, 0xa3, 0xa3, 0xa3, 0xa3, 0xa3, 0xa3,
+       0xa3, 0xa3, 0xa3, 0xa3, 0xa3, 0xa3, 0xa3, 0xa3, 0xa3, 0xa3, 0xa3, 0xa3,
+       0xa3, 0xa3, 0xa3, 0xa3, 0xa3, 0xa3, 0xa3, 0xa3, 0xa3, 0xa3, 0xa3, 0xa2,
+       0xa2, 0xa2, 0xa2, 0xa2, 0xa2, 0xa2, 0xa2, 0xa2, 0xa2, 0xa2, 0xa2, 0xa2,
+       0xa2, 0xa2, 0xa2, 0xa2, 0xa2, 0xa2, 0xa2, 0xa2, 0xa2, 0xa2, 0xa2, 0xa2,
+       0xa2, 0xa2, 0xa2, 0xa2, 0xa2, 0xa2, 0xa2, 0xa2, 0xa2, 0xa2, 0xa2, 0xa2,
+       0xa2, 0xa2, 0xa2, 0xa2, 0xa2, 0xa2, 0xa2, 0xa2, 0xa2, 0xa2, 0xa2, 0xa2,
+       0xa2, 0xa2, 0xa2, 0xa2, 0xa2, 0xa2, 0xa2, 0xa2, 0xa2, 0xa2, 0xa2, 0xa2,
+       0xa2, 0xa2, 0xa2, 0xa1, 0xa1, 0xa1, 0xa1, 0xa1, 0xa1, 0xa1, 0xa1, 0xa1,
+       0xa1, 0xa1, 0xa1, 0xa1, 0xa1, 0xa1, 0xa1, 0xa1, 0xa1, 0xa1, 0xa1, 0xa1,
+       0xa1, 0xa1, 0xa1, 0xa1, 0xa1, 0xa1, 0xa1, 0xa1, 0xa1, 0xa1, 0xa1, 0xa1,
+       0xa1, 0xa1, 0xa1, 0xa1, 0xa1, 0xa1, 0xa1, 0xa1, 0xa1, 0xa1, 0xa1, 0xa1,
+       0xa1, 0xa1, 0xa1, 0xa1, 0xa1, 0xa1, 0xa1, 0xa1, 0xa1, 0xa1, 0xa1, 0xa1,
+       0xa1, 0xa1, 0xa1, 0xa1, 0xa1, 0xa1, 0xa1, 0xa0, 0xa0, 0xa0, 0xa0, 0xa0,
+       0xa0, 0xa0, 0xa0, 0xa0, 0xa0, 0xa0, 0xa0, 0xa0, 0xa0, 0xa0, 0xa0, 0xa0,
+       0xa0, 0xa0, 0xa0, 0xa0, 0xa0, 0xa0, 0xa0, 0xa0, 0xa0, 0xa0, 0xa0, 0xa0,
+       0xa0, 0xa0, 0xa0, 0xa0, 0xa0, 0xa0, 0xa0, 0xa0, 0xa0, 0xa0, 0xa0, 0xa0,
+       0xa0, 0xa0, 0xa0, 0xa0, 0xa0, 0xa0, 0xa0, 0xa0, 0xa0, 0xa0, 0xa0, 0xa0,
+       0xa0, 0xa0, 0xa0, 0xa0, 0xa0, 0xa0, 0xa0, 0xa0, 0xa0, 0xa0, 0xa0, 0x9f,
+       0x9f, 0x9f, 0x9f, 0x9f, 0x9f, 0x9f, 0x9f, 0x9f, 0x9f, 0x9f, 0x9f, 0x9f,
+       0x9f, 0x9f, 0x9f, 0x9f, 0x9f, 0x9f, 0x9f, 0x9f, 0x9f, 0x9f, 0x9f, 0x9f,
+       0x9f, 0x9f, 0x9f, 0x9f, 0x9f, 0x9f, 0x9f, 0x9f, 0x9f, 0x9f, 0x9f, 0x9f,
+       0x9f, 0x9f, 0x9f, 0x9f, 0x9f, 0x9f, 0x9f, 0x9f, 0x9f, 0x9f, 0x9f, 0x9f,
+       0x9f, 0x9f, 0x9f, 0x9f, 0x9f, 0x9f, 0x9f, 0x9f, 0x9f, 0x9f, 0x9f, 0x9f,
+       0x9f, 0x9f, 0x9f, 0x9f, 0x9f, 0x9f, 0x9f, 0x9f, 0x9f, 0x9f, 0x9f, 0x9f,
+       0x9f, 0x9f, 0x9f, 0x9f, 0x9f, 0x9f, 0x9f, 0x9f, 0x9f, 0x9f, 0x9f, 0x9f,
+       0x9f, 0x9f, 0x9f, 0x9f, 0x9f, 0x9f, 0x9f, 0x9f, 0x9f, 0x9f, 0x9f, 0x9f,
+       0x9f, 0x9f, 0x9f, 0x9f, 0x9f, 0x9f, 0x9f, 0x9f, 0x9f, 0x9f, 0x9f, 0x9f,
+       0x9f, 0x9f, 0x9f, 0x9f, 0x9f, 0x9f, 0x9f, 0x9f, 0x9f, 0x9f, 0x9f, 0x9f,
+       0x9f, 0x9f, 0x9f, 0x9f, 0x9f, 0x9f, 0x9f, 0x9e, 0x9e, 0x9e, 0x9e, 0x9e,
+       0x9e, 0x9e, 0x9e, 0x9e, 0x9e, 0x9e, 0x9e, 0x9e, 0x9e, 0x9e, 0x9e, 0x9e,
+       0x9e, 0x9e, 0x9e, 0x9e, 0x9e, 0x9e, 0x9e, 0x9e, 0x9e, 0x9e, 0x9e, 0x9e,
+       0x9e, 0x9e, 0x9e, 0x9e, 0x9e, 0x9e, 0x9e, 0x9e, 0x9e, 0x9e, 0x9e, 0x9e,
+       0x9e, 0x9e, 0x9e, 0x9e, 0x9e, 0x9e, 0x9e, 0x9e, 0x9e, 0x9e, 0x9e, 0x9e,
+       0x9e, 0x9e, 0x9e, 0x9e, 0x9e, 0x9e, 0x9e, 0x9e, 0x9e, 0x9e, 0x9e, 0x9e,
+       0x9e, 0x9e, 0x9e, 0x9e, 0x9e, 0x9e, 0x9e, 0x9e, 0x9e, 0x9e, 0x9e, 0x9e,
+       0x9e, 0x9e, 0x9e, 0x9e, 0x9e, 0x9e, 0x9e, 0x9e, 0x9e, 0x9e, 0x9e, 0x9e,
+       0x9e, 0x9e, 0x9e, 0x9e, 0x9e, 0x9e, 0x9e, 0x9e, 0x9e, 0x9e, 0x9e, 0x9e,
+       0x9e, 0x9e, 0x9e, 0x9e, 0x9e, 0x9e, 0x9e, 0x9e, 0x9e, 0x9e, 0x9e, 0x9e,
+       0x9e, 0x9e, 0x9e, 0x9e, 0x9e, 0x9e, 0x9e, 0x9e, 0x9e, 0x9e, 0x9e, 0x9e,
+       0x9e, 0x9e, 0x9e, 0x9d, 0x9d, 0x9d, 0x9d, 0x9d, 0x9d, 0x9d, 0x9d, 0x9d,
+       0x9d, 0x9d, 0x9d, 0x9d, 0x9d, 0x9d, 0x9d, 0x9d, 0x9d, 0x9d, 0x9d, 0x9d,
+       0x9d, 0x9d, 0x9d, 0x9d, 0x9d, 0x9d, 0x9d, 0x9d, 0x9d, 0x9d, 0x9d, 0x9d,
+       0x9d, 0x9d, 0x9d, 0x9d, 0x9d, 0x9d, 0x9d, 0x9d, 0x9d, 0x9d, 0x9d, 0x9d,
+       0x9d, 0x9d, 0x9d, 0x9d, 0x9d, 0x9d, 0x9d, 0x9d, 0x9d, 0x9d, 0x9d, 0x9d,
+       0x9d, 0x9d, 0x9d, 0x9d, 0x9d, 0x9d, 0x9d, 0x9d, 0x9d, 0x9d, 0x9d, 0x9d,
+       0x9d, 0x9d, 0x9d, 0x9d, 0x9d, 0x9d, 0x9d, 0x9d, 0x9d, 0x9d, 0x9d, 0x9d,
+       0x9d, 0x9d, 0x9d, 0x9d, 0x9d, 0x9d, 0x9d, 0x9d, 0x9d, 0x9d, 0x9d, 0x9d,
+       0x9d, 0x9d, 0x9d, 0x9d, 0x9d, 0x9d, 0x9d, 0x9d, 0x9d, 0x9d, 0x9d, 0x9d,
+       0x9d, 0x9d, 0x9d, 0x9d, 0x9d, 0x9d, 0x9d, 0x9d, 0x9d, 0x9d, 0x9d, 0x9d,
+       0x9d, 0x9d, 0x9d, 0x9d, 0x9d, 0x9d, 0x9d, 0x9d, 0x9d, 0x9d, 0x9d, 0x9c,
+       0x9c, 0x9c, 0x9c, 0x9c, 0x9c, 0x9c, 0x9c, 0x9c, 0x9c, 0x9c, 0x9c, 0x9c,
+       0x9c, 0x9c, 0x9c, 0x9c, 0x9c, 0x9c, 0x9c, 0x9c, 0x9c, 0x9c, 0x9c, 0x9c,
+       0x9c, 0x9c, 0x9c, 0x9c, 0x9c, 0x9c, 0x9c, 0x9c, 0x9c, 0x9c, 0x9c, 0x9c,
+       0x9c, 0x9c, 0x9c, 0x9c, 0x9c, 0x9c, 0x9c, 0x9c, 0x9c, 0x9c, 0x9c, 0x9c,
+       0x9c, 0x9c, 0x9c, 0x9c, 0x9c, 0x9c, 0x9c, 0x9c, 0x9c, 0x9c, 0x9c, 0x9c,
+       0x9c, 0x9c, 0x9c, 0x9c, 0x9c, 0x9c, 0x9c, 0x9c, 0x9c, 0x9c, 0x9c, 0x9c,
+       0x9c, 0x9c, 0x9c, 0x9c, 0x9c, 0x9c, 0x9c, 0x9c, 0x9c, 0x9c, 0x9c, 0x9c,
+       0x9c, 0x9c, 0x9c, 0x9c, 0x9c, 0x9c, 0x9c, 0x9c, 0x9c, 0x9c, 0x9c, 0x9c,
+       0x9c, 0x9c, 0x9c, 0x9c, 0x9c, 0x9c, 0x9c, 0x9c, 0x9c, 0x9c, 0x9c, 0x9c,
+       0x9c, 0x9c, 0x9c, 0x9c, 0x9c, 0x9c, 0x9c, 0x9c, 0x9c, 0x9c, 0x9c, 0x9c,
+       0x9c, 0x9c, 0x9c, 0x9c, 0x9c, 0x9c, 0x9c, 0x9b, 0x9b, 0x9b, 0x9b, 0x9b,
+       0x9b, 0x9b, 0x9b, 0x9b, 0x9b, 0x9b, 0x9b, 0x9b, 0x9b, 0x9b, 0x9b, 0x9b,
+       0x9b, 0x9b, 0x9b, 0x9b, 0x9b, 0x9b, 0x9b, 0x9b, 0x9b, 0x9b, 0x9b, 0x9b,
+       0x9b, 0x9b, 0x9b, 0x9b, 0x9b, 0x9b, 0x9b, 0x9b, 0x9b, 0x9b, 0x9b, 0x9b,
+       0x9b, 0x9b, 0x9b, 0x9b, 0x9b, 0x9b, 0x9b, 0x9b, 0x9b, 0x9b, 0x9b, 0x9b,
+       0x9b, 0x9b, 0x9b, 0x9b, 0x9b, 0x9b, 0x9b, 0x9b, 0x9b, 0x9b, 0x9b, 0x9b,
+       0x9b, 0x9b, 0x9b, 0x9b, 0x9b, 0x9b, 0x9b, 0x9b, 0x9b, 0x9b, 0x9b, 0x9b,
+       0x9b, 0x9b, 0x9b, 0x9b, 0x9b, 0x9b, 0x9b, 0x9b, 0x9b, 0x9b, 0x9b, 0x9b,
+       0x9b, 0x9b, 0x9b, 0x9b, 0x9b, 0x9b, 0x9b, 0x9b, 0x9b, 0x9b, 0x9b, 0x9b,
+       0x9b, 0x9b, 0x9b, 0x9b, 0x9b, 0x9b, 0x9b, 0x9b, 0x9b, 0x9b, 0x9b, 0x9b,
+       0x9b, 0x9b, 0x9b, 0x9b, 0x9b, 0x9b, 0x9b, 0x9b, 0x9b, 0x9b, 0x9b, 0x9b,
+       0x9b, 0x9b, 0x9b, 0x9a, 0x9a, 0x9a, 0x9a, 0x9a, 0x9a, 0x9a, 0x9a, 0x9a,
+       0x9a, 0x9a, 0x9a, 0x9a, 0x9a, 0x9a, 0x9a, 0x9a, 0x9a, 0x9a, 0x9a, 0x9a,
+       0x9a, 0x9a, 0x9a, 0x9a, 0x9a, 0x9a, 0x9a, 0x9a, 0x9a, 0x9a, 0x9a, 0x9a,
+       0x9a, 0x9a, 0x9a, 0x9a, 0x9a, 0x9a, 0x9a, 0x9a, 0x9a, 0x9a, 0x9a, 0x9a,
+       0x9a, 0x9a, 0x9a, 0x9a, 0x9a, 0x9a, 0x9a, 0x9a, 0x9a, 0x9a, 0x9a, 0x9a,
+       0x9a, 0x9a, 0x9a, 0x9a, 0x9a, 0x9a, 0x9a, 0x9a, 0x9a, 0x9a, 0x9a, 0x9a,
+       0x9a, 0x9a, 0x9a, 0x9a, 0x9a, 0x9a, 0x9a, 0x9a, 0x9a, 0x9a, 0x9a, 0x9a,
+       0x9a, 0x9a, 0x9a, 0x9a, 0x9a, 0x9a, 0x9a, 0x9a, 0x9a, 0x9a, 0x9a, 0x9a,
+       0x9a, 0x9a, 0x9a, 0x9a, 0x9a, 0x9a, 0x9a, 0x9a, 0x9a, 0x9a, 0x9a, 0x9a,
+       0x9a, 0x9a, 0x9a, 0x9a, 0x9a, 0x9a, 0x9a, 0x9a, 0x9a, 0x9a, 0x9a, 0x9a,
+       0x9a, 0x9a, 0x9a, 0x9a, 0x9a, 0x9a, 0x9a, 0x9a, 0x9a, 0x9a, 0x9a, 0x99,
+       0x99, 0x99, 0x99, 0x99, 0x99, 0x99, 0x99, 0x99, 0x99, 0x99, 0x99, 0x99,
+       0x99, 0x99, 0x99, 0x99, 0x99, 0x99, 0x99, 0x99, 0x99, 0x99, 0x99, 0x99,
+       0x99, 0x99, 0x99, 0x99, 0x99, 0x99, 0x99, 0x99, 0x99, 0x99, 0x99, 0x99,
+       0x99, 0x99, 0x99, 0x99, 0x99, 0x99, 0x99, 0x99, 0x99, 0x99, 0x99, 0x99,
+       0x99, 0x99, 0x99, 0x99, 0x99, 0x99, 0x99, 0x99, 0x99, 0x99, 0x99, 0x99,
+       0x99, 0x99, 0x99, 0x99, 0x99, 0x99, 0x99, 0x99, 0x99, 0x99, 0x99, 0x99,
+       0x99, 0x99, 0x99, 0x99, 0x99, 0x99, 0x99, 0x99, 0x99, 0x99, 0x99, 0x99,
+       0x99, 0x99, 0x99, 0x99, 0x99, 0x99, 0x99, 0x99, 0x99, 0x99, 0x99, 0x99,
+       0x99, 0x99, 0x99, 0x99, 0x99, 0x99, 0x99, 0x99, 0x99, 0x99, 0x99, 0x99,
+       0x99, 0x99, 0x99, 0x99, 0x99, 0x99, 0x99, 0x99, 0x99, 0x99, 0x99, 0x99,
+       0x99, 0x99, 0x99, 0x99, 0x99, 0x99, 0x99, 0x98, 0x98, 0x98, 0x98, 0x98,
+       0x98, 0x98, 0x98, 0x98, 0x98, 0x98, 0x98, 0x98, 0x98, 0x98, 0x98, 0x98,
+       0x98, 0x98, 0x98, 0x98, 0x98, 0x98, 0x98, 0x98, 0x98, 0x98, 0x98, 0x98,
+       0x98, 0x98, 0x98, 0x98, 0x98, 0x98, 0x98, 0x98, 0x98, 0x98, 0x98, 0x98,
+       0x98, 0x98, 0x98, 0x98, 0x98, 0x98, 0x98, 0x98, 0x98, 0x98, 0x98, 0x98,
+       0x98, 0x98, 0x98, 0x98, 0x98, 0x98, 0x98, 0x98, 0x98, 0x98, 0x98, 0x98,
+       0x98, 0x98, 0x98, 0x98, 0x98, 0x98, 0x98, 0x98, 0x98, 0x98, 0x98, 0x98,
+       0x98, 0x98, 0x98, 0x98, 0x98, 0x98, 0x98, 0x98, 0x98, 0x98, 0x98, 0x98,
+       0x98, 0x98, 0x98, 0x98, 0x98, 0x98, 0x98, 0x98, 0x98, 0x98, 0x98, 0x98,
+       0x98, 0x98, 0x98, 0x98, 0x98, 0x98, 0x98, 0x98, 0x98, 0x98, 0x98, 0x98,
+       0x98, 0x98, 0x98, 0x98, 0x98, 0x98, 0x98, 0x98, 0x98, 0x98, 0x98, 0x98,
+       0x98, 0x98, 0x98, 0x97, 0x97, 0x97, 0x97, 0x97, 0x97, 0x97, 0x97, 0x97,
+       0x97, 0x97, 0x97, 0x97, 0x97, 0x97, 0x97, 0x97, 0x97, 0x97, 0x97, 0x97,
+       0x97, 0x97, 0x97, 0x97, 0x97, 0x97, 0x97, 0x97, 0x97, 0x97, 0x97, 0x97,
+       0x97, 0x97, 0x97, 0x97, 0x97, 0x97, 0x97, 0x97, 0x97, 0x97, 0x97, 0x97,
+       0x97, 0x97, 0x97, 0x97, 0x97, 0x97, 0x97, 0x97, 0x97, 0x97, 0x97, 0x97,
+       0x97, 0x97, 0x97, 0x97, 0x97, 0x97, 0x97, 0x97, 0x97, 0x97, 0x97, 0x97,
+       0x97, 0x97, 0x97, 0x97, 0x97, 0x97, 0x97, 0x97, 0x97, 0x97, 0x97, 0x97,
+       0x97, 0x97, 0x97, 0x97, 0x97, 0x97, 0x97, 0x97, 0x97, 0x97, 0x97, 0x97,
+       0x97, 0x97, 0x97, 0x97, 0x97, 0x97, 0x97, 0x97, 0x97, 0x97, 0x97, 0x97,
+       0x97, 0x97, 0x97, 0x97, 0x97, 0x97, 0x97, 0x97, 0x97, 0x97, 0x97, 0x97,
+       0x97, 0x97, 0x97, 0x97, 0x97, 0x97, 0x97, 0x97, 0x97, 0x97, 0x97, 0x96,
+       0x96, 0x96, 0x96, 0x96, 0x96, 0x96, 0x96, 0x96, 0x96, 0x96, 0x96, 0x96,
+       0x96, 0x96, 0x96, 0x96, 0x96, 0x96, 0x96, 0x96, 0x96, 0x96, 0x96, 0x96,
+       0x96, 0x96, 0x96, 0x96, 0x96, 0x96, 0x96, 0x96, 0x96, 0x96, 0x96, 0x96,
+       0x96, 0x96, 0x96, 0x96, 0x96, 0x96, 0x96, 0x96, 0x96, 0x96, 0x96, 0x96,
+       0x96, 0x96, 0x96, 0x96, 0x96, 0x96, 0x96, 0x96, 0x96, 0x96, 0x96, 0x96,
+       0x96, 0x96, 0x96, 0x96, 0x96, 0x96, 0x96, 0x96, 0x96, 0x96, 0x96, 0x96,
+       0x96, 0x96, 0x96, 0x96, 0x96, 0x96, 0x96, 0x96, 0x96, 0x96, 0x96, 0x96,
+       0x96, 0x96, 0x96, 0x96, 0x96, 0x96, 0x96, 0x96, 0x96, 0x96, 0x96, 0x96,
+       0x96, 0x96, 0x96, 0x96, 0x96, 0x96, 0x96, 0x96, 0x96, 0x96, 0x96, 0x96,
+       0x96, 0x96, 0x96, 0x96, 0x96, 0x96, 0x96, 0x96, 0x96, 0x96, 0x96, 0x96,
+       0x96, 0x96, 0x96, 0x96, 0x96, 0x96, 0x96, 0x95, 0x95, 0x95, 0x95, 0x95,
+       0x95, 0x95, 0x95, 0x95, 0x95, 0x95, 0x95, 0x95, 0x95, 0x95, 0x95, 0x95,
+       0x95, 0x95, 0x95, 0x95, 0x95, 0x95, 0x95, 0x95, 0x95, 0x95, 0x95, 0x95,
+       0x95, 0x95, 0x95, 0x95, 0x95, 0x95, 0x95, 0x95, 0x95, 0x95, 0x95, 0x95,
+       0x95, 0x95, 0x95, 0x95, 0x95, 0x95, 0x95, 0x95, 0x95, 0x95, 0x95, 0x95,
+       0x95, 0x95, 0x95, 0x95, 0x95, 0x95, 0x95, 0x95, 0x95, 0x95, 0x95, 0x95,
+       0x95, 0x95, 0x95, 0x95, 0x95, 0x95, 0x95, 0x95, 0x95, 0x95, 0x95, 0x95,
+       0x95, 0x95, 0x95, 0x95, 0x95, 0x95, 0x95, 0x95, 0x95, 0x95, 0x95, 0x95,
+       0x95, 0x95, 0x95, 0x95, 0x95, 0x95, 0x95, 0x95, 0x95, 0x95, 0x95, 0x95,
+       0x95, 0x95, 0x95, 0x95, 0x95, 0x95, 0x95, 0x95, 0x95, 0x95, 0x95, 0x95,
+       0x95, 0x95, 0x95, 0x95, 0x95, 0x95, 0x95, 0x95, 0x95, 0x95, 0x95, 0x95,
+       0x95, 0x95, 0x95, 0x94, 0x94, 0x94, 0x94, 0x94, 0x94, 0x94, 0x94, 0x94,
+       0x94, 0x94, 0x94, 0x94, 0x94, 0x94, 0x94, 0x94, 0x94, 0x94, 0x94, 0x94,
+       0x94, 0x94, 0x94, 0x94, 0x94, 0x94, 0x94, 0x94, 0x94, 0x94, 0x94, 0x94,
+       0x94, 0x94, 0x94, 0x94, 0x94, 0x94, 0x94, 0x94, 0x94, 0x94, 0x94, 0x94,
+       0x94, 0x94, 0x94, 0x94, 0x94, 0x94, 0x94, 0x94, 0x94, 0x94, 0x94, 0x94,
+       0x94, 0x94, 0x94, 0x94, 0x94, 0x94, 0x94, 0x94, 0x94, 0x94, 0x94, 0x94,
+       0x94, 0x94, 0x94, 0x94, 0x94, 0x94, 0x94, 0x94, 0x94, 0x94, 0x94, 0x94,
+       0x94, 0x94, 0x94, 0x94, 0x94, 0x94, 0x94, 0x94, 0x94, 0x94, 0x94, 0x94,
+       0x94, 0x94, 0x94, 0x94, 0x94, 0x94, 0x94, 0x94, 0x94, 0x94, 0x94, 0x94,
+       0x94, 0x94, 0x94, 0x94, 0x94, 0x94, 0x94, 0x94, 0x94, 0x94, 0x94, 0x94,
+       0x94, 0x94, 0x94, 0x94, 0x94, 0x94, 0x94, 0x94, 0x94, 0x94, 0x94, 0x93,
+       0x93, 0x93, 0x93, 0x93, 0x93, 0x93, 0x93, 0x93, 0x93, 0x93, 0x93, 0x93,
+       0x93, 0x93, 0x93, 0x93, 0x93, 0x93, 0x93, 0x93, 0x93, 0x93, 0x93, 0x93,
+       0x93, 0x93, 0x93, 0x93, 0x93, 0x93, 0x93, 0x93, 0x93, 0x93, 0x93, 0x93,
+       0x93, 0x93, 0x93, 0x93, 0x93, 0x93, 0x93, 0x93, 0x93, 0x93, 0x93, 0x93,
+       0x93, 0x93, 0x93, 0x93, 0x93, 0x93, 0x93, 0x93, 0x93, 0x93, 0x93, 0x93,
+       0x93, 0x93, 0x93, 0x93, 0x93, 0x93, 0x93, 0x93, 0x93, 0x93, 0x93, 0x93,
+       0x93, 0x93, 0x93, 0x93, 0x93, 0x93, 0x93, 0x93, 0x93, 0x93, 0x93, 0x93,
+       0x93, 0x93, 0x93, 0x93, 0x93, 0x93, 0x93, 0x93, 0x93, 0x93, 0x93, 0x93,
+       0x93, 0x93, 0x93, 0x93, 0x93, 0x93, 0x93, 0x93, 0x93, 0x93, 0x93, 0x93,
+       0x93, 0x93, 0x93, 0x93, 0x93, 0x93, 0x93, 0x93, 0x93, 0x93, 0x93, 0x93,
+       0x93, 0x93, 0x93, 0x93, 0x93, 0x93, 0x93, 0x92, 0x92, 0x92, 0x92, 0x92,
+       0x92, 0x92, 0x92, 0x92, 0x92, 0x92, 0x92, 0x92, 0x92, 0x92, 0x92, 0x92,
+       0x92, 0x92, 0x92, 0x92, 0x92, 0x92, 0x92, 0x92, 0x92, 0x92, 0x92, 0x92,
+       0x92, 0x92, 0x92, 0x92, 0x92, 0x92, 0x92, 0x92, 0x92, 0x92, 0x92, 0x92,
+       0x92, 0x92, 0x92, 0x92, 0x92, 0x92, 0x92, 0x92, 0x92, 0x92, 0x92, 0x92,
+       0x92, 0x92, 0x92, 0x92, 0x92, 0x92, 0x92, 0x92, 0x92, 0x92, 0x92, 0x92,
+       0x92, 0x92, 0x92, 0x92, 0x92, 0x92, 0x92, 0x92, 0x92, 0x92, 0x92, 0x92,
+       0x92, 0x92, 0x92, 0x92, 0x92, 0x92, 0x92, 0x92, 0x92, 0x92, 0x92, 0x92,
+       0x92, 0x92, 0x92, 0x92, 0x92, 0x92, 0x92, 0x92, 0x92, 0x92, 0x92, 0x92,
+       0x92, 0x92, 0x92, 0x92, 0x92, 0x92, 0x92, 0x92, 0x92, 0x92, 0x92, 0x92,
+       0x92, 0x92, 0x92, 0x92, 0x92, 0x92, 0x92, 0x92, 0x92, 0x92, 0x92, 0x92,
+       0x92, 0x92, 0x92, 0x91, 0x91, 0x91, 0x91, 0x91, 0x91, 0x91, 0x91, 0x91,
+       0x91, 0x91, 0x91, 0x91, 0x91, 0x91, 0x91, 0x91, 0x91, 0x91, 0x91, 0x91,
+       0x91, 0x91, 0x91, 0x91, 0x91, 0x91, 0x91, 0x91, 0x91, 0x91, 0x91, 0x91,
+       0x91, 0x91, 0x91, 0x91, 0x91, 0x91, 0x91, 0x91, 0x91, 0x91, 0x91, 0x91,
+       0x91, 0x91, 0x91, 0x91, 0x91, 0x91, 0x91, 0x91, 0x91, 0x91, 0x91, 0x91,
+       0x91, 0x91, 0x91, 0x91, 0x91, 0x91, 0x91, 0x91, 0x91, 0x91, 0x91, 0x91,
+       0x91, 0x91, 0x91, 0x91, 0x91, 0x91, 0x91, 0x91, 0x91, 0x91, 0x91, 0x91,
+       0x91, 0x91, 0x91, 0x91, 0x91, 0x91, 0x91, 0x91, 0x91, 0x91, 0x91, 0x91,
+       0x91, 0x91, 0x91, 0x91, 0x91, 0x91, 0x91, 0x91, 0x91, 0x91, 0x91, 0x91,
+       0x91, 0x91, 0x91, 0x91, 0x91, 0x91, 0x91, 0x91, 0x91, 0x91, 0x91, 0x91,
+       0x91, 0x91, 0x91, 0x91, 0x91, 0x91, 0x91, 0x91, 0x91, 0x91, 0x91, 0x90,
+       0x90, 0x90, 0x90, 0x90, 0x90, 0x90, 0x90, 0x90, 0x90, 0x90, 0x90, 0x90,
+       0x90, 0x90, 0x90, 0x90, 0x90, 0x90, 0x90, 0x90, 0x90, 0x90, 0x90, 0x90,
+       0x90, 0x90, 0x90, 0x90, 0x90, 0x90, 0x90, 0x90, 0x90, 0x90, 0x90, 0x90,
+       0x90, 0x90, 0x90, 0x90, 0x90, 0x90, 0x90, 0x90, 0x90, 0x90, 0x90, 0x90,
+       0x90, 0x90, 0x90, 0x90, 0x90, 0x90, 0x90, 0x90, 0x90, 0x90, 0x90, 0x90,
+       0x90, 0x90, 0x90, 0x90, 0x90, 0x90, 0x90, 0x90, 0x90, 0x90, 0x90, 0x90,
+       0x90, 0x90, 0x90, 0x90, 0x90, 0x90, 0x90, 0x90, 0x90, 0x90, 0x90, 0x90,
+       0x90, 0x90, 0x90, 0x90, 0x90, 0x90, 0x90, 0x90, 0x90, 0x90, 0x90, 0x90,
+       0x90, 0x90, 0x90, 0x90, 0x90, 0x90, 0x90, 0x90, 0x90, 0x90, 0x90, 0x90,
+       0x90, 0x90, 0x90, 0x90, 0x90, 0x90, 0x90, 0x90, 0x90, 0x90, 0x90, 0x90,
+       0x90, 0x90, 0x90, 0x90, 0x90, 0x90, 0x90, 0x8f, 0x8f, 0x8f, 0x8f, 0x8f,
+       0x8f, 0x8f, 0x8f, 0x8f, 0x8f, 0x8f, 0x8f, 0x8f, 0x8f, 0x8f, 0x8f, 0x8f,
+       0x8f, 0x8f, 0x8f, 0x8f, 0x8f, 0x8f, 0x8f, 0x8f, 0x8f, 0x8f, 0x8f, 0x8f,
+       0x8f, 0x8f, 0x8f, 0x8f, 0x8f, 0x8f, 0x8f, 0x8f, 0x8f, 0x8f, 0x8f, 0x8f,
+       0x8f, 0x8f, 0x8f, 0x8f, 0x8f, 0x8f, 0x8f, 0x8f, 0x8f, 0x8f, 0x8f, 0x8f,
+       0x8f, 0x8f, 0x8f, 0x8f, 0x8f, 0x8f, 0x8f, 0x8f, 0x8f, 0x8f, 0x8f, 0x8f,
+       0x8f, 0x8f, 0x8f, 0x8f, 0x8f, 0x8f, 0x8f, 0x8f, 0x8f, 0x8f, 0x8f, 0x8f,
+       0x8f, 0x8f, 0x8f, 0x8f, 0x8f, 0x8f, 0x8f, 0x8f, 0x8f, 0x8f, 0x8f, 0x8f,
+       0x8f, 0x8f, 0x8f, 0x8f, 0x8f, 0x8f, 0x8f, 0x8f, 0x8f, 0x8f, 0x8f, 0x8f,
+       0x8f, 0x8f, 0x8f, 0x8f, 0x8f, 0x8f, 0x8f, 0x8f, 0x8f, 0x8f, 0x8f, 0x8f,
+       0x8f, 0x8f, 0x8f, 0x8f, 0x8f, 0x8f, 0x8f, 0x8f, 0x8f, 0x8f, 0x8f, 0x8f,
+       0x8f, 0x8f, 0x8f, 0x8f, 0x8f, 0x8f, 0x8f, 0x8f, 0x8f, 0x8f, 0x8f, 0x8f,
+       0x8f, 0x8f, 0x8f, 0x8f, 0x8f, 0x8f, 0x8f, 0x8f, 0x8f, 0x8f, 0x8f, 0x8f,
+       0x8f, 0x8f, 0x8f, 0x8f, 0x8f, 0x8f, 0x8f, 0x8f, 0x8f, 0x8f, 0x8f, 0x8f,
+       0x8f, 0x8f, 0x8f, 0x8f, 0x8f, 0x8f, 0x8f, 0x8f, 0x8f, 0x8f, 0x8f, 0x8f,
+       0x8f, 0x8f, 0x8f, 0x8f, 0x8f, 0x8f, 0x8f, 0x8f, 0x8f, 0x8f, 0x8f, 0x8f,
+       0x8f, 0x8f, 0x8f, 0x8f, 0x8f, 0x8f, 0x8f, 0x8f, 0x8f, 0x8f, 0x8f, 0x8f,
+       0x8f, 0x8f, 0x8f, 0x8f, 0x8f, 0x8f, 0x8f, 0x8f, 0x8f, 0x8f, 0x8f, 0x8f,
+       0x8f, 0x8f, 0x8f, 0x8f, 0x8f, 0x8f, 0x8f, 0x8f, 0x8f, 0x8f, 0x8f, 0x8f,
+       0x8f, 0x8f, 0x8f, 0x8f, 0x8f, 0x8f, 0x8f, 0x8f, 0x8f, 0x8f, 0x8f, 0x8f,
+       0x8f, 0x8f, 0x8f, 0x8f, 0x8f, 0x8f, 0x8f, 0x8f, 0x8f, 0x8f, 0x8f, 0x8f,
+       0x8f, 0x8f, 0x8f, 0x8f, 0x8f, 0x8f, 0x8f, 0x8f, 0x8f, 0x8f, 0x8f, 0x8e,
+       0x8e, 0x8e, 0x8e, 0x8e, 0x8e, 0x8e, 0x8e, 0x8e, 0x8e, 0x8e, 0x8e, 0x8e,
+       0x8e, 0x8e, 0x8e, 0x8e, 0x8e, 0x8e, 0x8e, 0x8e, 0x8e, 0x8e, 0x8e, 0x8e,
+       0x8e, 0x8e, 0x8e, 0x8e, 0x8e, 0x8e, 0x8e, 0x8e, 0x8e, 0x8e, 0x8e, 0x8e,
+       0x8e, 0x8e, 0x8e, 0x8e, 0x8e, 0x8e, 0x8e, 0x8e, 0x8e, 0x8e, 0x8e, 0x8e,
+       0x8e, 0x8e, 0x8e, 0x8e, 0x8e, 0x8e, 0x8e, 0x8e, 0x8e, 0x8e, 0x8e, 0x8e,
+       0x8e, 0x8e, 0x8e, 0x8e, 0x8e, 0x8e, 0x8e, 0x8e, 0x8e, 0x8e, 0x8e, 0x8e,
+       0x8e, 0x8e, 0x8e, 0x8e, 0x8e, 0x8e, 0x8e, 0x8e, 0x8e, 0x8e, 0x8e, 0x8e,
+       0x8e, 0x8e, 0x8e, 0x8e, 0x8e, 0x8e, 0x8e, 0x8e, 0x8e, 0x8e, 0x8e, 0x8e,
+       0x8e, 0x8e, 0x8e, 0x8e, 0x8e, 0x8e, 0x8e, 0x8e, 0x8e, 0x8e, 0x8e, 0x8e,
+       0x8e, 0x8e, 0x8e, 0x8e, 0x8e, 0x8e, 0x8e, 0x8e, 0x8e, 0x8e, 0x8e, 0x8e,
+       0x8e, 0x8e, 0x8e, 0x8e, 0x8e, 0x8e, 0x8e, 0x8e, 0x8e, 0x8e, 0x8e, 0x8e,
+       0x8e, 0x8e, 0x8e, 0x8e, 0x8e, 0x8e, 0x8e, 0x8e, 0x8e, 0x8e, 0x8e, 0x8e,
+       0x8e, 0x8e, 0x8e, 0x8e, 0x8e, 0x8e, 0x8e, 0x8e, 0x8e, 0x8e, 0x8e, 0x8e,
+       0x8e, 0x8e, 0x8e, 0x8e, 0x8e, 0x8e, 0x8e, 0x8e, 0x8e, 0x8e, 0x8e, 0x8e,
+       0x8e, 0x8e, 0x8e, 0x8e, 0x8e, 0x8e, 0x8e, 0x8e, 0x8e, 0x8e, 0x8e, 0x8e,
+       0x8e, 0x8e, 0x8e, 0x8e, 0x8e, 0x8e, 0x8e, 0x8e, 0x8e, 0x8e, 0x8e, 0x8e,
+       0x8e, 0x8e, 0x8e, 0x8e, 0x8e, 0x8e, 0x8e, 0x8e, 0x8e, 0x8e, 0x8e, 0x8e,
+       0x8e, 0x8e, 0x8e, 0x8e, 0x8e, 0x8e, 0x8e, 0x8e, 0x8e, 0x8e, 0x8e, 0x8e,
+       0x8e, 0x8e, 0x8e, 0x8e, 0x8e, 0x8e, 0x8e, 0x8e, 0x8e, 0x8e, 0x8e, 0x8e,
+       0x8e, 0x8e, 0x8e, 0x8e, 0x8e, 0x8e, 0x8e, 0x8e, 0x8e, 0x8e, 0x8e, 0x8e,
+       0x8e, 0x8e, 0x8e, 0x8e, 0x8e, 0x8e, 0x8e, 0x8e, 0x8e, 0x8e, 0x8e, 0x8e,
+       0x8e, 0x8e, 0x8e, 0x8d, 0x8d, 0x8d, 0x8d, 0x8d, 0x8d, 0x8d, 0x8d, 0x8d,
+       0x8d, 0x8d, 0x8d, 0x8d, 0x8d, 0x8d, 0x8d, 0x8d, 0x8d, 0x8d, 0x8d, 0x8d,
+       0x8d, 0x8d, 0x8d, 0x8d, 0x8d, 0x8d, 0x8d, 0x8d, 0x8d, 0x8d, 0x8d, 0x8d,
+       0x8d, 0x8d, 0x8d, 0x8d, 0x8d, 0x8d, 0x8d, 0x8d, 0x8d, 0x8d, 0x8d, 0x8d,
+       0x8d, 0x8d, 0x8d, 0x8d, 0x8d, 0x8d, 0x8d, 0x8d, 0x8d, 0x8d, 0x8d, 0x8d,
+       0x8d, 0x8d, 0x8d, 0x8d, 0x8d, 0x8d, 0x8d, 0x8d, 0x8d, 0x8d, 0x8d, 0x8d,
+       0x8d, 0x8d, 0x8d, 0x8d, 0x8d, 0x8d, 0x8d, 0x8d, 0x8d, 0x8d, 0x8d, 0x8d,
+       0x8d, 0x8d, 0x8d, 0x8d, 0x8d, 0x8d, 0x8d, 0x8d, 0x8d, 0x8d, 0x8d, 0x8d,
+       0x8d, 0x8d, 0x8d, 0x8d, 0x8d, 0x8d, 0x8d, 0x8d, 0x8d, 0x8d, 0x8d, 0x8d,
+       0x8d, 0x8d, 0x8d, 0x8d, 0x8d, 0x8d, 0x8d, 0x8d, 0x8d, 0x8d, 0x8d, 0x8d,
+       0x8d, 0x8d, 0x8d, 0x8d, 0x8d, 0x8d, 0x8d, 0x8d, 0x8d, 0x8d, 0x8d, 0x8d,
+       0x8d, 0x8d, 0x8d, 0x8d, 0x8d, 0x8d, 0x8d, 0x8d, 0x8d, 0x8d, 0x8d, 0x8d,
+       0x8d, 0x8d, 0x8d, 0x8d, 0x8d, 0x8d, 0x8d, 0x8d, 0x8d, 0x8d, 0x8d, 0x8d,
+       0x8d, 0x8d, 0x8d, 0x8d, 0x8d, 0x8d, 0x8d, 0x8d, 0x8d, 0x8d, 0x8d, 0x8d,
+       0x8d, 0x8d, 0x8d, 0x8d, 0x8d, 0x8d, 0x8d, 0x8d, 0x8d, 0x8d, 0x8d, 0x8d,
+       0x8d, 0x8d, 0x8d, 0x8d, 0x8d, 0x8d, 0x8d, 0x8d, 0x8d, 0x8d, 0x8d, 0x8d,
+       0x8d, 0x8d, 0x8d, 0x8d, 0x8d, 0x8d, 0x8d, 0x8d, 0x8d, 0x8d, 0x8d, 0x8d,
+       0x8d, 0x8d, 0x8d, 0x8d, 0x8d, 0x8d, 0x8d, 0x8d, 0x8d, 0x8d, 0x8d, 0x8d,
+       0x8d, 0x8d, 0x8d, 0x8d, 0x8d, 0x8d, 0x8d, 0x8d, 0x8d, 0x8d, 0x8d, 0x8d,
+       0x8d, 0x8d, 0x8d, 0x8d, 0x8d, 0x8d, 0x8d, 0x8d, 0x8d, 0x8d, 0x8d, 0x8d,
+       0x8d, 0x8d, 0x8d, 0x8d, 0x8d, 0x8d, 0x8d, 0x8d, 0x8d, 0x8d, 0x8d, 0x8d,
+       0x8d, 0x8d, 0x8d, 0x8d, 0x8d, 0x8d, 0x8d, 0x8c, 0x8c, 0x8c, 0x8c, 0x8c,
+       0x8c, 0x8c, 0x8c, 0x8c, 0x8c, 0x8c, 0x8c, 0x8c, 0x8c, 0x8c, 0x8c, 0x8c,
+       0x8c, 0x8c, 0x8c, 0x8c, 0x8c, 0x8c, 0x8c, 0x8c, 0x8c, 0x8c, 0x8c, 0x8c,
+       0x8c, 0x8c, 0x8c, 0x8c, 0x8c, 0x8c, 0x8c, 0x8c, 0x8c, 0x8c, 0x8c, 0x8c,
+       0x8c, 0x8c, 0x8c, 0x8c, 0x8c, 0x8c, 0x8c, 0x8c, 0x8c, 0x8c, 0x8c, 0x8c,
+       0x8c, 0x8c, 0x8c, 0x8c, 0x8c, 0x8c, 0x8c, 0x8c, 0x8c, 0x8c, 0x8c, 0x8c,
+       0x8c, 0x8c, 0x8c, 0x8c, 0x8c, 0x8c, 0x8c, 0x8c, 0x8c, 0x8c, 0x8c, 0x8c,
+       0x8c, 0x8c, 0x8c, 0x8c, 0x8c, 0x8c, 0x8c, 0x8c, 0x8c, 0x8c, 0x8c, 0x8c,
+       0x8c, 0x8c, 0x8c, 0x8c, 0x8c, 0x8c, 0x8c, 0x8c, 0x8c, 0x8c, 0x8c, 0x8c,
+       0x8c, 0x8c, 0x8c, 0x8c, 0x8c, 0x8c, 0x8c, 0x8c, 0x8c, 0x8c, 0x8c, 0x8c,
+       0x8c, 0x8c, 0x8c, 0x8c, 0x8c, 0x8c, 0x8c, 0x8c, 0x8c, 0x8c, 0x8c, 0x8c,
+       0x8c, 0x8c, 0x8c, 0x8c, 0x8c, 0x8c, 0x8c, 0x8c, 0x8c, 0x8c, 0x8c, 0x8c,
+       0x8c, 0x8c, 0x8c, 0x8c, 0x8c, 0x8c, 0x8c, 0x8c, 0x8c, 0x8c, 0x8c, 0x8c,
+       0x8c, 0x8c, 0x8c, 0x8c, 0x8c, 0x8c, 0x8c, 0x8c, 0x8c, 0x8c, 0x8c, 0x8c,
+       0x8c, 0x8c, 0x8c, 0x8c, 0x8c, 0x8c, 0x8c, 0x8c, 0x8c, 0x8c, 0x8c, 0x8c,
+       0x8c, 0x8c, 0x8c, 0x8c, 0x8c, 0x8c, 0x8c, 0x8c, 0x8c, 0x8c, 0x8c, 0x8c,
+       0x8c, 0x8c, 0x8c, 0x8c, 0x8c, 0x8c, 0x8c, 0x8c, 0x8c, 0x8c, 0x8c, 0x8c,
+       0x8c, 0x8c, 0x8c, 0x8c, 0x8c, 0x8c, 0x8c, 0x8c, 0x8c, 0x8c, 0x8c, 0x8c,
+       0x8c, 0x8c, 0x8c, 0x8c, 0x8c, 0x8c, 0x8c, 0x8c, 0x8c, 0x8c, 0x8c, 0x8c,
+       0x8c, 0x8c, 0x8c, 0x8c, 0x8c, 0x8c, 0x8c, 0x8c, 0x8c, 0x8c, 0x8c, 0x8c,
+       0x8c, 0x8c, 0x8c, 0x8c, 0x8c, 0x8c, 0x8c, 0x8c, 0x8c, 0x8c, 0x8c, 0x8c,
+       0x8c, 0x8c, 0x8c, 0x8c, 0x8c, 0x8c, 0x8c, 0x8c, 0x8c, 0x8c, 0x8c, 0x8b,
+       0x8b, 0x8b, 0x8b, 0x8b, 0x8b, 0x8b, 0x8b, 0x8b, 0x8b, 0x8b, 0x8b, 0x8b,
+       0x8b, 0x8b, 0x8b, 0x8b, 0x8b, 0x8b, 0x8b, 0x8b, 0x8b, 0x8b, 0x8b, 0x8b,
+       0x8b, 0x8b, 0x8b, 0x8b, 0x8b, 0x8b, 0x8b, 0x8b, 0x8b, 0x8b, 0x8b, 0x8b,
+       0x8b, 0x8b, 0x8b, 0x8b, 0x8b, 0x8b, 0x8b, 0x8b, 0x8b, 0x8b, 0x8b, 0x8b,
+       0x8b, 0x8b, 0x8b, 0x8b, 0x8b, 0x8b, 0x8b, 0x8b, 0x8b, 0x8b, 0x8b, 0x8b,
+       0x8b, 0x8b, 0x8b, 0x8b, 0x8b, 0x8b, 0x8b, 0x8b, 0x8b, 0x8b, 0x8b, 0x8b,
+       0x8b, 0x8b, 0x8b, 0x8b, 0x8b, 0x8b, 0x8b, 0x8b, 0x8b, 0x8b, 0x8b, 0x8b,
+       0x8b, 0x8b, 0x8b, 0x8b, 0x8b, 0x8b, 0x8b, 0x8b, 0x8b, 0x8b, 0x8b, 0x8b,
+       0x8b, 0x8b, 0x8b, 0x8b, 0x8b, 0x8b, 0x8b, 0x8b, 0x8b, 0x8b, 0x8b, 0x8b,
+       0x8b, 0x8b, 0x8b, 0x8b, 0x8b, 0x8b, 0x8b, 0x8b, 0x8b, 0x8b, 0x8b, 0x8b,
+       0x8b, 0x8b, 0x8b, 0x8b, 0x8b, 0x8b, 0x8b, 0x8b, 0x8b, 0x8b, 0x8b, 0x8b,
+       0x8b, 0x8b, 0x8b, 0x8b, 0x8b, 0x8b, 0x8b, 0x8b, 0x8b, 0x8b, 0x8b, 0x8b,
+       0x8b, 0x8b, 0x8b, 0x8b, 0x8b, 0x8b, 0x8b, 0x8b, 0x8b, 0x8b, 0x8b, 0x8b,
+       0x8b, 0x8b, 0x8b, 0x8b, 0x8b, 0x8b, 0x8b, 0x8b, 0x8b, 0x8b, 0x8b, 0x8b,
+       0x8b, 0x8b, 0x8b, 0x8b, 0x8b, 0x8b, 0x8b, 0x8b, 0x8b, 0x8b, 0x8b, 0x8b,
+       0x8b, 0x8b, 0x8b, 0x8b, 0x8b, 0x8b, 0x8b, 0x8b, 0x8b, 0x8b, 0x8b, 0x8b,
+       0x8b, 0x8b, 0x8b, 0x8b, 0x8b, 0x8b, 0x8b, 0x8b, 0x8b, 0x8b, 0x8b, 0x8b,
+       0x8b, 0x8b, 0x8b, 0x8b, 0x8b, 0x8b, 0x8b, 0x8b, 0x8b, 0x8b, 0x8b, 0x8b,
+       0x8b, 0x8b, 0x8b, 0x8b, 0x8b, 0x8b, 0x8b, 0x8b, 0x8b, 0x8b, 0x8b, 0x8b,
+       0x8b, 0x8b, 0x8b, 0x8b, 0x8b, 0x8b, 0x8b, 0x8b, 0x8b, 0x8b, 0x8b, 0x8b,
+       0x8b, 0x8b, 0x8b, 0x8b, 0x8b, 0x8b, 0x8b, 0x8b, 0x8b, 0x8b, 0x8b, 0x8b,
+       0x8b, 0x8b, 0x8b, 0x8a, 0x8a, 0x8a, 0x8a, 0x8a, 0x8a, 0x8a, 0x8a, 0x8a,
+       0x8a, 0x8a, 0x8a, 0x8a, 0x8a, 0x8a, 0x8a, 0x8a, 0x8a, 0x8a, 0x8a, 0x8a,
+       0x8a, 0x8a, 0x8a, 0x8a, 0x8a, 0x8a, 0x8a, 0x8a, 0x8a, 0x8a, 0x8a, 0x8a,
+       0x8a, 0x8a, 0x8a, 0x8a, 0x8a, 0x8a, 0x8a, 0x8a, 0x8a, 0x8a, 0x8a, 0x8a,
+       0x8a, 0x8a, 0x8a, 0x8a, 0x8a, 0x8a, 0x8a, 0x8a, 0x8a, 0x8a, 0x8a, 0x8a,
+       0x8a, 0x8a, 0x8a, 0x8a, 0x8a, 0x8a, 0x8a, 0x8a, 0x8a, 0x8a, 0x8a, 0x8a,
+       0x8a, 0x8a, 0x8a, 0x8a, 0x8a, 0x8a, 0x8a, 0x8a, 0x8a, 0x8a, 0x8a, 0x8a,
+       0x8a, 0x8a, 0x8a, 0x8a, 0x8a, 0x8a, 0x8a, 0x8a, 0x8a, 0x8a, 0x8a, 0x8a,
+       0x8a, 0x8a, 0x8a, 0x8a, 0x8a, 0x8a, 0x8a, 0x8a, 0x8a, 0x8a, 0x8a, 0x8a,
+       0x8a, 0x8a, 0x8a, 0x8a, 0x8a, 0x8a, 0x8a, 0x8a, 0x8a, 0x8a, 0x8a, 0x8a,
+       0x8a, 0x8a, 0x8a, 0x8a, 0x8a, 0x8a, 0x8a, 0x8a, 0x8a, 0x8a, 0x8a, 0x8a,
+       0x8a, 0x8a, 0x8a, 0x8a, 0x8a, 0x8a, 0x8a, 0x8a, 0x8a, 0x8a, 0x8a, 0x8a,
+       0x8a, 0x8a, 0x8a, 0x8a, 0x8a, 0x8a, 0x8a, 0x8a, 0x8a, 0x8a, 0x8a, 0x8a,
+       0x8a, 0x8a, 0x8a, 0x8a, 0x8a, 0x8a, 0x8a, 0x8a, 0x8a, 0x8a, 0x8a, 0x8a,
+       0x8a, 0x8a, 0x8a, 0x8a, 0x8a, 0x8a, 0x8a, 0x8a, 0x8a, 0x8a, 0x8a, 0x8a,
+       0x8a, 0x8a, 0x8a, 0x8a, 0x8a, 0x8a, 0x8a, 0x8a, 0x8a, 0x8a, 0x8a, 0x8a,
+       0x8a, 0x8a, 0x8a, 0x8a, 0x8a, 0x8a, 0x8a, 0x8a, 0x8a, 0x8a, 0x8a, 0x8a,
+       0x8a, 0x8a, 0x8a, 0x8a, 0x8a, 0x8a, 0x8a, 0x8a, 0x8a, 0x8a, 0x8a, 0x8a,
+       0x8a, 0x8a, 0x8a, 0x8a, 0x8a, 0x8a, 0x8a, 0x8a, 0x8a, 0x8a, 0x8a, 0x8a,
+       0x8a, 0x8a, 0x8a, 0x8a, 0x8a, 0x8a, 0x8a, 0x8a, 0x8a, 0x8a, 0x8a, 0x8a,
+       0x8a, 0x8a, 0x8a, 0x8a, 0x8a, 0x8a, 0x8a, 0x8a, 0x8a, 0x8a, 0x8a, 0x8a,
+       0x8a, 0x8a, 0x8a, 0x8a, 0x8a, 0x8a, 0x8a, 0x89, 0x89, 0x89, 0x89, 0x89,
+       0x89, 0x89, 0x89, 0x89, 0x89, 0x89, 0x89, 0x89, 0x89, 0x89, 0x89, 0x89,
+       0x89, 0x89, 0x89, 0x89, 0x89, 0x89, 0x89, 0x89, 0x89, 0x89, 0x89, 0x89,
+       0x89, 0x89, 0x89, 0x89, 0x89, 0x89, 0x89, 0x89, 0x89, 0x89, 0x89, 0x89,
+       0x89, 0x89, 0x89, 0x89, 0x89, 0x89, 0x89, 0x89, 0x89, 0x89, 0x89, 0x89,
+       0x89, 0x89, 0x89, 0x89, 0x89, 0x89, 0x89, 0x89, 0x89, 0x89, 0x89, 0x89,
+       0x89, 0x89, 0x89, 0x89, 0x89, 0x89, 0x89, 0x89, 0x89, 0x89, 0x89, 0x89,
+       0x89, 0x89, 0x89, 0x89, 0x89, 0x89, 0x89, 0x89, 0x89, 0x89, 0x89, 0x89,
+       0x89, 0x89, 0x89, 0x89, 0x89, 0x89, 0x89, 0x89, 0x89, 0x89, 0x89, 0x89,
+       0x89, 0x89, 0x89, 0x89, 0x89, 0x89, 0x89, 0x89, 0x89, 0x89, 0x89, 0x89,
+       0x89, 0x89, 0x89, 0x89, 0x89, 0x89, 0x89, 0x89, 0x89, 0x89, 0x89, 0x89,
+       0x89, 0x89, 0x89, 0x89, 0x89, 0x89, 0x89, 0x89, 0x89, 0x89, 0x89, 0x89,
+       0x89, 0x89, 0x89, 0x89, 0x89, 0x89, 0x89, 0x89, 0x89, 0x89, 0x89, 0x89,
+       0x89, 0x89, 0x89, 0x89, 0x89, 0x89, 0x89, 0x89, 0x89, 0x89, 0x89, 0x89,
+       0x89, 0x89, 0x89, 0x89, 0x89, 0x89, 0x89, 0x89, 0x89, 0x89, 0x89, 0x89,
+       0x89, 0x89, 0x89, 0x89, 0x89, 0x89, 0x89, 0x89, 0x89, 0x89, 0x89, 0x89,
+       0x89, 0x89, 0x89, 0x89, 0x89, 0x89, 0x89, 0x89, 0x89, 0x89, 0x89, 0x89,
+       0x89, 0x89, 0x89, 0x89, 0x89, 0x89, 0x89, 0x89, 0x89, 0x89, 0x89, 0x89,
+       0x89, 0x89, 0x89, 0x89, 0x89, 0x89, 0x89, 0x89, 0x89, 0x89, 0x89, 0x89,
+       0x89, 0x89, 0x89, 0x89, 0x89, 0x89, 0x89, 0x89, 0x89, 0x89, 0x89, 0x89,
+       0x89, 0x89, 0x89, 0x89, 0x89, 0x89, 0x89, 0x89, 0x89, 0x89, 0x89, 0x89,
+       0x89, 0x89, 0x89, 0x89, 0x89, 0x89, 0x89, 0x89, 0x89, 0x89, 0x89, 0x88,
+       0x88, 0x88, 0x88, 0x88, 0x88, 0x88, 0x88, 0x88, 0x88, 0x88, 0x88, 0x88,
+       0x88, 0x88, 0x88, 0x88, 0x88, 0x88, 0x88, 0x88, 0x88, 0x88, 0x88, 0x88,
+       0x88, 0x88, 0x88, 0x88, 0x88, 0x88, 0x88, 0x88, 0x88, 0x88, 0x88, 0x88,
+       0x88, 0x88, 0x88, 0x88, 0x88, 0x88, 0x88, 0x88, 0x88, 0x88, 0x88, 0x88,
+       0x88, 0x88, 0x88, 0x88, 0x88, 0x88, 0x88, 0x88, 0x88, 0x88, 0x88, 0x88,
+       0x88, 0x88, 0x88, 0x88, 0x88, 0x88, 0x88, 0x88, 0x88, 0x88, 0x88, 0x88,
+       0x88, 0x88, 0x88, 0x88, 0x88, 0x88, 0x88, 0x88, 0x88, 0x88, 0x88, 0x88,
+       0x88, 0x88, 0x88, 0x88, 0x88, 0x88, 0x88, 0x88, 0x88, 0x88, 0x88, 0x88,
+       0x88, 0x88, 0x88, 0x88, 0x88, 0x88, 0x88, 0x88, 0x88, 0x88, 0x88, 0x88,
+       0x88, 0x88, 0x88, 0x88, 0x88, 0x88, 0x88, 0x88, 0x88, 0x88, 0x88, 0x88,
+       0x88, 0x88, 0x88, 0x88, 0x88, 0x88, 0x88, 0x88, 0x88, 0x88, 0x88, 0x88,
+       0x88, 0x88, 0x88, 0x88, 0x88, 0x88, 0x88, 0x88, 0x88, 0x88, 0x88, 0x88,
+       0x88, 0x88, 0x88, 0x88, 0x88, 0x88, 0x88, 0x88, 0x88, 0x88, 0x88, 0x88,
+       0x88, 0x88, 0x88, 0x88, 0x88, 0x88, 0x88, 0x88, 0x88, 0x88, 0x88, 0x88,
+       0x88, 0x88, 0x88, 0x88, 0x88, 0x88, 0x88, 0x88, 0x88, 0x88, 0x88, 0x88,
+       0x88, 0x88, 0x88, 0x88, 0x88, 0x88, 0x88, 0x88, 0x88, 0x88, 0x88, 0x88,
+       0x88, 0x88, 0x88, 0x88, 0x88, 0x88, 0x88, 0x88, 0x88, 0x88, 0x88, 0x88,
+       0x88, 0x88, 0x88, 0x88, 0x88, 0x88, 0x88, 0x88, 0x88, 0x88, 0x88, 0x88,
+       0x88, 0x88, 0x88, 0x88, 0x88, 0x88, 0x88, 0x88, 0x88, 0x88, 0x88, 0x88,
+       0x88, 0x88, 0x88, 0x88, 0x88, 0x88, 0x88, 0x88, 0x88, 0x88, 0x88, 0x88,
+       0x88, 0x88, 0x88, 0x88, 0x88, 0x88, 0x88, 0x88, 0x88, 0x88, 0x88, 0x88,
+       0x88, 0x88, 0x88, 0x87, 0x87, 0x87, 0x87, 0x87, 0x87, 0x87, 0x87, 0x87,
+       0x87, 0x87, 0x87, 0x87, 0x87, 0x87, 0x87, 0x87, 0x87, 0x87, 0x87, 0x87,
+       0x87, 0x87, 0x87, 0x87, 0x87, 0x87, 0x87, 0x87, 0x87, 0x87, 0x87, 0x87,
+       0x87, 0x87, 0x87, 0x87, 0x87, 0x87, 0x87, 0x87, 0x87, 0x87, 0x87, 0x87,
+       0x87, 0x87, 0x87, 0x87, 0x87, 0x87, 0x87, 0x87, 0x87, 0x87, 0x87, 0x87,
+       0x87, 0x87, 0x87, 0x87, 0x87, 0x87, 0x87, 0x87, 0x87, 0x87, 0x87, 0x87,
+       0x87, 0x87, 0x87, 0x87, 0x87, 0x87, 0x87, 0x87, 0x87, 0x87, 0x87, 0x87,
+       0x87, 0x87, 0x87, 0x87, 0x87, 0x87, 0x87, 0x87, 0x87, 0x87, 0x87, 0x87,
+       0x87, 0x87, 0x87, 0x87, 0x87, 0x87, 0x87, 0x87, 0x87, 0x87, 0x87, 0x87,
+       0x87, 0x87, 0x87, 0x87, 0x87, 0x87, 0x87, 0x87, 0x87, 0x87, 0x87, 0x87,
+       0x87, 0x87, 0x87, 0x87, 0x87, 0x87, 0x87, 0x87, 0x87, 0x87, 0x87, 0x87,
+       0x87, 0x87, 0x87, 0x87, 0x87, 0x87, 0x87, 0x87, 0x87, 0x87, 0x87, 0x87,
+       0x87, 0x87, 0x87, 0x87, 0x87, 0x87, 0x87, 0x87, 0x87, 0x87, 0x87, 0x87,
+       0x87, 0x87, 0x87, 0x87, 0x87, 0x87, 0x87, 0x87, 0x87, 0x87, 0x87, 0x87,
+       0x87, 0x87, 0x87, 0x87, 0x87, 0x87, 0x87, 0x87, 0x87, 0x87, 0x87, 0x87,
+       0x87, 0x87, 0x87, 0x87, 0x87, 0x87, 0x87, 0x87, 0x87, 0x87, 0x87, 0x87,
+       0x87, 0x87, 0x87, 0x87, 0x87, 0x87, 0x87, 0x87, 0x87, 0x87, 0x87, 0x87,
+       0x87, 0x87, 0x87, 0x87, 0x87, 0x87, 0x87, 0x87, 0x87, 0x87, 0x87, 0x87,
+       0x87, 0x87, 0x87, 0x87, 0x87, 0x87, 0x87, 0x87, 0x87, 0x87, 0x87, 0x87,
+       0x87, 0x87, 0x87, 0x87, 0x87, 0x87, 0x87, 0x87, 0x87, 0x87, 0x87, 0x87,
+       0x87, 0x87, 0x87, 0x87, 0x87, 0x87, 0x87, 0x87, 0x87, 0x87, 0x87, 0x87,
+       0x87, 0x87, 0x87, 0x87, 0x87, 0x87, 0x87, 0x86, 0x86, 0x86, 0x86, 0x86,
+       0x86, 0x86, 0x86, 0x86, 0x86, 0x86, 0x86, 0x86, 0x86, 0x86, 0x86, 0x86,
+       0x86, 0x86, 0x86, 0x86, 0x86, 0x86, 0x86, 0x86, 0x86, 0x86, 0x86, 0x86,
+       0x86, 0x86, 0x86, 0x86, 0x86, 0x86, 0x86, 0x86, 0x86, 0x86, 0x86, 0x86,
+       0x86, 0x86, 0x86, 0x86, 0x86, 0x86, 0x86, 0x86, 0x86, 0x86, 0x86, 0x86,
+       0x86, 0x86, 0x86, 0x86, 0x86, 0x86, 0x86, 0x86, 0x86, 0x86, 0x86, 0x86,
+       0x86, 0x86, 0x86, 0x86, 0x86, 0x86, 0x86, 0x86, 0x86, 0x86, 0x86, 0x86,
+       0x86, 0x86, 0x86, 0x86, 0x86, 0x86, 0x86, 0x86, 0x86, 0x86, 0x86, 0x86,
+       0x86, 0x86, 0x86, 0x86, 0x86, 0x86, 0x86, 0x86, 0x86, 0x86, 0x86, 0x86,
+       0x86, 0x86, 0x86, 0x86, 0x86, 0x86, 0x86, 0x86, 0x86, 0x86, 0x86, 0x86,
+       0x86, 0x86, 0x86, 0x86, 0x86, 0x86, 0x86, 0x86, 0x86, 0x86, 0x86, 0x86,
+       0x86, 0x86, 0x86, 0x86, 0x86, 0x86, 0x86, 0x86, 0x86, 0x86, 0x86, 0x86,
+       0x86, 0x86, 0x86, 0x86, 0x86, 0x86, 0x86, 0x86, 0x86, 0x86, 0x86, 0x86,
+       0x86, 0x86, 0x86, 0x86, 0x86, 0x86, 0x86, 0x86, 0x86, 0x86, 0x86, 0x86,
+       0x86, 0x86, 0x86, 0x86, 0x86, 0x86, 0x86, 0x86, 0x86, 0x86, 0x86, 0x86,
+       0x86, 0x86, 0x86, 0x86, 0x86, 0x86, 0x86, 0x86, 0x86, 0x86, 0x86, 0x86,
+       0x86, 0x86, 0x86, 0x86, 0x86, 0x86, 0x86, 0x86, 0x86, 0x86, 0x86, 0x86,
+       0x86, 0x86, 0x86, 0x86, 0x86, 0x86, 0x86, 0x86, 0x86, 0x86, 0x86, 0x86,
+       0x86, 0x86, 0x86, 0x86, 0x86, 0x86, 0x86, 0x86, 0x86, 0x86, 0x86, 0x86,
+       0x86, 0x86, 0x86, 0x86, 0x86, 0x86, 0x86, 0x86, 0x86, 0x86, 0x86, 0x86,
+       0x86, 0x86, 0x86, 0x86, 0x86, 0x86, 0x86, 0x86, 0x86, 0x86, 0x86, 0x86,
+       0x86, 0x86, 0x86, 0x86, 0x86, 0x86, 0x86, 0x86, 0x86, 0x86, 0x86, 0x85,
+       0x85, 0x85, 0x85, 0x85, 0x85, 0x85, 0x85, 0x85, 0x85, 0x85, 0x85, 0x85,
+       0x85, 0x85, 0x85, 0x85, 0x85, 0x85, 0x85, 0x85, 0x85, 0x85, 0x85, 0x85,
+       0x85, 0x85, 0x85, 0x85, 0x85, 0x85, 0x85, 0x85, 0x85, 0x85, 0x85, 0x85,
+       0x85, 0x85, 0x85, 0x85, 0x85, 0x85, 0x85, 0x85, 0x85, 0x85, 0x85, 0x85,
+       0x85, 0x85, 0x85, 0x85, 0x85, 0x85, 0x85, 0x85, 0x85, 0x85, 0x85, 0x85,
+       0x85, 0x85, 0x85, 0x85, 0x85, 0x85, 0x85, 0x85, 0x85, 0x85, 0x85, 0x85,
+       0x85, 0x85, 0x85, 0x85, 0x85, 0x85, 0x85, 0x85, 0x85, 0x85, 0x85, 0x85,
+       0x85, 0x85, 0x85, 0x85, 0x85, 0x85, 0x85, 0x85, 0x85, 0x85, 0x85, 0x85,
+       0x85, 0x85, 0x85, 0x85, 0x85, 0x85, 0x85, 0x85, 0x85, 0x85, 0x85, 0x85,
+       0x85, 0x85, 0x85, 0x85, 0x85, 0x85, 0x85, 0x85, 0x85, 0x85, 0x85, 0x85,
+       0x85, 0x85, 0x85, 0x85, 0x85, 0x85, 0x85, 0x85, 0x85, 0x85, 0x85, 0x85,
+       0x85, 0x85, 0x85, 0x85, 0x85, 0x85, 0x85, 0x85, 0x85, 0x85, 0x85, 0x85,
+       0x85, 0x85, 0x85, 0x85, 0x85, 0x85, 0x85, 0x85, 0x85, 0x85, 0x85, 0x85,
+       0x85, 0x85, 0x85, 0x85, 0x85, 0x85, 0x85, 0x85, 0x85, 0x85, 0x85, 0x85,
+       0x85, 0x85, 0x85, 0x85, 0x85, 0x85, 0x85, 0x85, 0x85, 0x85, 0x85, 0x85,
+       0x85, 0x85, 0x85, 0x85, 0x85, 0x85, 0x85, 0x85, 0x85, 0x85, 0x85, 0x85,
+       0x85, 0x85, 0x85, 0x85, 0x85, 0x85, 0x85, 0x85, 0x85, 0x85, 0x85, 0x85,
+       0x85, 0x85, 0x85, 0x85, 0x85, 0x85, 0x85, 0x85, 0x85, 0x85, 0x85, 0x85,
+       0x85, 0x85, 0x85, 0x85, 0x85, 0x85, 0x85, 0x85, 0x85, 0x85, 0x85, 0x85,
+       0x85, 0x85, 0x85, 0x85, 0x85, 0x85, 0x85, 0x85, 0x85, 0x85, 0x85, 0x85,
+       0x85, 0x85, 0x85, 0x85, 0x85, 0x85, 0x85, 0x85, 0x85, 0x85, 0x85, 0x85,
+       0x85, 0x85, 0x85, 0x84, 0x84, 0x84, 0x84, 0x84, 0x84, 0x84, 0x84, 0x84,
+       0x84, 0x84, 0x84, 0x84, 0x84, 0x84, 0x84, 0x84, 0x84, 0x84, 0x84, 0x84,
+       0x84, 0x84, 0x84, 0x84, 0x84, 0x84, 0x84, 0x84, 0x84, 0x84, 0x84, 0x84,
+       0x84, 0x84, 0x84, 0x84, 0x84, 0x84, 0x84, 0x84, 0x84, 0x84, 0x84, 0x84,
+       0x84, 0x84, 0x84, 0x84, 0x84, 0x84, 0x84, 0x84, 0x84, 0x84, 0x84, 0x84,
+       0x84, 0x84, 0x84, 0x84, 0x84, 0x84, 0x84, 0x84, 0x84, 0x84, 0x84, 0x84,
+       0x84, 0x84, 0x84, 0x84, 0x84, 0x84, 0x84, 0x84, 0x84, 0x84, 0x84, 0x84,
+       0x84, 0x84, 0x84, 0x84, 0x84, 0x84, 0x84, 0x84, 0x84, 0x84, 0x84, 0x84,
+       0x84, 0x84, 0x84, 0x84, 0x84, 0x84, 0x84, 0x84, 0x84, 0x84, 0x84, 0x84,
+       0x84, 0x84, 0x84, 0x84, 0x84, 0x84, 0x84, 0x84, 0x84, 0x84, 0x84, 0x84,
+       0x84, 0x84, 0x84, 0x84, 0x84, 0x84, 0x84, 0x84, 0x84, 0x84, 0x84, 0x84,
+       0x84, 0x84, 0x84, 0x84, 0x84, 0x84, 0x84, 0x84, 0x84, 0x84, 0x84, 0x84,
+       0x84, 0x84, 0x84, 0x84, 0x84, 0x84, 0x84, 0x84, 0x84, 0x84, 0x84, 0x84,
+       0x84, 0x84, 0x84, 0x84, 0x84, 0x84, 0x84, 0x84, 0x84, 0x84, 0x84, 0x84,
+       0x84, 0x84, 0x84, 0x84, 0x84, 0x84, 0x84, 0x84, 0x84, 0x84, 0x84, 0x84,
+       0x84, 0x84, 0x84, 0x84, 0x84, 0x84, 0x84, 0x84, 0x84, 0x84, 0x84, 0x84,
+       0x84, 0x84, 0x84, 0x84, 0x84, 0x84, 0x84, 0x84, 0x84, 0x84, 0x84, 0x84,
+       0x84, 0x84, 0x84, 0x84, 0x84, 0x84, 0x84, 0x84, 0x84, 0x84, 0x84, 0x84,
+       0x84, 0x84, 0x84, 0x84, 0x84, 0x84, 0x84, 0x84, 0x84, 0x84, 0x84, 0x84,
+       0x84, 0x84, 0x84, 0x84, 0x84, 0x84, 0x84, 0x84, 0x84, 0x84, 0x84, 0x84,
+       0x84, 0x84, 0x84, 0x84, 0x84, 0x84, 0x84, 0x84, 0x84, 0x84, 0x84, 0x84,
+       0x84, 0x84, 0x84, 0x84, 0x84, 0x84, 0x84, 0x83, 0x83, 0x83, 0x83, 0x83,
+       0x83, 0x83, 0x83, 0x83, 0x83, 0x83, 0x83, 0x83, 0x83, 0x83, 0x83, 0x83,
+       0x83, 0x83, 0x83, 0x83, 0x83, 0x83, 0x83, 0x83, 0x83, 0x83, 0x83, 0x83,
+       0x83, 0x83, 0x83, 0x83, 0x83, 0x83, 0x83, 0x83, 0x83, 0x83, 0x83, 0x83,
+       0x83, 0x83, 0x83, 0x83, 0x83, 0x83, 0x83, 0x83, 0x83, 0x83, 0x83, 0x83,
+       0x83, 0x83, 0x83, 0x83, 0x83, 0x83, 0x83, 0x83, 0x83, 0x83, 0x83, 0x83,
+       0x83, 0x83, 0x83, 0x83, 0x83, 0x83, 0x83, 0x83, 0x83, 0x83, 0x83, 0x83,
+       0x83, 0x83, 0x83, 0x83, 0x83, 0x83, 0x83, 0x83, 0x83, 0x83, 0x83, 0x83,
+       0x83, 0x83, 0x83, 0x83, 0x83, 0x83, 0x83, 0x83, 0x83, 0x83, 0x83, 0x83,
+       0x83, 0x83, 0x83, 0x83, 0x83, 0x83, 0x83, 0x83, 0x83, 0x83, 0x83, 0x83,
+       0x83, 0x83, 0x83, 0x83, 0x83, 0x83, 0x83, 0x83, 0x83, 0x83, 0x83, 0x83,
+       0x83, 0x83, 0x83, 0x83, 0x83, 0x83, 0x83, 0x83, 0x83, 0x83, 0x83, 0x83,
+       0x83, 0x83, 0x83, 0x83, 0x83, 0x83, 0x83, 0x83, 0x83, 0x83, 0x83, 0x83,
+       0x83, 0x83, 0x83, 0x83, 0x83, 0x83, 0x83, 0x83, 0x83, 0x83, 0x83, 0x83,
+       0x83, 0x83, 0x83, 0x83, 0x83, 0x83, 0x83, 0x83, 0x83, 0x83, 0x83, 0x83,
+       0x83, 0x83, 0x83, 0x83, 0x83, 0x83, 0x83, 0x83, 0x83, 0x83, 0x83, 0x83,
+       0x83, 0x83, 0x83, 0x83, 0x83, 0x83, 0x83, 0x83, 0x83, 0x83, 0x83, 0x83,
+       0x83, 0x83, 0x83, 0x83, 0x83, 0x83, 0x83, 0x83, 0x83, 0x83, 0x83, 0x83,
+       0x83, 0x83, 0x83, 0x83, 0x83, 0x83, 0x83, 0x83, 0x83, 0x83, 0x83, 0x83,
+       0x83, 0x83, 0x83, 0x83, 0x83, 0x83, 0x83, 0x83, 0x83, 0x83, 0x83, 0x83,
+       0x83, 0x83, 0x83, 0x83, 0x83, 0x83, 0x83, 0x83, 0x83, 0x83, 0x83, 0x83,
+       0x83, 0x83, 0x83, 0x83, 0x83, 0x83, 0x83, 0x83, 0x83, 0x83, 0x83, 0x82,
+       0x82, 0x82, 0x82, 0x82, 0x82, 0x82, 0x82, 0x82, 0x82, 0x82, 0x82, 0x82,
+       0x82, 0x82, 0x82, 0x82, 0x82, 0x82, 0x82, 0x82, 0x82, 0x82, 0x82, 0x82,
+       0x82, 0x82, 0x82, 0x82, 0x82, 0x82, 0x82, 0x82, 0x82, 0x82, 0x82, 0x82,
+       0x82, 0x82, 0x82, 0x82, 0x82, 0x82, 0x82, 0x82, 0x82, 0x82, 0x82, 0x82,
+       0x82, 0x82, 0x82, 0x82, 0x82, 0x82, 0x82, 0x82, 0x82, 0x82, 0x82, 0x82,
+       0x82, 0x82, 0x82, 0x82, 0x82, 0x82, 0x82, 0x82, 0x82, 0x82, 0x82, 0x82,
+       0x82, 0x82, 0x82, 0x82, 0x82, 0x82, 0x82, 0x82, 0x82, 0x82, 0x82, 0x82,
+       0x82, 0x82, 0x82, 0x82, 0x82, 0x82, 0x82, 0x82, 0x82, 0x82, 0x82, 0x82,
+       0x82, 0x82, 0x82, 0x82, 0x82, 0x82, 0x82, 0x82, 0x82, 0x82, 0x82, 0x82,
+       0x82, 0x82, 0x82, 0x82, 0x82, 0x82, 0x82, 0x82, 0x82, 0x82, 0x82, 0x82,
+       0x82, 0x82, 0x82, 0x82, 0x82, 0x82, 0x82, 0x82, 0x82, 0x82, 0x82, 0x82,
+       0x82, 0x82, 0x82, 0x82, 0x82, 0x82, 0x82, 0x82, 0x82, 0x82, 0x82, 0x82,
+       0x82, 0x82, 0x82, 0x82, 0x82, 0x82, 0x82, 0x82, 0x82, 0x82, 0x82, 0x82,
+       0x82, 0x82, 0x82, 0x82, 0x82, 0x82, 0x82, 0x82, 0x82, 0x82, 0x82, 0x82,
+       0x82, 0x82, 0x82, 0x82, 0x82, 0x82, 0x82, 0x82, 0x82, 0x82, 0x82, 0x82,
+       0x82, 0x82, 0x82, 0x82, 0x82, 0x82, 0x82, 0x82, 0x82, 0x82, 0x82, 0x82,
+       0x82, 0x82, 0x82, 0x82, 0x82, 0x82, 0x82, 0x82, 0x82, 0x82, 0x82, 0x82,
+       0x82, 0x82, 0x82, 0x82, 0x82, 0x82, 0x82, 0x82, 0x82, 0x82, 0x82, 0x82,
+       0x82, 0x82, 0x82, 0x82, 0x82, 0x82, 0x82, 0x82, 0x82, 0x82, 0x82, 0x82,
+       0x82, 0x82, 0x82, 0x82, 0x82, 0x82, 0x82, 0x82, 0x82, 0x82, 0x82, 0x82,
+       0x82, 0x82, 0x82, 0x82, 0x82, 0x82, 0x82, 0x82, 0x82, 0x82, 0x82, 0x82,
+       0x82, 0x82, 0x82, 0x81, 0x81, 0x81, 0x81, 0x81, 0x81, 0x81, 0x81, 0x81,
+       0x81, 0x81, 0x81, 0x81, 0x81, 0x81, 0x81, 0x81, 0x81, 0x81, 0x81, 0x81,
+       0x81, 0x81, 0x81, 0x81, 0x81, 0x81, 0x81, 0x81, 0x81, 0x81, 0x81, 0x81,
+       0x81, 0x81, 0x81, 0x81, 0x81, 0x81, 0x81, 0x81, 0x81, 0x81, 0x81, 0x81,
+       0x81, 0x81, 0x81, 0x81, 0x81, 0x81, 0x81, 0x81, 0x81, 0x81, 0x81, 0x81,
+       0x81, 0x81, 0x81, 0x81, 0x81, 0x81, 0x81, 0x81, 0x81, 0x81, 0x81, 0x81,
+       0x81, 0x81, 0x81, 0x81, 0x81, 0x81, 0x81, 0x81, 0x81, 0x81, 0x81, 0x81,
+       0x81, 0x81, 0x81, 0x81, 0x81, 0x81, 0x81, 0x81, 0x81, 0x81, 0x81, 0x81,
+       0x81, 0x81, 0x81, 0x81, 0x81, 0x81, 0x81, 0x81, 0x81, 0x81, 0x81, 0x81,
+       0x81, 0x81, 0x81, 0x81, 0x81, 0x81, 0x81, 0x81, 0x81, 0x81, 0x81, 0x81,
+       0x81, 0x81, 0x81, 0x81, 0x81, 0x81, 0x81, 0x81, 0x81, 0x81, 0x81, 0x81,
+       0x81, 0x81, 0x81, 0x81, 0x81, 0x81, 0x81, 0x81, 0x81, 0x81, 0x81, 0x81,
+       0x81, 0x81, 0x81, 0x81, 0x81, 0x81, 0x81, 0x81, 0x81, 0x81, 0x81, 0x81,
+       0x81, 0x81, 0x81, 0x81, 0x81, 0x81, 0x81, 0x81, 0x81, 0x81, 0x81, 0x81,
+       0x81, 0x81, 0x81, 0x81, 0x81, 0x81, 0x81, 0x81, 0x81, 0x81, 0x81, 0x81,
+       0x81, 0x81, 0x81, 0x81, 0x81, 0x81, 0x81, 0x81, 0x81, 0x81, 0x81, 0x81,
+       0x81, 0x81, 0x81, 0x81, 0x81, 0x81, 0x81, 0x81, 0x81, 0x81, 0x81, 0x81,
+       0x81, 0x81, 0x81, 0x81, 0x81, 0x81, 0x81, 0x81, 0x81, 0x81, 0x81, 0x81,
+       0x81, 0x81, 0x81, 0x81, 0x81, 0x81, 0x81, 0x81, 0x81, 0x81, 0x81, 0x81,
+       0x81, 0x81, 0x81, 0x81, 0x81, 0x81, 0x81, 0x81, 0x81, 0x81, 0x81, 0x81,
+       0x81, 0x81, 0x81, 0x81, 0x81, 0x81, 0x81, 0x81, 0x81, 0x81, 0x81, 0x81,
+       0x81, 0x81, 0x81, 0x81, 0x81, 0x81, 0x81, 0x80, 0x80, 0x80, 0x80, 0x80,
+       0x80, 0x80, 0x80, 0x80, 0x80, 0x80, 0x80, 0x80, 0x80, 0x80, 0x80, 0x80,
+       0x80, 0x80, 0x80, 0x80, 0x80, 0x80, 0x80, 0x80, 0x80, 0x80, 0x80, 0x80,
+       0x80, 0x80, 0x80, 0x80, 0x80, 0x80, 0x80, 0x80, 0x80, 0x80, 0x80, 0x80,
+       0x80, 0x80, 0x80, 0x80, 0x80, 0x80, 0x80, 0x80, 0x80, 0x80, 0x80, 0x80,
+       0x80, 0x80, 0x80, 0x80, 0x80, 0x80, 0x80, 0x80, 0x80, 0x80, 0x80, 0x80,
+       0x80, 0x80, 0x80, 0x80, 0x80, 0x80, 0x80, 0x80, 0x80, 0x80, 0x80, 0x80,
+       0x80, 0x80, 0x80, 0x80, 0x80, 0x80, 0x80, 0x80, 0x80, 0x80, 0x80, 0x80,
+       0x80, 0x80, 0x80, 0x80, 0x80, 0x80, 0x80, 0x80, 0x80, 0x80, 0x80, 0x80,
+       0x80, 0x80, 0x80, 0x80, 0x80, 0x80, 0x80, 0x80, 0x80, 0x80, 0x80, 0x80,
+       0x80, 0x80, 0x80, 0x80, 0x80, 0x80, 0x80, 0x80, 0x80, 0x80, 0x80, 0x80,
+       0x80, 0x80, 0x80, 0x80, 0x80, 0x80, 0x80, 0x80, 0x80, 0x80, 0x80, 0x80,
+       0x80, 0x80, 0x80, 0x80, 0x80, 0x80, 0x80, 0x80, 0x80, 0x80, 0x80, 0x80,
+       0x80, 0x80, 0x80, 0x80, 0x80, 0x80, 0x80, 0x80, 0x80, 0x80, 0x80, 0x80,
+       0x80, 0x80, 0x80, 0x80, 0x80, 0x80, 0x80, 0x80, 0x80, 0x80, 0x80, 0x80,
+       0x80, 0x80, 0x80, 0x80, 0x80, 0x80, 0x80, 0x80, 0x80, 0x80, 0x80, 0x80,
+       0x80, 0x80, 0x80, 0x80, 0x80, 0x80, 0x80, 0x80, 0x80, 0x80, 0x80, 0x80,
+       0x80, 0x80, 0x80, 0x80, 0x80, 0x80, 0x80, 0x80, 0x80, 0x80, 0x80, 0x80,
+       0x80, 0x80, 0x80, 0x80, 0x80, 0x80, 0x80, 0x80, 0x80, 0x80, 0x80, 0x80,
+       0x80, 0x80, 0x80, 0x80, 0x80, 0x80, 0x80, 0x80, 0x80, 0x80, 0x80, 0x80,
+       0x80, 0x80, 0x80, 0x80, 0x80, 0x80, 0x80, 0x80, 0x80, 0x80, 0x80, 0x80,
+       0x80, 0x80, 0x80, 0x80, 0x80, 0x80, 0x80, 0x80, 0x80, 0x80, 0x80, 0x80,
+       0x80, 0x80, 0x80, 0x80, 0x80, 0x80, 0x80, 0x80, 0x80, 0x80, 0x80, 0x80,
+       0x80, 0x80, 0x80, 0x80, 0x80, 0x80, 0x80, 0x80, 0x80, 0x80, 0x80, 0x80,
+       0x80, 0x80, 0x80, 0x80, 0x80, 0x80, 0x80, 0x80, 0x00
+} ;
+
+static inline void
+ulaw2s_array (unsigned char *buffer, int count, short *ptr)
+{      while (--count >= 0)
+               ptr [count] = ulaw_decode [(int) buffer [count]] ;
+} /* ulaw2s_array */
+
+static inline void
+ulaw2i_array (unsigned char *buffer, int count, int *ptr)
+{      while (--count >= 0)
+               ptr [count] = ulaw_decode [buffer [count]] << 16 ;
+} /* ulaw2i_array */
+
+static inline void
+ulaw2f_array (unsigned char *buffer, int count, float *ptr, float normfact)
+{      while (--count >= 0)
+               ptr [count] = normfact * ulaw_decode [(int) buffer [count]] ;
+} /* ulaw2f_array */
+
+static inline void
+ulaw2d_array (const unsigned char *buffer, int count, double *ptr, double normfact)
+{      while (--count >= 0)
+               ptr [count] = normfact * ulaw_decode [(int) buffer [count]] ;
+} /* ulaw2d_array */
+
+static inline void
+s2ulaw_array (const short *ptr, int count, unsigned char *buffer)
+{      while (--count >= 0)
+       {       if (ptr [count] >= 0)
+                       buffer [count] = ulaw_encode [ptr [count] / 4] ;
+               else
+                       buffer [count] = 0x7F & ulaw_encode [ptr [count] / -4] ;
+               } ;
+} /* s2ulaw_array */
+
+static inline void
+i2ulaw_array (const int *ptr, int count, unsigned char *buffer)
+{      while (--count >= 0)
+       {       if (ptr [count] >= 0)
+                       buffer [count] = ulaw_encode [ptr [count] >> (16 + 2)] ;
+               else
+                       buffer [count] = 0x7F & ulaw_encode [-ptr [count] >> (16 + 2)] ;
+               } ;
+} /* i2ulaw_array */
+
+static inline void
+f2ulaw_array (const float *ptr, int count, unsigned char *buffer, float normfact)
+{      while (--count >= 0)
+       {       if (ptr [count] >= 0)
+                       buffer [count] = ulaw_encode [lrintf (normfact * ptr [count])] ;
+               else
+                       buffer [count] = 0x7F & ulaw_encode [- lrintf (normfact * ptr [count])] ;
+               } ;
+} /* f2ulaw_array */
+
+static inline void
+d2ulaw_array (const double *ptr, int count, unsigned char *buffer, double normfact)
+{      while (--count >= 0)
+       {       if (ptr [count] >= 0)
+                       buffer [count] = ulaw_encode [lrint (normfact * ptr [count])] ;
+               else
+                       buffer [count] = 0x7F & ulaw_encode [- lrint (normfact * ptr [count])] ;
+               } ;
+} /* d2ulaw_array */
+
+/*==============================================================================
+*/
+
+static sf_count_t
+ulaw_read_ulaw2s (SF_PRIVATE *psf, short *ptr, sf_count_t len)
+{      int                     bufferlen, readcount ;
+       sf_count_t      total = 0 ;
+
+       bufferlen = ARRAY_LEN (psf->u.ucbuf) ;
+
+       while (len > 0)
+       {       if (len < bufferlen)
+                       bufferlen = (int) len ;
+               readcount = psf_fread (psf->u.ucbuf, 1, bufferlen, psf) ;
+               ulaw2s_array (psf->u.ucbuf, readcount, ptr + total) ;
+               total += readcount ;
+               if (readcount < bufferlen)
+                       break ;
+               len -= readcount ;
+               } ;
+
+       return total ;
+} /* ulaw_read_ulaw2s */
+
+static sf_count_t
+ulaw_read_ulaw2i (SF_PRIVATE *psf, int *ptr, sf_count_t len)
+{      int                     bufferlen, readcount ;
+       sf_count_t      total = 0 ;
+
+       bufferlen = ARRAY_LEN (psf->u.ucbuf) ;
+
+       while (len > 0)
+       {       if (len < bufferlen)
+                       bufferlen = (int) len ;
+               readcount = psf_fread (psf->u.ucbuf, 1, bufferlen, psf) ;
+               ulaw2i_array (psf->u.ucbuf, readcount, ptr + total) ;
+               total += readcount ;
+               if (readcount < bufferlen)
+                       break ;
+               len -= readcount ;
+               } ;
+
+       return total ;
+} /* ulaw_read_ulaw2i */
+
+static sf_count_t
+ulaw_read_ulaw2f (SF_PRIVATE *psf, float *ptr, sf_count_t len)
+{      int                     bufferlen, readcount ;
+       sf_count_t      total = 0 ;
+       float   normfact ;
+
+       normfact = (psf->norm_float == SF_TRUE) ? 1.0 / ((float) 0x8000) : 1.0 ;
+
+       bufferlen = ARRAY_LEN (psf->u.ucbuf) ;
+
+       while (len > 0)
+       {       if (len < bufferlen)
+                       bufferlen = (int) len ;
+               readcount = psf_fread (psf->u.ucbuf, 1, bufferlen, psf) ;
+               ulaw2f_array (psf->u.ucbuf, readcount, ptr + total, normfact) ;
+               total += readcount ;
+               if (readcount < bufferlen)
+                       break ;
+               len -= readcount ;
+               } ;
+
+       return total ;
+} /* ulaw_read_ulaw2f */
+
+static sf_count_t
+ulaw_read_ulaw2d (SF_PRIVATE *psf, double *ptr, sf_count_t len)
+{      int                     bufferlen, readcount ;
+       sf_count_t      total = 0 ;
+       double  normfact ;
+
+       normfact = (psf->norm_double) ? 1.0 / ((double) 0x8000) : 1.0 ;
+       bufferlen = ARRAY_LEN (psf->u.ucbuf) ;
+
+       while (len > 0)
+       {       if (len < bufferlen)
+                       bufferlen = (int) len ;
+               readcount = psf_fread (psf->u.ucbuf, 1, bufferlen, psf) ;
+               ulaw2d_array (psf->u.ucbuf, readcount, ptr + total, normfact) ;
+               total += readcount ;
+               if (readcount < bufferlen)
+                       break ;
+               len -= readcount ;
+               } ;
+
+       return total ;
+} /* ulaw_read_ulaw2d */
+
+/*=============================================================================================
+*/
+
+static sf_count_t
+ulaw_write_s2ulaw      (SF_PRIVATE *psf, const short *ptr, sf_count_t len)
+{      int                     bufferlen, writecount ;
+       sf_count_t      total = 0 ;
+
+       bufferlen = ARRAY_LEN (psf->u.ucbuf) ;
+
+       while (len > 0)
+       {       if (len < bufferlen)
+                       bufferlen = (int) len ;
+               s2ulaw_array (ptr + total, bufferlen, psf->u.ucbuf) ;
+               writecount = psf_fwrite (psf->u.ucbuf, 1, bufferlen, psf) ;
+               total += writecount ;
+               if (writecount < bufferlen)
+                       break ;
+               len -= writecount ;
+               } ;
+
+       return total ;
+} /* ulaw_write_s2ulaw */
+
+static sf_count_t
+ulaw_write_i2ulaw      (SF_PRIVATE *psf, const int *ptr, sf_count_t len)
+{      int                     bufferlen, writecount ;
+       sf_count_t      total = 0 ;
+
+       bufferlen = ARRAY_LEN (psf->u.ucbuf) ;
+
+       while (len > 0)
+       {       if (len < bufferlen)
+                       bufferlen = (int) len ;
+               i2ulaw_array (ptr + total, bufferlen, psf->u.ucbuf) ;
+               writecount = psf_fwrite (psf->u.ucbuf, 1, bufferlen, psf) ;
+               total += writecount ;
+               if (writecount < bufferlen)
+                       break ;
+               len -= writecount ;
+               } ;
+
+       return total ;
+} /* ulaw_write_i2ulaw */
+
+static sf_count_t
+ulaw_write_f2ulaw      (SF_PRIVATE *psf, const float *ptr, sf_count_t len)
+{      int                     bufferlen, writecount ;
+       sf_count_t      total = 0 ;
+       float   normfact ;
+
+       /* Factor in a divide by 4. */
+       normfact = (psf->norm_float == SF_TRUE) ? (0.25 * 0x7FFF) : 0.25 ;
+
+       bufferlen = ARRAY_LEN (psf->u.ucbuf) ;
+
+       while (len > 0)
+       {       if (len < bufferlen)
+                       bufferlen = (int) len ;
+               f2ulaw_array (ptr + total, bufferlen, psf->u.ucbuf, normfact) ;
+               writecount = psf_fwrite (psf->u.ucbuf, 1, bufferlen, psf) ;
+               total += writecount ;
+               if (writecount < bufferlen)
+                       break ;
+               len -= writecount ;
+               } ;
+
+       return total ;
+} /* ulaw_write_f2ulaw */
+
+static sf_count_t
+ulaw_write_d2ulaw      (SF_PRIVATE *psf, const double *ptr, sf_count_t len)
+{      int                     bufferlen, writecount ;
+       sf_count_t      total = 0 ;
+       double  normfact ;
+
+       /* Factor in a divide by 4. */
+       normfact = (psf->norm_double) ? (0.25 * 0x7FFF) : 0.25 ;
+
+       bufferlen = ARRAY_LEN (psf->u.ucbuf) ;
+
+       while (len > 0)
+       {       if (len < bufferlen)
+                       bufferlen = (int) len ;
+               d2ulaw_array (ptr + total, bufferlen, psf->u.ucbuf, normfact) ;
+               writecount = psf_fwrite (psf->u.ucbuf, 1, bufferlen, psf) ;
+               total += writecount ;
+               if (writecount < bufferlen)
+                       break ;
+               len -= writecount ;
+               } ;
+
+       return total ;
+} /* ulaw_write_d2ulaw */
+
+/*
+** Do not edit or modify anything in this comment block.
+** The arch-tag line is a file identity tag for the GNU Arch 
+** revision control system.
+**
+** arch-tag: 655cc790-f058-45e8-89c9-86967cccc37e
+*/
diff --git a/libs/libsndfile/src/voc.c b/libs/libsndfile/src/voc.c
new file mode 100644 (file)
index 0000000..e1388c4
--- /dev/null
@@ -0,0 +1,878 @@
+/*
+** Copyright (C) 2001-2004 Erik de Castro Lopo <erikd@mega-nerd.com>
+**
+** This program is free software; you can redistribute it and/or modify
+** it under the terms of the GNU Lesser General Public License as published by
+** the Free Software Foundation; either version 2.1 of the License, or
+** (at your option) any later version.
+**
+** This program is distributed in the hope that it will be useful,
+** but WITHOUT ANY WARRANTY; without even the implied warranty of
+** MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+** GNU Lesser General Public License for more details.
+**
+** You should have received a copy of the GNU Lesser General Public License
+** along with this program; if not, write to the Free Software
+** Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA.
+*/
+
+/*     RANT:
+**     The VOC file format is the most brain damaged format I have yet had to deal
+**     with. No one programmer could have bee stupid enough to put this together.
+**     Instead it looks like a series of manic, dyslexic assembly language programmers
+**     hacked it to fit their needs.
+**     Utterly woeful.
+*/
+
+#include "sfconfig.h"
+
+#include <stdio.h>
+#include <stdlib.h>
+#include <string.h>
+
+#include "sndfile.h"
+#include "sfendian.h"
+#include "common.h"
+
+
+/*------------------------------------------------------------------------------
+ * Typedefs for file chunks.
+*/
+
+#define        VOC_MAX_SECTIONS        200
+
+enum
+{      VOC_TERMINATOR          = 0,
+       VOC_SOUND_DATA          = 1,
+       VOC_SOUND_CONTINUE      = 2,
+       VOC_SILENCE                     = 3,
+       VOC_MARKER                      = 4,
+       VOC_ASCII                       = 5,
+       VOC_REPEAT                      = 6,
+       VOC_END_REPEAT          = 7,
+       VOC_EXTENDED            = 8,
+       VOC_EXTENDED_II         = 9
+} ;
+
+typedef struct
+{      int     samples ;
+       int             offset ;        /* Offset of zero => silence. */
+} SND_DATA_BLOCKS ;
+
+typedef struct
+{      unsigned int    sections, section_types ;
+       int                             samplerate, channels, bitwidth ;
+       SND_DATA_BLOCKS blocks [VOC_MAX_SECTIONS] ;
+} VOC_DATA ;
+
+/*------------------------------------------------------------------------------
+ * Private static functions.
+*/
+
+static int     voc_close       (SF_PRIVATE *psf) ;
+static int voc_write_header (SF_PRIVATE *psf, int calc_length) ;
+static int voc_read_header     (SF_PRIVATE *psf) ;
+
+static const char* voc_encoding2str (int encoding) ;
+
+#if 0
+
+/*     These functions would be required for files with more than one VOC_SOUND_DATA
+**     segment. Not sure whether to bother implementing this.
+*/
+
+static int     voc_multi_init (SF_PRIVATE *psf, VOC_DATA *pvoc) ;
+
+static int     voc_multi_read_uc2s             (SF_PRIVATE *psf, short *ptr, int len) ;
+static int     voc_multi_read_les2s    (SF_PRIVATE *psf, short *ptr, int len) ;
+
+static int     voc_multi_read_uc2i             (SF_PRIVATE *psf, int *ptr, int len) ;
+static int     voc_multi_read_les2i    (SF_PRIVATE *psf, int *ptr, int len) ;
+
+static int     voc_multi_read_uc2f             (SF_PRIVATE *psf, float *ptr, int len) ;
+static int     voc_multi_read_les2f    (SF_PRIVATE *psf, float *ptr, int len) ;
+
+static int     voc_multi_read_uc2d             (SF_PRIVATE *psf, double *ptr, int len) ;
+static int     voc_multi_read_les2d    (SF_PRIVATE *psf, double *ptr, int len) ;
+#endif
+
+/*------------------------------------------------------------------------------
+** Public function.
+*/
+
+int
+voc_open       (SF_PRIVATE *psf)
+{      int subformat, error = 0 ;
+
+       if (psf->is_pipe)
+               return SFE_VOC_NO_PIPE ;
+
+       if (psf->mode == SFM_READ || (psf->mode == SFM_RDWR && psf->filelength > 0))
+       {       if ((error = voc_read_header (psf)))
+                       return error ;
+               } ;
+
+       subformat = psf->sf.format & SF_FORMAT_SUBMASK ;
+
+       if (psf->mode == SFM_WRITE || psf->mode == SFM_RDWR)
+       {       if ((psf->sf.format & SF_FORMAT_TYPEMASK) != SF_FORMAT_VOC)
+                       return  SFE_BAD_OPEN_FORMAT ;
+
+               psf->endian = SF_ENDIAN_LITTLE ;
+
+               if ((error = voc_write_header (psf, SF_FALSE)))
+                       return error ;
+
+               psf->write_header = voc_write_header ;
+               } ;
+
+       psf->blockwidth = psf->bytewidth * psf->sf.channels ;
+
+       psf->container_close = voc_close ;
+
+       switch (subformat)
+       {       case SF_FORMAT_PCM_U8 :
+               case SF_FORMAT_PCM_16 :
+                               error = pcm_init (psf) ;
+                               break ;
+
+               case SF_FORMAT_ALAW :
+                               error = alaw_init (psf) ;
+                               break ;
+
+               case SF_FORMAT_ULAW :
+                               error = ulaw_init (psf) ;
+                               break ;
+
+               default : return SFE_UNIMPLEMENTED ;
+               } ;
+
+       return error ;
+} /* voc_open */
+
+/*------------------------------------------------------------------------------
+*/
+
+static int
+voc_read_header        (SF_PRIVATE *psf)
+{      VOC_DATA        *pvoc ;
+       char    creative [20] ;
+       unsigned char block_type, rate_byte ;
+       short   version, checksum, encoding, dataoffset ;
+       int             offset ;
+
+       /* Set position to start of file to begin reading header. */
+       offset = psf_binheader_readf (psf, "pb", 0, creative, SIGNED_SIZEOF (creative)) ;
+
+       if (creative [sizeof (creative) - 1] != 0x1A)
+               return SFE_VOC_NO_CREATIVE ;
+
+       /* Terminate the string. */
+       creative [sizeof (creative) - 1] = 0 ;
+
+       if (strcmp ("Creative Voice File", creative))
+               return SFE_VOC_NO_CREATIVE ;
+
+       psf_log_printf (psf, "%s\n", creative) ;
+
+       offset += psf_binheader_readf (psf, "e222", &dataoffset, &version, &checksum) ;
+
+       psf->dataoffset = dataoffset ;
+
+       psf_log_printf (psf,    "dataoffset : %d\n"
+                                                       "version    : 0x%X\n"
+                                                       "checksum   : 0x%X\n", psf->dataoffset, version, checksum) ;
+
+       if (version != 0x010A && version != 0x0114)
+               return SFE_VOC_BAD_VERSION ;
+
+       if (! (psf->fdata = malloc (sizeof (VOC_DATA))))
+               return SFE_MALLOC_FAILED ;
+
+       pvoc = (VOC_DATA*) psf->fdata ;
+
+       memset (pvoc, 0, sizeof (VOC_DATA)) ;
+
+       /* Set the default encoding now. */
+       psf->sf.format = SF_FORMAT_VOC ; /* Major format */
+       encoding = SF_FORMAT_PCM_U8 ; /* Minor format */
+       psf->endian = SF_ENDIAN_LITTLE ;
+
+       while (1)
+       {       offset += psf_binheader_readf (psf, "1", &block_type) ;
+
+               switch (block_type)
+               {       case VOC_ASCII :
+                                       {       int size ;
+
+                                               offset += psf_binheader_readf (psf, "e3", &size) ;
+
+                                               psf_log_printf (psf, " ASCII : %d\n", size) ;
+
+                                               offset += psf_binheader_readf (psf, "b", psf->header, size) ;
+                                               psf->header [size] = 0 ;
+                                               psf_log_printf (psf, "  text : %s\n", psf->header) ;
+                                               } ;
+                                       continue ;
+
+                       case VOC_SOUND_DATA :
+                       case VOC_EXTENDED :
+                       case VOC_EXTENDED_II :
+                                       break ;
+
+                       default : psf_log_printf (psf, "*** Weird block marker (%d)\n", block_type) ;
+                       } ;
+
+               break ;
+               } ;
+
+       if (block_type == VOC_SOUND_DATA)
+       {       unsigned char compression ;
+               int     size ;
+
+               offset += psf_binheader_readf (psf, "e311", &size, &rate_byte, &compression) ;
+
+               psf->sf.samplerate = 1000000 / (256 - (rate_byte & 0xFF)) ;
+
+               psf_log_printf (psf, " Sound Data : %d\n  sr   : %d => %dHz\n  comp : %d\n",
+                                                               size, rate_byte, psf->sf.samplerate, compression) ;
+
+               if (offset + size - 1 > psf->filelength)
+               {       psf_log_printf (psf, "Seems to be a truncated file.\n") ;
+                       psf_log_printf (psf, "offset: %d    size: %d    sum: %d    filelength: %D\n", offset, size, offset + size, psf->filelength) ;
+                       return SFE_VOC_BAD_SECTIONS ;
+                       }
+               else if (offset + size - 1 < psf->filelength)
+               {       psf_log_printf (psf, "Seems to be a multi-segment file (#1).\n") ;
+                       psf_log_printf (psf, "offset: %d    size: %d    sum: %d    filelength: %D\n", offset, size, offset + size, psf->filelength) ;
+                       return SFE_VOC_BAD_SECTIONS ;
+                       } ;
+
+               psf->dataoffset = offset ;
+               psf->dataend    = psf->filelength - 1 ;
+
+               psf->sf.channels = 1 ;
+               psf->bytewidth = 1 ;
+
+               psf->sf.format = SF_FORMAT_VOC | SF_FORMAT_PCM_U8 ;
+
+               return 0 ;
+               } ;
+
+       if (block_type == VOC_EXTENDED)
+       {       unsigned char pack, stereo, compression ;
+               unsigned short rate_short ;
+               int             size ;
+
+               offset += psf_binheader_readf (psf, "e3211", &size, &rate_short, &pack, &stereo) ;
+
+               psf_log_printf (psf, " Extended : %d\n", size) ;
+               if (size == 4)
+                       psf_log_printf (psf, "  size   : 4\n") ;
+               else
+                       psf_log_printf (psf, "  size   : %d (should be 4)\n", size) ;
+
+               psf_log_printf (psf,    "  pack   : %d\n"
+                                                               "  stereo : %s\n", pack, (stereo ? "yes" : "no")) ;
+
+               if (stereo)
+               {       psf->sf.channels = 2 ;
+                       psf->sf.samplerate = 128000000 / (65536 - rate_short) ;
+                       }
+               else
+               {       psf->sf.channels = 1 ;
+                       psf->sf.samplerate = 256000000 / (65536 - rate_short) ;
+                       } ;
+
+               psf_log_printf (psf, "  sr     : %d => %dHz\n", (rate_short & 0xFFFF), psf->sf.samplerate) ;
+
+               offset += psf_binheader_readf (psf, "1", &block_type) ;
+
+               if (block_type != VOC_SOUND_DATA)
+               {       psf_log_printf (psf, "*** Expecting VOC_SOUND_DATA section.\n") ;
+                       return SFE_VOC_BAD_FORMAT ;
+                       } ;
+
+               offset += psf_binheader_readf (psf, "e311", &size, &rate_byte, &compression) ;
+
+               psf_log_printf (psf,    " Sound Data : %d\n"
+                                                               "  sr     : %d\n"
+                                                               "  comp   : %d\n", size, rate_byte, compression) ;
+
+
+               if (offset + size - 1 > psf->filelength)
+               {       psf_log_printf (psf, "Seems to be a truncated file.\n") ;
+                       psf_log_printf (psf, "offset: %d    size: %d    sum: %d    filelength: %D\n", offset, size, offset + size, psf->filelength) ;
+                       return SFE_VOC_BAD_SECTIONS ;
+                       }
+               else if (offset + size - 1 < psf->filelength)
+               {       psf_log_printf (psf, "Seems to be a multi-segment file (#2).\n") ;
+                       psf_log_printf (psf, "offset: %d    size: %d    sum: %d    filelength: %D\n", offset, size, offset + size, psf->filelength) ;
+                       return SFE_VOC_BAD_SECTIONS ;
+                       } ;
+
+               psf->dataoffset = offset ;
+               psf->dataend = psf->filelength - 1 ;
+
+               psf->bytewidth = 1 ;
+
+               psf->sf.format = SF_FORMAT_VOC | SF_FORMAT_PCM_U8 ;
+
+               return 0 ;
+               }
+
+       if (block_type == VOC_EXTENDED_II)
+       {       unsigned char bitwidth, channels ;
+               int size, fourbytes ;
+
+               offset += psf_binheader_readf (psf, "e341124", &size, &psf->sf.samplerate,
+                                                               &bitwidth, &channels, &encoding, &fourbytes) ;
+
+               if (size * 2 == psf->filelength - 39)
+               {       int temp_size = psf->filelength - 31 ;
+
+                       psf_log_printf (psf, " Extended II : %d (SoX bug: should be %d)\n", size, temp_size) ;
+                       size = temp_size ;
+                       }
+               else
+                       psf_log_printf (psf, " Extended II : %d\n", size) ;
+
+               psf_log_printf (psf,    "  sample rate : %d\n"
+                                                               "  bit width   : %d\n"
+                                                               "  channels    : %d\n", psf->sf.samplerate, bitwidth, channels) ;
+
+               if (bitwidth == 16 && encoding == 0)
+               {       encoding = 4 ;
+                       psf_log_printf (psf, "  encoding    : 0 (SoX bug: should be 4 for 16 bit signed PCM)\n") ;
+                       }
+               else
+                       psf_log_printf (psf, "  encoding    : %d => %s\n", encoding, voc_encoding2str (encoding)) ;
+
+
+               psf_log_printf (psf, "  fourbytes   : %X\n", fourbytes) ;
+
+               psf->sf.channels = channels ;
+
+               psf->dataoffset = offset ;
+               psf->dataend    = psf->filelength - 1 ;
+
+               if (size + 31 == psf->filelength + 1)
+               {       /* Hack for reading files produced using
+                       ** sf_command (SFC_UPDATE_HEADER_NOW).
+                       */
+                       psf_log_printf (psf, "Missing zero byte at end of file.\n") ;
+                       size = psf->filelength - 30 ;
+                       psf->dataend = 0 ;
+                       }
+               else if (size + 31 > psf->filelength)
+               {       psf_log_printf (psf, "Seems to be a truncated file.\n") ;
+                       size = psf->filelength - 31 ;
+                       }
+               else if (size + 31 < psf->filelength)
+                       psf_log_printf (psf, "Seems to be a multi-segment file (#3).\n") ;
+
+               switch (encoding)
+               {       case 0 :
+                                       psf->sf.format = SF_FORMAT_VOC | SF_FORMAT_PCM_U8 ;
+                                       psf->bytewidth = 1 ;
+                                       break ;
+
+                       case 4 :
+                                       psf->sf.format = SF_FORMAT_VOC | SF_FORMAT_PCM_16 ;
+                                       psf->bytewidth = 2 ;
+                                       break ;
+
+                       case 6 :
+                                       psf->sf.format = SF_FORMAT_VOC | SF_FORMAT_ALAW ;
+                                       psf->bytewidth = 1 ;
+                                       break ;
+
+                       case 7 :
+                                       psf->sf.format = SF_FORMAT_VOC | SF_FORMAT_ULAW ;
+                                       psf->bytewidth = 1 ;
+                                       break ;
+
+                       default : /* Unknown */
+                                       return SFE_UNKNOWN_FORMAT ;
+                                       break ;
+                       } ;
+
+               } ;
+
+       return 0 ;
+} /* voc_read_header */
+
+/*====================================================================================
+*/
+
+static int
+voc_write_header (SF_PRIVATE *psf, int calc_length)
+{      sf_count_t      current ;
+       int                     rate_const, subformat ;
+
+       current = psf_ftell (psf) ;
+
+       if (calc_length)
+       {       psf->filelength = psf_get_filelen (psf) ;
+
+               psf->datalength = psf->filelength - psf->dataoffset ;
+               if (psf->dataend)
+                       psf->datalength -= psf->filelength - psf->dataend ;
+
+               psf->sf.frames = psf->datalength / (psf->bytewidth * psf->sf.channels) ;
+               } ;
+
+       subformat = psf->sf.format & SF_FORMAT_SUBMASK ;
+       /* Reset the current header length to zero. */
+       psf->header [0] = 0 ;
+       psf->headindex = 0 ;
+       psf_fseek (psf, 0, SEEK_SET) ;
+
+       /* VOC marker and 0x1A byte. */
+       psf_binheader_writef (psf, "eb1", "Creative Voice File", 19, 0x1A) ;
+
+       /* Data offset, version and other. */
+       psf_binheader_writef (psf, "e222", 26, 0x0114, 0x111F) ;
+
+       /*      Use same logic as SOX.
+       **      If the file is mono 8 bit data, use VOC_SOUND_DATA.
+       **      If the file is mono 16 bit data, use VOC_EXTENED.
+       **      Otherwise use VOC_EXTENED_2.
+       */
+
+       if (subformat == SF_FORMAT_PCM_U8 && psf->sf.channels == 1)
+       {       /* samplerate = 1000000 / (256 - rate_const) ; */
+               rate_const = 256 - 1000000 / psf->sf.samplerate ;
+
+               /* First type marker, length, rate_const and compression */
+               psf_binheader_writef (psf, "e1311", VOC_SOUND_DATA, (int) (psf->datalength + 1), rate_const, 0) ;
+               }
+       else if (subformat == SF_FORMAT_PCM_U8 && psf->sf.channels == 2)
+       {       /* sample_rate = 128000000 / (65536 - rate_short) ; */
+               rate_const = 65536 - 128000000 / psf->sf.samplerate ;
+
+               /* First write the VOC_EXTENDED section
+               **              marker, length, rate_const and compression
+               */
+               psf_binheader_writef (psf, "e13211", VOC_EXTENDED, 4, rate_const, 0, 1) ;
+
+               /* samplerate = 1000000 / (256 - rate_const) ; */
+               rate_const = 256 - 1000000 / psf->sf.samplerate ;
+
+               /*      Now write the VOC_SOUND_DATA section
+               **              marker, length, rate_const and compression
+               */
+               psf_binheader_writef (psf, "e1311", VOC_SOUND_DATA, (int) (psf->datalength + 1), rate_const, 0) ;
+               }
+       else
+       {       int length ;
+
+               if (psf->sf.channels < 1 || psf->sf.channels > 2)
+                       return SFE_CHANNEL_COUNT ;
+
+               switch (subformat)
+               {       case SF_FORMAT_PCM_U8 :
+                                       psf->bytewidth = 1 ;
+                                       length = psf->sf.frames * psf->sf.channels * psf->bytewidth + 12 ;
+                                       /* Marker, length, sample rate, bitwidth, stereo flag, encoding and fourt zero bytes. */
+                                       psf_binheader_writef (psf, "e1341124", VOC_EXTENDED_II, length, psf->sf.samplerate, 16, psf->sf.channels, 4, 0) ;
+                                       break ;
+
+                       case SF_FORMAT_PCM_16 :
+                                       psf->bytewidth = 2 ;
+                                       length = psf->sf.frames * psf->sf.channels * psf->bytewidth + 12 ;
+                                       /* Marker, length, sample rate, bitwidth, stereo flag, encoding and fourt zero bytes. */
+                                       psf_binheader_writef (psf, "e1341124", VOC_EXTENDED_II, length, psf->sf.samplerate, 16, psf->sf.channels, 4, 0) ;
+                                       break ;
+
+                       case SF_FORMAT_ALAW :
+                                       psf->bytewidth = 1 ;
+                                       length = psf->sf.frames * psf->sf.channels * psf->bytewidth + 12 ;
+                                       psf_binheader_writef (psf, "e1341124", VOC_EXTENDED_II, length, psf->sf.samplerate, 8, psf->sf.channels, 6, 0) ;
+                                       break ;
+
+                       case SF_FORMAT_ULAW :
+                                       psf->bytewidth = 1 ;
+                                       length = psf->sf.frames * psf->sf.channels * psf->bytewidth + 12 ;
+                                       psf_binheader_writef (psf, "e1341124", VOC_EXTENDED_II, length, psf->sf.samplerate, 8, psf->sf.channels, 7, 0) ;
+                                       break ;
+
+                       default : return SFE_UNIMPLEMENTED ;
+                       } ;
+               } ;
+
+       psf_fwrite (psf->header, psf->headindex, 1, psf) ;
+
+       if (psf->error)
+               return psf->error ;
+
+       psf->dataoffset = psf->headindex ;
+
+       if (current > 0)
+               psf_fseek (psf, current, SEEK_SET) ;
+
+       return psf->error ;
+} /* voc_write_header */
+
+static int
+voc_close      (SF_PRIVATE *psf)
+{
+       if (psf->mode == SFM_WRITE || psf->mode == SFM_RDWR)
+       {       /*  Now we know for certain the length of the file we can re-write
+               **      correct values for the FORM, 8SVX and BODY chunks.
+               */
+               unsigned byte = VOC_TERMINATOR ;
+
+
+               psf_fseek (psf, 0, SEEK_END) ;
+
+               /* Write terminator */
+               psf_fwrite (&byte, 1, 1, psf) ;
+
+               voc_write_header (psf, SF_TRUE) ;
+               } ;
+
+       return 0 ;
+} /* voc_close */
+
+static const   char*
+voc_encoding2str (int encoding)
+{
+       switch (encoding)
+       {       case 0 :        return "8 bit unsigned PCM" ;
+               case 4 :        return "16 bit signed PCM" ;
+               case 6 :        return "A-law" ;
+               case 7 :        return "u-law" ;
+               default :       break ;
+               }
+       return "*** Unknown ***" ;
+} /* voc_encoding2str */
+
+/*====================================================================================
+*/
+
+#if 0
+static int
+voc_multi_init (SF_PRIVATE *psf, VOC_DATA *pvoc)
+{
+       psf->sf.frames = 0 ;
+
+       if (pvoc->bitwidth == 8)
+       {       psf->read_short         = voc_multi_read_uc2s ;
+               psf->read_int           = voc_multi_read_uc2i ;
+               psf->read_float         = voc_multi_read_uc2f ;
+               psf->read_double        = voc_multi_read_uc2d ;
+               return 0 ;
+               } ;
+
+       if (pvoc->bitwidth == 16)
+       {       psf->read_short         = voc_multi_read_les2s ;
+               psf->read_int           = voc_multi_read_les2i ;
+               psf->read_float         = voc_multi_read_les2f ;
+               psf->read_double        = voc_multi_read_les2d ;
+               return 0 ;
+               } ;
+
+       psf_log_printf (psf, "Error : bitwith != 8 && bitwidth != 16.\n") ;
+
+       return SFE_UNIMPLEMENTED ;
+} /* voc_multi_read_int */
+
+/*------------------------------------------------------------------------------------
+*/
+
+static int
+voc_multi_read_uc2s (SF_PRIVATE *psf, short *ptr, int len)
+{
+
+       return 0 ;
+} /* voc_multi_read_uc2s */
+
+static int
+voc_multi_read_les2s (SF_PRIVATE *psf, short *ptr, int len)
+{
+
+       return 0 ;
+} /* voc_multi_read_les2s */
+
+
+static int
+voc_multi_read_uc2i (SF_PRIVATE *psf, int *ptr, int len)
+{
+
+       return 0 ;
+} /* voc_multi_read_uc2i */
+
+static int
+voc_multi_read_les2i (SF_PRIVATE *psf, int *ptr, int len)
+{
+
+       return 0 ;
+} /* voc_multi_read_les2i */
+
+
+static int
+voc_multi_read_uc2f (SF_PRIVATE *psf, float *ptr, int len)
+{
+
+       return 0 ;
+} /* voc_multi_read_uc2f */
+
+static int
+voc_multi_read_les2f (SF_PRIVATE *psf, float *ptr, int len)
+{
+
+       return 0 ;
+} /* voc_multi_read_les2f */
+
+
+static int
+voc_multi_read_uc2d (SF_PRIVATE *psf, double *ptr, int len)
+{
+
+       return 0 ;
+} /* voc_multi_read_uc2d */
+
+static int
+voc_multi_read_les2d (SF_PRIVATE *psf, double *ptr, int len)
+{
+
+       return 0 ;
+} /* voc_multi_read_les2d */
+
+#endif
+
+/*------------------------------------------------------------------------------------
+
+Creative Voice (VOC) file format
+--------------------------------
+
+~From: galt@dsd.es.com
+
+(byte numbers are hex!)
+
+    HEADER (bytes 00-19)
+    Series of DATA BLOCKS (bytes 1A+) [Must end w/ Terminator Block]
+
+- ---------------------------------------------------------------
+
+HEADER:
+=======
+     byte #     Description
+     ------     ------------------------------------------
+     00-12      "Creative Voice File"
+     13         1A (eof to abort printing of file)
+     14-15      Offset of first datablock in .voc file (std 1A 00
+                in Intel Notation)
+     16-17      Version number (minor,major) (VOC-HDR puts 0A 01)
+     18-19      1's Comp of Ver. # + 1234h (VOC-HDR puts 29 11)
+
+- ---------------------------------------------------------------
+
+DATA BLOCK:
+===========
+
+   Data Block:  TYPE(1-byte), SIZE(3-bytes), INFO(0+ bytes)
+   NOTE: Terminator Block is an exception -- it has only the TYPE byte.
+
+      TYPE   Description     Size (3-byte int)   Info
+      ----   -----------     -----------------   -----------------------
+      00     Terminator      (NONE)              (NONE)
+      01     Sound data      2+length of data    *
+      02     Sound continue  length of data      Voice Data
+      03     Silence         3                   **
+      04     Marker          2                   Marker# (2 bytes)
+      05     ASCII           length of string    null terminated string
+      06     Repeat          2                   Count# (2 bytes)
+      07     End repeat      0                   (NONE)
+      08     Extended        4                   ***
+
+      *Sound Info Format:
+       ---------------------
+       00   Sample Rate
+       01   Compression Type
+       02+  Voice Data
+
+      **Silence Info Format:
+      ----------------------------
+      00-01  Length of silence - 1
+      02     Sample Rate
+
+
+    ***Extended Info Format:
+       ---------------------
+       00-01  Time Constant: Mono: 65536 - (256000000/sample_rate)
+                             Stereo: 65536 - (25600000/(2*sample_rate))
+       02     Pack
+       03     Mode: 0 = mono
+                    1 = stereo
+
+
+  Marker#           -- Driver keeps the most recent marker in a status byte
+  Count#            -- Number of repetitions + 1
+                         Count# may be 1 to FFFE for 0 - FFFD repetitions
+                         or FFFF for endless repetitions
+  Sample Rate       -- SR byte = 256-(1000000/sample_rate)
+  Length of silence -- in units of sampling cycle
+  Compression Type  -- of voice data
+                         8-bits    = 0
+                         4-bits    = 1
+                         2.6-bits  = 2
+                         2-bits    = 3
+                         Multi DAC = 3+(# of channels) [interesting--
+                                       this isn't in the developer's manual]
+
+
+---------------------------------------------------------------------------------
+Addendum submitted by Votis Kokavessis:
+
+After some experimenting with .VOC files I found out that there is a Data Block
+Type 9, which is not covered in the VOC.TXT file. Here is what I was able to discover
+about this block type:
+
+
+TYPE: 09
+SIZE: 12 + length of data
+INFO: 12 (twelve) bytes
+
+INFO STRUCTURE:
+
+Bytes 0-1: (Word) Sample Rate (e.g. 44100)
+Bytes 2-3: zero (could be that bytes 0-3 are a DWord for Sample Rate)
+Byte 4: Sample Size in bits (e.g. 16)
+Byte 5: Number of channels (e.g. 1 for mono, 2 for stereo)
+Byte 6: Unknown (equal to 4 in all files I examined)
+Bytes 7-11: zero
+
+
+-------------------------------------------------------------------------------------*/
+
+/*=====================================================================================
+**=====================================================================================
+**=====================================================================================
+**=====================================================================================
+*/
+
+/*------------------------------------------------------------------------
+The following is taken from the Audio File Formats FAQ dated 2-Jan-1995
+and submitted by Guido van Rossum <guido@cwi.nl>.
+--------------------------------------------------------------------------
+Creative Voice (VOC) file format
+--------------------------------
+
+From: galt@dsd.es.com
+
+(byte numbers are hex!)
+
+    HEADER (bytes 00-19)
+    Series of DATA BLOCKS (bytes 1A+) [Must end w/ Terminator Block]
+
+- ---------------------------------------------------------------
+
+HEADER:
+-------
+     byte #     Description
+     ------     ------------------------------------------
+     00-12      "Creative Voice File"
+     13         1A (eof to abort printing of file)
+     14-15      Offset of first datablock in .voc file (std 1A 00
+                in Intel Notation)
+     16-17      Version number (minor,major) (VOC-HDR puts 0A 01)
+     18-19      2's Comp of Ver. # + 1234h (VOC-HDR puts 29 11)
+
+- ---------------------------------------------------------------
+
+DATA BLOCK:
+-----------
+
+   Data Block:  TYPE(1-byte), SIZE(3-bytes), INFO(0+ bytes)
+   NOTE: Terminator Block is an exception -- it has only the TYPE byte.
+
+      TYPE   Description     Size (3-byte int)   Info
+      ----   -----------     -----------------   -----------------------
+      00     Terminator      (NONE)              (NONE)
+      01     Sound data      2+length of data    *
+      02     Sound continue  length of data      Voice Data
+      03     Silence         3                   **
+      04     Marker          2                   Marker# (2 bytes)
+      05     ASCII           length of string    null terminated string
+      06     Repeat          2                   Count# (2 bytes)
+      07     End repeat      0                   (NONE)
+      08     Extended        4                   ***
+
+      *Sound Info Format:       **Silence Info Format:
+       ---------------------      ----------------------------
+       00   Sample Rate           00-01  Length of silence - 1
+       01   Compression Type      02     Sample Rate
+       02+  Voice Data
+
+    ***Extended Info Format:
+       ---------------------
+       00-01  Time Constant: Mono: 65536 - (256000000/sample_rate)
+                             Stereo: 65536 - (25600000/(2*sample_rate))
+       02     Pack
+       03     Mode: 0 = mono
+                    1 = stereo
+
+
+  Marker#           -- Driver keeps the most recent marker in a status byte
+  Count#            -- Number of repetitions + 1
+                         Count# may be 1 to FFFE for 0 - FFFD repetitions
+                         or FFFF for endless repetitions
+  Sample Rate       -- SR byte = 256-(1000000/sample_rate)
+  Length of silence -- in units of sampling cycle
+  Compression Type  -- of voice data
+                         8-bits    = 0
+                         4-bits    = 1
+                         2.6-bits  = 2
+                         2-bits    = 3
+                         Multi DAC = 3+(# of channels) [interesting--
+                                       this isn't in the developer's manual]
+
+Detailed description of new data blocks (VOC files version 1.20 and above):
+
+        (Source is fax from Barry Boone at Creative Labs, 405/742-6622)
+
+BLOCK 8 - digitized sound attribute extension, must preceed block 1.
+          Used to define stereo, 8 bit audio
+        BYTE bBlockID;       // = 8
+        BYTE nBlockLen[3];   // 3 byte length
+        WORD wTimeConstant;  // time constant = same as block 1
+        BYTE bPackMethod;    // same as in block 1
+        BYTE bVoiceMode;     // 0-mono, 1-stereo
+
+        Data is stored left, right
+
+BLOCK 9 - data block that supersedes blocks 1 and 8.
+          Used for stereo, 16 bit.
+
+        BYTE bBlockID;          // = 9
+        BYTE nBlockLen[3];      // length 12 plus length of sound
+        DWORD dwSamplesPerSec;  // samples per second, not time const.
+        BYTE bBitsPerSample;    // e.g., 8 or 16
+        BYTE bChannels;         // 1 for mono, 2 for stereo
+        WORD wFormat;           // see below
+        BYTE reserved[4];       // pad to make block w/o data
+                                // have a size of 16 bytes
+
+        Valid values of wFormat are:
+
+                0x0000  8-bit unsigned PCM
+                0x0001  Creative 8-bit to 4-bit ADPCM
+                0x0002  Creative 8-bit to 3-bit ADPCM
+                0x0003  Creative 8-bit to 2-bit ADPCM
+                0x0004  16-bit signed PCM
+                0x0006  CCITT a-Law
+                0x0007  CCITT u-Law
+                0x02000 Creative 16-bit to 4-bit ADPCM
+
+        Data is stored left, right
+
+------------------------------------------------------------------------*/
+/*
+** Do not edit or modify anything in this comment block.
+** The arch-tag line is a file identity tag for the GNU Arch 
+** revision control system.
+**
+** arch-tag: 40a50167-a81c-463a-9e1d-3282ff84e09d
+*/
diff --git a/libs/libsndfile/src/vox_adpcm.c b/libs/libsndfile/src/vox_adpcm.c
new file mode 100644 (file)
index 0000000..f743a72
--- /dev/null
@@ -0,0 +1,537 @@
+/*
+** Copyright (C) 2002-2005 Erik de Castro Lopo <erikd@mega-nerd.com>
+**
+** This program is free software; you can redistribute it and/or modify
+** it under the terms of the GNU Lesser General Public License as published by
+** the Free Software Foundation; either version 2.1 of the License, or
+** (at your option) any later version.
+**
+** This program is distributed in the hope that it will be useful,
+** but WITHOUT ANY WARRANTY; without even the implied warranty of
+** MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+** GNU Lesser General Public License for more details.
+**
+** You should have received a copy of the GNU Lesser General Public License
+** along with this program; if not, write to the Free Software
+** Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA.
+*/
+
+/*
+**     This is the OKI / Dialogic ADPCM encoder/decoder. It converts from
+**     12 bit linear sample data to a 4 bit ADPCM.
+**
+**     Implemented from the description found here:
+**
+**             http://www.comptek.ru:8100/telephony/tnotes/tt1-13.html
+**
+**     and compared against the encoder/decoder found here:
+**
+**             http://ibiblio.org/pub/linux/apps/sound/convert/vox.tar.gz
+*/
+
+#include       "sfconfig.h"
+
+#include       <stdio.h>
+#include       <stdlib.h>
+#include       <string.h>
+
+#include       "sndfile.h"
+#include       "sfendian.h"
+#include       "float_cast.h"
+#include       "common.h"
+
+#define                VOX_DATA_LEN    2048
+#define                PCM_DATA_LEN    (VOX_DATA_LEN *2)
+
+typedef struct
+{      short last ;
+       short step_index ;
+
+       int             vox_bytes, pcm_samples ;
+
+       unsigned char   vox_data [VOX_DATA_LEN] ;
+       short                   pcm_data [PCM_DATA_LEN] ;
+} VOX_ADPCM_PRIVATE ;
+
+static int vox_adpcm_encode_block (VOX_ADPCM_PRIVATE *pvox) ;
+static int vox_adpcm_decode_block (VOX_ADPCM_PRIVATE *pvox) ;
+
+static short vox_adpcm_decode (char code, VOX_ADPCM_PRIVATE *pvox) ;
+static char vox_adpcm_encode (short samp, VOX_ADPCM_PRIVATE *pvox) ;
+
+static sf_count_t vox_read_s (SF_PRIVATE *psf, short *ptr, sf_count_t len) ;
+static sf_count_t vox_read_i (SF_PRIVATE *psf, int *ptr, sf_count_t len) ;
+static sf_count_t vox_read_f (SF_PRIVATE *psf, float *ptr, sf_count_t len) ;
+static sf_count_t vox_read_d (SF_PRIVATE *psf, double *ptr, sf_count_t len) ;
+
+static sf_count_t vox_write_s (SF_PRIVATE *psf, const short *ptr, sf_count_t len) ;
+static sf_count_t vox_write_i (SF_PRIVATE *psf, const int *ptr, sf_count_t len) ;
+static sf_count_t vox_write_f (SF_PRIVATE *psf, const float *ptr, sf_count_t len) ;
+static sf_count_t vox_write_d (SF_PRIVATE *psf, const double *ptr, sf_count_t len) ;
+
+static int vox_read_block (SF_PRIVATE *psf, VOX_ADPCM_PRIVATE *pvox, short *ptr, int len) ;
+
+/*============================================================================================
+** Predefined OKI ADPCM encoder/decoder tables.
+*/
+
+static short step_size_table [49] =
+{      16, 17, 19, 21, 23, 25, 28, 31, 34, 37, 41, 45, 50, 55, 60,
+       66, 73, 80, 88, 97, 107, 118, 130, 143, 157, 173, 190, 209,
+       230, 253, 279, 307, 337, 371, 408, 449, 494, 544, 598, 658,
+       724, 796, 876, 963, 1060, 1166, 1282, 1408, 1552
+} ; /* step_size_table */
+
+static short step_adjust_table [8] =
+{      -1, -1, -1, -1, 2, 4, 6, 8
+} ; /* step_adjust_table */
+
+/*------------------------------------------------------------------------------
+*/
+
+int
+vox_adpcm_init (SF_PRIVATE *psf)
+{      VOX_ADPCM_PRIVATE *pvox = NULL ;
+
+       if (psf->mode == SFM_RDWR)
+               return SFE_BAD_MODE_RW ;
+
+       if (psf->mode == SFM_WRITE && psf->sf.channels != 1)
+               return SFE_CHANNEL_COUNT ;
+
+       if ((pvox = malloc (sizeof (VOX_ADPCM_PRIVATE))) == NULL)
+               return SFE_MALLOC_FAILED ;
+
+       psf->fdata = (void*) pvox ;
+       memset (pvox, 0, sizeof (VOX_ADPCM_PRIVATE)) ;
+
+       if (psf->mode == SFM_WRITE)
+       {       psf->write_short        = vox_write_s ;
+               psf->write_int          = vox_write_i ;
+               psf->write_float        = vox_write_f ;
+               psf->write_double       = vox_write_d ;
+               }
+       else
+       {       psf_log_printf (psf, "Header-less OKI Dialogic ADPCM encoded file.\n") ;
+               psf_log_printf (psf, "Setting up for 8kHz, mono, Vox ADPCM.\n") ;
+
+               psf->read_short         = vox_read_s ;
+               psf->read_int           = vox_read_i ;
+               psf->read_float         = vox_read_f ;
+               psf->read_double        = vox_read_d ;
+               } ;
+
+       /* Standard sample rate chennels etc. */
+       if (psf->sf.samplerate < 1)
+               psf->sf.samplerate      = 8000 ;
+       psf->sf.channels        = 1 ;
+
+       psf->sf.frames = psf->filelength * 2 ;
+
+       psf->sf.seekable = SF_FALSE ;
+
+       /* Seek back to start of data. */
+       if (psf_fseek (psf, 0 , SEEK_SET) == -1)
+               return SFE_BAD_SEEK ;
+
+       return 0 ;
+} /* vox_adpcm_init */
+
+/*------------------------------------------------------------------------------
+*/
+
+static char
+vox_adpcm_encode (short samp, VOX_ADPCM_PRIVATE *pvox)
+{      short code ;
+       short diff, error, stepsize ;
+
+       stepsize = step_size_table [pvox->step_index] ;
+       code = 0 ;
+
+       diff = samp - pvox->last ;
+       if (diff < 0)
+       {       code = 0x08 ;
+               error = -diff ;
+               }
+       else
+               error = diff ;
+
+       if (error >= stepsize)
+       {       code = code | 0x04 ;
+               error -= stepsize ;
+               } ;
+
+       if (error >= stepsize / 2)
+       {       code = code | 0x02 ;
+               error -= stepsize / 2 ;
+               } ;
+
+       if (error >= stepsize / 4)
+               code = code | 0x01 ;
+
+       /*
+       ** To close the feedback loop, the deocder is used to set the
+       ** estimate of last sample and in doing so, also set the step_index.
+       */
+       pvox->last = vox_adpcm_decode (code, pvox) ;
+
+       return code ;
+} /* vox_adpcm_encode */
+
+static short
+vox_adpcm_decode (char code, VOX_ADPCM_PRIVATE *pvox)
+{      short diff, error, stepsize, samp ;
+
+       stepsize = step_size_table [pvox->step_index] ;
+
+       error = stepsize / 8 ;
+
+       if (code & 0x01)
+               error += stepsize / 4 ;
+
+       if (code & 0x02)
+               error += stepsize / 2 ;
+
+       if (code & 0x04)
+               error += stepsize ;
+
+       diff = (code & 0x08) ? -error : error ;
+       samp = pvox->last + diff ;
+
+       /*
+       **  Apply clipping.
+       */
+       if (samp > 2048)
+               samp = 2048 ;
+       if (samp < -2048)
+               samp = -2048 ;
+
+       pvox->last = samp ;
+       pvox->step_index += step_adjust_table [code & 0x7] ;
+
+       if (pvox->step_index < 0)
+               pvox->step_index = 0 ;
+       if (pvox->step_index > 48)
+               pvox->step_index = 48 ;
+
+       return samp ;
+} /* vox_adpcm_decode */
+
+static int
+vox_adpcm_encode_block (VOX_ADPCM_PRIVATE *pvox)
+{      unsigned char code ;
+       int j, k ;
+
+       /* If data_count is odd, add an extra zero valued sample. */
+       if (pvox->pcm_samples & 1)
+               pvox->pcm_data [pvox->pcm_samples++] = 0 ;
+
+       for (j = k = 0 ; k < pvox->pcm_samples ; j++)
+       {       code = vox_adpcm_encode (pvox->pcm_data [k++] / 16, pvox) << 4 ;
+               code |= vox_adpcm_encode (pvox->pcm_data [k++] / 16, pvox) ;
+               pvox->vox_data [j] = code ;
+               } ;
+
+       pvox->vox_bytes = j ;
+
+       return 0 ;
+} /* vox_adpcm_encode_block */
+
+static int
+vox_adpcm_decode_block (VOX_ADPCM_PRIVATE *pvox)
+{      unsigned char code ;
+       int j, k ;
+
+       for (j = k = 0 ; j < pvox->vox_bytes ; j++)
+       {       code = pvox->vox_data [j] ;
+               pvox->pcm_data [k++] = 16 * vox_adpcm_decode ((code >> 4) & 0x0f, pvox) ;
+               pvox->pcm_data [k++] = 16 * vox_adpcm_decode (code & 0x0f, pvox) ;
+               } ;
+
+       pvox->pcm_samples = k ;
+
+       return 0 ;
+} /* vox_adpcm_decode_block */
+
+/*==============================================================================
+*/
+
+static int
+vox_read_block (SF_PRIVATE *psf, VOX_ADPCM_PRIVATE *pvox, short *ptr, int len)
+{      int     indx = 0, k ;
+
+       while (indx < len)
+       {       pvox->vox_bytes = (len - indx > PCM_DATA_LEN) ? VOX_DATA_LEN : (len - indx + 1) / 2 ;
+
+               if ((k = psf_fread (pvox->vox_data, 1, pvox->vox_bytes, psf)) != pvox->vox_bytes)
+               {       if (psf_ftell (psf) + k != psf->filelength)
+                               psf_log_printf (psf, "*** Warning : short read (%d != %d).\n", k, pvox->vox_bytes) ;
+                       if (k == 0)
+                               break ;
+                       } ;
+
+               pvox->vox_bytes = k ;
+
+               vox_adpcm_decode_block (pvox) ;
+
+               memcpy (&(ptr [indx]), pvox->pcm_data, pvox->pcm_samples * sizeof (short)) ;
+               indx += pvox->pcm_samples ;
+               } ;
+
+       return indx ;
+} /* vox_read_block */
+
+
+static sf_count_t
+vox_read_s (SF_PRIVATE *psf, short *ptr, sf_count_t len)
+{      VOX_ADPCM_PRIVATE       *pvox ;
+       int                     readcount, count ;
+       sf_count_t      total = 0 ;
+
+       if (! psf->fdata)
+               return 0 ;
+       pvox = (VOX_ADPCM_PRIVATE*) psf->fdata ;
+
+       while (len > 0)
+       {       readcount = (len > 0x10000000) ? 0x10000000 : (int) len ;
+
+               count = vox_read_block (psf, pvox, ptr, readcount) ;
+
+               total += count ;
+               len -= count ;
+               if (count != readcount)
+                       break ;
+               } ;
+
+       return total ;
+} /* vox_read_s */
+
+static sf_count_t
+vox_read_i     (SF_PRIVATE *psf, int *ptr, sf_count_t len)
+{      VOX_ADPCM_PRIVATE *pvox ;
+       short           *sptr ;
+       int                     k, bufferlen, readcount, count ;
+       sf_count_t      total = 0 ;
+
+       if (! psf->fdata)
+               return 0 ;
+       pvox = (VOX_ADPCM_PRIVATE*) psf->fdata ;
+
+       sptr = psf->u.sbuf ;
+       bufferlen = ARRAY_LEN (psf->u.sbuf) ;
+       while (len > 0)
+       {       readcount = (len >= bufferlen) ? bufferlen : (int) len ;
+               count = vox_read_block (psf, pvox, sptr, readcount) ;
+               for (k = 0 ; k < readcount ; k++)
+                       ptr [total + k] = ((int) sptr [k]) << 16 ;
+               total += count ;
+               len -= readcount ;
+               if (count != readcount)
+                       break ;
+               } ;
+
+       return total ;
+} /* vox_read_i */
+
+static sf_count_t
+vox_read_f (SF_PRIVATE *psf, float *ptr, sf_count_t len)
+{      VOX_ADPCM_PRIVATE *pvox ;
+       short           *sptr ;
+       int                     k, bufferlen, readcount, count ;
+       sf_count_t      total = 0 ;
+       float           normfact ;
+
+       if (! psf->fdata)
+               return 0 ;
+       pvox = (VOX_ADPCM_PRIVATE*) psf->fdata ;
+
+       normfact = (psf->norm_float == SF_TRUE) ? 1.0 / ((float) 0x8000) : 1.0 ;
+
+       sptr = psf->u.sbuf ;
+       bufferlen = ARRAY_LEN (psf->u.sbuf) ;
+       while (len > 0)
+       {       readcount = (len >= bufferlen) ? bufferlen : (int) len ;
+               count = vox_read_block (psf, pvox, sptr, readcount) ;
+               for (k = 0 ; k < readcount ; k++)
+                       ptr [total + k] = normfact * (float) (sptr [k]) ;
+               total += count ;
+               len -= readcount ;
+               if (count != readcount)
+                       break ;
+               } ;
+
+       return total ;
+} /* vox_read_f */
+
+static sf_count_t
+vox_read_d (SF_PRIVATE *psf, double *ptr, sf_count_t len)
+{      VOX_ADPCM_PRIVATE *pvox ;
+       short           *sptr ;
+       int                     k, bufferlen, readcount, count ;
+       sf_count_t      total = 0 ;
+       double          normfact ;
+
+       if (! psf->fdata)
+               return 0 ;
+       pvox = (VOX_ADPCM_PRIVATE*) psf->fdata ;
+
+       normfact = (psf->norm_double == SF_TRUE) ? 1.0 / ((double) 0x8000) : 1.0 ;
+
+       sptr = psf->u.sbuf ;
+       bufferlen = ARRAY_LEN (psf->u.sbuf) ;
+       while (len > 0)
+       {       readcount = (len >= bufferlen) ? bufferlen : (int) len ;
+               count = vox_read_block (psf, pvox, sptr, readcount) ;
+               for (k = 0 ; k < readcount ; k++)
+                       ptr [total + k] = normfact * (double) (sptr [k]) ;
+               total += count ;
+               len -= readcount ;
+               if (count != readcount)
+                       break ;
+               } ;
+
+       return total ;
+} /* vox_read_d */
+
+/*------------------------------------------------------------------------------
+*/
+
+static int
+vox_write_block (SF_PRIVATE *psf, VOX_ADPCM_PRIVATE *pvox, const short *ptr, int len)
+{      int     indx = 0, k ;
+
+       while (indx < len)
+       {       pvox->pcm_samples = (len - indx > PCM_DATA_LEN) ? PCM_DATA_LEN : len - indx ;
+
+               memcpy (pvox->pcm_data, &(ptr [indx]), pvox->pcm_samples * sizeof (short)) ;
+
+               vox_adpcm_encode_block (pvox) ;
+
+               if ((k = psf_fwrite (pvox->vox_data, 1, pvox->vox_bytes, psf)) != pvox->vox_bytes)
+                       psf_log_printf (psf, "*** Warning : short read (%d != %d).\n", k, pvox->vox_bytes) ;
+
+               indx += pvox->pcm_samples ;
+               } ;
+
+       return indx ;
+} /* vox_write_block */
+
+static sf_count_t
+vox_write_s (SF_PRIVATE *psf, const short *ptr, sf_count_t len)
+{      VOX_ADPCM_PRIVATE       *pvox ;
+       int                     writecount, count ;
+       sf_count_t      total = 0 ;
+
+       if (! psf->fdata)
+               return 0 ;
+       pvox = (VOX_ADPCM_PRIVATE*) psf->fdata ;
+
+       while (len)
+       {       writecount = (len > 0x10000000) ? 0x10000000 : (int) len ;
+
+               count = vox_write_block (psf, pvox, ptr, writecount) ;
+
+               total += count ;
+               len -= count ;
+               if (count != writecount)
+                       break ;
+               } ;
+
+       return total ;
+} /* vox_write_s */
+
+static sf_count_t
+vox_write_i    (SF_PRIVATE *psf, const int *ptr, sf_count_t len)
+{      VOX_ADPCM_PRIVATE *pvox ;
+       short           *sptr ;
+       int                     k, bufferlen, writecount, count ;
+       sf_count_t      total = 0 ;
+
+       if (! psf->fdata)
+               return 0 ;
+       pvox = (VOX_ADPCM_PRIVATE*) psf->fdata ;
+
+       sptr = psf->u.sbuf ;
+       bufferlen = ARRAY_LEN (psf->u.sbuf) ;
+       while (len > 0)
+       {       writecount = (len >= bufferlen) ? bufferlen : (int) len ;
+               for (k = 0 ; k < writecount ; k++)
+                       sptr [k] = ptr [total + k] >> 16 ;
+               count = vox_write_block (psf, pvox, sptr, writecount) ;
+               total += count ;
+               len -= writecount ;
+               if (count != writecount)
+                       break ;
+               } ;
+
+       return total ;
+} /* vox_write_i */
+
+static sf_count_t
+vox_write_f (SF_PRIVATE *psf, const float *ptr, sf_count_t len)
+{      VOX_ADPCM_PRIVATE *pvox ;
+       short           *sptr ;
+       int                     k, bufferlen, writecount, count ;
+       sf_count_t      total = 0 ;
+       float           normfact ;
+
+       if (! psf->fdata)
+               return 0 ;
+       pvox = (VOX_ADPCM_PRIVATE*) psf->fdata ;
+
+       normfact = (psf->norm_float == SF_TRUE) ? (1.0 * 0x7FFF) : 1.0 ;
+
+       sptr = psf->u.sbuf ;
+       bufferlen = ARRAY_LEN (psf->u.sbuf) ;
+       while (len > 0)
+       {       writecount = (len >= bufferlen) ? bufferlen : (int) len ;
+               for (k = 0 ; k < writecount ; k++)
+                       sptr [k] = lrintf (normfact * ptr [total + k]) ;
+               count = vox_write_block (psf, pvox, sptr, writecount) ;
+               total += count ;
+               len -= writecount ;
+               if (count != writecount)
+                       break ;
+               } ;
+
+       return total ;
+} /* vox_write_f */
+
+static sf_count_t
+vox_write_d    (SF_PRIVATE *psf, const double *ptr, sf_count_t len)
+{      VOX_ADPCM_PRIVATE *pvox ;
+       short           *sptr ;
+       int                     k, bufferlen, writecount, count ;
+       sf_count_t      total = 0 ;
+       double          normfact ;
+
+       if (! psf->fdata)
+               return 0 ;
+       pvox = (VOX_ADPCM_PRIVATE*) psf->fdata ;
+
+       normfact = (psf->norm_double == SF_TRUE) ? (1.0 * 0x7FFF) : 1.0 ;
+
+       sptr = psf->u.sbuf ;
+       bufferlen = ARRAY_LEN (psf->u.sbuf) ;
+       while (len > 0)
+       {       writecount = (len >= bufferlen) ? bufferlen : (int) len ;
+               for (k = 0 ; k < writecount ; k++)
+                       sptr [k] = lrint (normfact * ptr [total + k]) ;
+               count = vox_write_block (psf, pvox, sptr, writecount) ;
+               total += count ;
+               len -= writecount ;
+               if (count != writecount)
+                       break ;
+               } ;
+
+       return total ;
+} /* vox_write_d */
+
+
+/*
+** Do not edit or modify anything in this comment block.
+** The arch-tag line is a file identity tag for the GNU Arch 
+** revision control system.
+**
+** arch-tag: e15e97fe-ff9d-4b46-a489-7059fb2d0b1e
+*/
diff --git a/libs/libsndfile/src/w64.c b/libs/libsndfile/src/w64.c
new file mode 100644 (file)
index 0000000..756b093
--- /dev/null
@@ -0,0 +1,578 @@
+/*
+** Copyright (C) 1999-2005 Erik de Castro Lopo <erikd@mega-nerd.com>
+**
+** This program is free software; you can redistribute it and/or modify
+** it under the terms of the GNU Lesser General Public License as published by
+** the Free Software Foundation; either version 2.1 of the License, or
+** (at your option) any later version.
+**
+** This program is distributed in the hope that it will be useful,
+** but WITHOUT ANY WARRANTY; without even the implied warranty of
+** MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+** GNU Lesser General Public License for more details.
+**
+** You should have received a copy of the GNU Lesser General Public License
+** along with this program; if not, write to the Free Software
+** Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA.
+*/
+
+#include       "sfconfig.h"
+
+#include       <stdio.h>
+#include       <string.h>
+#include       <ctype.h>
+#include       <time.h>
+
+#include       "sndfile.h"
+#include       "sfendian.h"
+#include       "common.h"
+#include       "wav_w64.h"
+
+/*------------------------------------------------------------------------------
+** W64 files use 16 byte markers as opposed to the four byte marker of
+** WAV files.
+** For comparison purposes, an integer is required, so make an integer
+** hash for the 16 bytes using MAKE_HASH16 macro, but also create a 16
+** byte array containing the complete 16 bytes required when writing the
+** header.
+*/
+
+#define MAKE_HASH16(x0,x1,x2,x3,x4,x5,x6,x7,x8,x9,xa,xb,xc,xd,xe,xf)   \
+                       (       (x0)                    ^ ((x1) << 1)   ^ ((x2) << 2)   ^ ((x3) << 3) ^ \
+                               ((x4) << 4)     ^ ((x5) << 5)   ^ ((x6) << 6)   ^ ((x7) << 7) ^ \
+                               ((x8) << 8)     ^ ((x9) << 9)   ^ ((xa) << 10)  ^ ((xb) << 11) ^ \
+                               ((xc) << 12)    ^ ((xd) << 13)  ^ ((xe) << 14)  ^ ((xf) << 15)  )
+
+#define MAKE_MARKER16(name,x0,x1,x2,x3,x4,x5,x6,x7,x8,x9,xa,xb,xc,xd,xe,xf)    \
+                       static unsigned char name [16] = { (x0), (x1), (x2), (x3), (x4), (x5), \
+                               (x6), (x7), (x8), (x9), (xa), (xb), (xc), (xd), (xe), (xf) }
+
+#define        riff_HASH16 MAKE_HASH16 ('r', 'i', 'f', 'f', 0x2E, 0x91, 0xCF, 0x11, 0xA5, \
+                                                               0xD6, 0x28, 0xDB, 0x04, 0xC1, 0x00, 0x00)
+
+#define        wave_HASH16     MAKE_HASH16 ('w', 'a', 'v', 'e', 0xF3, 0xAC, 0xD3, 0x11, \
+                                                               0x8C, 0xD1, 0x00, 0xC0, 0x4F, 0x8E, 0xDB, 0x8A)
+
+#define        fmt_HASH16              MAKE_HASH16 ('f', 'm', 't', ' ', 0xF3, 0xAC, 0xD3, 0x11, \
+                                                               0x8C, 0xD1, 0x00, 0xC0, 0x4F, 0x8E, 0xDB, 0x8A)
+
+#define        fact_HASH16     MAKE_HASH16 ('f', 'a', 'c', 't', 0xF3, 0xAC, 0xD3, 0x11, \
+                                                               0x8C, 0xD1, 0x00, 0xC0, 0x4F, 0x8E, 0xDB, 0x8A)
+
+#define        data_HASH16     MAKE_HASH16 ('d', 'a', 't', 'a', 0xF3, 0xAC, 0xD3, 0x11, \
+                                                               0x8C, 0xD1, 0x00, 0xC0, 0x4F, 0x8E, 0xDB, 0x8A)
+
+#define        ACID_HASH16     MAKE_HASH16 (0x6D, 0x07, 0x1C, 0xEA, 0xA3, 0xEF, 0x78, 0x4C, \
+                                                               0x90, 0x57, 0x7F, 0x79, 0xEE, 0x25, 0x2A, 0xAE)
+
+MAKE_MARKER16 (riff_MARKER16, 'r', 'i', 'f', 'f', 0x2E, 0x91, 0xCF, 0x11,
+                                                               0xA5, 0xD6, 0x28, 0xDB, 0x04, 0xC1, 0x00, 0x00) ;
+
+
+MAKE_MARKER16 (wave_MARKER16, 'w', 'a', 'v', 'e', 0xF3, 0xAC, 0xD3, 0x11,
+                                                               0x8C, 0xD1, 0x00, 0xC0, 0x4F, 0x8E, 0xDB, 0x8A) ;
+
+MAKE_MARKER16 (fmt_MARKER16, 'f', 'm', 't', ' ', 0xF3, 0xAC, 0xD3, 0x11,
+                                                               0x8C, 0xD1, 0x00, 0xC0, 0x4F, 0x8E, 0xDB, 0x8A) ;
+
+MAKE_MARKER16 (fact_MARKER16, 'f', 'a', 'c', 't', 0xF3, 0xAC, 0xD3, 0x11,
+                                                               0x8C, 0xD1, 0x00, 0xC0, 0x4F, 0x8E, 0xDB, 0x8A) ;
+
+MAKE_MARKER16 (data_MARKER16, 'd', 'a', 't', 'a', 0xF3, 0xAC, 0xD3, 0x11,
+                                                               0x8C, 0xD1, 0x00, 0xC0, 0x4F, 0x8E, 0xDB, 0x8A) ;
+
+enum
+{      HAVE_riff       = 0x01,
+       HAVE_wave       = 0x02,
+       HAVE_fmt        = 0x04,
+       HAVE_fact       = 0x08,
+       HAVE_data       = 0x20
+} ;
+
+/*------------------------------------------------------------------------------
+ * Private static functions.
+ */
+
+static int     w64_read_header (SF_PRIVATE *psf, int *blockalign, int *framesperblock) ;
+static int     w64_write_header (SF_PRIVATE *psf, int calc_length) ;
+static int     w64_close (SF_PRIVATE *psf) ;
+
+/*------------------------------------------------------------------------------
+** Public function.
+*/
+
+int
+w64_open       (SF_PRIVATE *psf)
+{      int     subformat, error, blockalign = 0, framesperblock = 0 ;
+
+       if (psf->mode == SFM_READ || (psf->mode == SFM_RDWR &&psf->filelength > 0))
+       {       if ((error = w64_read_header (psf, &blockalign, &framesperblock)))
+                       return error ;
+               } ;
+
+       if ((psf->sf.format & SF_FORMAT_TYPEMASK) != SF_FORMAT_W64)
+               return  SFE_BAD_OPEN_FORMAT ;
+
+       subformat = psf->sf.format & SF_FORMAT_SUBMASK ;
+
+       if (psf->mode == SFM_WRITE || psf->mode == SFM_RDWR)
+       {       if (psf->is_pipe)
+                       return SFE_NO_PIPE_WRITE ;
+
+               psf->endian = SF_ENDIAN_LITTLE ;                /* All W64 files are little endian. */
+
+               psf->blockwidth = psf->bytewidth * psf->sf.channels ;
+
+               if (subformat == SF_FORMAT_IMA_ADPCM || subformat == SF_FORMAT_MS_ADPCM)
+               {       blockalign = wav_w64_srate2blocksize (psf->sf.samplerate * psf->sf.channels) ;
+                       framesperblock = -1 ;
+
+                       /* FIXME : This block must go */
+                       psf->filelength = SF_COUNT_MAX ;
+                       psf->datalength = psf->filelength ;
+                       if (psf->sf.frames <= 0)
+                               psf->sf.frames = (psf->blockwidth) ? psf->filelength / psf->blockwidth : psf->filelength ;
+                       /* EMXIF : This block must go */
+                       } ;
+
+               if ((error = w64_write_header (psf, SF_FALSE)))
+                       return error ;
+
+               psf->write_header = w64_write_header ;
+               } ;
+
+       psf->container_close = w64_close ;
+
+       switch (subformat)
+       {       case SF_FORMAT_PCM_U8 :
+                                       error = pcm_init (psf) ;
+                                       break ;
+
+               case SF_FORMAT_PCM_16 :
+               case SF_FORMAT_PCM_24 :
+               case SF_FORMAT_PCM_32 :
+                                       error = pcm_init (psf) ;
+                                       break ;
+
+               case SF_FORMAT_ULAW :
+                                       error = ulaw_init (psf) ;
+                                       break ;
+
+               case SF_FORMAT_ALAW :
+                                       error = alaw_init (psf) ;
+                                       break ;
+
+               /* Lite remove start */
+               case SF_FORMAT_FLOAT :
+                                       error = float32_init (psf) ;
+                                       break ;
+
+               case SF_FORMAT_DOUBLE :
+                                       error = double64_init (psf) ;
+                                       break ;
+
+               case SF_FORMAT_IMA_ADPCM :
+                                       error = wav_w64_ima_init (psf, blockalign, framesperblock) ;
+                                       break ;
+
+               case SF_FORMAT_MS_ADPCM :
+                                       error = wav_w64_msadpcm_init (psf, blockalign, framesperblock) ;
+                                       break ;
+               /* Lite remove end */
+
+               case SF_FORMAT_GSM610 :
+                                       error = gsm610_init (psf) ;
+                                       break ;
+
+               default :       return SFE_UNIMPLEMENTED ;
+               } ;
+
+       return error ;
+} /* w64_open */
+
+/*=========================================================================
+** Private functions.
+*/
+
+static int
+w64_read_header        (SF_PRIVATE *psf, int *blockalign, int *framesperblock)
+{      WAV_FMT         wav_fmt ;
+       int                     dword = 0, marker, format = 0 ;
+       sf_count_t      chunk_size, bytesread = 0 ;
+       int                     parsestage = 0, error, done = 0 ;
+
+       /* Set position to start of file to begin reading header. */
+       memset (&wav_fmt, 0, sizeof (wav_fmt)) ;
+       psf_binheader_readf (psf, "p", 0) ;
+
+       while (! done)
+       {       /* Read the 4 byte marker and jump 12 bytes. */
+               bytesread += psf_binheader_readf (psf, "h", &marker) ;
+               chunk_size = 0 ;
+
+               switch (marker)
+               {       case riff_HASH16 :
+                                       if (parsestage)
+                                               return SFE_W64_NO_RIFF ;
+
+                                       bytesread += psf_binheader_readf (psf, "e8", &chunk_size) ;
+
+                                       if (psf->filelength < chunk_size)
+                                               psf_log_printf (psf, "riff : %D (should be %D)\n", chunk_size, psf->filelength) ;
+                                       else
+                                               psf_log_printf (psf, "riff : %D\n", chunk_size) ;
+
+                                       parsestage |= HAVE_riff ;
+                                       break ;
+
+                       case ACID_HASH16:
+                                       psf_log_printf (psf, "Looks like an ACID file. Exiting.\n") ;
+                                       return SFE_UNIMPLEMENTED ;
+
+                       case wave_HASH16 :
+                                       if ((parsestage & HAVE_riff) != HAVE_riff)
+                                               return SFE_W64_NO_WAVE ;
+                                       psf_log_printf (psf, "wave\n") ;
+                                       parsestage |= HAVE_wave ;
+                                       break ;
+
+                       case fmt_HASH16 :
+                                       if ((parsestage & (HAVE_riff | HAVE_wave)) != (HAVE_riff | HAVE_wave))
+                                               return SFE_W64_NO_FMT ;
+
+                                       bytesread += psf_binheader_readf (psf, "e8", &chunk_size) ;
+                                       psf_log_printf (psf, " fmt : %D\n", chunk_size) ;
+
+                                       /* size of 16 byte marker and 8 byte chunk_size value. */
+                                       chunk_size -= 24 ;
+
+                                       if ((error = wav_w64_read_fmt_chunk (psf, &wav_fmt, (int) chunk_size)))
+                                               return error ;
+
+                                       if (chunk_size % 8)
+                                               psf_binheader_readf (psf, "j", 8 - (chunk_size % 8)) ;
+
+                                       format          = wav_fmt.format ;
+                                       parsestage |= HAVE_fmt ;
+                                       break ;
+
+                       case fact_HASH16:
+                                       {       sf_count_t frames ;
+
+                                               psf_binheader_readf (psf, "e88", &chunk_size, &frames) ;
+                                               psf_log_printf (psf, "   fact : %D\n     frames : %D\n",
+                                                                               chunk_size, frames) ;
+                                               } ;
+                                       break ;
+
+
+                       case data_HASH16 :
+                                       if ((parsestage & (HAVE_riff | HAVE_wave | HAVE_fmt)) != (HAVE_riff | HAVE_wave | HAVE_fmt))
+                                               return SFE_W64_NO_DATA ;
+
+                                       psf_binheader_readf (psf, "e8", &chunk_size) ;
+
+                                       psf->dataoffset = psf_ftell (psf) ;
+
+                                       psf->datalength = chunk_size - 24 ;
+
+                                       if (chunk_size % 8)
+                                               chunk_size += 8 - (chunk_size % 8) ;
+
+                                       psf_log_printf (psf, "data : %D\n", chunk_size) ;
+
+                                       parsestage |= HAVE_data ;
+
+                                       if (! psf->sf.seekable)
+                                               break ;
+
+                                       /* Seek past data and continue reading header. */
+                                       psf_fseek (psf, chunk_size, SEEK_CUR) ;
+                                       break ;
+
+                       default :
+                                       if (psf_ftell (psf) & 0x0F)
+                                       {       psf_log_printf (psf, "  Unknown chunk marker at position %d. Resynching.\n", dword - 4) ;
+                                               psf_binheader_readf (psf, "j", -3) ;
+                                               break ;
+                                               } ;
+                                       psf_log_printf (psf, "*** Unknown chunk marker : %X. Exiting parser.\n", marker) ;
+                                       done = SF_TRUE ;
+                                       break ;
+                       } ;     /* switch (dword) */
+
+               if (psf->sf.seekable == 0 && (parsestage & HAVE_data))
+                       break ;
+
+               if (psf_ftell (psf) >= (psf->filelength - (2 * SIGNED_SIZEOF (dword))))
+                       break ;
+               } ; /* while (1) */
+
+       if (! psf->dataoffset)
+               return SFE_W64_NO_DATA ;
+
+       psf->endian = SF_ENDIAN_LITTLE ;                /* All WAV files are little endian. */
+
+       if (psf_ftell (psf) != psf->dataoffset)
+               psf_fseek (psf, psf->dataoffset, SEEK_SET) ;
+
+       if (psf->blockwidth)
+       {       if (psf->filelength - psf->dataoffset < psf->datalength)
+                       psf->sf.frames = (psf->filelength - psf->dataoffset) / psf->blockwidth ;
+               else
+                       psf->sf.frames = psf->datalength / psf->blockwidth ;
+               } ;
+
+       switch (format)
+       {       case WAVE_FORMAT_PCM :
+               case WAVE_FORMAT_EXTENSIBLE :
+                                       /* extensible might be FLOAT, MULAW, etc as well! */
+                                       psf->sf.format = SF_FORMAT_W64 | u_bitwidth_to_subformat (psf->bytewidth * 8) ;
+                                       break ;
+
+               case WAVE_FORMAT_MULAW :
+                                       psf->sf.format = (SF_FORMAT_W64 | SF_FORMAT_ULAW) ;
+                                       break ;
+
+               case WAVE_FORMAT_ALAW :
+                                       psf->sf.format = (SF_FORMAT_W64 | SF_FORMAT_ALAW) ;
+                                       break ;
+
+               case WAVE_FORMAT_MS_ADPCM :
+                                       psf->sf.format = (SF_FORMAT_W64 | SF_FORMAT_MS_ADPCM) ;
+                                       *blockalign = wav_fmt.msadpcm.blockalign ;
+                                       *framesperblock = wav_fmt.msadpcm.samplesperblock ;
+                                       break ;
+
+               case WAVE_FORMAT_IMA_ADPCM :
+                                       psf->sf.format = (SF_FORMAT_W64 | SF_FORMAT_IMA_ADPCM) ;
+                                       *blockalign = wav_fmt.ima.blockalign ;
+                                       *framesperblock = wav_fmt.ima.samplesperblock ;
+                                       break ;
+
+               case WAVE_FORMAT_GSM610 :
+                                       psf->sf.format = (SF_FORMAT_W64 | SF_FORMAT_GSM610) ;
+                                       break ;
+
+               case WAVE_FORMAT_IEEE_FLOAT :
+                                       psf->sf.format = SF_FORMAT_W64 ;
+                                       psf->sf.format |= (psf->bytewidth == 8) ? SF_FORMAT_DOUBLE : SF_FORMAT_FLOAT ;
+                                       break ;
+
+               default : return SFE_UNIMPLEMENTED ;
+               } ;
+
+       return 0 ;
+} /* w64_read_header */
+
+static int
+w64_write_header (SF_PRIVATE *psf, int calc_length)
+{      sf_count_t      fmt_size, current ;
+       size_t          fmt_pad = 0 ;
+       int             subformat, add_fact_chunk = SF_FALSE ;
+
+       current = psf_ftell (psf) ;
+
+       if (calc_length)
+       {       psf->filelength = psf_get_filelen (psf) ;
+
+               psf->datalength = psf->filelength - psf->dataoffset ;
+               if (psf->dataend)
+                       psf->datalength -= psf->filelength - psf->dataend ;
+
+               if (psf->bytewidth)
+                       psf->sf.frames = psf->datalength / (psf->bytewidth * psf->sf.channels) ;
+               } ;
+
+       /* Reset the current header length to zero. */
+       psf->header [0] = 0 ;
+       psf->headindex = 0 ;
+       psf_fseek (psf, 0, SEEK_SET) ;
+
+       /* riff marker, length, wave and 'fmt ' markers. */
+       psf_binheader_writef (psf, "eh8hh", riff_MARKER16, psf->filelength - 8, wave_MARKER16, fmt_MARKER16) ;
+
+       subformat = psf->sf.format & SF_FORMAT_SUBMASK ;
+
+       switch (subformat)
+       {       case    SF_FORMAT_PCM_U8 :
+               case    SF_FORMAT_PCM_16 :
+               case    SF_FORMAT_PCM_24 :
+               case    SF_FORMAT_PCM_32 :
+                                       fmt_size = 24 + 2 + 2 + 4 + 4 + 2 + 2 ;
+                                       fmt_pad = (size_t) (8 - (fmt_size & 0x7)) ;
+                                       fmt_size += fmt_pad ;
+
+                                       /* fmt : format, channels, samplerate */
+                                       psf_binheader_writef (psf, "e8224", fmt_size, WAVE_FORMAT_PCM, psf->sf.channels, psf->sf.samplerate) ;
+                                       /*  fmt : bytespersec */
+                                       psf_binheader_writef (psf, "e4", psf->sf.samplerate * psf->bytewidth * psf->sf.channels) ;
+                                       /*  fmt : blockalign, bitwidth */
+                                       psf_binheader_writef (psf, "e22", psf->bytewidth * psf->sf.channels, psf->bytewidth * 8) ;
+                                       break ;
+
+               case SF_FORMAT_FLOAT :
+               case SF_FORMAT_DOUBLE :
+                                       fmt_size = 24 + 2 + 2 + 4 + 4 + 2 + 2 ;
+                                       fmt_pad = (size_t) (8 - (fmt_size & 0x7)) ;
+                                       fmt_size += fmt_pad ;
+
+                                       /* fmt : format, channels, samplerate */
+                                       psf_binheader_writef (psf, "e8224", fmt_size, WAVE_FORMAT_IEEE_FLOAT, psf->sf.channels, psf->sf.samplerate) ;
+                                       /*  fmt : bytespersec */
+                                       psf_binheader_writef (psf, "e4", psf->sf.samplerate * psf->bytewidth * psf->sf.channels) ;
+                                       /*  fmt : blockalign, bitwidth */
+                                       psf_binheader_writef (psf, "e22", psf->bytewidth * psf->sf.channels, psf->bytewidth * 8) ;
+
+                                       add_fact_chunk = SF_TRUE ;
+                                       break ;
+
+               case SF_FORMAT_ULAW :
+                                       fmt_size = 24 + 2 + 2 + 4 + 4 + 2 + 2 ;
+                                       fmt_pad = (size_t) (8 - (fmt_size & 0x7)) ;
+                                       fmt_size += fmt_pad ;
+
+                                       /* fmt : format, channels, samplerate */
+                                       psf_binheader_writef (psf, "e8224", fmt_size, WAVE_FORMAT_MULAW, psf->sf.channels, psf->sf.samplerate) ;
+                                       /*  fmt : bytespersec */
+                                       psf_binheader_writef (psf, "e4", psf->sf.samplerate * psf->bytewidth * psf->sf.channels) ;
+                                       /*  fmt : blockalign, bitwidth */
+                                       psf_binheader_writef (psf, "e22", psf->bytewidth * psf->sf.channels, 8) ;
+
+                                       add_fact_chunk = SF_TRUE ;
+                                       break ;
+
+               case SF_FORMAT_ALAW :
+                                       fmt_size = 24 + 2 + 2 + 4 + 4 + 2 + 2 ;
+                                       fmt_pad = (size_t) (8 - (fmt_size & 0x7)) ;
+                                       fmt_size += fmt_pad ;
+
+                                       /* fmt : format, channels, samplerate */
+                                       psf_binheader_writef (psf, "e8224", fmt_size, WAVE_FORMAT_ALAW, psf->sf.channels, psf->sf.samplerate) ;
+                                       /*  fmt : bytespersec */
+                                       psf_binheader_writef (psf, "e4", psf->sf.samplerate * psf->bytewidth * psf->sf.channels) ;
+                                       /*  fmt : blockalign, bitwidth */
+                                       psf_binheader_writef (psf, "e22", psf->bytewidth * psf->sf.channels, 8) ;
+
+                                       add_fact_chunk = SF_TRUE ;
+                                       break ;
+
+               /* Lite remove start */
+               case SF_FORMAT_IMA_ADPCM :
+                                       {       int             blockalign, framesperblock, bytespersec ;
+
+                                               blockalign              = wav_w64_srate2blocksize (psf->sf.samplerate * psf->sf.channels) ;
+                                               framesperblock  = 2 * (blockalign - 4 * psf->sf.channels) / psf->sf.channels + 1 ;
+                                               bytespersec             = (psf->sf.samplerate * blockalign) / framesperblock ;
+
+                                               /* fmt chunk. */
+                                               fmt_size = 24 + 2 + 2 + 4 + 4 + 2 + 2 + 2 + 2 ;
+                                               fmt_pad = (size_t) (8 - (fmt_size & 0x7)) ;
+                                               fmt_size += fmt_pad ;
+
+                                               /* fmt : size, WAV format type, channels. */
+                                               psf_binheader_writef (psf, "e822", fmt_size, WAVE_FORMAT_IMA_ADPCM, psf->sf.channels) ;
+
+                                               /* fmt : samplerate, bytespersec. */
+                                               psf_binheader_writef (psf, "e44", psf->sf.samplerate, bytespersec) ;
+
+                                               /* fmt : blockalign, bitwidth, extrabytes, framesperblock. */
+                                               psf_binheader_writef (psf, "e2222", blockalign, 4, 2, framesperblock) ;
+                                               } ;
+
+                                       add_fact_chunk = SF_TRUE ;
+                                       break ;
+
+               case SF_FORMAT_MS_ADPCM :
+                                       {       int blockalign, framesperblock, bytespersec, extrabytes ;
+
+                                               blockalign              = wav_w64_srate2blocksize (psf->sf.samplerate * psf->sf.channels) ;
+                                               framesperblock  = 2 + 2 * (blockalign - 7 * psf->sf.channels) / psf->sf.channels ;
+                                               bytespersec             = (psf->sf.samplerate * blockalign) / framesperblock ;
+
+                                               /* fmt chunk. */
+                                               extrabytes      = 2 + 2 + MSADPCM_ADAPT_COEFF_COUNT * (2 + 2) ;
+                                               fmt_size        = 24 + 2 + 2 + 4 + 4 + 2 + 2 + 2 + extrabytes ;
+                                               fmt_pad = (size_t) (8 - (fmt_size & 0x7)) ;
+                                               fmt_size += fmt_pad ;
+
+                                               /* fmt : size, W64 format type, channels. */
+                                               psf_binheader_writef (psf, "e822", fmt_size, WAVE_FORMAT_MS_ADPCM, psf->sf.channels) ;
+
+                                               /* fmt : samplerate, bytespersec. */
+                                               psf_binheader_writef (psf, "e44", psf->sf.samplerate, bytespersec) ;
+
+                                               /* fmt : blockalign, bitwidth, extrabytes, framesperblock. */
+                                               psf_binheader_writef (psf, "e22222", blockalign, 4, extrabytes, framesperblock, 7) ;
+
+                                               msadpcm_write_adapt_coeffs (psf) ;
+                                               } ;
+
+                                       add_fact_chunk = SF_TRUE ;
+                                       break ;
+               /* Lite remove end */
+
+               case SF_FORMAT_GSM610 :
+                                       {       int bytespersec ;
+
+                                               bytespersec = (psf->sf.samplerate * WAV_W64_GSM610_BLOCKSIZE) / WAV_W64_GSM610_SAMPLES ;
+
+                                               /* fmt chunk. */
+                                               fmt_size = 24 + 2 + 2 + 4 + 4 + 2 + 2 + 2 + 2 ;
+                                               fmt_pad = (size_t) (8 - (fmt_size & 0x7)) ;
+                                               fmt_size += fmt_pad ;
+
+                                               /* fmt : size, WAV format type, channels. */
+                                               psf_binheader_writef (psf, "e822", fmt_size, WAVE_FORMAT_GSM610, psf->sf.channels) ;
+
+                                               /* fmt : samplerate, bytespersec. */
+                                               psf_binheader_writef (psf, "e44", psf->sf.samplerate, bytespersec) ;
+
+                                               /* fmt : blockalign, bitwidth, extrabytes, framesperblock. */
+                                               psf_binheader_writef (psf, "e2222", WAV_W64_GSM610_BLOCKSIZE, 0, 2, WAV_W64_GSM610_SAMPLES) ;
+                                               } ;
+
+                                       add_fact_chunk = SF_TRUE ;
+                                       break ;
+
+               default :       return SFE_UNIMPLEMENTED ;
+               } ;
+
+       /* Pad to 8 bytes with zeros. */
+       if (fmt_pad > 0)
+               psf_binheader_writef (psf, "z", fmt_pad) ;
+
+       if (add_fact_chunk)
+               psf_binheader_writef (psf, "eh88", fact_MARKER16, (sf_count_t) (16 + 8 + 8), psf->sf.frames) ;
+
+       psf_binheader_writef (psf, "eh8", data_MARKER16, psf->datalength + 24) ;
+       psf_fwrite (psf->header, psf->headindex, 1, psf) ;
+
+       if (psf->error)
+               return psf->error ;
+
+       psf->dataoffset = psf->headindex ;
+
+       if (current > 0)
+               psf_fseek (psf, current, SEEK_SET) ;
+
+       return psf->error ;
+} /* w64_write_header */
+
+static int
+w64_close (SF_PRIVATE *psf)
+{
+       if (psf->mode == SFM_WRITE || psf->mode == SFM_RDWR)
+               w64_write_header (psf, SF_TRUE) ;
+
+       return 0 ;
+} /* w64_close */
+
+
+/*
+** Do not edit or modify anything in this comment block.
+** The arch-tag line is a file identity tag for the GNU Arch
+** revision control system.
+**
+** arch-tag: 9aa4e141-538a-4dd9-99c9-b3f0f2dd4f4a
+*/
diff --git a/libs/libsndfile/src/wav.c b/libs/libsndfile/src/wav.c
new file mode 100644 (file)
index 0000000..f2fbcd7
--- /dev/null
@@ -0,0 +1,1633 @@
+/*
+** Copyright (C) 1999-2006 Erik de Castro Lopo <erikd@mega-nerd.com>
+** Copyright (C) 2004-2005 David Viens <davidv@plogue.com>
+**
+** This program is free software; you can redistribute it and/or modify
+** it under the terms of the GNU Lesser General Public License as published by
+** the Free Software Foundation; either version 2.1 of the License, or
+** (at your option) any later version.
+**
+** This program is distributed in the hope that it will be useful,
+** but WITHOUT ANY WARRANTY; without even the implied warranty of
+** MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+** GNU Lesser General Public License for more details.
+**
+** You should have received a copy of the GNU Lesser General Public License
+** along with this program; if not, write to the Free Software
+** Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA.
+*/
+
+#include       "sfconfig.h"
+
+#include       <stdio.h>
+#include       <stdlib.h>
+#include       <string.h>
+#include       <ctype.h>
+#include       <time.h>
+
+#include       "sndfile.h"
+#include       "sfendian.h"
+#include       "common.h"
+#include       "wav_w64.h"
+
+/*------------------------------------------------------------------------------
+ * Macros to handle big/little endian issues.
+ */
+
+#define RIFF_MARKER     (MAKE_MARKER ('R', 'I', 'F', 'F'))
+#define RIFX_MARKER     (MAKE_MARKER ('R', 'I', 'F', 'X'))
+#define WAVE_MARKER     (MAKE_MARKER ('W', 'A', 'V', 'E'))
+#define fmt_MARKER      (MAKE_MARKER ('f', 'm', 't', ' '))
+#define data_MARKER     (MAKE_MARKER ('d', 'a', 't', 'a'))
+#define fact_MARKER     (MAKE_MARKER ('f', 'a', 'c', 't'))
+#define PEAK_MARKER     (MAKE_MARKER ('P', 'E', 'A', 'K'))
+
+#define cue_MARKER      (MAKE_MARKER ('c', 'u', 'e', ' '))
+#define LIST_MARKER     (MAKE_MARKER ('L', 'I', 'S', 'T'))
+#define slnt_MARKER     (MAKE_MARKER ('s', 'l', 'n', 't'))
+#define wavl_MARKER     (MAKE_MARKER ('w', 'a', 'v', 'l'))
+#define INFO_MARKER     (MAKE_MARKER ('I', 'N', 'F', 'O'))
+#define plst_MARKER     (MAKE_MARKER ('p', 'l', 's', 't'))
+#define adtl_MARKER     (MAKE_MARKER ('a', 'd', 't', 'l'))
+#define labl_MARKER     (MAKE_MARKER ('l', 'a', 'b', 'l'))
+#define ltxt_MARKER     (MAKE_MARKER ('l', 't', 'x', 't'))
+#define note_MARKER     (MAKE_MARKER ('n', 'o', 't', 'e'))
+#define smpl_MARKER     (MAKE_MARKER ('s', 'm', 'p', 'l'))
+#define bext_MARKER     (MAKE_MARKER ('b', 'e', 'x', 't'))
+#define levl_MARKER     (MAKE_MARKER ('l', 'e', 'v', 'l'))
+#define MEXT_MARKER     (MAKE_MARKER ('M', 'E', 'X', 'T'))
+#define DISP_MARKER     (MAKE_MARKER ('D', 'I', 'S', 'P'))
+#define acid_MARKER     (MAKE_MARKER ('a', 'c', 'i', 'd'))
+#define strc_MARKER     (MAKE_MARKER ('s', 't', 'r', 'c'))
+#define PAD_MARKER      (MAKE_MARKER ('P', 'A', 'D', ' '))
+#define afsp_MARKER     (MAKE_MARKER ('a', 'f', 's', 'p'))
+#define clm_MARKER      (MAKE_MARKER ('c', 'l', 'm', ' '))
+#define elmo_MARKER     (MAKE_MARKER ('e', 'l', 'm', 'o'))
+
+#define ISFT_MARKER     (MAKE_MARKER ('I', 'S', 'F', 'T'))
+#define ICRD_MARKER     (MAKE_MARKER ('I', 'C', 'R', 'D'))
+#define ICOP_MARKER     (MAKE_MARKER ('I', 'C', 'O', 'P'))
+#define IARL_MARKER     (MAKE_MARKER ('I', 'A', 'R', 'L'))
+#define IART_MARKER     (MAKE_MARKER ('I', 'A', 'R', 'T'))
+#define INAM_MARKER     (MAKE_MARKER ('I', 'N', 'A', 'M'))
+#define IENG_MARKER     (MAKE_MARKER ('I', 'E', 'N', 'G'))
+#define IART_MARKER     (MAKE_MARKER ('I', 'A', 'R', 'T'))
+#define ICOP_MARKER     (MAKE_MARKER ('I', 'C', 'O', 'P'))
+#define IPRD_MARKER     (MAKE_MARKER ('I', 'P', 'R', 'D'))
+#define ISRC_MARKER     (MAKE_MARKER ('I', 'S', 'R', 'C'))
+#define ISBJ_MARKER     (MAKE_MARKER ('I', 'S', 'B', 'J'))
+#define ICMT_MARKER     (MAKE_MARKER ('I', 'C', 'M', 'T'))
+
+/* Weird WAVPACK marker which can show up at the start of the DATA section. */
+#define wvpk_MARKER (MAKE_MARKER ('w', 'v', 'p', 'k'))
+#define OggS_MARKER (MAKE_MARKER ('O', 'g', 'g', 'S'))
+
+#define WAV_PEAK_CHUNK_SIZE(ch)        (2 * sizeof (int) + ch * (sizeof (float) + sizeof (int)))
+#define WAV_BEXT_CHUNK_SIZE                    602
+
+enum
+{      HAVE_RIFF       = 0x01,
+       HAVE_WAVE       = 0x02,
+       HAVE_fmt        = 0x04,
+       HAVE_fact       = 0x08,
+       HAVE_PEAK       = 0x10,
+       HAVE_data       = 0x20,
+       HAVE_other      = 0x80000000
+} ;
+
+
+
+/*  known WAVEFORMATEXTENSIBLE GUIDS  */
+static const EXT_SUBFORMAT MSGUID_SUBTYPE_PCM =
+{      0x00000001, 0x0000, 0x0010, {   0x80, 0x00, 0x00, 0xaa, 0x00, 0x38, 0x9b, 0x71 }
+} ;
+
+static const EXT_SUBFORMAT MSGUID_SUBTYPE_MS_ADPCM =
+{      0x00000002, 0x0000, 0x0010, {   0x80, 0x00, 0x00, 0xaa, 0x00, 0x38, 0x9b, 0x71 }
+} ;
+
+static const EXT_SUBFORMAT MSGUID_SUBTYPE_IEEE_FLOAT =
+{      0x00000003, 0x0000, 0x0010, {   0x80, 0x00, 0x00, 0xaa, 0x00, 0x38, 0x9b, 0x71 }
+} ;
+
+static const EXT_SUBFORMAT MSGUID_SUBTYPE_ALAW =
+{      0x00000006, 0x0000, 0x0010, {   0x80, 0x00, 0x00, 0xaa, 0x00, 0x38, 0x9b, 0x71 }
+} ;
+
+static const EXT_SUBFORMAT MSGUID_SUBTYPE_MULAW =
+{      0x00000007, 0x0000, 0x0010, {   0x80, 0x00, 0x00, 0xaa, 0x00, 0x38, 0x9b, 0x71 }
+} ;
+
+/*
+** the next two are from
+** http://dream.cs.bath.ac.uk/researchdev/wave-ex/bformat.html
+*/
+static const EXT_SUBFORMAT MSGUID_SUBTYPE_AMBISONIC_B_FORMAT_PCM =
+{      0x00000001, 0x0721, 0x11d3, {   0x86, 0x44, 0xC8, 0xC1, 0xCA, 0x00, 0x00, 0x00 }
+} ;
+
+static const EXT_SUBFORMAT MSGUID_SUBTYPE_AMBISONIC_B_FORMAT_IEEE_FLOAT =
+{      0x00000003, 0x0721, 0x11d3, {   0x86, 0x44, 0xC8, 0xC1, 0xCA, 0x00, 0x00, 0x00 }
+} ;
+
+
+#if 0
+/* maybe interesting one day to read the following through sf_read_raw */
+/* http://www.bath.ac.uk/~masrwd/pvocex/pvocex.html */
+static const EXT_SUBFORMAT MSGUID_SUBTYPE_PVOCEX =
+{      0x8312B9C2, 0x2E6E, 0x11d4, {   0xA8, 0x24, 0xDE, 0x5B, 0x96, 0xC3, 0xAB, 0x21 }
+} ;
+#endif
+
+/*------------------------------------------------------------------------------
+** Private static functions.
+*/
+
+static int     wav_read_header  (SF_PRIVATE *psf, int *blockalign, int *framesperblock) ;
+static int     wav_write_header (SF_PRIVATE *psf, int calc_length) ;
+
+static int     wavex_write_header (SF_PRIVATE *psf, int calc_length) ;
+
+static int     wav_write_tailer (SF_PRIVATE *psf) ;
+static void wav_write_strings (SF_PRIVATE *psf, int location) ;
+static int     wav_command (SF_PRIVATE *psf, int command, void *data, int datasize) ;
+static int     wav_close (SF_PRIVATE *psf) ;
+
+static int     wav_subchunk_parse       (SF_PRIVATE *psf, int chunk) ;
+static int     wav_read_smpl_chunk (SF_PRIVATE *psf, unsigned int chunklen) ;
+static int     wav_read_acid_chunk (SF_PRIVATE *psf, unsigned int chunklen) ;
+static int     wav_read_bext_chunk (SF_PRIVATE *psf, unsigned int chunklen) ;
+static int     wav_write_bext_chunk (SF_PRIVATE *psf) ;
+
+/*------------------------------------------------------------------------------
+** Public function.
+*/
+
+int
+wav_open        (SF_PRIVATE *psf)
+{      int     format, subformat, error, blockalign = 0, framesperblock = 0 ;
+
+       if (psf->mode == SFM_READ || (psf->mode == SFM_RDWR && psf->filelength > 0))
+       {       if ((error = wav_read_header (psf, &blockalign, &framesperblock)))
+                       return error ;
+               } ;
+
+       subformat = psf->sf.format & SF_FORMAT_SUBMASK ;
+
+       if (psf->mode == SFM_WRITE || psf->mode == SFM_RDWR)
+       {       if (psf->is_pipe)
+                       return SFE_NO_PIPE_WRITE ;
+
+               format = psf->sf.format & SF_FORMAT_TYPEMASK ;
+               if (format != SF_FORMAT_WAV && format != SF_FORMAT_WAVEX)
+                       return  SFE_BAD_OPEN_FORMAT ;
+
+               psf->blockwidth = psf->bytewidth * psf->sf.channels ;
+
+               /* RIFF WAVs are little-endian, RIFX WAVs are big-endian, default to little */
+               psf->endian = psf->sf.format & SF_FORMAT_ENDMASK ;
+               if (CPU_IS_BIG_ENDIAN && psf->endian == SF_ENDIAN_CPU)
+                       psf->endian = SF_ENDIAN_BIG ;
+               else if (psf->endian != SF_ENDIAN_BIG)
+                       psf->endian = SF_ENDIAN_LITTLE ;
+
+               if (psf->mode != SFM_RDWR || psf->filelength < 44)
+               {       psf->filelength = 0 ;
+                       psf->datalength = 0 ;
+                       psf->dataoffset = 0 ;
+                       psf->sf.frames = 0 ;
+                       } ;
+
+               if (subformat == SF_FORMAT_IMA_ADPCM || subformat == SF_FORMAT_MS_ADPCM)
+               {       blockalign = wav_w64_srate2blocksize (psf->sf.samplerate * psf->sf.channels) ;
+                       framesperblock = -1 ; /* Corrected later. */
+                       } ;
+
+               psf->str_flags = SF_STR_ALLOW_START | SF_STR_ALLOW_END ;
+
+               /* By default, add the peak chunk to floating point files. Default behaviour
+               ** can be switched off using sf_command (SFC_SET_PEAK_CHUNK, SF_FALSE).
+               */
+               if (psf->mode == SFM_WRITE && (subformat == SF_FORMAT_FLOAT || subformat == SF_FORMAT_DOUBLE))
+               {       if ((psf->peak_info = peak_info_calloc (psf->sf.channels)) == NULL)
+                               return SFE_MALLOC_FAILED ;
+                       psf->peak_info->peak_loc = SF_PEAK_START ;
+                       } ;
+
+               psf->write_header = (format == SF_FORMAT_WAV) ? wav_write_header : wavex_write_header ;
+               } ;
+
+       psf->container_close = wav_close ;
+       psf->command = wav_command ;
+
+       switch (subformat)
+       {       case SF_FORMAT_PCM_U8 :
+               case SF_FORMAT_PCM_16 :
+               case SF_FORMAT_PCM_24 :
+               case SF_FORMAT_PCM_32 :
+                                       error = pcm_init (psf) ;
+                                       break ;
+
+               case SF_FORMAT_ULAW :
+                                       error = ulaw_init (psf) ;
+                                       break ;
+
+               case SF_FORMAT_ALAW :
+                                       error = alaw_init (psf) ;
+                                       break ;
+
+               /* Lite remove start */
+               case SF_FORMAT_FLOAT :
+                                       error = float32_init (psf) ;
+                                       break ;
+
+               case SF_FORMAT_DOUBLE :
+                                       error = double64_init (psf) ;
+                                       break ;
+
+               case SF_FORMAT_IMA_ADPCM :
+                                       error = wav_w64_ima_init (psf, blockalign, framesperblock) ;
+                                       break ;
+
+               case SF_FORMAT_MS_ADPCM :
+                                       error = wav_w64_msadpcm_init (psf, blockalign, framesperblock) ;
+                                       break ;
+
+               case SF_FORMAT_G721_32 :
+                                       error = g72x_init (psf) ;
+                                       break ;
+               /* Lite remove end */
+
+               case SF_FORMAT_GSM610 :
+                                       error = gsm610_init (psf) ;
+                                       break ;
+
+               default :       return SFE_UNIMPLEMENTED ;
+               } ;
+
+       if (psf->mode == SFM_WRITE || (psf->mode == SFM_RDWR && psf->filelength == 0))
+               return psf->write_header (psf, SF_FALSE) ;
+
+       return error ;
+} /* wav_open */
+
+/*=========================================================================
+** Private functions.
+*/
+
+static int
+wav_read_header         (SF_PRIVATE *psf, int *blockalign, int *framesperblock)
+{      WAV_FMT         wav_fmt ;
+       FACT_CHUNK      fact_chunk ;
+       unsigned        dword = 0, marker, RIFFsize, done = 0 ;
+       int                     parsestage = 0, error, format = 0 ;
+       char            *cptr ;
+
+       memset (&wav_fmt, 0, sizeof (wav_fmt)) ;
+       /* Set position to start of file to begin reading header. */
+       psf_binheader_readf (psf, "p", 0) ;
+
+       while (! done)
+       {       psf_binheader_readf (psf, "m", &marker) ;
+
+               switch (marker)
+               {       case RIFF_MARKER :
+                       case RIFX_MARKER :
+                                       if (parsestage)
+                                               return SFE_WAV_NO_RIFF ;
+
+                                       parsestage |= HAVE_RIFF ;
+
+                                       /* RIFX signifies big-endian format for all header and data
+                                       ** to prevent lots of code copying here, we'll set the psf->rwf_endian
+                                       ** flag once here, and never specify endian-ness for all other header ops
+                                       */
+                                       if (marker == RIFF_MARKER)
+                                               psf->rwf_endian = SF_ENDIAN_LITTLE ;
+                                       else
+                                               psf->rwf_endian = SF_ENDIAN_BIG ;
+
+                                       psf_binheader_readf (psf, "4", &RIFFsize) ;
+
+                                       if (psf->fileoffset > 0 && psf->filelength > RIFFsize + 8)
+                                       {       /* Set file length. */
+                                               psf->filelength = RIFFsize + 8 ;
+                                               if (marker == RIFF_MARKER)
+                                                       psf_log_printf (psf, "RIFF : %u\n", RIFFsize) ;
+                                               else
+                                                       psf_log_printf (psf, "RIFX : %u\n", RIFFsize) ;
+                                               }
+                                       else if (psf->filelength < RIFFsize + 2 * SIGNED_SIZEOF (dword))
+                                       {       if (marker == RIFF_MARKER)
+                                                       psf_log_printf (psf, "RIFF : %u (should be %D)\n", RIFFsize, psf->filelength - 2 * SIGNED_SIZEOF (dword)) ;
+                                               else
+                                                       psf_log_printf (psf, "RIFX : %u (should be %D)\n", RIFFsize, psf->filelength - 2 * SIGNED_SIZEOF (dword)) ;
+
+                                               RIFFsize = dword ;
+                                               }
+                                       else
+                                       {       if (marker == RIFF_MARKER)
+                                                       psf_log_printf (psf, "RIFF : %u\n", RIFFsize) ;
+                                               else
+                                                       psf_log_printf (psf, "RIFX : %u\n", RIFFsize) ;
+                                       } ;
+                                       break ;
+
+                       case WAVE_MARKER :
+                                       if ((parsestage & HAVE_RIFF) != HAVE_RIFF)
+                                               return SFE_WAV_NO_WAVE ;
+                                       parsestage |= HAVE_WAVE ;
+
+                                       psf_log_printf (psf, "WAVE\n") ;
+                                       break ;
+
+                       case fmt_MARKER :
+                                       if ((parsestage & (HAVE_RIFF | HAVE_WAVE)) != (HAVE_RIFF | HAVE_WAVE))
+                                               return SFE_WAV_NO_FMT ;
+
+                                       /* If this file has a SECOND fmt chunk, I don't want to know about it. */
+                                       if (parsestage & HAVE_fmt)
+                                               break ;
+
+                                       parsestage |= HAVE_fmt ;
+
+                                       psf_binheader_readf (psf, "4", &dword) ;
+                                       psf_log_printf (psf, "fmt  : %d\n", dword) ;
+
+                                       if ((error = wav_w64_read_fmt_chunk (psf, &wav_fmt, dword)))
+                                               return error ;
+
+                                       format = wav_fmt.format ;
+                                       break ;
+
+                       case data_MARKER :
+                                       if ((parsestage & (HAVE_RIFF | HAVE_WAVE | HAVE_fmt)) != (HAVE_RIFF | HAVE_WAVE | HAVE_fmt))
+                                               return SFE_WAV_NO_DATA ;
+
+                                       if (psf->mode == SFM_RDWR && (parsestage & HAVE_other) != 0)
+                                               return SFE_RDWR_BAD_HEADER ;
+
+                                       parsestage |= HAVE_data ;
+
+                                       psf_binheader_readf (psf, "4", &dword) ;
+
+                                       psf->datalength = dword ;
+                                       psf->dataoffset = psf_ftell (psf) ;
+
+                                       if (dword == 0 && RIFFsize == 8 && psf->filelength > 44)
+                                       {       psf_log_printf (psf, "*** Looks like a WAV file which wasn't closed properly. Fixing it.\n") ;
+                                               psf->datalength = dword = psf->filelength - psf->dataoffset ;
+                                               } ;
+
+                                       if (psf->datalength > psf->filelength - psf->dataoffset)
+                                       {       psf_log_printf (psf, "data : %D (should be %D)\n", psf->datalength, psf->filelength - psf->dataoffset) ;
+                                               psf->datalength = psf->filelength - psf->dataoffset ;
+                                               }
+                                       else
+                                               psf_log_printf (psf, "data : %D\n", psf->datalength) ;
+
+                                       /* Only set dataend if there really is data at the end. */
+                                       if (psf->datalength + psf->dataoffset < psf->filelength)
+                                               psf->dataend = psf->datalength + psf->dataoffset ;
+
+                                       if (format == WAVE_FORMAT_MS_ADPCM && psf->datalength % 2)
+                                       {       psf->datalength ++ ;
+                                               psf_log_printf (psf, "*** Data length odd. Increasing it by 1.\n") ;
+                                               } ;
+
+                                       if (! psf->sf.seekable)
+                                               break ;
+
+                                       /* Seek past data and continue reading header. */
+                                       psf_fseek (psf, psf->datalength, SEEK_CUR) ;
+
+                                       dword = psf_ftell (psf) ;
+                                       if (dword != (sf_count_t) (psf->dataoffset + psf->datalength))
+                                               psf_log_printf (psf, "*** psf_fseek past end error ***\n", dword, psf->dataoffset + psf->datalength) ;
+                                       break ;
+
+                       case fact_MARKER :
+                                       if ((parsestage & (HAVE_RIFF | HAVE_WAVE)) != (HAVE_RIFF | HAVE_WAVE))
+                                               return SFE_WAV_BAD_FACT ;
+
+                                       parsestage |= HAVE_fact ;
+
+                                       if ((parsestage & HAVE_fmt) != HAVE_fmt)
+                                               psf_log_printf (psf, "*** Should have 'fmt ' chunk before 'fact'\n") ;
+
+                                       psf_binheader_readf (psf, "44", &dword, & (fact_chunk.frames)) ;
+
+                                       if (dword > SIGNED_SIZEOF (fact_chunk))
+                                               psf_binheader_readf (psf, "j", (int) (dword - SIGNED_SIZEOF (fact_chunk))) ;
+
+                                       if (dword)
+                                               psf_log_printf (psf, "%M : %d\n", marker, dword) ;
+                                       else
+                                               psf_log_printf (psf, "%M : %d (should not be zero)\n", marker, dword) ;
+
+                                       psf_log_printf (psf, "  frames  : %d\n", fact_chunk.frames) ;
+                                       break ;
+
+                       case PEAK_MARKER :
+                                       if ((parsestage & (HAVE_RIFF | HAVE_WAVE | HAVE_fmt)) != (HAVE_RIFF | HAVE_WAVE | HAVE_fmt))
+                                               return SFE_WAV_PEAK_B4_FMT ;
+
+                                       parsestage |= HAVE_PEAK ;
+
+                                       psf_binheader_readf (psf, "4", &dword) ;
+
+                                       psf_log_printf (psf, "%M : %d\n", marker, dword) ;
+                                       if (dword != WAV_PEAK_CHUNK_SIZE (psf->sf.channels))
+                                       {       psf_binheader_readf (psf, "j", dword) ;
+                                               psf_log_printf (psf, "*** File PEAK chunk size doesn't fit with number of channels (%d).\n", psf->sf.channels) ;
+                                               return SFE_WAV_BAD_PEAK ;
+                                               } ;
+
+                                       if ((psf->peak_info = peak_info_calloc (psf->sf.channels)) == NULL)
+                                               return SFE_MALLOC_FAILED ;
+
+                                       /* read in rest of PEAK chunk. */
+                                       psf_binheader_readf (psf, "44", & (psf->peak_info->version), & (psf->peak_info->timestamp)) ;
+
+                                       if (psf->peak_info->version != 1)
+                                               psf_log_printf (psf, "  version    : %d *** (should be version 1)\n", psf->peak_info->version) ;
+                                       else
+                                               psf_log_printf (psf, "  version    : %d\n", psf->peak_info->version) ;
+
+                                       psf_log_printf (psf, "  time stamp : %d\n", psf->peak_info->timestamp) ;
+                                       psf_log_printf (psf, "    Ch   Position       Value\n") ;
+
+                                       cptr = psf->u.cbuf ;
+                                       for (dword = 0 ; dword < (unsigned) psf->sf.channels ; dword++)
+                                       {       float value ;
+                                               unsigned int position ;
+                                               psf_binheader_readf (psf, "f4", &value, &position) ;
+                                               psf->peak_info->peaks [dword].value = value ;
+                                               psf->peak_info->peaks [dword].position = position ;
+
+                                               LSF_SNPRINTF (cptr, sizeof (psf->u.cbuf), "    %2d   %-12ld   %g\n",
+                                                               dword, (long) psf->peak_info->peaks [dword].position, psf->peak_info->peaks [dword].value) ;
+                                               cptr [sizeof (psf->u.cbuf) - 1] = 0 ;
+                                               psf_log_printf (psf, cptr) ;
+                                               } ;
+
+                                       psf->peak_info->peak_loc = ((parsestage & HAVE_data) == 0) ? SF_PEAK_START : SF_PEAK_END ;
+                                       break ;
+
+                       case cue_MARKER :
+                                       parsestage |= HAVE_other ;
+
+                                       {       unsigned bytesread, cue_count ;
+                                               int id, position, chunk_id, chunk_start, block_start, offset ;
+
+                                               bytesread = psf_binheader_readf (psf, "44", &dword, &cue_count) ;
+                                               bytesread -= 4 ; /* Remove bytes for first dword. */
+                                               psf_log_printf (psf, "%M : %u\n", marker, dword) ;
+
+                                               if (cue_count > 10)
+                                               {       psf_log_printf (psf, "  Count : %d (skipping)\n", cue_count) ;
+                                                       psf_binheader_readf (psf, "j", cue_count * 24) ;
+                                                       break ;
+                                                       } ;
+
+                                               psf_log_printf (psf, "  Count : %d\n", cue_count) ;
+
+                                               while (cue_count)
+                                               {       bytesread += psf_binheader_readf (psf, "444444", &id, &position,
+                                                                       &chunk_id, &chunk_start, &block_start, &offset) ;
+                                                       psf_log_printf (psf, "   Cue ID : %2d"
+                                                                                                "  Pos : %5u  Chunk : %M"
+                                                                                                "  Chk Start : %d  Blk Start : %d"
+                                                                                                "  Offset : %5d\n",
+                                                                       id, position, chunk_id, chunk_start, block_start, offset) ;
+                                                       cue_count -- ;
+                                                       } ;
+
+                                               if (bytesread != dword)
+                                               {       psf_log_printf (psf, "**** Chunk size weirdness (%d != %d)\n", dword, bytesread) ;
+                                                       psf_binheader_readf (psf, "j", dword - bytesread) ;
+                                                       } ;
+                                               } ;
+                                       break ;
+
+                       case smpl_MARKER :
+                                       parsestage |= HAVE_other ;
+
+                                       psf_binheader_readf (psf, "4", &dword) ;
+                                       psf_log_printf (psf, "smpl : %u\n", dword) ;
+
+                                       if ((error = wav_read_smpl_chunk (psf, dword)))
+                                               return error ;
+                                       break ;
+
+                       case acid_MARKER :
+                                       parsestage |= HAVE_other ;
+
+                                       psf_binheader_readf (psf, "4", &dword) ;
+                                       psf_log_printf (psf, "acid : %u\n", dword) ;
+
+                                       if ((error = wav_read_acid_chunk (psf, dword)))
+                                               return error ;
+                                       break ;
+
+                       case INFO_MARKER :
+                       case LIST_MARKER :
+                                       parsestage |= HAVE_other ;
+
+                                       if ((error = wav_subchunk_parse (psf, marker)) != 0)
+                                               return error ;
+                                       break ;
+
+                       case bext_MARKER :
+                                       parsestage |= HAVE_other ;
+
+                                       psf_binheader_readf (psf, "4", &dword) ;
+                                       if (dword < WAV_BEXT_CHUNK_SIZE)
+                                               psf_log_printf (psf, "bext : %u (should be >= %d)\n", dword, WAV_BEXT_CHUNK_SIZE) ;
+                                       else
+                                               psf_log_printf (psf, "bext : %u\n", dword) ;
+
+                                       if ((error = wav_read_bext_chunk (psf, dword)))
+                                               return error ;
+                                       break ;
+
+                       case strc_MARKER : /* Multiple of 32 bytes. */
+
+                       case afsp_MARKER :
+                       case clm_MARKER :
+                       case elmo_MARKER :
+                       case levl_MARKER :
+                       case plst_MARKER :
+                       case DISP_MARKER :
+                       case MEXT_MARKER :
+                       case PAD_MARKER :
+                                       parsestage |= HAVE_other ;
+
+                                       psf_binheader_readf (psf, "4", &dword) ;
+                                       psf_log_printf (psf, "%M : %u\n", marker, dword) ;
+                                       dword += (dword & 1) ;
+                                       psf_binheader_readf (psf, "j", dword) ;
+                                       break ;
+
+                       default :
+                                       parsestage |= HAVE_other ;
+                                       if (isprint ((marker >> 24) & 0xFF) && isprint ((marker >> 16) & 0xFF)
+                                               && isprint ((marker >> 8) & 0xFF) && isprint (marker & 0xFF))
+                                       {       psf_binheader_readf (psf, "4", &dword) ;
+                                               psf_log_printf (psf, "*** %M : %d (unknown marker)\n", marker, dword) ;
+                                               psf_binheader_readf (psf, "j", dword) ;
+                                               break ;
+                                               } ;
+                                       if (psf_ftell (psf) & 0x03)
+                                       {       psf_log_printf (psf, "  Unknown chunk marker at position %d. Resynching.\n", dword - 4) ;
+                                               psf_binheader_readf (psf, "j", -3) ;
+                                               break ;
+                                               } ;
+                                       psf_log_printf (psf, "*** Unknown chunk marker (%X) at position %D. Exiting parser.\n", marker, psf_ftell (psf) - 4) ;
+                                       done = SF_TRUE ;
+                                       break ;
+                       } ;     /* switch (dword) */
+
+               if (! psf->sf.seekable && (parsestage & HAVE_data))
+                       break ;
+
+               if (psf_ftell (psf) >= psf->filelength - SIGNED_SIZEOF (dword))
+               {       psf_log_printf (psf, "End\n") ;
+                       break ;
+                       } ;
+               } ; /* while (1) */
+
+       if (! psf->dataoffset)
+               return SFE_WAV_NO_DATA ;
+
+       /* WAVs can be little or big endian */
+       psf->endian = psf->rwf_endian ;
+
+       psf_fseek (psf, psf->dataoffset, SEEK_SET) ;
+
+       if (psf->is_pipe == 0)
+       {       /*
+               ** Check for 'wvpk' at the start of the DATA section. Not able to
+               ** handle this.
+               */
+               psf_binheader_readf (psf, "4", &marker) ;
+               if (marker == wvpk_MARKER || marker == OggS_MARKER)
+                       return SFE_WAV_WVPK_DATA ;
+               } ;
+
+       /* Seek to start of DATA section. */
+       psf_fseek (psf, psf->dataoffset, SEEK_SET) ;
+
+       if (psf->blockwidth)
+       {       if (psf->filelength - psf->dataoffset < psf->datalength)
+                       psf->sf.frames = (psf->filelength - psf->dataoffset) / psf->blockwidth ;
+               else
+                       psf->sf.frames = psf->datalength / psf->blockwidth ;
+               } ;
+
+       switch (format)
+       {       case WAVE_FORMAT_EXTENSIBLE :
+                       if (psf->sf.format == (SF_FORMAT_WAVEX | SF_FORMAT_MS_ADPCM))
+                       {       *blockalign = wav_fmt.msadpcm.blockalign ;
+                               *framesperblock = wav_fmt.msadpcm.samplesperblock ;
+                               } ;
+                       break ;
+
+               case WAVE_FORMAT_PCM :
+                                       psf->sf.format = SF_FORMAT_WAV | u_bitwidth_to_subformat (psf->bytewidth * 8) ;
+                                       break ;
+
+               case WAVE_FORMAT_MULAW :
+               case IBM_FORMAT_MULAW :
+                                       psf->sf.format = (SF_FORMAT_WAV | SF_FORMAT_ULAW) ;
+                                       break ;
+
+               case WAVE_FORMAT_ALAW :
+               case IBM_FORMAT_ALAW :
+                                       psf->sf.format = (SF_FORMAT_WAV | SF_FORMAT_ALAW) ;
+                                       break ;
+
+               case WAVE_FORMAT_MS_ADPCM :
+                                       psf->sf.format = (SF_FORMAT_WAV | SF_FORMAT_MS_ADPCM) ;
+                                       *blockalign = wav_fmt.msadpcm.blockalign ;
+                                       *framesperblock = wav_fmt.msadpcm.samplesperblock ;
+                                       break ;
+
+               case WAVE_FORMAT_IMA_ADPCM :
+                                       psf->sf.format = (SF_FORMAT_WAV | SF_FORMAT_IMA_ADPCM) ;
+                                       *blockalign = wav_fmt.ima.blockalign ;
+                                       *framesperblock = wav_fmt.ima.samplesperblock ;
+                                       break ;
+
+               case WAVE_FORMAT_GSM610 :
+                                       psf->sf.format = (SF_FORMAT_WAV | SF_FORMAT_GSM610) ;
+                                       break ;
+
+               case WAVE_FORMAT_IEEE_FLOAT :
+                                       psf->sf.format = SF_FORMAT_WAV ;
+                                       psf->sf.format |= (psf->bytewidth == 8) ? SF_FORMAT_DOUBLE : SF_FORMAT_FLOAT ;
+                                       break ;
+
+               case WAVE_FORMAT_G721_ADPCM :
+                                       psf->sf.format = SF_FORMAT_WAV | SF_FORMAT_G721_32 ;
+                                       break ;
+
+               default : return SFE_UNIMPLEMENTED ;
+               } ;
+
+       /* Only set the format endian-ness if its non-standard big-endian. */
+       if (psf->endian == SF_ENDIAN_BIG)
+               psf->sf.format |= SF_ENDIAN_BIG ;
+
+       return 0 ;
+} /* wav_read_header */
+
+static int
+wav_write_header (SF_PRIVATE *psf, int calc_length)
+{      sf_count_t      current ;
+       int             fmt_size, k, subformat, add_fact_chunk = SF_FALSE ;
+
+       current = psf_ftell (psf) ;
+
+       if (calc_length)
+       {       psf->filelength = psf_get_filelen (psf) ;
+
+               psf->datalength = psf->filelength - psf->dataoffset ;
+
+               if (psf->dataend)
+                       psf->datalength -= psf->filelength - psf->dataend ;
+
+               if (psf->bytewidth > 0)
+                       psf->sf.frames = psf->datalength / (psf->bytewidth * psf->sf.channels) ;
+               } ;
+
+       /* Reset the current header length to zero. */
+       psf->header [0] = 0 ;
+       psf->headindex = 0 ;
+       psf_fseek (psf, 0, SEEK_SET) ;
+
+       /*
+       ** RIFX signifies big-endian format for all header and data.
+       ** To prevent lots of code copying here, we'll set the psf->rwf_endian flag
+       ** once here, and never specify endian-ness for all other header operations.
+       */
+
+       /* RIFF/RIFX marker, length, WAVE and 'fmt ' markers. */
+
+       if (psf->endian == SF_ENDIAN_LITTLE)
+               psf_binheader_writef (psf, "etm8", RIFF_MARKER, (psf->filelength < 8) ? 8 : psf->filelength - 8) ;
+       else
+               psf_binheader_writef (psf, "Etm8", RIFX_MARKER, (psf->filelength < 8) ? 8 : psf->filelength - 8) ;
+
+       /* WAVE and 'fmt ' markers. */
+       psf_binheader_writef (psf, "mm", WAVE_MARKER, fmt_MARKER) ;
+
+       subformat = psf->sf.format & SF_FORMAT_SUBMASK ;
+
+       switch (subformat)
+       {       case SF_FORMAT_PCM_U8 :
+               case SF_FORMAT_PCM_16 :
+               case SF_FORMAT_PCM_24 :
+               case SF_FORMAT_PCM_32 :
+                                       fmt_size = 2 + 2 + 4 + 4 + 2 + 2 ;
+
+                                       /* fmt : format, channels, samplerate */
+                                       psf_binheader_writef (psf, "4224", fmt_size, WAVE_FORMAT_PCM, psf->sf.channels, psf->sf.samplerate) ;
+                                       /*  fmt : bytespersec */
+                                       psf_binheader_writef (psf, "4", psf->sf.samplerate * psf->bytewidth * psf->sf.channels) ;
+                                       /*  fmt : blockalign, bitwidth */
+                                       psf_binheader_writef (psf, "22", psf->bytewidth * psf->sf.channels, psf->bytewidth * 8) ;
+                                       break ;
+
+               case SF_FORMAT_FLOAT :
+               case SF_FORMAT_DOUBLE :
+                                       fmt_size = 2 + 2 + 4 + 4 + 2 + 2 ;
+
+                                       /* fmt : format, channels, samplerate */
+                                       psf_binheader_writef (psf, "4224", fmt_size, WAVE_FORMAT_IEEE_FLOAT, psf->sf.channels, psf->sf.samplerate) ;
+                                       /*  fmt : bytespersec */
+                                       psf_binheader_writef (psf, "4", psf->sf.samplerate * psf->bytewidth * psf->sf.channels) ;
+                                       /*  fmt : blockalign, bitwidth */
+                                       psf_binheader_writef (psf, "22", psf->bytewidth * psf->sf.channels, psf->bytewidth * 8) ;
+
+                                       add_fact_chunk = SF_TRUE ;
+                                       break ;
+
+               case SF_FORMAT_ULAW :
+                                       fmt_size = 2 + 2 + 4 + 4 + 2 + 2 ;
+
+                                       /* fmt : format, channels, samplerate */
+                                       psf_binheader_writef (psf, "4224", fmt_size, WAVE_FORMAT_MULAW, psf->sf.channels, psf->sf.samplerate) ;
+                                       /*  fmt : bytespersec */
+                                       psf_binheader_writef (psf, "4", psf->sf.samplerate * psf->bytewidth * psf->sf.channels) ;
+                                       /*  fmt : blockalign, bitwidth */
+                                       psf_binheader_writef (psf, "22", psf->bytewidth * psf->sf.channels, 8) ;
+
+                                       add_fact_chunk = SF_TRUE ;
+                                       break ;
+
+               case SF_FORMAT_ALAW :
+                                       fmt_size = 2 + 2 + 4 + 4 + 2 + 2 ;
+
+                                       /* fmt : format, channels, samplerate */
+                                       psf_binheader_writef (psf, "4224", fmt_size, WAVE_FORMAT_ALAW, psf->sf.channels, psf->sf.samplerate) ;
+                                       /*  fmt : bytespersec */
+                                       psf_binheader_writef (psf, "4", psf->sf.samplerate * psf->bytewidth * psf->sf.channels) ;
+                                       /*  fmt : blockalign, bitwidth */
+                                       psf_binheader_writef (psf, "22", psf->bytewidth * psf->sf.channels, 8) ;
+
+                                       add_fact_chunk = SF_TRUE ;
+                                       break ;
+
+               /* Lite remove start */
+               case SF_FORMAT_IMA_ADPCM :
+                                       {       int blockalign, framesperblock, bytespersec ;
+
+                                               blockalign              = wav_w64_srate2blocksize (psf->sf.samplerate * psf->sf.channels) ;
+                                               framesperblock  = 2 * (blockalign - 4 * psf->sf.channels) / psf->sf.channels + 1 ;
+                                               bytespersec             = (psf->sf.samplerate * blockalign) / framesperblock ;
+
+                                               /* fmt chunk. */
+                                               fmt_size = 2 + 2 + 4 + 4 + 2 + 2 + 2 + 2 ;
+
+                                               /* fmt : size, WAV format type, channels, samplerate, bytespersec */
+                                               psf_binheader_writef (psf, "42244", fmt_size, WAVE_FORMAT_IMA_ADPCM,
+                                                                       psf->sf.channels, psf->sf.samplerate, bytespersec) ;
+
+                                               /* fmt : blockalign, bitwidth, extrabytes, framesperblock. */
+                                               psf_binheader_writef (psf, "2222", blockalign, 4, 2, framesperblock) ;
+                                               } ;
+
+                                       add_fact_chunk = SF_TRUE ;
+                                       break ;
+
+               case SF_FORMAT_MS_ADPCM :
+                                       {       int     blockalign, framesperblock, bytespersec, extrabytes ;
+
+                                               blockalign              = wav_w64_srate2blocksize (psf->sf.samplerate * psf->sf.channels) ;
+                                               framesperblock  = 2 + 2 * (blockalign - 7 * psf->sf.channels) / psf->sf.channels ;
+                                               bytespersec             = (psf->sf.samplerate * blockalign) / framesperblock ;
+
+                                               /* fmt chunk. */
+                                               extrabytes      = 2 + 2 + MSADPCM_ADAPT_COEFF_COUNT * (2 + 2) ;
+                                               fmt_size        = 2 + 2 + 4 + 4 + 2 + 2 + 2 + extrabytes ;
+
+                                               /* fmt : size, WAV format type, channels. */
+                                               psf_binheader_writef (psf, "422", fmt_size, WAVE_FORMAT_MS_ADPCM, psf->sf.channels) ;
+
+                                               /* fmt : samplerate, bytespersec. */
+                                               psf_binheader_writef (psf, "44", psf->sf.samplerate, bytespersec) ;
+
+                                               /* fmt : blockalign, bitwidth, extrabytes, framesperblock. */
+                                               psf_binheader_writef (psf, "22222", blockalign, 4, extrabytes, framesperblock, 7) ;
+
+                                               msadpcm_write_adapt_coeffs (psf) ;
+                                               } ;
+
+                                       add_fact_chunk = SF_TRUE ;
+                                       break ;
+
+
+               case SF_FORMAT_G721_32 :
+                                       /* fmt chunk. */
+                                       fmt_size = 2 + 2 + 4 + 4 + 2 + 2 + 2 + 2 ;
+
+                                       /* fmt : size, WAV format type, channels, samplerate, bytespersec */
+                                       psf_binheader_writef (psf, "42244", fmt_size, WAVE_FORMAT_G721_ADPCM,
+                                                               psf->sf.channels, psf->sf.samplerate, psf->sf.samplerate * psf->sf.channels / 2) ;
+
+                                       /* fmt : blockalign, bitwidth, extrabytes, auxblocksize. */
+                                       psf_binheader_writef (psf, "2222", 64, 4, 2, 0) ;
+
+                                       add_fact_chunk = SF_TRUE ;
+                                       break ;
+
+               /* Lite remove end */
+
+               case SF_FORMAT_GSM610 :
+                                       {       int     blockalign, framesperblock, bytespersec ;
+
+                                               blockalign              = WAV_W64_GSM610_BLOCKSIZE ;
+                                               framesperblock  = WAV_W64_GSM610_SAMPLES ;
+                                               bytespersec             = (psf->sf.samplerate * blockalign) / framesperblock ;
+
+                                               /* fmt chunk. */
+                                               fmt_size = 2 + 2 + 4 + 4 + 2 + 2 + 2 + 2 ;
+
+                                               /* fmt : size, WAV format type, channels. */
+                                               psf_binheader_writef (psf, "422", fmt_size, WAVE_FORMAT_GSM610, psf->sf.channels) ;
+
+                                               /* fmt : samplerate, bytespersec. */
+                                               psf_binheader_writef (psf, "44", psf->sf.samplerate, bytespersec) ;
+
+                                               /* fmt : blockalign, bitwidth, extrabytes, framesperblock. */
+                                               psf_binheader_writef (psf, "2222", blockalign, 0, 2, framesperblock) ;
+                                               } ;
+
+                                       add_fact_chunk = SF_TRUE ;
+                                       break ;
+
+               default :       return SFE_UNIMPLEMENTED ;
+               } ;
+
+       if (add_fact_chunk)
+               psf_binheader_writef (psf, "tm48", fact_MARKER, 4, psf->sf.frames) ;
+
+       if (psf->str_flags & SF_STR_LOCATE_START)
+               wav_write_strings (psf, SF_STR_LOCATE_START) ;
+
+       if (psf->peak_info != NULL && psf->peak_info->peak_loc == SF_PEAK_START)
+       {       psf_binheader_writef (psf, "m4", PEAK_MARKER, WAV_PEAK_CHUNK_SIZE (psf->sf.channels)) ;
+               psf_binheader_writef (psf, "44", 1, time (NULL)) ;
+               for (k = 0 ; k < psf->sf.channels ; k++)
+                       psf_binheader_writef (psf, "ft8", (float) psf->peak_info->peaks [k].value, psf->peak_info->peaks [k].position) ;
+               } ;
+
+       if (psf->broadcast_info != NULL)
+               wav_write_bext_chunk (psf) ;
+
+       if (psf->instrument != NULL)
+       {       int             tmp ;
+               double  dtune = (double) (0x40000000) / 25.0 ;
+
+               psf_binheader_writef (psf, "m4", smpl_MARKER, 9 * 4 + psf->instrument->loop_count * 6 * 4) ;
+               psf_binheader_writef (psf, "44", 0, 0) ; /* Manufacturer zero is everyone */
+               tmp = (int) (1.0e9 / psf->sf.samplerate) ; /* Sample period in nano seconds */
+               psf_binheader_writef (psf, "44", tmp, psf->instrument->basenote) ;
+               tmp = (unsigned int) (psf->instrument->detune * dtune + 0.5) ;
+               psf_binheader_writef (psf, "4", tmp) ;
+               psf_binheader_writef (psf, "44", 0, 0) ; /* SMTPE format */
+               psf_binheader_writef (psf, "44", psf->instrument->loop_count, 0) ;
+
+               for (tmp = 0 ; tmp < psf->instrument->loop_count ; tmp++)
+               {       int type ;
+
+                       type = psf->instrument->loops [tmp].mode ;
+                       type = (type == SF_LOOP_FORWARD ? 0 : type==SF_LOOP_BACKWARD ? 2 : type == SF_LOOP_ALTERNATING ? 1 : 32) ;
+
+                       psf_binheader_writef (psf, "44", tmp, type) ;
+                       psf_binheader_writef (psf, "44", psf->instrument->loops [tmp].start, psf->instrument->loops [tmp].end) ;
+                       psf_binheader_writef (psf, "44", 0, psf->instrument->loops [tmp].count) ;
+                       } ;
+               } ;
+
+       psf_binheader_writef (psf, "tm8", data_MARKER, psf->datalength) ;
+       psf_fwrite (psf->header, psf->headindex, 1, psf) ;
+       if (psf->error)
+               return psf->error ;
+
+       psf->dataoffset = psf->headindex ;
+
+       if (current < psf->dataoffset)
+               psf_fseek (psf, psf->dataoffset, SEEK_SET) ;
+       else if (current > 0)
+               psf_fseek (psf, current, SEEK_SET) ;
+
+       return psf->error ;
+} /* wav_write_header */
+
+
+
+static int
+wavex_write_header (SF_PRIVATE *psf, int calc_length)
+{      sf_count_t      current ;
+       int             fmt_size, k, subformat, add_fact_chunk = SF_FALSE ;
+
+       current = psf_ftell (psf) ;
+
+       if (calc_length)
+       {       psf->filelength = psf_get_filelen (psf) ;
+
+               psf->datalength = psf->filelength - psf->dataoffset ;
+
+               if (psf->dataend)
+                       psf->datalength -= psf->filelength - psf->dataend ;
+
+               if (psf->bytewidth > 0)
+                       psf->sf.frames = psf->datalength / (psf->bytewidth * psf->sf.channels) ;
+               } ;
+
+
+       /* Reset the current header length to zero. */
+       psf->header [0] = 0 ;
+       psf->headindex = 0 ;
+       psf_fseek (psf, 0, SEEK_SET) ;
+
+       /* RIFX signifies big-endian format for all header and data
+       ** to prevent lots of code copying here, we'll set the psf->rwf_endian
+       ** flag once here, and never specify endian-ness for all other header ops
+       */
+
+       /* RIFF marker, length, WAVE and 'fmt ' markers. */
+
+       if (psf->endian == SF_ENDIAN_LITTLE)
+       {       if (psf->filelength < 8)
+                       psf_binheader_writef (psf, "tm8", RIFF_MARKER, 8) ;
+               else
+                       psf_binheader_writef (psf, "tm8", RIFF_MARKER, psf->filelength - 8) ;
+               }
+       else
+       {       if (psf->filelength < 8)
+                       psf_binheader_writef (psf, "Etm8", RIFX_MARKER, 8) ;
+               else
+                       psf_binheader_writef (psf, "Etm8", RIFX_MARKER, psf->filelength - 8) ;
+               } ;
+
+       /* WAVE and 'fmt ' markers. */
+       psf_binheader_writef (psf, "mm", WAVE_MARKER, fmt_MARKER) ;
+
+       subformat = psf->sf.format & SF_FORMAT_SUBMASK ;
+
+       /* initial section (same for all, it appears) */
+       switch (subformat)
+       {       case SF_FORMAT_PCM_U8 :
+               case SF_FORMAT_PCM_16 :
+               case SF_FORMAT_PCM_24 :
+               case SF_FORMAT_PCM_32 :
+               case SF_FORMAT_FLOAT :
+               case SF_FORMAT_DOUBLE :
+               case SF_FORMAT_ULAW :
+               case SF_FORMAT_ALAW :
+                       fmt_size = 2 + 2 + 4 + 4 + 2 + 2 + 2 + 2 + 4 + 4 + 2 + 2 + 8 ;
+
+                       /* fmt : format, channels, samplerate */
+                       psf_binheader_writef (psf, "4224", fmt_size, WAVE_FORMAT_EXTENSIBLE, psf->sf.channels, psf->sf.samplerate) ;
+                       /*  fmt : bytespersec */
+                       psf_binheader_writef (psf, "4", psf->sf.samplerate * psf->bytewidth * psf->sf.channels) ;
+                       /*  fmt : blockalign, bitwidth */
+                       psf_binheader_writef (psf, "22", psf->bytewidth * psf->sf.channels, psf->bytewidth * 8) ;
+
+                       /* cbSize 22 is sizeof (WAVEFORMATEXTENSIBLE) - sizeof (WAVEFORMATEX) */
+                       psf_binheader_writef (psf, "2", 22) ;
+
+                       /* wValidBitsPerSample, for our use same as bitwidth as we use it fully */
+                       psf_binheader_writef (psf, "2", psf->bytewidth * 8) ;
+
+                       /*
+                       ** Ok some liberty is taken here to use the most commonly used channel masks
+                       ** instead of "no mapping". If you really want to use "no mapping" for 8 channels and less
+                       ** please don't use wavex. (otherwise we'll have to create a new SF_COMMAND)
+                       */
+                       switch (psf->sf.channels)
+                       {       case 1 :        /* center channel mono */
+                                       psf_binheader_writef (psf, "4", 0x4) ;
+                                       break ;
+
+                               case 2 :        /* front left and right */
+                                       psf_binheader_writef (psf, "4", 0x1 | 0x2) ;
+                                       break ;
+
+                               case 4 :        /* Quad */
+                                       psf_binheader_writef (psf, "4", 0x1 | 0x2 | 0x10 | 0x20) ;
+                                       break ;
+
+                               case 6 :        /* 5.1 */
+                                       psf_binheader_writef (psf, "4", 0x1 | 0x2 | 0x4 | 0x8 | 0x10 | 0x20) ;
+                                       break ;
+
+                               case 8 :        /* 7.1 */
+                                       psf_binheader_writef (psf, "4", 0x1 | 0x2 | 0x4 | 0x8 | 0x10 | 0x20 | 0x40 | 0x80) ;
+                                       break ;
+
+                               default :       /* 0 when in doubt , use direct out, ie NO mapping*/
+                                       psf_binheader_writef (psf, "4", 0x0) ;
+                                       break ;
+                               }
+
+                       break ;
+
+               case SF_FORMAT_MS_ADPCM : /* Todo, GUID exists might have different header as per wav_write_header */
+               default :
+                       return SFE_UNIMPLEMENTED ;
+               } ;
+
+       /* GUID section, different for each */
+
+       switch (subformat)
+       {       case SF_FORMAT_PCM_U8 :
+               case SF_FORMAT_PCM_16 :
+               case SF_FORMAT_PCM_24 :
+               case SF_FORMAT_PCM_32 :
+                       wavex_write_guid (psf, &MSGUID_SUBTYPE_PCM) ;
+                       break ;
+
+               case SF_FORMAT_FLOAT :
+               case SF_FORMAT_DOUBLE :
+                       wavex_write_guid (psf, &MSGUID_SUBTYPE_IEEE_FLOAT) ;
+                       add_fact_chunk = SF_TRUE ;
+                       break ;
+
+               case SF_FORMAT_ULAW :
+                       wavex_write_guid (psf, &MSGUID_SUBTYPE_MULAW) ;
+                       add_fact_chunk = SF_TRUE ;
+                       break ;
+
+               case SF_FORMAT_ALAW :
+                       wavex_write_guid (psf, &MSGUID_SUBTYPE_ALAW) ;
+                       add_fact_chunk = SF_TRUE ;
+                       break ;
+
+               case SF_FORMAT_MS_ADPCM : /* todo, GUID exists */
+
+               default : return SFE_UNIMPLEMENTED ;
+               } ;
+
+       if (add_fact_chunk)
+               psf_binheader_writef (psf, "tm48", fact_MARKER, 4, psf->sf.frames) ;
+
+       if (psf->str_flags & SF_STR_LOCATE_START)
+               wav_write_strings (psf, SF_STR_LOCATE_START) ;
+
+       if (psf->peak_info != NULL && psf->peak_info->peak_loc == SF_PEAK_START)
+       {       psf_binheader_writef (psf, "m4", PEAK_MARKER, WAV_PEAK_CHUNK_SIZE (psf->sf.channels)) ;
+               psf_binheader_writef (psf, "44", 1, time (NULL)) ;
+               for (k = 0 ; k < psf->sf.channels ; k++)
+                       psf_binheader_writef (psf, "ft8", (float) psf->peak_info->peaks [k].value, psf->peak_info->peaks [k].position) ;
+               } ;
+
+       psf_binheader_writef (psf, "tm8", data_MARKER, psf->datalength) ;
+       psf_fwrite (psf->header, psf->headindex, 1, psf) ;
+       if (psf->error)
+               return psf->error ;
+
+       psf->dataoffset = psf->headindex ;
+
+       if (current < psf->dataoffset)
+               psf_fseek (psf, psf->dataoffset, SEEK_SET) ;
+       else if (current > 0)
+               psf_fseek (psf, current, SEEK_SET) ;
+
+       return psf->error ;
+} /* wavex_write_header */
+
+
+
+static int
+wav_write_tailer (SF_PRIVATE *psf)
+{      int             k ;
+
+       /* Reset the current header buffer length to zero. */
+       psf->header [0] = 0 ;
+       psf->headindex = 0 ;
+
+       psf->dataend = psf_fseek (psf, 0, SEEK_END) ;
+
+       /* Add a PEAK chunk if requested. */
+       if (psf->peak_info != NULL && psf->peak_info->peak_loc == SF_PEAK_END)
+       {       psf_binheader_writef (psf, "m4", PEAK_MARKER, WAV_PEAK_CHUNK_SIZE (psf->sf.channels)) ;
+               psf_binheader_writef (psf, "44", 1, time (NULL)) ;
+               for (k = 0 ; k < psf->sf.channels ; k++)
+                       psf_binheader_writef (psf, "f4", psf->peak_info->peaks [k].value, psf->peak_info->peaks [k].position) ;
+               } ;
+
+       if (psf->str_flags & SF_STR_LOCATE_END)
+               wav_write_strings (psf, SF_STR_LOCATE_END) ;
+
+       /* Write the tailer. */
+       if (psf->headindex > 0)
+               psf_fwrite (psf->header, psf->headindex, 1, psf) ;
+
+       return 0 ;
+} /* wav_write_tailer */
+
+static void
+wav_write_strings (SF_PRIVATE *psf, int location)
+{      int     k, prev_head_index, saved_head_index ;
+
+       prev_head_index = psf->headindex + 4 ;
+
+       psf_binheader_writef (psf, "m4m", LIST_MARKER, 0xBADBAD, INFO_MARKER) ;
+
+       for (k = 0 ; k < SF_MAX_STRINGS ; k++)
+       {       if (psf->strings [k].type == 0)
+                       break ;
+               if (psf->strings [k].flags != location)
+                       continue ;
+
+               switch (psf->strings [k].type)
+               {       case SF_STR_SOFTWARE :
+                               psf_binheader_writef (psf, "ms", ISFT_MARKER, psf->strings [k].str) ;
+                               break ;
+
+                       case SF_STR_TITLE :
+                               psf_binheader_writef (psf, "ms", INAM_MARKER, psf->strings [k].str) ;
+                               break ;
+
+                       case SF_STR_COPYRIGHT :
+                               psf_binheader_writef (psf, "ms", ICOP_MARKER, psf->strings [k].str) ;
+                               break ;
+
+                       case SF_STR_ARTIST :
+                               psf_binheader_writef (psf, "ms", IART_MARKER, psf->strings [k].str) ;
+                               break ;
+
+                       case SF_STR_COMMENT :
+                               psf_binheader_writef (psf, "ms", ICMT_MARKER, psf->strings [k].str) ;
+                               break ;
+
+                       case SF_STR_DATE :
+                               psf_binheader_writef (psf, "ms", ICRD_MARKER, psf->strings [k].str) ;
+                               break ;
+                       } ;
+               } ;
+
+       saved_head_index = psf->headindex ;
+       psf->headindex = prev_head_index ;
+       psf_binheader_writef (psf, "4", saved_head_index - prev_head_index - 4) ;
+       psf->headindex = saved_head_index ;
+
+} /* wav_write_strings */
+
+static int
+wav_close (SF_PRIVATE *psf)
+{
+       if (psf->mode == SFM_WRITE || psf->mode == SFM_RDWR)
+       {       wav_write_tailer (psf) ;
+
+               psf->write_header (psf, SF_TRUE) ;
+               } ;
+
+       return 0 ;
+} /* wav_close */
+
+static int
+wav_command (SF_PRIVATE *psf, int command, void *data, int datasize)
+{
+       /* Avoid compiler warnings. */
+       psf = psf ;
+       data = data ;
+       datasize = datasize ;
+
+       switch (command)
+       {       default : break ;
+               } ;
+
+       return 0 ;
+} /* wav_command */
+
+static int
+wav_subchunk_parse (SF_PRIVATE *psf, int chunk)
+{      sf_count_t      current_pos ;
+       char            *cptr ;
+       int             dword, bytesread, length ;
+
+       current_pos = psf_fseek (psf, 0, SEEK_CUR) ;
+
+       bytesread = psf_binheader_readf (psf, "4", &length) ;
+
+       if (length <= 8)
+       {       /* This case is for broken files generated by PEAK. */
+               psf_log_printf (psf, "%M : %d (weird length)\n", chunk, length) ;
+               psf_binheader_readf (psf, "mj", &chunk, length - 4) ;
+               psf_log_printf (psf, "  %M\n", chunk) ;
+               return 0 ;
+               } ;
+
+       if (psf->headindex + length > SIGNED_SIZEOF (psf->header))
+       {       psf_log_printf (psf, "%M : %d (too long)\n", chunk, length) ;
+               psf_binheader_readf (psf, "j", length) ;
+               return 0 ;
+               } ;
+
+       if (current_pos + length > psf->filelength)
+       {       psf_log_printf (psf, "%M : %d (should be %d)\n", chunk, length, (int) (psf->filelength - current_pos)) ;
+               length = psf->filelength - current_pos ;
+               }
+       else
+               psf_log_printf (psf, "%M : %d\n", chunk, length) ;
+
+       while (bytesread < length)
+       {       bytesread += psf_binheader_readf (psf, "m", &chunk) ;
+
+               switch (chunk)
+               {       case adtl_MARKER :
+                       case INFO_MARKER :
+                                       /* These markers don't contain anything. */
+                                       psf_log_printf (psf, "  %M\n", chunk) ;
+                                       break ;
+
+                       case data_MARKER:
+                                       psf_log_printf (psf, "  %M inside a LIST block??? Backing out.\n", chunk) ;
+                                       /* Jump back four bytes and return to caller. */
+                                       psf_binheader_readf (psf, "j", -4) ;
+                                       return 0 ;
+
+                       case ISFT_MARKER :
+                       case ICOP_MARKER :
+                       case IARL_MARKER :
+                       case IART_MARKER :
+                       case ICMT_MARKER :
+                       case ICRD_MARKER :
+                       case IENG_MARKER :
+
+                       case INAM_MARKER :
+                       case IPRD_MARKER :
+                       case ISBJ_MARKER :
+                       case ISRC_MARKER :
+                                       bytesread += psf_binheader_readf (psf, "4", &dword) ;
+                                       dword += (dword & 1) ;
+                                       if (dword < 0 || dword > SIGNED_SIZEOF (psf->u.cbuf))
+                                       {       psf_log_printf (psf, "  *** %M : %d (too big)\n", chunk, dword) ;
+                                               psf_binheader_readf (psf, "j", dword) ;
+                                               break ;
+                                               } ;
+
+                                       cptr = psf->u.cbuf ;
+                                       psf_binheader_readf (psf, "b", cptr, dword) ;
+                                       bytesread += dword ;
+                                       cptr [dword - 1] = 0 ;
+                                       psf_log_printf (psf, "    %M : %s\n", chunk, cptr) ;
+                                       break ;
+
+                       case labl_MARKER :
+                                       {       int mark_id ;
+
+                                               bytesread += psf_binheader_readf (psf, "44", &dword, &mark_id) ;
+                                               dword -= 4 ;
+                                               dword += (dword & 1) ;
+                                               if (dword < 1 || dword > SIGNED_SIZEOF (psf->u.cbuf))
+                                               {       psf_log_printf (psf, "  *** %M : %d (too big)\n", chunk, dword) ;
+                                                       psf_binheader_readf (psf, "j", dword) ;
+                                                       break ;
+                                                       } ;
+
+                                               cptr = psf->u.cbuf ;
+                                               psf_binheader_readf (psf, "b", cptr, dword) ;
+                                               bytesread += dword ;
+                                               cptr [dword - 1] = 0 ;
+                                               psf_log_printf (psf, "    %M : %d : %s\n", chunk, mark_id, cptr) ;
+                                               } ;
+                                       break ;
+
+
+                       case DISP_MARKER :
+                       case ltxt_MARKER :
+                       case note_MARKER :
+                                       bytesread += psf_binheader_readf (psf, "4", &dword) ;
+                                       dword += (dword & 1) ;
+                                       psf_binheader_readf (psf, "j", dword) ;
+                                       bytesread += dword ;
+                                       psf_log_printf (psf, "    %M : %d\n", chunk, dword) ;
+                                       break ;
+
+                       default :
+                                       psf_binheader_readf (psf, "4", &dword) ;
+                                       bytesread += sizeof (dword) ;
+                                       dword += (dword & 1) ;
+                                       psf_binheader_readf (psf, "j", dword) ;
+                                       bytesread += dword ;
+                                       psf_log_printf (psf, "    *** %M : %d\n", chunk, dword) ;
+                                       if (dword > length)
+                                               return 0 ;
+                                       break ;
+                       } ;
+
+               switch (chunk)
+               {       case ISFT_MARKER :
+                                       psf_store_string (psf, SF_STR_SOFTWARE, psf->u.cbuf) ;
+                                       break ;
+                       case ICOP_MARKER :
+                                       psf_store_string (psf, SF_STR_COPYRIGHT, psf->u.cbuf) ;
+                                       break ;
+                       case INAM_MARKER :
+                                       psf_store_string (psf, SF_STR_TITLE, psf->u.cbuf) ;
+                                       break ;
+                       case IART_MARKER :
+                                       psf_store_string (psf, SF_STR_ARTIST, psf->u.cbuf) ;
+                                       break ;
+                       case ICMT_MARKER :
+                                       psf_store_string (psf, SF_STR_COMMENT, psf->u.cbuf) ;
+                                       break ;
+                       case ICRD_MARKER :
+                                       psf_store_string (psf, SF_STR_DATE, psf->u.cbuf) ;
+                                       break ;
+                       } ;
+               } ;
+
+       current_pos = psf_fseek (psf, 0, SEEK_CUR) - current_pos ;
+
+       if (current_pos - 4 != length)
+               psf_log_printf (psf, "**** Bad chunk length %d sbould be %D\n", length, current_pos - 4) ;
+
+       return 0 ;
+} /* wav_subchunk_parse */
+
+static int
+wav_read_smpl_chunk (SF_PRIVATE *psf, unsigned int chunklen)
+{      unsigned int bytesread = 0, dword, sampler_data, loop_count ;
+       unsigned int note, start, end, type = -1, count ;
+       int j, k ;
+
+       chunklen += (chunklen & 1) ;
+
+       bytesread += psf_binheader_readf (psf, "4", &dword) ;
+       psf_log_printf (psf, "  Manufacturer : %X\n", dword) ;
+
+       bytesread += psf_binheader_readf (psf, "4", &dword) ;
+       psf_log_printf (psf, "  Product      : %u\n", dword) ;
+
+       bytesread += psf_binheader_readf (psf, "4", &dword) ;
+       psf_log_printf (psf, "  Period       : %u nsec\n", dword) ;
+
+       bytesread += psf_binheader_readf (psf, "4", &note) ;
+       psf_log_printf (psf, "  Midi Note    : %u\n", note) ;
+
+       bytesread += psf_binheader_readf (psf, "4", &dword) ;
+       if (dword != 0)
+       {       LSF_SNPRINTF (psf->u.cbuf, sizeof (psf->u.cbuf), "%f",
+                                (1.0 * 0x80000000) / ((unsigned int) dword)) ;
+               psf_log_printf (psf, "  Pitch Fract. : %s\n", psf->u.cbuf) ;
+               }
+       else
+               psf_log_printf (psf, "  Pitch Fract. : 0\n") ;
+
+       bytesread += psf_binheader_readf (psf, "4", &dword) ;
+       psf_log_printf (psf, "  SMPTE Format : %u\n", dword) ;
+
+       bytesread += psf_binheader_readf (psf, "4", &dword) ;
+       LSF_SNPRINTF (psf->u.cbuf, sizeof (psf->u.cbuf), "%02d:%02d:%02d %02d",
+                (dword >> 24) & 0x7F, (dword >> 16) & 0x7F, (dword >> 8) & 0x7F, dword & 0x7F) ;
+       psf_log_printf (psf, "  SMPTE Offset : %s\n", psf->u.cbuf) ;
+
+       bytesread += psf_binheader_readf (psf, "4", &loop_count) ;
+       psf_log_printf (psf, "  Loop Count   : %u\n", loop_count) ;
+
+       /* Sampler Data holds the number of data bytes after the CUE chunks which
+       ** is not actually CUE data. Display value after CUE data.
+       */
+       bytesread += psf_binheader_readf (psf, "4", &sampler_data) ;
+
+       if ((psf->instrument = psf_instrument_alloc ()) == NULL)
+               return SFE_MALLOC_FAILED ;
+
+       psf->instrument->loop_count = loop_count ;
+
+       for (j = 0 ; loop_count > 0 && chunklen - bytesread >= 24 ; j ++)
+       {       bytesread += psf_binheader_readf (psf, "4", &dword) ;
+               psf_log_printf (psf, "    Cue ID : %2u", dword) ;
+
+               bytesread += psf_binheader_readf (psf, "4", &type) ;
+               psf_log_printf (psf, "  Type : %2u", type) ;
+
+               bytesread += psf_binheader_readf (psf, "4", &start) ;
+               psf_log_printf (psf, "  Start : %5u", start) ;
+
+               bytesread += psf_binheader_readf (psf, "4", &end) ;
+               psf_log_printf (psf, "  End : %5u", end) ;
+
+               bytesread += psf_binheader_readf (psf, "4", &dword) ;
+               psf_log_printf (psf, "  Fraction : %5u", dword) ;
+
+               bytesread += psf_binheader_readf (psf, "4", &count) ;
+               psf_log_printf (psf, "  Count : %5u\n", count) ;
+
+               if (j < ARRAY_LEN (psf->instrument->loops))
+               {       psf->instrument->loops [j].start = start ;
+                       psf->instrument->loops [j].end = end ;
+                       psf->instrument->loops [j].count = count ;
+
+                       switch (type)
+                       {       case 0 :
+                                       psf->instrument->loops [j].mode = SF_LOOP_FORWARD ;
+                                       break ;
+                               case 1 :
+                                       psf->instrument->loops [j].mode = SF_LOOP_ALTERNATING ;
+                                       break ;
+                               case 2 :
+                                       psf->instrument->loops [j].mode = SF_LOOP_BACKWARD ;
+                                       break ;
+                               default:
+                                       psf->instrument->loops [j].mode = SF_LOOP_NONE ;
+                                       break ;
+                               } ;
+                       } ;
+
+               loop_count -- ;
+               } ;
+
+       if (chunklen - bytesread == 0)
+       {       if (sampler_data != 0)
+                       psf_log_printf (psf, "  Sampler Data : %u (should be 0)\n", sampler_data) ;
+               else
+                       psf_log_printf (psf, "  Sampler Data : %u\n", sampler_data) ;
+               }
+       else
+       {       if (sampler_data != chunklen - bytesread)
+               {       psf_log_printf (psf, "  Sampler Data : %u (should have been %u)\n", sampler_data, chunklen - bytesread) ;
+                       sampler_data = chunklen - bytesread ;
+                       }
+               else
+                       psf_log_printf (psf, "  Sampler Data : %u\n", sampler_data) ;
+
+               psf_log_printf (psf, "      ") ;
+               for (k = 0 ; k < (int) sampler_data ; k++)
+               {       char ch ;
+
+                       if (k > 0 && (k % 20) == 0)
+                               psf_log_printf (psf, "\n      ") ;
+
+                       bytesread += psf_binheader_readf (psf, "1", &ch) ;
+                       psf_log_printf (psf, "%02X ", ch & 0xFF) ;
+                       } ;
+
+               psf_log_printf (psf, "\n") ;
+               } ;
+
+       psf->instrument->basenote = note ;
+       psf->instrument->gain = 1 ;
+       psf->instrument->velocity_lo = psf->instrument->key_lo = 0 ;
+       psf->instrument->velocity_hi = psf->instrument->key_hi = 127 ;
+
+       return 0 ;
+} /* wav_read_smpl_chunk */
+
+/*
+** The acid chunk goes a little something like this:
+**
+** 4 bytes          'acid'
+** 4 bytes (int)     length of chunk starting at next byte
+**
+** 4 bytes (int)     type of file:
+**        this appears to be a bit mask,however some combinations
+**        are probably impossible and/or qualified as "errors"
+**
+**        0x01 On: One Shot         Off: Loop
+**        0x02 On: Root note is Set Off: No root
+**        0x04 On: Stretch is On,   Off: Strech is OFF
+**        0x08 On: Disk Based       Off: Ram based
+**        0x10 On: ??????????       Off: ????????? (Acidizer puts that ON)
+**
+** 2 bytes (short)      root note
+**        if type 0x10 is OFF : [C,C#,(...),B] -> [0x30 to 0x3B]
+**        if type 0x10 is ON  : [C,C#,(...),B] -> [0x3C to 0x47]
+**         (both types fit on same MIDI pitch albeit different octaves, so who cares)
+**
+** 2 bytes (short)      ??? always set to 0x8000
+** 4 bytes (float)      ??? seems to be always 0
+** 4 bytes (int)        number of beats
+** 2 bytes (short)      meter denominator   //always 4 in SF/ACID
+** 2 bytes (short)      meter numerator     //always 4 in SF/ACID
+**                      //are we sure about the order?? usually its num/denom
+** 4 bytes (float)      tempo
+**
+*/
+
+static int
+wav_read_acid_chunk (SF_PRIVATE *psf, unsigned int chunklen)
+{      unsigned int bytesread = 0 ;
+       int     beats, flags ;
+       short rootnote, q1, meter_denom, meter_numer ;
+       float q2, tempo ;
+
+       chunklen += (chunklen & 1) ;
+
+       bytesread += psf_binheader_readf (psf, "422f", &flags, &rootnote, &q1, &q2) ;
+
+       LSF_SNPRINTF (psf->u.cbuf, sizeof (psf->u.cbuf), "%f", q2) ;
+
+       psf_log_printf (psf, "  Flags     : 0x%04x (%s,%s,%s,%s,%s)\n", flags,
+                       (flags & 0x01) ? "OneShot" : "Loop",
+                       (flags & 0x02) ? "RootNoteValid" : "RootNoteInvalid",
+                       (flags & 0x04) ? "StretchOn" : "StretchOff",
+                       (flags & 0x08) ? "DiskBased" : "RAMBased",
+                       (flags & 0x10) ? "??On" : "??Off") ;
+
+       psf_log_printf (psf, "  Root note : 0x%x\n  ????      : 0x%04x\n  ????      : %s\n",
+                               rootnote, q1, psf->u.cbuf) ;
+
+       bytesread += psf_binheader_readf (psf, "422f", &beats, &meter_denom, &meter_numer, &tempo) ;
+       LSF_SNPRINTF (psf->u.cbuf, sizeof (psf->u.cbuf), "%f", tempo) ;
+       psf_log_printf (psf, "  Beats     : %d\n  Meter     : %d/%d\n  Tempo     : %s\n",
+                               beats, meter_numer, meter_denom, psf->u.cbuf) ;
+
+       psf_binheader_readf (psf, "j", chunklen - bytesread) ;
+
+       if ((psf->loop_info = calloc (1, sizeof (SF_LOOP_INFO))) == NULL)
+               return SFE_MALLOC_FAILED ;
+
+       psf->loop_info->time_sig_num    = meter_numer ;
+       psf->loop_info->time_sig_den    = meter_denom ;
+       psf->loop_info->loop_mode               = (flags & 0x01) ? SF_LOOP_NONE : SF_LOOP_FORWARD ;
+       psf->loop_info->num_beats               = beats ;
+       psf->loop_info->bpm                             = tempo ;
+       psf->loop_info->root_key                = (flags & 0x02) ? rootnote : -1 ;
+
+       return 0 ;
+} /* wav_read_acid_chunk */
+
+int
+wav_read_bext_chunk (SF_PRIVATE *psf, unsigned int chunksize)
+{
+       SF_BROADCAST_INFO* b ;
+
+       if ((psf->broadcast_info = calloc (1, sizeof (SF_BROADCAST_INFO))) == NULL)
+       {       psf->error = SFE_MALLOC_FAILED ;
+               return -1 ;
+               } ;
+
+       b = psf->broadcast_info ;
+
+       psf_binheader_readf (psf, "b", b->description, sizeof (b->description)) ;
+       psf_binheader_readf (psf, "b", b->originator, sizeof (b->originator)) ;
+       psf_binheader_readf (psf, "b", b->originator_reference, sizeof (b->originator_reference)) ;
+       psf_binheader_readf (psf, "b", b->origination_date, sizeof (b->origination_date)) ;
+       psf_binheader_readf (psf, "b", b->origination_time, sizeof (b->origination_time)) ;
+       psf_binheader_readf (psf, "442", &b->time_reference_low, &b->time_reference_high, &b->version) ;
+       psf_binheader_readf (psf, "bj", &b->umid, sizeof (b->umid), 190) ;
+
+       if (chunksize > WAV_BEXT_CHUNK_SIZE)
+       {       /* File has coding history data. */
+
+               b->coding_history_size = chunksize - WAV_BEXT_CHUNK_SIZE ;
+
+               if (b->coding_history_size > SIGNED_SIZEOF (b->coding_history))
+               {       free (psf->broadcast_info) ;
+                       psf->broadcast_info = NULL ;
+                       psf->error = SFE_MALLOC_FAILED ;
+                       return -1 ;
+                       } ;
+
+               /* We do not parse the coding history */
+               psf_binheader_readf (psf, "b", b->coding_history, b->coding_history_size) ;
+               b->coding_history [sizeof (b->coding_history) - 1] = 0 ;
+               } ;
+
+       return 0 ;
+} /* wav_read_bext_chunk */
+
+static int
+wav_write_bext_chunk (SF_PRIVATE *psf)
+{      SF_BROADCAST_INFO *b ;
+
+       if ((b = psf->broadcast_info) == NULL)
+               return -1 ;
+
+       psf_binheader_writef (psf, "m4", bext_MARKER, WAV_BEXT_CHUNK_SIZE + b->coding_history_size) ;
+
+       /*
+       **      Note that it is very important the the field widths of the SF_BROADCAST_INFO
+       **      struct match those for the bext chunk fields.
+       */
+
+       psf_binheader_writef (psf, "b", b->description, sizeof (b->description)) ;
+       psf_binheader_writef (psf, "b", b->originator, sizeof (b->originator)) ;
+       psf_binheader_writef (psf, "b", b->originator_reference, sizeof (b->originator_reference)) ;
+       psf_binheader_writef (psf, "b", b->origination_date, sizeof (b->origination_date)) ;
+       psf_binheader_writef (psf, "b", b->origination_time, sizeof (b->origination_time)) ;
+       psf_binheader_writef (psf, "442", b->time_reference_low, b->time_reference_high, b->version) ;
+       psf_binheader_writef (psf, "b", b->umid, sizeof (b->umid)) ;
+       psf_binheader_writef (psf, "z", make_size_t (190)) ;
+
+       if (b->coding_history_size > 0)
+               psf_binheader_writef (psf, "b", b->coding_history, b->coding_history_size) ;
+
+       return 0 ;
+} /* wav_write_bext_chunk */
+
+/*
+** Do not edit or modify anything in this comment block.
+** The arch-tag line is a file identity tag for the GNU Arch
+** revision control system.
+**
+** arch-tag: 9c551689-a1d8-4905-9f56-26a204374f18
+*/
diff --git a/libs/libsndfile/src/wav_w64.c b/libs/libsndfile/src/wav_w64.c
new file mode 100644 (file)
index 0000000..85cb132
--- /dev/null
@@ -0,0 +1,494 @@
+/*
+** Copyright (C) 1999-2005 Erik de Castro Lopo <erikd@mega-nerd.com>
+** Copyright (C) 2004-2005 David Viens <davidv@plogue.com>
+**
+** This program is free software; you can redistribute it and/or modify
+** it under the terms of the GNU Lesser General Public License as published by
+** the Free Software Foundation; either version 2.1 of the License, or
+** (at your option) any later version.
+**
+** This program is distributed in the hope that it will be useful,
+** but WITHOUT ANY WARRANTY; without even the implied warranty of
+** MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+** GNU Lesser General Public License for more details.
+**
+** You should have received a copy of the GNU Lesser General Public License
+** along with this program; if not, write to the Free Software
+** Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA.
+*/
+
+#include       "sfconfig.h"
+
+#include       <stdio.h>
+#include       <string.h>
+#include       <ctype.h>
+#include       <time.h>
+
+#include       "sndfile.h"
+#include       "sfendian.h"
+#include       "common.h"
+#include       "wav_w64.h"
+
+/*  Known WAVEFORMATEXTENSIBLE GUIDS.  */
+static const EXT_SUBFORMAT MSGUID_SUBTYPE_PCM =
+{      0x00000001, 0x0000, 0x0010, {   0x80, 0x00, 0x00, 0xaa, 0x00, 0x38, 0x9b, 0x71 }
+} ;
+
+static const EXT_SUBFORMAT MSGUID_SUBTYPE_MS_ADPCM =
+{      0x00000002, 0x0000, 0x0010, {   0x80, 0x00, 0x00, 0xaa, 0x00, 0x38, 0x9b, 0x71 }
+} ;
+
+static const EXT_SUBFORMAT MSGUID_SUBTYPE_IEEE_FLOAT =
+{      0x00000003, 0x0000, 0x0010, {   0x80, 0x00, 0x00, 0xaa, 0x00, 0x38, 0x9b, 0x71 }
+} ;
+
+static const EXT_SUBFORMAT MSGUID_SUBTYPE_ALAW =
+{      0x00000006, 0x0000, 0x0010, {   0x80, 0x00, 0x00, 0xaa, 0x00, 0x38, 0x9b, 0x71 }
+} ;
+
+static const EXT_SUBFORMAT MSGUID_SUBTYPE_MULAW =
+{      0x00000007, 0x0000, 0x0010, {   0x80, 0x00, 0x00, 0xaa, 0x00, 0x38, 0x9b, 0x71 }
+} ;
+
+/*
+** the next two are from
+** http://dream.cs.bath.ac.uk/researchdev/wave-ex/bformat.html
+*/
+
+static const EXT_SUBFORMAT MSGUID_SUBTYPE_AMBISONIC_B_FORMAT_PCM =
+{      0x00000001, 0x0721, 0x11d3, {   0x86, 0x44, 0xC8, 0xC1, 0xCA, 0x00, 0x00, 0x00 }
+} ;
+
+static const EXT_SUBFORMAT MSGUID_SUBTYPE_AMBISONIC_B_FORMAT_IEEE_FLOAT =
+{      0x00000003, 0x0721, 0x11d3, {   0x86, 0x44, 0xC8, 0xC1, 0xCA, 0x00, 0x00, 0x00 }
+} ;
+
+
+#if 0
+/* maybe interesting one day to read the following through sf_read_raw */
+/* http://www.bath.ac.uk/~masrwd/pvocex/pvocex.html */
+static const EXT_SUBFORMAT MSGUID_SUBTYPE_PVOCEX =
+{      0x8312B9C2, 0x2E6E, 0x11d4, {   0xA8, 0x24, 0xDE, 0x5B, 0x96, 0xC3, 0xAB, 0x21 }
+} ;
+#endif
+
+/*------------------------------------------------------------------------------
+ * Private static functions.
+ */
+
+static int
+wavex_write_guid_equal (const EXT_SUBFORMAT * first, const EXT_SUBFORMAT * second)
+{      return !memcmp (first, second, sizeof (EXT_SUBFORMAT)) ;
+} /* wavex_write_guid_equal */
+
+
+
+int
+wav_w64_read_fmt_chunk (SF_PRIVATE *psf, WAV_FMT *wav_fmt, int structsize)
+{      int     bytesread, k, bytespersec = 0 ;
+
+       memset (wav_fmt, 0, sizeof (WAV_FMT)) ;
+
+       if (structsize < 16)
+               return SFE_WAV_FMT_SHORT ;
+
+       /* assume psf->rwf_endian is already properly set */
+
+       /* Read the minimal WAV file header here. */
+       bytesread =
+       psf_binheader_readf (psf, "224422", &(wav_fmt->format), &(wav_fmt->min.channels),
+                       &(wav_fmt->min.samplerate), &(wav_fmt->min.bytespersec),
+                       &(wav_fmt->min.blockalign), &(wav_fmt->min.bitwidth)) ;
+
+       psf_log_printf (psf, "  Format        : 0x%X => %s\n", wav_fmt->format, wav_w64_format_str (wav_fmt->format)) ;
+       psf_log_printf (psf, "  Channels      : %d\n", wav_fmt->min.channels) ;
+       psf_log_printf (psf, "  Sample Rate   : %d\n", wav_fmt->min.samplerate) ;
+       psf_log_printf (psf, "  Block Align   : %d\n", wav_fmt->min.blockalign) ;
+
+       if (wav_fmt->format == WAVE_FORMAT_PCM && wav_fmt->min.bitwidth == 24 &&
+                       wav_fmt->min.blockalign == 4 * wav_fmt->min.channels)
+       {
+               psf_log_printf (psf, "\nInvalid file generated by Syntrillium's Cooledit!\n"
+                               "Treating as WAVE_FORMAT_IEEE_FLOAT 32 bit floating point file.\n\n") ;
+               psf_log_printf (psf, "  Bit Width     : 24 (should be 32)\n") ;
+               wav_fmt->min.bitwidth = 32 ;
+               wav_fmt->format = WAVE_FORMAT_IEEE_FLOAT ;
+               }
+       else if (wav_fmt->format != WAVE_FORMAT_GSM610 && wav_fmt->min.bitwidth == 0)
+               psf_log_printf (psf, "  Bit Width     : %d (should not be 0)\n", wav_fmt->min.bitwidth) ;
+       else if (wav_fmt->format == WAVE_FORMAT_GSM610 && wav_fmt->min.bitwidth != 0)
+               psf_log_printf (psf, "  Bit Width     : %d (should be 0)\n", wav_fmt->min.bitwidth) ;
+       else
+               psf_log_printf (psf, "  Bit Width     : %d\n", wav_fmt->min.bitwidth) ;
+
+       psf->sf.samplerate      = wav_fmt->min.samplerate ;
+       psf->sf.frames          = 0 ;                                   /* Correct this when reading data chunk. */
+       psf->sf.channels        = wav_fmt->min.channels ;
+
+       switch (wav_fmt->format)
+       {       case WAVE_FORMAT_PCM :
+               case WAVE_FORMAT_IEEE_FLOAT :
+                               bytespersec = wav_fmt->min.samplerate * wav_fmt->min.blockalign ;
+                               if (wav_fmt->min.bytespersec != (unsigned) bytespersec)
+                                       psf_log_printf (psf, "  Bytes/sec     : %d (should be %d)\n", wav_fmt->min.bytespersec, bytespersec) ;
+                               else
+                                       psf_log_printf (psf, "  Bytes/sec     : %d\n", wav_fmt->min.bytespersec) ;
+
+                               psf->bytewidth = BITWIDTH2BYTES (wav_fmt->min.bitwidth) ;
+                               break ;
+
+               case WAVE_FORMAT_ALAW :
+               case WAVE_FORMAT_MULAW :
+                               if (wav_fmt->min.bytespersec / wav_fmt->min.blockalign != wav_fmt->min.samplerate)
+                                       psf_log_printf (psf, "  Bytes/sec     : %d (should be %d)\n", wav_fmt->min.bytespersec, wav_fmt->min.samplerate * wav_fmt->min.blockalign) ;
+                               else
+                                       psf_log_printf (psf, "  Bytes/sec     : %d\n", wav_fmt->min.bytespersec) ;
+
+                               psf->bytewidth = 1 ;
+                               if (structsize >= 18)
+                               {       bytesread += psf_binheader_readf (psf, "2", &(wav_fmt->size20.extrabytes)) ;
+                                       psf_log_printf (psf, "  Extra Bytes   : %d\n", wav_fmt->size20.extrabytes) ;
+                                       } ;
+                               break ;
+
+               case WAVE_FORMAT_IMA_ADPCM :
+                               if (wav_fmt->min.bitwidth != 4)
+                                       return SFE_WAV_ADPCM_NOT4BIT ;
+                               if (wav_fmt->min.channels < 1 || wav_fmt->min.channels > 2)
+                                       return SFE_WAV_ADPCM_CHANNELS ;
+
+                               bytesread +=
+                               psf_binheader_readf (psf, "22", &(wav_fmt->ima.extrabytes), &(wav_fmt->ima.samplesperblock)) ;
+
+                               bytespersec = (wav_fmt->ima.samplerate * wav_fmt->ima.blockalign) / wav_fmt->ima.samplesperblock ;
+                               if (wav_fmt->ima.bytespersec != (unsigned) bytespersec)
+                                       psf_log_printf (psf, "  Bytes/sec     : %d (should be %d)\n", wav_fmt->ima.bytespersec, bytespersec) ;
+                               else
+                                       psf_log_printf (psf, "  Bytes/sec     : %d\n", wav_fmt->ima.bytespersec) ;
+
+                               psf->bytewidth = 2 ;
+                               psf_log_printf (psf, "  Extra Bytes   : %d\n", wav_fmt->ima.extrabytes) ;
+                               psf_log_printf (psf, "  Samples/Block : %d\n", wav_fmt->ima.samplesperblock) ;
+                               break ;
+
+               case WAVE_FORMAT_MS_ADPCM :
+                               if (wav_fmt->msadpcm.bitwidth != 4)
+                                       return SFE_WAV_ADPCM_NOT4BIT ;
+                               if (wav_fmt->msadpcm.channels < 1 || wav_fmt->msadpcm.channels > 2)
+                                       return SFE_WAV_ADPCM_CHANNELS ;
+
+                               bytesread +=
+                               psf_binheader_readf (psf, "222", &(wav_fmt->msadpcm.extrabytes),
+                                               &(wav_fmt->msadpcm.samplesperblock), &(wav_fmt->msadpcm.numcoeffs)) ;
+
+                               bytespersec = (wav_fmt->min.samplerate * wav_fmt->min.blockalign) / wav_fmt->msadpcm.samplesperblock ;
+                               if (wav_fmt->min.bytespersec == (unsigned) bytespersec)
+                                       psf_log_printf (psf, "  Bytes/sec     : %d\n", wav_fmt->min.bytespersec) ;
+                               else if (wav_fmt->min.bytespersec == (wav_fmt->min.samplerate / wav_fmt->msadpcm.samplesperblock) * wav_fmt->min.blockalign)
+                                       psf_log_printf (psf, "  Bytes/sec     : %d (should be %d (MS BUG!))\n", wav_fmt->min.bytespersec, bytespersec) ;
+                               else
+                                       psf_log_printf (psf, "  Bytes/sec     : %d (should be %d)\n", wav_fmt->min.bytespersec, bytespersec) ;
+
+
+                               psf->bytewidth = 2 ;
+                               psf_log_printf (psf, "  Extra Bytes   : %d\n", wav_fmt->msadpcm.extrabytes) ;
+                               psf_log_printf (psf, "  Samples/Block : %d\n", wav_fmt->msadpcm.samplesperblock) ;
+                               if (wav_fmt->msadpcm.numcoeffs > SIGNED_SIZEOF (MS_ADPCM_WAV_FMT) / SIGNED_SIZEOF (int))
+                               {       psf_log_printf (psf, "  No. of Coeffs : %d ****\n", wav_fmt->msadpcm.numcoeffs) ;
+                                       wav_fmt->msadpcm.numcoeffs = SIGNED_SIZEOF (MS_ADPCM_WAV_FMT) / SIGNED_SIZEOF (int) ;
+                                       }
+                               else
+                                       psf_log_printf (psf, "  No. of Coeffs : %d\n", wav_fmt->msadpcm.numcoeffs) ;
+
+                               psf_log_printf (psf, "    Index   Coeffs1   Coeffs2\n") ;
+                               for (k = 0 ; k < wav_fmt->msadpcm.numcoeffs ; k++)
+                               {       bytesread +=
+                                       psf_binheader_readf (psf, "22", &(wav_fmt->msadpcm.coeffs [k].coeff1), &(wav_fmt->msadpcm.coeffs [k].coeff2)) ;
+                                       LSF_SNPRINTF (psf->u.cbuf, sizeof (psf->u.cbuf), "     %2d     %7d   %7d\n", k, wav_fmt->msadpcm.coeffs [k].coeff1, wav_fmt->msadpcm.coeffs [k].coeff2) ;
+                                       psf_log_printf (psf, psf->u.cbuf) ;
+                                       } ;
+                               break ;
+
+               case WAVE_FORMAT_GSM610 :
+                               if (wav_fmt->gsm610.channels != 1 || wav_fmt->gsm610.blockalign != 65)
+                                       return SFE_WAV_GSM610_FORMAT ;
+
+                               bytesread +=
+                               psf_binheader_readf (psf, "22", &(wav_fmt->gsm610.extrabytes), &(wav_fmt->gsm610.samplesperblock)) ;
+
+                               if (wav_fmt->gsm610.samplesperblock != 320)
+                                       return SFE_WAV_GSM610_FORMAT ;
+
+                               bytespersec = (wav_fmt->gsm610.samplerate * wav_fmt->gsm610.blockalign) / wav_fmt->gsm610.samplesperblock ;
+                               if (wav_fmt->gsm610.bytespersec != (unsigned) bytespersec)
+                                       psf_log_printf (psf, "  Bytes/sec     : %d (should be %d)\n", wav_fmt->gsm610.bytespersec, bytespersec) ;
+                               else
+                                       psf_log_printf (psf, "  Bytes/sec     : %d\n", wav_fmt->gsm610.bytespersec) ;
+
+                               psf->bytewidth = 2 ;
+                               psf_log_printf (psf, "  Extra Bytes   : %d\n", wav_fmt->gsm610.extrabytes) ;
+                               psf_log_printf (psf, "  Samples/Block : %d\n", wav_fmt->gsm610.samplesperblock) ;
+                               break ;
+
+               case WAVE_FORMAT_EXTENSIBLE :
+                               if (wav_fmt->ext.bytespersec / wav_fmt->ext.blockalign != wav_fmt->ext.samplerate)
+                                       psf_log_printf (psf, "  Bytes/sec     : %d (should be %d)\n", wav_fmt->ext.bytespersec, wav_fmt->ext.samplerate * wav_fmt->ext.blockalign) ;
+                               else
+                                       psf_log_printf (psf, "  Bytes/sec     : %d\n", wav_fmt->ext.bytespersec) ;
+
+                               bytesread +=
+                               psf_binheader_readf (psf, "224", &(wav_fmt->ext.extrabytes), &(wav_fmt->ext.validbits),
+                                               &(wav_fmt->ext.channelmask)) ;
+
+                               psf_log_printf (psf, "  Valid Bits    : %d\n", wav_fmt->ext.validbits) ;
+                               psf_log_printf (psf, "  Channel Mask  : 0x%X\n", wav_fmt->ext.channelmask) ;
+
+                               bytesread +=
+                               psf_binheader_readf (psf, "422", &(wav_fmt->ext.esf.esf_field1), &(wav_fmt->ext.esf.esf_field2),
+                                               &(wav_fmt->ext.esf.esf_field3)) ;
+
+                               /* compare the esf_fields with each known GUID? and print? */
+                               psf_log_printf (psf, "  Subformat\n") ;
+                               psf_log_printf (psf, "    esf_field1 : 0x%X\n", wav_fmt->ext.esf.esf_field1) ;
+                               psf_log_printf (psf, "    esf_field2 : 0x%X\n", wav_fmt->ext.esf.esf_field2) ;
+                               psf_log_printf (psf, "    esf_field3 : 0x%X\n", wav_fmt->ext.esf.esf_field3) ;
+                               psf_log_printf (psf, "    esf_field4 : ") ;
+                               for (k = 0 ; k < 8 ; k++)
+                               {       bytesread += psf_binheader_readf (psf, "1", &(wav_fmt->ext.esf.esf_field4 [k])) ;
+                                       psf_log_printf (psf, "0x%X ", wav_fmt->ext.esf.esf_field4 [k] & 0xFF) ;
+                                       } ;
+                               psf_log_printf (psf, "\n") ;
+                               psf->bytewidth = BITWIDTH2BYTES (wav_fmt->ext.bitwidth) ;
+
+                               /* Compare GUIDs for known ones. */
+                               if (wavex_write_guid_equal (&wav_fmt->ext.esf, &MSGUID_SUBTYPE_PCM)
+                                       || wavex_write_guid_equal (&wav_fmt->ext.esf, &MSGUID_SUBTYPE_AMBISONIC_B_FORMAT_PCM))
+                               {       psf->sf.format = SF_FORMAT_WAVEX | u_bitwidth_to_subformat (psf->bytewidth * 8) ;
+                                       psf_log_printf (psf, "    format : pcm\n") ;
+                                       }
+                               else if (wavex_write_guid_equal (&wav_fmt->ext.esf, &MSGUID_SUBTYPE_MS_ADPCM))
+                               {       psf->sf.format = (SF_FORMAT_WAVEX | SF_FORMAT_MS_ADPCM) ;
+                                       psf_log_printf (psf, "    format : ms adpcm\n") ;
+                                       }
+                               else if (wavex_write_guid_equal (&wav_fmt->ext.esf, &MSGUID_SUBTYPE_IEEE_FLOAT)
+                                               || wavex_write_guid_equal (&wav_fmt->ext.esf, &MSGUID_SUBTYPE_AMBISONIC_B_FORMAT_PCM))
+                               {       psf->sf.format = SF_FORMAT_WAVEX | ((psf->bytewidth == 8) ? SF_FORMAT_DOUBLE : SF_FORMAT_FLOAT) ;
+                                       psf_log_printf (psf, "    format : IEEE float\n") ;
+                                       }
+                               else if (wavex_write_guid_equal (&wav_fmt->ext.esf, &MSGUID_SUBTYPE_ALAW))
+                               {       psf->sf.format = (SF_FORMAT_WAVEX | SF_FORMAT_ALAW) ;
+                                       psf_log_printf (psf, "    format : A-law\n") ;
+                                       }
+                               else if (wavex_write_guid_equal (&wav_fmt->ext.esf, &MSGUID_SUBTYPE_MULAW))
+                               {       psf->sf.format = (SF_FORMAT_WAVEX | SF_FORMAT_ULAW) ;
+                                       psf_log_printf (psf, "    format : u-law\n") ;
+                                       }
+                               else
+                                       return SFE_UNIMPLEMENTED ;
+                               break ;
+
+               case WAVE_FORMAT_G721_ADPCM :
+                               psf_log_printf (psf, "  Bytes/sec     : %d\n", wav_fmt->g72x.bytespersec) ;
+                               if (structsize >= 20)
+                               {       bytesread += psf_binheader_readf (psf, "22", &(wav_fmt->g72x.extrabytes), &(wav_fmt->g72x.auxblocksize)) ;
+                                       if (wav_fmt->g72x.extrabytes == 0)
+                                               psf_log_printf (psf, "  Extra Bytes   : %d (should be 2)\n", wav_fmt->g72x.extrabytes) ;
+                                       else
+                                               psf_log_printf (psf, "  Extra Bytes   : %d\n", wav_fmt->g72x.extrabytes) ;
+                                               psf_log_printf (psf, "  Aux Blk Size  : %d\n", wav_fmt->g72x.auxblocksize) ;
+                                       }
+                               else if (structsize == 18)
+                               {       bytesread += psf_binheader_readf (psf, "2", &(wav_fmt->g72x.extrabytes)) ;
+                                       psf_log_printf (psf, "  Extra Bytes   : %d%s\n", wav_fmt->g72x.extrabytes, wav_fmt->g72x.extrabytes != 0 ? " (should be 0)" : "") ;
+                                       }
+                               else
+                                       psf_log_printf (psf, "*** 'fmt ' chunk should be bigger than this!\n") ;
+                               break ;
+
+               default :
+                               psf_log_printf (psf, "*** No 'fmt ' chunk dumper for this format!\n") ;
+                               break ;
+               } ;
+
+       if (bytesread > structsize)
+       {       psf_log_printf (psf, "*** wav_w64_read_fmt_chunk (bytesread > structsize)\n") ;
+               return SFE_W64_FMT_SHORT ;
+               }
+       else
+               psf_binheader_readf (psf, "j", structsize - bytesread) ;
+
+       psf->blockwidth = wav_fmt->min.channels * psf->bytewidth ;
+
+       return 0 ;
+} /* wav_w64_read_fmt_chunk */
+
+void
+wavex_write_guid (SF_PRIVATE *psf, const EXT_SUBFORMAT * subformat)
+{
+       psf_binheader_writef (psf, "422b", subformat->esf_field1,
+                                       subformat->esf_field2, subformat->esf_field3,
+                                       subformat->esf_field4, 8) ;
+} /* wavex_write_guid */
+
+
+/*==============================================================================
+*/
+
+typedef struct
+{      int                     ID ;
+       const char      *name ;
+} WAV_FORMAT_DESC ;
+
+#define STR(x)                 #x
+#define FORMAT_TYPE(x) { x, STR (x) }
+
+static WAV_FORMAT_DESC wave_descs [] =
+{      FORMAT_TYPE     (WAVE_FORMAT_PCM),
+       FORMAT_TYPE (WAVE_FORMAT_MS_ADPCM),
+       FORMAT_TYPE (WAVE_FORMAT_IEEE_FLOAT),
+       FORMAT_TYPE (WAVE_FORMAT_VSELP),
+       FORMAT_TYPE (WAVE_FORMAT_IBM_CVSD),
+       FORMAT_TYPE (WAVE_FORMAT_ALAW),
+       FORMAT_TYPE (WAVE_FORMAT_MULAW),
+       FORMAT_TYPE (WAVE_FORMAT_OKI_ADPCM),
+       FORMAT_TYPE (WAVE_FORMAT_IMA_ADPCM),
+       FORMAT_TYPE (WAVE_FORMAT_MEDIASPACE_ADPCM),
+       FORMAT_TYPE (WAVE_FORMAT_SIERRA_ADPCM),
+       FORMAT_TYPE (WAVE_FORMAT_G723_ADPCM),
+       FORMAT_TYPE (WAVE_FORMAT_DIGISTD),
+       FORMAT_TYPE (WAVE_FORMAT_DIGIFIX),
+       FORMAT_TYPE (WAVE_FORMAT_DIALOGIC_OKI_ADPCM),
+       FORMAT_TYPE (WAVE_FORMAT_MEDIAVISION_ADPCM),
+       FORMAT_TYPE (WAVE_FORMAT_CU_CODEC),
+       FORMAT_TYPE (WAVE_FORMAT_YAMAHA_ADPCM),
+       FORMAT_TYPE (WAVE_FORMAT_SONARC),
+       FORMAT_TYPE (WAVE_FORMAT_DSPGROUP_TRUESPEECH),
+       FORMAT_TYPE (WAVE_FORMAT_ECHOSC1),
+       FORMAT_TYPE (WAVE_FORMAT_AUDIOFILE_AF36),
+       FORMAT_TYPE (WAVE_FORMAT_APTX),
+       FORMAT_TYPE (WAVE_FORMAT_AUDIOFILE_AF10),
+       FORMAT_TYPE (WAVE_FORMAT_PROSODY_1612),
+       FORMAT_TYPE (WAVE_FORMAT_LRC),
+       FORMAT_TYPE (WAVE_FORMAT_DOLBY_AC2),
+       FORMAT_TYPE (WAVE_FORMAT_GSM610),
+       FORMAT_TYPE (WAVE_FORMAT_MSNAUDIO),
+       FORMAT_TYPE (WAVE_FORMAT_ANTEX_ADPCME),
+       FORMAT_TYPE (WAVE_FORMAT_CONTROL_RES_VQLPC),
+       FORMAT_TYPE (WAVE_FORMAT_DIGIREAL),
+       FORMAT_TYPE (WAVE_FORMAT_DIGIADPCM),
+       FORMAT_TYPE (WAVE_FORMAT_CONTROL_RES_CR10),
+       FORMAT_TYPE (WAVE_FORMAT_NMS_VBXADPCM),
+       FORMAT_TYPE (WAVE_FORMAT_ROLAND_RDAC),
+       FORMAT_TYPE (WAVE_FORMAT_ECHOSC3),
+       FORMAT_TYPE (WAVE_FORMAT_ROCKWELL_ADPCM),
+       FORMAT_TYPE (WAVE_FORMAT_ROCKWELL_DIGITALK),
+       FORMAT_TYPE (WAVE_FORMAT_XEBEC),
+       FORMAT_TYPE (WAVE_FORMAT_G721_ADPCM),
+       FORMAT_TYPE (WAVE_FORMAT_G728_CELP),
+       FORMAT_TYPE (WAVE_FORMAT_MSG723),
+       FORMAT_TYPE (WAVE_FORMAT_MPEG),
+       FORMAT_TYPE (WAVE_FORMAT_RT24),
+       FORMAT_TYPE (WAVE_FORMAT_PAC),
+       FORMAT_TYPE (WAVE_FORMAT_MPEGLAYER3),
+       FORMAT_TYPE (WAVE_FORMAT_LUCENT_G723),
+       FORMAT_TYPE (WAVE_FORMAT_CIRRUS),
+       FORMAT_TYPE (WAVE_FORMAT_ESPCM),
+       FORMAT_TYPE (WAVE_FORMAT_VOXWARE),
+       FORMAT_TYPE (WAVE_FORMAT_CANOPUS_ATRAC),
+       FORMAT_TYPE (WAVE_FORMAT_G726_ADPCM),
+       FORMAT_TYPE (WAVE_FORMAT_G722_ADPCM),
+       FORMAT_TYPE (WAVE_FORMAT_DSAT),
+       FORMAT_TYPE (WAVE_FORMAT_DSAT_DISPLAY),
+       FORMAT_TYPE (WAVE_FORMAT_VOXWARE_BYTE_ALIGNED),
+       FORMAT_TYPE (WAVE_FORMAT_VOXWARE_AC8),
+       FORMAT_TYPE (WAVE_FORMAT_VOXWARE_AC10),
+       FORMAT_TYPE (WAVE_FORMAT_VOXWARE_AC16),
+       FORMAT_TYPE (WAVE_FORMAT_VOXWARE_AC20),
+       FORMAT_TYPE (WAVE_FORMAT_VOXWARE_RT24),
+       FORMAT_TYPE (WAVE_FORMAT_VOXWARE_RT29),
+       FORMAT_TYPE (WAVE_FORMAT_VOXWARE_RT29HW),
+       FORMAT_TYPE (WAVE_FORMAT_VOXWARE_VR12),
+       FORMAT_TYPE (WAVE_FORMAT_VOXWARE_VR18),
+       FORMAT_TYPE (WAVE_FORMAT_VOXWARE_TQ40),
+       FORMAT_TYPE (WAVE_FORMAT_SOFTSOUND),
+       FORMAT_TYPE (WAVE_FORMAT_VOXARE_TQ60),
+       FORMAT_TYPE (WAVE_FORMAT_MSRT24),
+       FORMAT_TYPE (WAVE_FORMAT_G729A),
+       FORMAT_TYPE (WAVE_FORMAT_MVI_MV12),
+       FORMAT_TYPE (WAVE_FORMAT_DF_G726),
+       FORMAT_TYPE (WAVE_FORMAT_DF_GSM610),
+       FORMAT_TYPE (WAVE_FORMAT_ONLIVE),
+       FORMAT_TYPE (WAVE_FORMAT_SBC24),
+       FORMAT_TYPE (WAVE_FORMAT_DOLBY_AC3_SPDIF),
+       FORMAT_TYPE (WAVE_FORMAT_ZYXEL_ADPCM),
+       FORMAT_TYPE (WAVE_FORMAT_PHILIPS_LPCBB),
+       FORMAT_TYPE (WAVE_FORMAT_PACKED),
+       FORMAT_TYPE (WAVE_FORMAT_RHETOREX_ADPCM),
+       FORMAT_TYPE (IBM_FORMAT_MULAW),
+       FORMAT_TYPE (IBM_FORMAT_ALAW),
+       FORMAT_TYPE (IBM_FORMAT_ADPCM),
+       FORMAT_TYPE (WAVE_FORMAT_VIVO_G723),
+       FORMAT_TYPE (WAVE_FORMAT_VIVO_SIREN),
+       FORMAT_TYPE (WAVE_FORMAT_DIGITAL_G723),
+       FORMAT_TYPE (WAVE_FORMAT_CREATIVE_ADPCM),
+       FORMAT_TYPE (WAVE_FORMAT_CREATIVE_FASTSPEECH8),
+       FORMAT_TYPE (WAVE_FORMAT_CREATIVE_FASTSPEECH10),
+       FORMAT_TYPE (WAVE_FORMAT_QUARTERDECK),
+       FORMAT_TYPE (WAVE_FORMAT_FM_TOWNS_SND),
+       FORMAT_TYPE (WAVE_FORMAT_BZV_DIGITAL),
+       FORMAT_TYPE (WAVE_FORMAT_VME_VMPCM),
+       FORMAT_TYPE (WAVE_FORMAT_OLIGSM),
+       FORMAT_TYPE (WAVE_FORMAT_OLIADPCM),
+       FORMAT_TYPE (WAVE_FORMAT_OLICELP),
+       FORMAT_TYPE (WAVE_FORMAT_OLISBC),
+       FORMAT_TYPE (WAVE_FORMAT_OLIOPR),
+       FORMAT_TYPE (WAVE_FORMAT_LH_CODEC),
+       FORMAT_TYPE (WAVE_FORMAT_NORRIS),
+       FORMAT_TYPE (WAVE_FORMAT_SOUNDSPACE_MUSICOMPRESS),
+       FORMAT_TYPE (WAVE_FORMAT_DVM),
+       FORMAT_TYPE (WAVE_FORMAT_INTERWAV_VSC112),
+       FORMAT_TYPE (WAVE_FORMAT_EXTENSIBLE),
+} ;
+
+char const*
+wav_w64_format_str (int k)
+{      int lower, upper, mid ;
+
+       lower = -1 ;
+       upper = sizeof (wave_descs) / sizeof (WAV_FORMAT_DESC) ;
+
+       /* binary search */
+       if ((wave_descs [0].ID <= k) & (k <= wave_descs [upper - 1].ID))
+       {
+               while (lower + 1 < upper)
+               {       mid = (upper + lower) / 2 ;
+
+                       if (k == wave_descs [mid].ID)
+                               return wave_descs [mid].name ;
+                       if (k < wave_descs [mid].ID)
+                               upper = mid ;
+                       else
+                               lower = mid ;
+                       } ;
+               } ;
+
+       return "Unknown format" ;
+} /* wav_w64_format_str */
+
+int
+wav_w64_srate2blocksize (int srate_chan_product)
+{      if (srate_chan_product < 12000)
+               return 256 ;
+       if (srate_chan_product < 23000)
+               return 512 ;
+       if (srate_chan_product < 44000)
+               return 1024 ;
+       return 2048 ;
+} /* srate2blocksize */
+/*
+** Do not edit or modify anything in this comment block.
+** The arch-tag line is a file identity tag for the GNU Arch
+** revision control system.
+**
+** arch-tag: 43c1b1dd-8abd-43da-a8cd-44da914b64a5
+*/
diff --git a/libs/libsndfile/src/wav_w64.h b/libs/libsndfile/src/wav_w64.h
new file mode 100644 (file)
index 0000000..3f33f1b
--- /dev/null
@@ -0,0 +1,283 @@
+/*
+** Copyright (C) 1999-2005 Erik de Castro Lopo <erikd@mega-nerd.com>
+**
+** This program is free software; you can redistribute it and/or modify
+** it under the terms of the GNU Lesser General Public License as published by
+** the Free Software Foundation; either version 2.1 of the License, or
+** (at your option) any later version.
+**
+** This program is distributed in the hope that it will be useful,
+** but WITHOUT ANY WARRANTY; without even the implied warranty of
+** MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+** GNU Lesser General Public License for more details.
+**
+** You should have received a copy of the GNU Lesser General Public License
+** along with this program; if not, write to the Free Software
+** Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA.
+*/
+
+/* This file contains definitions commong to WAV and W64 files. */
+
+
+#ifndef WAV_W64_H_INCLUDED
+#define WAV_W64_H_INCLUDED
+
+/*------------------------------------------------------------------------------
+** List of known WAV format tags
+*/
+
+enum
+{
+  /* keep sorted for wav_w64_format_str() */
+       WAVE_FORMAT_UNKNOWN                                     = 0x0000,               /* Microsoft Corporation */
+       WAVE_FORMAT_PCM                                         = 0x0001,               /* Microsoft PCM format */
+       WAVE_FORMAT_MS_ADPCM                            = 0x0002,               /* Microsoft ADPCM */
+       WAVE_FORMAT_IEEE_FLOAT                          = 0x0003,               /* Micrososft 32 bit float format */
+       WAVE_FORMAT_VSELP                                       = 0x0004,               /* Compaq Computer Corporation */
+       WAVE_FORMAT_IBM_CVSD                            = 0x0005,               /* IBM Corporation */
+       WAVE_FORMAT_ALAW                                        = 0x0006,               /* Microsoft Corporation */
+       WAVE_FORMAT_MULAW                                       = 0x0007,               /* Microsoft Corporation */
+       WAVE_FORMAT_OKI_ADPCM                           = 0x0010,               /* OKI */
+       WAVE_FORMAT_IMA_ADPCM                           = 0x0011,               /* Intel Corporation */
+       WAVE_FORMAT_MEDIASPACE_ADPCM            = 0x0012,               /* Videologic */
+       WAVE_FORMAT_SIERRA_ADPCM                        = 0x0013,               /* Sierra Semiconductor Corp */
+       WAVE_FORMAT_G723_ADPCM                          = 0x0014,               /* Antex Electronics Corporation */
+       WAVE_FORMAT_DIGISTD                                     = 0x0015,               /* DSP Solutions, Inc. */
+       WAVE_FORMAT_DIGIFIX                                     = 0x0016,               /* DSP Solutions, Inc. */
+       WAVE_FORMAT_DIALOGIC_OKI_ADPCM          = 0x0017,               /*  Dialogic Corporation  */
+       WAVE_FORMAT_MEDIAVISION_ADPCM           = 0x0018,               /*  Media Vision, Inc. */
+       WAVE_FORMAT_CU_CODEC                            = 0x0019,               /* Hewlett-Packard Company */
+       WAVE_FORMAT_YAMAHA_ADPCM                        = 0x0020,               /* Yamaha Corporation of America */
+       WAVE_FORMAT_SONARC                                      = 0x0021,               /* Speech Compression */
+       WAVE_FORMAT_DSPGROUP_TRUESPEECH         = 0x0022,               /* DSP Group, Inc */
+       WAVE_FORMAT_ECHOSC1                                     = 0x0023,               /* Echo Speech Corporation */
+       WAVE_FORMAT_AUDIOFILE_AF36                      = 0x0024,               /* Audiofile, Inc. */
+       WAVE_FORMAT_APTX                                        = 0x0025,               /* Audio Processing Technology */
+       WAVE_FORMAT_AUDIOFILE_AF10                      = 0x0026,               /* Audiofile, Inc. */
+       WAVE_FORMAT_PROSODY_1612                        = 0x0027,               /* Aculab plc */
+       WAVE_FORMAT_LRC                                         = 0x0028,               /* Merging Technologies S.A. */
+       WAVE_FORMAT_DOLBY_AC2                           = 0x0030,               /* Dolby Laboratories */
+       WAVE_FORMAT_GSM610                                      = 0x0031,               /* Microsoft Corporation */
+       WAVE_FORMAT_MSNAUDIO                            = 0x0032,               /* Microsoft Corporation */
+       WAVE_FORMAT_ANTEX_ADPCME                        = 0x0033,               /* Antex Electronics Corporation */
+       WAVE_FORMAT_CONTROL_RES_VQLPC           = 0x0034,               /* Control Resources Limited */
+       WAVE_FORMAT_DIGIREAL                            = 0x0035,               /* DSP Solutions, Inc. */
+       WAVE_FORMAT_DIGIADPCM                           = 0x0036,               /* DSP Solutions, Inc. */
+       WAVE_FORMAT_CONTROL_RES_CR10            = 0x0037,               /* Control Resources Limited */
+       WAVE_FORMAT_NMS_VBXADPCM                        = 0x0038,               /* Natural MicroSystems */
+       WAVE_FORMAT_ROLAND_RDAC                         = 0x0039,               /* Roland */
+       WAVE_FORMAT_ECHOSC3                                     = 0x003A,               /* Echo Speech Corporation */
+       WAVE_FORMAT_ROCKWELL_ADPCM                      = 0x003B,               /* Rockwell International */
+       WAVE_FORMAT_ROCKWELL_DIGITALK           = 0x003C,               /* Rockwell International */
+       WAVE_FORMAT_XEBEC                                       = 0x003D,               /* Xebec Multimedia Solutions Limited */
+       WAVE_FORMAT_G721_ADPCM                          = 0x0040,               /* Antex Electronics Corporation */
+       WAVE_FORMAT_G728_CELP                           = 0x0041,               /* Antex Electronics Corporation */
+       WAVE_FORMAT_MSG723                                      = 0x0042,               /* Microsoft Corporation */
+       WAVE_FORMAT_MPEG                                        = 0x0050,               /* Microsoft Corporation */
+       WAVE_FORMAT_RT24                                        = 0x0052,               /* InSoft Inc. */
+       WAVE_FORMAT_PAC                                         = 0x0053,               /* InSoft Inc. */
+       WAVE_FORMAT_MPEGLAYER3                          = 0x0055,               /* MPEG 3 Layer 1 */
+       WAVE_FORMAT_LUCENT_G723                         = 0x0059,               /* Lucent Technologies */
+       WAVE_FORMAT_CIRRUS                                      = 0x0060,               /* Cirrus Logic */
+       WAVE_FORMAT_ESPCM                                       = 0x0061,               /* ESS Technology */
+       WAVE_FORMAT_VOXWARE                                     = 0x0062,               /* Voxware Inc */
+       WAVE_FORMAT_CANOPUS_ATRAC                       = 0x0063,               /* Canopus, Co., Ltd. */
+       WAVE_FORMAT_G726_ADPCM                          = 0x0064,               /* APICOM */
+       WAVE_FORMAT_G722_ADPCM                          = 0x0065,               /* APICOM */
+       WAVE_FORMAT_DSAT                                        = 0x0066,               /* Microsoft Corporation */
+       WAVE_FORMAT_DSAT_DISPLAY                        = 0x0067,               /* Microsoft Corporation */
+       WAVE_FORMAT_VOXWARE_BYTE_ALIGNED        = 0x0069,               /* Voxware Inc. */
+       WAVE_FORMAT_VOXWARE_AC8                         = 0x0070,               /* Voxware Inc. */
+       WAVE_FORMAT_VOXWARE_AC10                        = 0x0071,               /* Voxware Inc. */
+       WAVE_FORMAT_VOXWARE_AC16                        = 0x0072,               /* Voxware Inc. */
+       WAVE_FORMAT_VOXWARE_AC20                        = 0x0073,               /* Voxware Inc. */
+       WAVE_FORMAT_VOXWARE_RT24                        = 0x0074,               /* Voxware Inc. */
+       WAVE_FORMAT_VOXWARE_RT29                        = 0x0075,               /* Voxware Inc. */
+       WAVE_FORMAT_VOXWARE_RT29HW                      = 0x0076,               /* Voxware Inc. */
+       WAVE_FORMAT_VOXWARE_VR12                        = 0x0077,               /* Voxware Inc. */
+       WAVE_FORMAT_VOXWARE_VR18                        = 0x0078,               /* Voxware Inc. */
+       WAVE_FORMAT_VOXWARE_TQ40                        = 0x0079,               /* Voxware Inc. */
+       WAVE_FORMAT_SOFTSOUND                           = 0x0080,               /* Softsound, Ltd. */
+       WAVE_FORMAT_VOXARE_TQ60                         = 0x0081,               /* Voxware Inc. */
+       WAVE_FORMAT_MSRT24                                      = 0x0082,               /* Microsoft Corporation */
+       WAVE_FORMAT_G729A                                       = 0x0083,               /* AT&T Laboratories */
+       WAVE_FORMAT_MVI_MV12                            = 0x0084,               /* Motion Pixels */
+       WAVE_FORMAT_DF_G726                                     = 0x0085,               /* DataFusion Systems (Pty) (Ltd) */
+       WAVE_FORMAT_DF_GSM610                           = 0x0086,               /* DataFusion Systems (Pty) (Ltd) */
+       /* removed because duplicate */
+       /* WAVE_FORMAT_ISIAUDIO                         = 0x0088, */    /* Iterated Systems, Inc. */
+       WAVE_FORMAT_ONLIVE                                      = 0x0089,               /* OnLive! Technologies, Inc. */
+       WAVE_FORMAT_SBC24                                       = 0x0091,               /* Siemens Business Communications Systems */
+       WAVE_FORMAT_DOLBY_AC3_SPDIF                     = 0x0092,               /* Sonic Foundry */
+       WAVE_FORMAT_ZYXEL_ADPCM                         = 0x0097,               /* ZyXEL Communications, Inc. */
+       WAVE_FORMAT_PHILIPS_LPCBB                       = 0x0098,               /* Philips Speech Processing */
+       WAVE_FORMAT_PACKED                                      = 0x0099,               /* Studer Professional Audio AG */
+       WAVE_FORMAT_RHETOREX_ADPCM                      = 0x0100,               /* Rhetorex, Inc. */
+
+       /* removed because of the following */
+       /* WAVE_FORMAT_IRAT                                     = 0x0101,*/             /* BeCubed Software Inc. */
+
+       /* these three are unofficial */
+       IBM_FORMAT_MULAW                                        = 0x0101,               /* IBM mu-law format */
+       IBM_FORMAT_ALAW                                         = 0x0102,               /* IBM a-law format */
+       IBM_FORMAT_ADPCM                                        = 0x0103,               /* IBM AVC Adaptive Differential PCM format */
+
+       WAVE_FORMAT_VIVO_G723                           = 0x0111,               /* Vivo Software */
+       WAVE_FORMAT_VIVO_SIREN                          = 0x0112,               /* Vivo Software */
+       WAVE_FORMAT_DIGITAL_G723                        = 0x0123,               /* Digital Equipment Corporation */
+       WAVE_FORMAT_CREATIVE_ADPCM                      = 0x0200,               /* Creative Labs, Inc */
+       WAVE_FORMAT_CREATIVE_FASTSPEECH8        = 0x0202,               /* Creative Labs, Inc */
+       WAVE_FORMAT_CREATIVE_FASTSPEECH10       = 0x0203,               /* Creative Labs, Inc */
+       WAVE_FORMAT_QUARTERDECK                         = 0x0220,               /* Quarterdeck Corporation */
+       WAVE_FORMAT_FM_TOWNS_SND                        = 0x0300,               /* Fujitsu Corporation */
+       WAVE_FORMAT_BZV_DIGITAL                         = 0x0400,               /* Brooktree Corporation */
+       WAVE_FORMAT_VME_VMPCM                           = 0x0680,               /* AT&T Labs, Inc. */
+       WAVE_FORMAT_OLIGSM                                      = 0x1000,               /* Ing C. Olivetti & C., S.p.A. */
+       WAVE_FORMAT_OLIADPCM                            = 0x1001,               /* Ing C. Olivetti & C., S.p.A. */
+       WAVE_FORMAT_OLICELP                                     = 0x1002,               /* Ing C. Olivetti & C., S.p.A. */
+       WAVE_FORMAT_OLISBC                                      = 0x1003,               /* Ing C. Olivetti & C., S.p.A. */
+       WAVE_FORMAT_OLIOPR                                      = 0x1004,               /* Ing C. Olivetti & C., S.p.A. */
+       WAVE_FORMAT_LH_CODEC                            = 0x1100,               /* Lernout & Hauspie */
+       WAVE_FORMAT_NORRIS                                      = 0x1400,               /* Norris Communications, Inc. */
+       /* removed because duplicate */
+       /* WAVE_FORMAT_ISIAUDIO                         = 0x1401, */    /* AT&T Labs, Inc. */
+       WAVE_FORMAT_SOUNDSPACE_MUSICOMPRESS     = 0x1500,               /* AT&T Labs, Inc. */
+       WAVE_FORMAT_DVM                                         = 0x2000,               /* FAST Multimedia AG */
+       WAVE_FORMAT_INTERWAV_VSC112                     = 0x7150,               /* ????? */
+       WAVE_FORMAT_EXTENSIBLE                          = 0xFFFE
+} ;
+
+typedef        struct
+{      unsigned short  format ;
+       unsigned short  channels ;
+       unsigned int    samplerate ;
+       unsigned int    bytespersec ;
+       unsigned short  blockalign ;
+       unsigned short  bitwidth ;
+} MIN_WAV_FMT ;
+
+typedef        struct
+{      unsigned short  format ;
+       unsigned short  channels ;
+       unsigned int    samplerate ;
+       unsigned int    bytespersec ;
+       unsigned short  blockalign ;
+       unsigned short  bitwidth ;
+       unsigned short  extrabytes ;
+       unsigned short  dummy ;
+} WAV_FMT_SIZE20 ;
+
+typedef        struct
+{      unsigned short  format ;
+       unsigned short  channels ;
+       unsigned int    samplerate ;
+       unsigned int    bytespersec ;
+       unsigned short  blockalign ;
+       unsigned short  bitwidth ;
+       unsigned short  extrabytes ;
+       unsigned short  samplesperblock ;
+       unsigned short  numcoeffs ;
+       struct
+       {       short   coeff1 ;
+               short   coeff2 ;
+       }       coeffs [7] ;
+} MS_ADPCM_WAV_FMT ;
+
+typedef        struct
+{      unsigned short  format ;
+       unsigned short  channels ;
+       unsigned int    samplerate ;
+       unsigned int    bytespersec ;
+       unsigned short  blockalign ;
+       unsigned short  bitwidth ;
+       unsigned short  extrabytes ;
+       unsigned short  samplesperblock ;
+} IMA_ADPCM_WAV_FMT ;
+
+typedef        struct
+{      unsigned short  format ;
+       unsigned short  channels ;
+       unsigned int    samplerate ;
+       unsigned int    bytespersec ;
+       unsigned short  blockalign ;
+       unsigned short  bitwidth ;
+       unsigned short  extrabytes ;
+       unsigned short  auxblocksize ;
+} G72x_ADPCM_WAV_FMT ;
+
+
+typedef        struct
+{      unsigned short  format ;
+       unsigned short  channels ;
+       unsigned int    samplerate ;
+       unsigned int    bytespersec ;
+       unsigned short  blockalign ;
+       unsigned short  bitwidth ;
+       unsigned short  extrabytes ;
+       unsigned short  samplesperblock ;
+} GSM610_WAV_FMT ;
+
+typedef struct
+{      unsigned int    esf_field1 ;
+       unsigned short  esf_field2 ;
+       unsigned short  esf_field3 ;
+       char                    esf_field4 [8] ;
+} EXT_SUBFORMAT ;
+
+typedef        struct
+{      unsigned short  format ;
+       unsigned short  channels ;
+       unsigned int    samplerate ;
+       unsigned int    bytespersec ;
+       unsigned short  blockalign ;
+       unsigned short  bitwidth ;
+       unsigned short  extrabytes ;
+       unsigned short  validbits ;
+       unsigned int    channelmask ;
+       EXT_SUBFORMAT   esf ;
+} EXTENSIBLE_WAV_FMT ;
+
+typedef union
+{      unsigned short          format ;
+       MIN_WAV_FMT                     min ;
+       IMA_ADPCM_WAV_FMT       ima ;
+       MS_ADPCM_WAV_FMT        msadpcm ;
+       G72x_ADPCM_WAV_FMT      g72x ;
+       EXTENSIBLE_WAV_FMT      ext ;
+       GSM610_WAV_FMT          gsm610 ;
+       WAV_FMT_SIZE20          size20 ;
+       char                            padding [512] ;
+} WAV_FMT ;
+
+typedef struct
+{      int frames ;
+} FACT_CHUNK ;
+
+#define                WAV_W64_GSM610_BLOCKSIZE        65
+#define                WAV_W64_GSM610_SAMPLES          320
+
+/*------------------------------------------------------------------------------------
+**     Functions defined in wav_ms_adpcm.c
+*/
+
+#define        MSADPCM_ADAPT_COEFF_COUNT       7
+
+void   msadpcm_write_adapt_coeffs (SF_PRIVATE *psf) ;
+
+/*------------------------------------------------------------------------------------
+**     Functions defined in wav_w64.c
+*/
+
+int    wav_w64_srate2blocksize (int srate_chan_product) ;
+char const* wav_w64_format_str (int k) ;
+int            wav_w64_read_fmt_chunk (SF_PRIVATE *psf, WAV_FMT *wav_fmt, int structsize) ;
+void   wavex_write_guid (SF_PRIVATE *psf, const EXT_SUBFORMAT * subformat) ;
+
+#endif
+/*
+** Do not edit or modify anything in this comment block.
+** The arch-tag line is a file identity tag for the GNU Arch 
+** revision control system.
+**
+** arch-tag: 877fde12-9be3-4a31-8a5a-fdae39958613
+*/
diff --git a/libs/libsndfile/src/wve.c b/libs/libsndfile/src/wve.c
new file mode 100644 (file)
index 0000000..54a0833
--- /dev/null
@@ -0,0 +1,125 @@
+/*
+** Copyright (C) 2002-2004 Erik de Castro Lopo <erikd@mega-nerd.com>
+**
+** This program is free software; you can redistribute it and/or modify
+** it under the terms of the GNU Lesser General Public License as published by
+** the Free Software Foundation; either version 2.1 of the License, or
+** (at your option) any later version.
+**
+** This program is distributed in the hope that it will be useful,
+** but WITHOUT ANY WARRANTY; without even the implied warranty of
+** MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+** GNU Lesser General Public License for more details.
+**
+** You should have received a copy of the GNU Lesser General Public License
+** along with this program; if not, write to the Free Software
+** Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA.
+*/
+
+#include       "sfconfig.h"
+
+#include       <stdio.h>
+#include       <fcntl.h>
+#include       <string.h>
+#include       <ctype.h>
+
+#include       "sndfile.h"
+#include       "sfendian.h"
+#include       "common.h"
+
+#if (ENABLE_EXPERIMENTAL_CODE == 0)
+
+int
+wve_open       (SF_PRIVATE *psf)
+{      if (psf)
+               return SFE_UNIMPLEMENTED ;
+       return (psf && 0) ;
+} /* wve_open */
+
+#else
+
+#define        SFE_WVE_NOT_WVE 666
+
+/*------------------------------------------------------------------------------
+** Macros to handle big/little endian issues.
+*/
+
+#define ALAW_MARKER            MAKE_MARKER ('A', 'L', 'a', 'w')
+#define SOUN_MARKER            MAKE_MARKER ('S', 'o', 'u', 'n')
+#define DFIL_MARKER            MAKE_MARKER ('d', 'F', 'i', 'l')
+
+/*------------------------------------------------------------------------------
+** Private static functions.
+*/
+
+static int     wve_read_header (SF_PRIVATE *psf) ;
+
+/*------------------------------------------------------------------------------
+** Public function.
+*/
+
+int
+wve_open (SF_PRIVATE *psf)
+{      int     subformat, error = 0 ;
+
+       if (psf->mode == SFM_WRITE || psf->mode == SFM_RDWR)
+               return SFE_UNIMPLEMENTED ;
+
+       if ((error = wve_read_header (psf)))
+               return error ;
+
+       if ((psf->sf.format & SF_FORMAT_TYPEMASK) != SF_FORMAT_WVE)
+               return  SFE_BAD_OPEN_FORMAT ;
+
+       subformat = psf->sf.format & SF_FORMAT_SUBMASK ;
+
+       return error ;
+} /* wve_open */
+
+/*------------------------------------------------------------------------------
+*/
+
+static int
+wve_read_header (SF_PRIVATE *psf)
+{      int marker ;
+
+       /* Set position to start of file to begin reading header. */
+       psf_binheader_readf (psf, "pm", 0, &marker) ;
+       if (marker != ALAW_MARKER)
+               return SFE_WVE_NOT_WVE ;
+
+       psf_binheader_readf (psf, "m", &marker) ;
+       if (marker != SOUN_MARKER)
+               return SFE_WVE_NOT_WVE ;
+
+       psf_binheader_readf (psf, "m", &marker) ;
+       if (marker != DFIL_MARKER)
+               return SFE_WVE_NOT_WVE ;
+
+       psf_log_printf (psf, "Read only : Psion Palmtop Alaw (.wve)\n"
+                       "  Sample Rate : 8000\n"
+                       "  Channels    : 1\n"
+                       "  Encoding    : A-law\n") ;
+
+       psf->dataoffset = 0x20 ;
+       psf->datalength = psf->filelength - psf->dataoffset ;
+
+       psf->sf.format          = SF_FORMAT_WVE | SF_FORMAT_ALAW ;
+       psf->sf.samplerate      = 8000 ;
+       psf->sf.frames          = psf->datalength ;
+       psf->sf.channels        = 1 ;
+
+       return alaw_init (psf) ;
+} /* wve_read_header */
+
+/*------------------------------------------------------------------------------
+*/
+
+#endif
+/*
+** Do not edit or modify anything in this comment block.
+** The arch-tag line is a file identity tag for the GNU Arch 
+** revision control system.
+**
+** arch-tag: ba368cb5-523f-45e4-98c1-5b99a102f73f
+*/
diff --git a/libs/libsndfile/src/xi.c b/libs/libsndfile/src/xi.c
new file mode 100644 (file)
index 0000000..dcd8120
--- /dev/null
@@ -0,0 +1,1204 @@
+/*
+** Copyright (C) 2003-2006 Erik de Castro Lopo <erikd@mega-nerd.com>
+**
+** This program is free software; you can redistribute it and/or modify
+** it under the terms of the GNU Lesser General Public License as published by
+** the Free Software Foundation; either version 2.1 of the License, or
+** (at your option) any later version.
+**
+** This program is distributed in the hope that it will be useful,
+** but WITHOUT ANY WARRANTY; without even the implied warranty of
+** MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+** GNU Lesser General Public License for more details.
+**
+** You should have received a copy of the GNU Lesser General Public License
+** along with this program; if not, write to the Free Software
+** Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA.
+*/
+
+#include "sfconfig.h"
+
+#include <stdio.h>
+#include <stdlib.h>
+#include <fcntl.h>
+#include <string.h>
+#include <ctype.h>
+
+#include "sndfile.h"
+#include "sfendian.h"
+#include "common.h"
+#include "float_cast.h"
+
+#define        MAX_XI_SAMPLES  16
+
+/*------------------------------------------------------------------------------
+** Private static functions and tyepdefs.
+*/
+
+typedef struct
+{      /* Warning, this filename is NOT nul terminated. */
+       char    filename [22] ;
+       char    software [20] ;
+       char    sample_name [22] ;
+
+       int             loop_begin, loop_end ;
+       int             sample_flags ;
+
+       /* Data for encoder and decoder. */
+       short   last_16 ;
+} XI_PRIVATE ;
+
+static int     xi_close                (SF_PRIVATE *psf) ;
+static int     xi_write_header (SF_PRIVATE *psf, int calc_length) ;
+static int     xi_read_header  (SF_PRIVATE *psf) ;
+static int     dpcm_init               (SF_PRIVATE *psf) ;
+
+
+static sf_count_t      dpcm_seek (SF_PRIVATE *psf, int mode, sf_count_t offset) ;
+
+/*------------------------------------------------------------------------------
+** Public function.
+*/
+
+int
+xi_open        (SF_PRIVATE *psf)
+{      XI_PRIVATE *pxi ;
+       int             subformat, error = 0 ;
+
+       if (psf->is_pipe)
+               return SFE_XI_NO_PIPE ;
+
+       if (psf->fdata)
+               pxi = psf->fdata ;
+       else if ((pxi = calloc (1, sizeof (XI_PRIVATE))) == NULL)
+               return SFE_MALLOC_FAILED ;
+
+       psf->fdata = pxi ;
+
+       if (psf->mode == SFM_READ || (psf->mode == SFM_RDWR && psf->filelength > 0))
+       {       if ((error = xi_read_header (psf)))
+                       return error ;
+               } ;
+
+       subformat = psf->sf.format & SF_FORMAT_SUBMASK ;
+
+       if (psf->mode == SFM_WRITE || psf->mode == SFM_RDWR)
+       {       if ((psf->sf.format & SF_FORMAT_TYPEMASK) != SF_FORMAT_XI)
+                       return  SFE_BAD_OPEN_FORMAT ;
+
+               psf->endian = SF_ENDIAN_LITTLE ;
+               psf->sf.channels = 1 ; /* Always mono */
+               psf->sf.samplerate = 44100 ; /* Always */
+
+               /* Set up default instrument and software name. */
+               memcpy (pxi->filename, "Default Name            ", sizeof (pxi->filename)) ;
+               memcpy (pxi->software, PACKAGE "-" VERSION "               ", sizeof (pxi->software)) ;
+
+               memset (pxi->sample_name, 0, sizeof (pxi->sample_name)) ;
+               LSF_SNPRINTF (pxi->sample_name, sizeof (pxi->sample_name), "%s", "Sample #1") ;
+
+               pxi->sample_flags = (subformat == SF_FORMAT_DPCM_16) ? 16 : 0 ;
+
+               if (xi_write_header (psf, SF_FALSE))
+                       return psf->error ;
+
+               psf->write_header = xi_write_header ;
+               } ;
+
+       psf->container_close = xi_close ;
+       psf->seek = dpcm_seek ;
+
+       psf->sf.seekable = SF_FALSE ;
+
+       psf->blockwidth = psf->bytewidth * psf->sf.channels ;
+
+       switch (subformat)
+       {       case SF_FORMAT_DPCM_8 :         /* 8-bit differential PCM. */
+               case SF_FORMAT_DPCM_16 :        /* 16-bit differential PCM. */
+                               error = dpcm_init (psf) ;
+                               break ;
+
+               default : break ;
+               } ;
+
+       return error ;
+} /* xi_open */
+
+/*------------------------------------------------------------------------------
+*/
+
+static int
+xi_close       (SF_PRIVATE *psf)
+{
+       psf = psf ;
+
+       return 0 ;
+} /* xi_close */
+
+/*==============================================================================
+*/
+
+static sf_count_t dpcm_read_dsc2s (SF_PRIVATE *psf, short *ptr, sf_count_t len) ;
+static sf_count_t dpcm_read_dsc2i (SF_PRIVATE *psf, int *ptr, sf_count_t len) ;
+static sf_count_t dpcm_read_dsc2f (SF_PRIVATE *psf, float *ptr, sf_count_t len) ;
+static sf_count_t dpcm_read_dsc2d (SF_PRIVATE *psf, double *ptr, sf_count_t len) ;
+
+static sf_count_t dpcm_write_s2dsc (SF_PRIVATE *psf, const short *ptr, sf_count_t len) ;
+static sf_count_t dpcm_write_i2dsc (SF_PRIVATE *psf, const int *ptr, sf_count_t len) ;
+static sf_count_t dpcm_write_f2dsc (SF_PRIVATE *psf, const float *ptr, sf_count_t len) ;
+static sf_count_t dpcm_write_d2dsc (SF_PRIVATE *psf, const double *ptr, sf_count_t len) ;
+
+static sf_count_t dpcm_read_dles2s (SF_PRIVATE *psf, short *ptr, sf_count_t len) ;
+static sf_count_t dpcm_read_dles2i (SF_PRIVATE *psf, int *ptr, sf_count_t len) ;
+static sf_count_t dpcm_read_dles2f (SF_PRIVATE *psf, float *ptr, sf_count_t len) ;
+static sf_count_t dpcm_read_dles2d (SF_PRIVATE *psf, double *ptr, sf_count_t len) ;
+
+static sf_count_t dpcm_write_s2dles (SF_PRIVATE *psf, const short *ptr, sf_count_t len) ;
+static sf_count_t dpcm_write_i2dles (SF_PRIVATE *psf, const int *ptr, sf_count_t len) ;
+static sf_count_t dpcm_write_f2dles (SF_PRIVATE *psf, const float *ptr, sf_count_t len) ;
+static sf_count_t dpcm_write_d2dles (SF_PRIVATE *psf, const double *ptr, sf_count_t len) ;
+
+static int
+dpcm_init (SF_PRIVATE *psf)
+{      if (psf->bytewidth == 0 || psf->sf.channels == 0)
+               return SFE_INTERNAL ;
+
+       psf->blockwidth = psf->bytewidth * psf->sf.channels ;
+
+       if (psf->mode == SFM_READ || psf->mode == SFM_RDWR)
+       {       switch (psf->bytewidth)
+               {       case 1 :
+                                       psf->read_short         = dpcm_read_dsc2s ;
+                                       psf->read_int           = dpcm_read_dsc2i ;
+                                       psf->read_float         = dpcm_read_dsc2f ;
+                                       psf->read_double        = dpcm_read_dsc2d ;
+                                       break ;
+                       case 2 :
+                                       psf->read_short         = dpcm_read_dles2s ;
+                                       psf->read_int           = dpcm_read_dles2i ;
+                                       psf->read_float         = dpcm_read_dles2f ;
+                                       psf->read_double        = dpcm_read_dles2d ;
+                                       break ;
+                       default :
+                               psf_log_printf (psf, "dpcm_init() returning SFE_UNIMPLEMENTED\n") ;
+                               return SFE_UNIMPLEMENTED ;
+                       } ;
+               } ;
+
+       if (psf->mode == SFM_WRITE || psf->mode == SFM_RDWR)
+       {       switch (psf->bytewidth)
+               {       case 1 :
+                                       psf->write_short        = dpcm_write_s2dsc ;
+                                       psf->write_int          = dpcm_write_i2dsc ;
+                                       psf->write_float        = dpcm_write_f2dsc ;
+                                       psf->write_double       = dpcm_write_d2dsc ;
+                                       break ;
+                       case 2 :
+                                       psf->write_short        = dpcm_write_s2dles ;
+                                       psf->write_int          = dpcm_write_i2dles ;
+                                       psf->write_float        = dpcm_write_f2dles ;
+                                       psf->write_double       = dpcm_write_d2dles ;
+                                       break ;
+                       default :
+                               psf_log_printf (psf, "dpcm_init() returning SFE_UNIMPLEMENTED\n") ;
+                               return SFE_UNIMPLEMENTED ;
+                       } ;
+               } ;
+
+       psf->filelength = psf_get_filelen (psf) ;
+       psf->datalength = (psf->dataend) ? psf->dataend - psf->dataoffset :
+                                                       psf->filelength - psf->dataoffset ;
+       psf->sf.frames = psf->datalength / psf->blockwidth ;
+
+       return 0 ;
+} /* dpcm_init */
+
+/*==============================================================================
+*/
+
+static sf_count_t
+dpcm_seek (SF_PRIVATE *psf, int mode, sf_count_t offset)
+{      XI_PRIVATE      *pxi ;
+       int                     total, bufferlen, len ;
+
+       if ((pxi = psf->fdata) == NULL)
+               return SFE_INTERNAL ;
+
+       if (psf->datalength < 0 || psf->dataoffset < 0)
+       {       psf->error = SFE_BAD_SEEK ;
+               return  PSF_SEEK_ERROR ;
+               } ;
+
+       if (offset == 0)
+       {       psf_fseek (psf, psf->dataoffset, SEEK_SET) ;
+               pxi->last_16 = 0 ;
+               return 0 ;
+               } ;
+
+       if (offset < 0 || offset > psf->sf.frames)
+       {       psf->error = SFE_BAD_SEEK ;
+               return  PSF_SEEK_ERROR ;
+               } ;
+
+       if (mode != SFM_READ)
+       {       /* What to do about write??? */
+               psf->error = SFE_BAD_SEEK ;
+               return  PSF_SEEK_ERROR ;
+               } ;
+
+       psf_fseek (psf, psf->dataoffset, SEEK_SET) ;
+
+       if ((psf->sf.format & SF_FORMAT_SUBMASK) == SF_FORMAT_DPCM_16)
+       {       total = offset ;
+               bufferlen = ARRAY_LEN (psf->u.sbuf) ;
+               while (total > 0)
+               {       len = (total > bufferlen) ? bufferlen : total ;
+                       total -= dpcm_read_dles2s (psf, psf->u.sbuf, len) ;
+                       } ;
+               }
+       else
+       {       total = offset ;
+               bufferlen = ARRAY_LEN (psf->u.sbuf) ;
+               while (total > 0)
+               {       len = (total > bufferlen) ? bufferlen : total ;
+                       total -= dpcm_read_dsc2s (psf, psf->u.sbuf, len) ;
+                       } ;
+               } ;
+
+       return offset ;
+} /* dpcm_seek */
+
+
+static int
+xi_write_header (SF_PRIVATE *psf, int calc_length)
+{      XI_PRIVATE      *pxi ;
+       sf_count_t      current ;
+       const char      *string ;
+
+       if ((pxi = psf->fdata) == NULL)
+               return SFE_INTERNAL ;
+
+       calc_length = calc_length ; /* Avoid a compiler warning. */
+
+       current = psf_ftell (psf) ;
+
+       /* Reset the current header length to zero. */
+       psf->header [0] = 0 ;
+       psf->headindex = 0 ;
+       psf_fseek (psf, 0, SEEK_SET) ;
+
+       string = "Extended Instrument: " ;
+       psf_binheader_writef (psf, "b", string, strlen (string)) ;
+       psf_binheader_writef (psf, "b1", pxi->filename, sizeof (pxi->filename), 0x1A) ;
+
+       /* Write software version and two byte XI version. */
+       psf_binheader_writef (psf, "eb2", pxi->software, sizeof (pxi->software), (1 << 8) + 2) ;
+
+       /*
+       ** Jump note numbers (96), volume envelope (48), pan envelope (48),
+       ** volume points (1), pan points (1)
+       */
+       psf_binheader_writef (psf, "z", (size_t) (96 + 48 + 48 + 1 + 1)) ;
+
+       /* Jump volume loop (3 bytes), pan loop (3), envelope flags (3), vibrato (3)
+       ** fade out (2), 22 unknown bytes, and then write sample_count (2 bytes).
+       */
+       psf_binheader_writef (psf, "ez2z2", (size_t) (4 * 3), 0x1234, make_size_t (22), 1) ;
+
+       pxi->loop_begin = 0 ;
+       pxi->loop_end = 0 ;
+
+       psf_binheader_writef (psf, "et844", psf->sf.frames, pxi->loop_begin, pxi->loop_end) ;
+
+       /* volume, fine tune, flags, pan, note, namelen */
+       psf_binheader_writef (psf, "111111", 128, 0, pxi->sample_flags, 128, 0, strlen (pxi->sample_name)) ;
+
+       psf_binheader_writef (psf, "b", pxi->sample_name, sizeof (pxi->sample_name)) ;
+
+
+
+
+
+       /* Header construction complete so write it out. */
+       psf_fwrite (psf->header, psf->headindex, 1, psf) ;
+
+       if (psf->error)
+               return psf->error ;
+
+       psf->dataoffset = psf->headindex ;
+
+       if (current > 0)
+               psf_fseek (psf, current, SEEK_SET) ;
+
+       return psf->error ;
+} /* xi_write_header */
+
+static int
+xi_read_header (SF_PRIVATE *psf)
+{      char    buffer [64], name [32] ;
+       short   version, fade_out, sample_count ;
+       int             k, loop_begin, loop_end ;
+       int     sample_sizes [MAX_XI_SAMPLES] ;
+
+       psf_binheader_readf (psf, "pb", 0, buffer, 21) ;
+
+       memset (sample_sizes, 0, sizeof (sample_sizes)) ;
+
+       buffer [20] = 0 ;
+       if (strcmp (buffer, "Extended Instrument:") != 0)
+               return SFE_XI_BAD_HEADER ;
+
+       memset (buffer, 0, sizeof (buffer)) ;
+       psf_binheader_readf (psf, "b", buffer, 23) ;
+
+       if (buffer [22] != 0x1A)
+               return SFE_XI_BAD_HEADER ;
+
+       buffer [22] = 0 ;
+       psf_log_printf (psf, "Extended Instrument : %s\n", buffer) ;
+
+       psf_binheader_readf (psf, "be2", buffer, 20, &version) ;
+       buffer [19] = 0 ;
+       psf_log_printf (psf, "Software : %s\nVersion  : %d.%02d\n", buffer, version / 256, version % 256) ;
+
+       /* Jump note numbers (96), volume envelope (48), pan envelope (48),
+       ** volume points (1), pan points (1)
+       */
+       psf_binheader_readf (psf, "j", 96 + 48 + 48 + 1 + 1) ;
+
+       psf_binheader_readf (psf, "b", buffer, 12) ;
+       psf_log_printf (psf, "Volume Loop\n  sustain : %u\n  begin   : %u\n  end     : %u\n",
+                                               buffer [0], buffer [1], buffer [2]) ;
+       psf_log_printf (psf, "Pan Loop\n  sustain : %u\n  begin   : %u\n  end     : %u\n",
+                                               buffer [3], buffer [4], buffer [5]) ;
+       psf_log_printf (psf, "Envelope Flags\n  volume  : 0x%X\n  pan     : 0x%X\n",
+                               buffer [6] & 0xFF, buffer [7] & 0xFF) ;
+
+       psf_log_printf (psf, "Vibrato\n  type    : %u\n  sweep   : %u\n  depth   : %u\n  rate    : %u\n",
+                               buffer [8], buffer [9], buffer [10], buffer [11]) ;
+
+       /*
+       ** Read fade_out then jump reserved (2 bytes) and ???? (20 bytes) and
+       ** sample_count.
+       */
+       psf_binheader_readf (psf, "e2j2", &fade_out, 2 + 20, &sample_count) ;
+       psf_log_printf (psf, "Fade out  : %d\n", fade_out) ;
+
+       /* XI file can contain up to 16 samples. */
+       if (sample_count > MAX_XI_SAMPLES)
+               return SFE_XI_EXCESS_SAMPLES ;
+
+       if (psf->instrument == NULL && (psf->instrument = psf_instrument_alloc ()) == NULL)
+               return SFE_MALLOC_FAILED ;
+
+       /* Log all data for each sample. */
+       for (k = 0 ; k < sample_count ; k++)
+       {       psf_binheader_readf (psf, "e444", &(sample_sizes [k]), &loop_begin, &loop_end) ;
+
+               /* Read 5 know bytes, 1 unknown byte and 22 name bytes. */
+               psf_binheader_readf (psf, "bb", buffer, 6, name, 22) ;
+               name [21] = 0 ;
+
+               psf_log_printf (psf, "Sample #%d\n  name    : %s\n", k + 1, name) ;
+
+               psf_log_printf (psf, "  size    : %d\n", sample_sizes [k]) ;
+
+
+
+               psf_log_printf (psf, "  loop\n    begin : %d\n    end   : %d\n", loop_begin, loop_end) ;
+
+               psf_log_printf (psf, "  volume  : %u\n  f. tune : %d\n  flags   : 0x%02X ",
+                                       buffer [0] & 0xFF, buffer [1] & 0xFF, buffer [2] & 0xFF) ;
+
+               psf_log_printf (psf, " (") ;
+               if (buffer [2] & 1)
+                       psf_log_printf (psf, " Loop") ;
+               if (buffer [2] & 2)
+                       psf_log_printf (psf, " PingPong") ;
+               psf_log_printf (psf, (buffer [2] & 16) ? " 16bit" : " 8bit") ;
+               psf_log_printf (psf, " )\n") ;
+
+               psf_log_printf (psf, "  pan     : %u\n  note    : %d\n  namelen : %d\n",
+                                       buffer [3] & 0xFF, buffer [4], buffer [5]) ;
+
+               if (k != 0)
+                       continue ;
+
+               if (buffer [2] & 16)
+               {       psf->sf.format = SF_FORMAT_XI | SF_FORMAT_DPCM_16 ;
+                       psf->bytewidth = 2 ;
+                       }
+               else
+               {       psf->sf.format = SF_FORMAT_XI | SF_FORMAT_DPCM_8 ;
+                       psf->bytewidth = 1 ;
+                       } ;
+               } ;
+
+       while (sample_count > 1 && sample_sizes [sample_count - 1] == 0)
+               sample_count -- ;
+
+       /* Currently, we can only handle 1 sample per file. */
+
+       if (sample_count > 2)
+       {       psf_log_printf (psf, "*** Sample count is less than 16 but more than 1.\n") ;
+               psf_log_printf (psf, "  sample count : %d    sample_sizes [%d] : %d\n",
+                                               sample_count, sample_count - 1, sample_sizes [sample_count - 1]) ;
+               return SFE_XI_EXCESS_SAMPLES ;
+               } ;
+
+       psf->dataoffset = psf_fseek (psf, 0, SEEK_CUR) ;
+       psf_log_printf (psf, "Data Offset : %D\n", psf->dataoffset) ;
+
+       psf->datalength = sample_sizes [0] ;
+
+       if (psf->dataoffset + psf->datalength > psf->filelength)
+       {       psf_log_printf (psf, "*** File seems to be truncated. Should be at least %D bytes long.\n",
+                               psf->dataoffset + sample_sizes [0]) ;
+               psf->datalength = psf->filelength - psf->dataoffset ;
+               } ;
+
+       if (psf_fseek (psf, psf->dataoffset, SEEK_SET) != psf->dataoffset)
+               return SFE_BAD_SEEK ;
+
+       psf->endian = SF_ENDIAN_LITTLE ;
+       psf->sf.channels = 1 ; /* Always mono */
+       psf->sf.samplerate = 44100 ; /* Always */
+
+       psf->blockwidth = psf->sf.channels * psf->bytewidth ;
+
+       if (! psf->sf.frames && psf->blockwidth)
+               psf->sf.frames = (psf->filelength - psf->dataoffset) / psf->blockwidth ;
+
+       psf->instrument->basenote = 0 ;
+       psf->instrument->gain = 1 ;
+       psf->instrument->velocity_lo = psf->instrument->key_lo = 0 ;
+       psf->instrument->velocity_hi = psf->instrument->key_hi = 127 ;
+
+       return 0 ;
+} /* xi_read_header */
+
+/*==============================================================================
+*/
+
+static void dsc2s_array (XI_PRIVATE *pxi, signed char *src, int count, short *dest) ;
+static void dsc2i_array (XI_PRIVATE *pxi, signed char *src, int count, int *dest) ;
+static void dsc2f_array (XI_PRIVATE *pxi, signed char *src, int count, float *dest, float normfact) ;
+static void dsc2d_array (XI_PRIVATE *pxi, signed char *src, int count, double *dest, double normfact) ;
+
+static void dles2s_array (XI_PRIVATE *pxi, short *src, int count, short *dest) ;
+static void dles2i_array (XI_PRIVATE *pxi, short *src, int count, int *dest) ;
+static void dles2f_array (XI_PRIVATE *pxi, short *src, int count, float *dest, float normfact) ;
+static void dles2d_array (XI_PRIVATE *pxi, short *src, int count, double *dest, double normfact) ;
+
+static sf_count_t
+dpcm_read_dsc2s (SF_PRIVATE *psf, short *ptr, sf_count_t len)
+{      XI_PRIVATE      *pxi ;
+       int                     bufferlen, readcount ;
+       sf_count_t      total = 0 ;
+
+       if ((pxi = psf->fdata) == NULL)
+               return 0 ;
+
+       bufferlen = ARRAY_LEN (psf->u.ucbuf) ;
+
+       while (len > 0)
+       {       if (len < bufferlen)
+                       bufferlen = (int) len ;
+               readcount = psf_fread (psf->u.scbuf, sizeof (signed char), bufferlen, psf) ;
+               dsc2s_array (pxi, psf->u.scbuf, readcount, ptr + total) ;
+               total += readcount ;
+               if (readcount < bufferlen)
+                       break ;
+               len -= readcount ;
+               } ;
+
+       return total ;
+} /* dpcm_read_dsc2s */
+
+static sf_count_t
+dpcm_read_dsc2i (SF_PRIVATE *psf, int *ptr, sf_count_t len)
+{      XI_PRIVATE      *pxi ;
+       int                     bufferlen, readcount ;
+       sf_count_t      total = 0 ;
+
+       if ((pxi = psf->fdata) == NULL)
+               return 0 ;
+
+       bufferlen = ARRAY_LEN (psf->u.ucbuf) ;
+
+       while (len > 0)
+       {       if (len < bufferlen)
+                       bufferlen = (int) len ;
+               readcount = psf_fread (psf->u.scbuf, sizeof (signed char), bufferlen, psf) ;
+               dsc2i_array (pxi, psf->u.scbuf, readcount, ptr + total) ;
+               total += readcount ;
+               if (readcount < bufferlen)
+                       break ;
+               len -= readcount ;
+               } ;
+
+       return total ;
+} /* dpcm_read_dsc2i */
+
+static sf_count_t
+dpcm_read_dsc2f (SF_PRIVATE *psf, float *ptr, sf_count_t len)
+{      XI_PRIVATE      *pxi ;
+       int                     bufferlen, readcount ;
+       sf_count_t      total = 0 ;
+       float           normfact ;
+
+       if ((pxi = psf->fdata) == NULL)
+               return 0 ;
+
+       normfact = (psf->norm_float == SF_TRUE) ? 1.0 / ((float) 0x80) : 1.0 ;
+
+       bufferlen = ARRAY_LEN (psf->u.ucbuf) ;
+
+       while (len > 0)
+       {       if (len < bufferlen)
+                       bufferlen = (int) len ;
+               readcount = psf_fread (psf->u.scbuf, sizeof (signed char), bufferlen, psf) ;
+               dsc2f_array (pxi, psf->u.scbuf, readcount, ptr + total, normfact) ;
+               total += readcount ;
+               if (readcount < bufferlen)
+                       break ;
+               len -= readcount ;
+               } ;
+
+       return total ;
+} /* dpcm_read_dsc2f */
+
+static sf_count_t
+dpcm_read_dsc2d (SF_PRIVATE *psf, double *ptr, sf_count_t len)
+{      XI_PRIVATE      *pxi ;
+       int                     bufferlen, readcount ;
+       sf_count_t      total = 0 ;
+       double          normfact ;
+
+       if ((pxi = psf->fdata) == NULL)
+               return 0 ;
+
+       normfact = (psf->norm_double == SF_TRUE) ? 1.0 / ((double) 0x80) : 1.0 ;
+
+       bufferlen = ARRAY_LEN (psf->u.ucbuf) ;
+
+       while (len > 0)
+       {       if (len < bufferlen)
+                       bufferlen = (int) len ;
+               readcount = psf_fread (psf->u.scbuf, sizeof (signed char), bufferlen, psf) ;
+               dsc2d_array (pxi, psf->u.scbuf, readcount, ptr + total, normfact) ;
+               total += readcount ;
+               if (readcount < bufferlen)
+                       break ;
+               len -= readcount ;
+               } ;
+
+       return total ;
+} /* dpcm_read_dsc2d */
+
+/*------------------------------------------------------------------------------
+*/
+
+static sf_count_t
+dpcm_read_dles2s (SF_PRIVATE *psf, short *ptr, sf_count_t len)
+{      XI_PRIVATE      *pxi ;
+       int                     bufferlen, readcount ;
+       sf_count_t      total = 0 ;
+
+       if ((pxi = psf->fdata) == NULL)
+               return 0 ;
+
+       bufferlen = ARRAY_LEN (psf->u.sbuf) ;
+
+       while (len > 0)
+       {       if (len < bufferlen)
+                       bufferlen = (int) len ;
+               readcount = psf_fread (psf->u.sbuf, sizeof (short), bufferlen, psf) ;
+               dles2s_array (pxi, psf->u.sbuf, readcount, ptr + total) ;
+               total += readcount ;
+               if (readcount < bufferlen)
+                       break ;
+               len -= readcount ;
+               } ;
+
+       return total ;
+} /* dpcm_read_dles2s */
+
+static sf_count_t
+dpcm_read_dles2i (SF_PRIVATE *psf, int *ptr, sf_count_t len)
+{      XI_PRIVATE      *pxi ;
+       int                     bufferlen, readcount ;
+       sf_count_t      total = 0 ;
+
+       if ((pxi = psf->fdata) == NULL)
+               return 0 ;
+
+       bufferlen = ARRAY_LEN (psf->u.sbuf) ;
+
+       while (len > 0)
+       {       if (len < bufferlen)
+                       bufferlen = (int) len ;
+               readcount = psf_fread (psf->u.sbuf, sizeof (short), bufferlen, psf) ;
+               dles2i_array (pxi, psf->u.sbuf, readcount, ptr + total) ;
+               total += readcount ;
+               if (readcount < bufferlen)
+                       break ;
+               len -= readcount ;
+               } ;
+
+       return total ;
+} /* dpcm_read_dles2i */
+
+static sf_count_t
+dpcm_read_dles2f (SF_PRIVATE *psf, float *ptr, sf_count_t len)
+{      XI_PRIVATE      *pxi ;
+       int                     bufferlen, readcount ;
+       sf_count_t      total = 0 ;
+       float           normfact ;
+
+       if ((pxi = psf->fdata) == NULL)
+               return 0 ;
+
+       normfact = (psf->norm_float == SF_TRUE) ? 1.0 / ((float) 0x8000) : 1.0 ;
+
+       bufferlen = ARRAY_LEN (psf->u.sbuf) ;
+
+       while (len > 0)
+       {       if (len < bufferlen)
+                       bufferlen = (int) len ;
+               readcount = psf_fread (psf->u.sbuf, sizeof (short), bufferlen, psf) ;
+               dles2f_array (pxi, psf->u.sbuf, readcount, ptr + total, normfact) ;
+               total += readcount ;
+               if (readcount < bufferlen)
+                       break ;
+               len -= readcount ;
+               } ;
+
+       return total ;
+} /* dpcm_read_dles2f */
+
+static sf_count_t
+dpcm_read_dles2d (SF_PRIVATE *psf, double *ptr, sf_count_t len)
+{      XI_PRIVATE      *pxi ;
+       int                     bufferlen, readcount ;
+       sf_count_t      total = 0 ;
+       double          normfact ;
+
+       if ((pxi = psf->fdata) == NULL)
+               return 0 ;
+
+       normfact = (psf->norm_double == SF_TRUE) ? 1.0 / ((double) 0x8000) : 1.0 ;
+
+       bufferlen = ARRAY_LEN (psf->u.sbuf) ;
+
+       while (len > 0)
+       {       if (len < bufferlen)
+                       bufferlen = (int) len ;
+               readcount = psf_fread (psf->u.sbuf, sizeof (short), bufferlen, psf) ;
+               dles2d_array (pxi, psf->u.sbuf, readcount, ptr + total, normfact) ;
+               total += readcount ;
+               if (readcount < bufferlen)
+                       break ;
+               len -= readcount ;
+               } ;
+
+       return total ;
+} /* dpcm_read_dles2d */
+
+/*==============================================================================
+*/
+
+static void s2dsc_array (XI_PRIVATE *pxi, const short *src, signed char *dest, int count) ;
+static void i2dsc_array (XI_PRIVATE *pxi, const int *src, signed char *dest, int count) ;
+static void f2dsc_array (XI_PRIVATE *pxi, const float *src, signed char *dest, int count, float normfact) ;
+static void d2dsc_array (XI_PRIVATE *pxi, const double *src, signed char *dest, int count, double normfact) ;
+
+static void    s2dles_array (XI_PRIVATE *pxi, const short *src, short *dest, int count) ;
+static void i2dles_array (XI_PRIVATE *pxi, const int *src, short *dest, int count) ;
+static void f2dles_array (XI_PRIVATE *pxi, const float *src, short *dest, int count, float normfact) ;
+static void d2dles_array (XI_PRIVATE *pxi, const double *src, short *dest, int count, double normfact) ;
+
+
+static sf_count_t
+dpcm_write_s2dsc (SF_PRIVATE *psf, const short *ptr, sf_count_t len)
+{      XI_PRIVATE      *pxi ;
+       int                     bufferlen, writecount ;
+       sf_count_t      total = 0 ;
+
+       if ((pxi = psf->fdata) == NULL)
+               return 0 ;
+
+       bufferlen = ARRAY_LEN (psf->u.ucbuf) ;
+
+       while (len > 0)
+       {       if (len < bufferlen)
+                       bufferlen = (int) len ;
+               s2dsc_array (pxi, ptr + total, psf->u.scbuf, bufferlen) ;
+               writecount = psf_fwrite (psf->u.scbuf, sizeof (signed char), bufferlen, psf) ;
+               total += writecount ;
+               if (writecount < bufferlen)
+                       break ;
+               len -= writecount ;
+               } ;
+
+       return total ;
+} /* dpcm_write_s2dsc */
+
+static sf_count_t
+dpcm_write_i2dsc (SF_PRIVATE *psf, const int *ptr, sf_count_t len)
+{      XI_PRIVATE      *pxi ;
+       int                     bufferlen, writecount ;
+       sf_count_t      total = 0 ;
+
+       if ((pxi = psf->fdata) == NULL)
+               return 0 ;
+
+       bufferlen = ARRAY_LEN (psf->u.ucbuf) ;
+
+       while (len > 0)
+       {       if (len < bufferlen)
+                       bufferlen = (int) len ;
+               i2dsc_array (pxi, ptr + total, psf->u.scbuf, bufferlen) ;
+               writecount = psf_fwrite (psf->u.scbuf, sizeof (signed char), bufferlen, psf) ;
+               total += writecount ;
+               if (writecount < bufferlen)
+                       break ;
+               len -= writecount ;
+               } ;
+
+       return total ;
+} /* dpcm_write_i2dsc */
+
+static sf_count_t
+dpcm_write_f2dsc (SF_PRIVATE *psf, const float *ptr, sf_count_t len)
+{      XI_PRIVATE      *pxi ;
+       int                     bufferlen, writecount ;
+       sf_count_t      total = 0 ;
+       float           normfact ;
+
+       if ((pxi = psf->fdata) == NULL)
+               return 0 ;
+
+       normfact = (psf->norm_float == SF_TRUE) ? (1.0 * 0x7F) : 1.0 ;
+
+       bufferlen = ARRAY_LEN (psf->u.ucbuf) ;
+
+       while (len > 0)
+       {       if (len < bufferlen)
+                       bufferlen = (int) len ;
+               f2dsc_array (pxi, ptr + total, psf->u.scbuf, bufferlen, normfact) ;
+               writecount = psf_fwrite (psf->u.scbuf, sizeof (signed char), bufferlen, psf) ;
+               total += writecount ;
+               if (writecount < bufferlen)
+                       break ;
+               len -= writecount ;
+               } ;
+
+       return total ;
+} /* dpcm_write_f2dsc */
+
+static sf_count_t
+dpcm_write_d2dsc (SF_PRIVATE *psf, const double *ptr, sf_count_t len)
+{      XI_PRIVATE      *pxi ;
+       int                     bufferlen, writecount ;
+       sf_count_t      total = 0 ;
+       double          normfact ;
+
+       if ((pxi = psf->fdata) == NULL)
+               return 0 ;
+
+       normfact = (psf->norm_double == SF_TRUE) ? (1.0 * 0x7F) : 1.0 ;
+
+       bufferlen = ARRAY_LEN (psf->u.ucbuf) ;
+
+       while (len > 0)
+       {       if (len < bufferlen)
+                       bufferlen = (int) len ;
+               d2dsc_array (pxi, ptr + total, psf->u.scbuf, bufferlen, normfact) ;
+               writecount = psf_fwrite (psf->u.scbuf, sizeof (signed char), bufferlen, psf) ;
+               total += writecount ;
+               if (writecount < bufferlen)
+                       break ;
+               len -= writecount ;
+               } ;
+
+       return total ;
+} /* dpcm_write_d2dsc */
+
+
+static sf_count_t
+dpcm_write_s2dles (SF_PRIVATE *psf, const short *ptr, sf_count_t len)
+{      XI_PRIVATE      *pxi ;
+       int                     bufferlen, writecount ;
+       sf_count_t      total = 0 ;
+
+       if ((pxi = psf->fdata) == NULL)
+               return 0 ;
+
+       bufferlen = ARRAY_LEN (psf->u.sbuf) ;
+
+       while (len > 0)
+       {       if (len < bufferlen)
+                       bufferlen = (int) len ;
+               s2dles_array (pxi, ptr + total, psf->u.sbuf, bufferlen) ;
+               writecount = psf_fwrite (psf->u.sbuf, sizeof (short), bufferlen, psf) ;
+               total += writecount ;
+               if (writecount < bufferlen)
+                       break ;
+               len -= writecount ;
+               } ;
+
+       return total ;
+} /* dpcm_write_s2dles */
+
+static sf_count_t
+dpcm_write_i2dles (SF_PRIVATE *psf, const int *ptr, sf_count_t len)
+{      XI_PRIVATE      *pxi ;
+       int                     bufferlen, writecount ;
+       sf_count_t      total = 0 ;
+
+       if ((pxi = psf->fdata) == NULL)
+               return 0 ;
+
+       bufferlen = ARRAY_LEN (psf->u.sbuf) ;
+
+       while (len > 0)
+       {       if (len < bufferlen)
+                       bufferlen = (int) len ;
+               i2dles_array (pxi, ptr + total, psf->u.sbuf, bufferlen) ;
+               writecount = psf_fwrite (psf->u.sbuf, sizeof (short), bufferlen, psf) ;
+               total += writecount ;
+               if (writecount < bufferlen)
+                       break ;
+               len -= writecount ;
+               } ;
+
+       return total ;
+} /* dpcm_write_i2dles */
+
+static sf_count_t
+dpcm_write_f2dles (SF_PRIVATE *psf, const float *ptr, sf_count_t len)
+{      XI_PRIVATE      *pxi ;
+       int                     bufferlen, writecount ;
+       sf_count_t      total = 0 ;
+       float           normfact ;
+
+       if ((pxi = psf->fdata) == NULL)
+               return 0 ;
+
+       normfact = (psf->norm_float == SF_TRUE) ? (1.0 * 0x7FFF) : 1.0 ;
+
+       bufferlen = ARRAY_LEN (psf->u.sbuf) ;
+
+       while (len > 0)
+       {       if (len < bufferlen)
+                       bufferlen = (int) len ;
+               f2dles_array (pxi, ptr + total, psf->u.sbuf, bufferlen, normfact) ;
+               writecount = psf_fwrite (psf->u.sbuf, sizeof (short), bufferlen, psf) ;
+               total += writecount ;
+               if (writecount < bufferlen)
+                       break ;
+               len -= writecount ;
+               } ;
+
+       return total ;
+} /* dpcm_write_f2dles */
+
+static sf_count_t
+dpcm_write_d2dles (SF_PRIVATE *psf, const double *ptr, sf_count_t len)
+{      XI_PRIVATE      *pxi ;
+       int                     bufferlen, writecount ;
+       sf_count_t      total = 0 ;
+       double          normfact ;
+
+       if ((pxi = psf->fdata) == NULL)
+               return 0 ;
+
+       normfact = (psf->norm_double == SF_TRUE) ? (1.0 * 0x7FFF) : 1.0 ;
+
+       bufferlen = ARRAY_LEN (psf->u.sbuf) ;
+
+       while (len > 0)
+       {       if (len < bufferlen)
+                       bufferlen = (int) len ;
+               d2dles_array (pxi, ptr + total, psf->u.sbuf, bufferlen, normfact) ;
+               writecount = psf_fwrite (psf->u.sbuf, sizeof (short), bufferlen, psf) ;
+               total += writecount ;
+               if (writecount < bufferlen)
+                       break ;
+               len -= writecount ;
+               } ;
+
+       return total ;
+} /* dpcm_write_d2dles */
+
+
+/*==============================================================================
+*/
+
+static void
+dsc2s_array (XI_PRIVATE *pxi, signed char *src, int count, short *dest)
+{      signed char     last_val ;
+       int                     k ;
+
+       last_val = pxi->last_16 >> 8 ;
+
+       for (k = 0 ; k < count ; k++)
+       {       last_val += src [k] ;
+               dest [k] = last_val << 8 ;
+               } ;
+
+       pxi->last_16 = last_val << 8 ;
+} /* dsc2s_array */
+
+static void
+dsc2i_array (XI_PRIVATE *pxi, signed char *src, int count, int *dest)
+{      signed char     last_val ;
+       int                     k ;
+
+       last_val = pxi->last_16 >> 8 ;
+
+       for (k = 0 ; k < count ; k++)
+       {       last_val += src [k] ;
+               dest [k] = last_val << 24 ;
+               } ;
+
+       pxi->last_16 = last_val << 8 ;
+} /* dsc2i_array */
+
+static void
+dsc2f_array (XI_PRIVATE *pxi, signed char *src, int count, float *dest, float normfact)
+{      signed char     last_val ;
+       int                     k ;
+
+       last_val = pxi->last_16 >> 8 ;
+
+       for (k = 0 ; k < count ; k++)
+       {       last_val += src [k] ;
+               dest [k] = last_val * normfact ;
+               } ;
+
+       pxi->last_16 = last_val << 8 ;
+} /* dsc2f_array */
+
+static void
+dsc2d_array (XI_PRIVATE *pxi, signed char *src, int count, double *dest, double normfact)
+{      signed char     last_val ;
+       int                     k ;
+
+       last_val = pxi->last_16 >> 8 ;
+
+       for (k = 0 ; k < count ; k++)
+       {       last_val += src [k] ;
+               dest [k] = last_val * normfact ;
+               } ;
+
+       pxi->last_16 = last_val << 8 ;
+} /* dsc2d_array */
+
+/*------------------------------------------------------------------------------
+*/
+
+static void
+s2dsc_array (XI_PRIVATE *pxi, const short *src, signed char *dest, int count)
+{      signed char     last_val, current ;
+       int                     k ;
+
+       last_val = pxi->last_16 >> 8 ;
+
+       for (k = 0 ; k < count ; k++)
+       {       current = src [k] >> 8 ;
+               dest [k] = current - last_val ;
+               last_val = current ;
+               } ;
+
+       pxi->last_16 = last_val << 8 ;
+} /* s2dsc_array */
+
+static void
+i2dsc_array (XI_PRIVATE *pxi, const int *src, signed char *dest, int count)
+{      signed char     last_val, current ;
+       int                     k ;
+
+       last_val = pxi->last_16 >> 8 ;
+
+       for (k = 0 ; k < count ; k++)
+       {       current = src [k] >> 24 ;
+               dest [k] = current - last_val ;
+               last_val = current ;
+               } ;
+
+       pxi->last_16 = last_val << 8 ;
+} /* i2dsc_array */
+
+static void
+f2dsc_array (XI_PRIVATE *pxi, const float *src, signed char *dest, int count, float normfact)
+{      signed char     last_val, current ;
+       int                     k ;
+
+       last_val = pxi->last_16 >> 8 ;
+
+       for (k = 0 ; k < count ; k++)
+       {       current = lrintf (src [k] * normfact) ;
+               dest [k] = current - last_val ;
+               last_val = current ;
+               } ;
+
+       pxi->last_16 = last_val << 8 ;
+} /* f2dsc_array */
+
+static void
+d2dsc_array (XI_PRIVATE *pxi, const double *src, signed char *dest, int count, double normfact)
+{      signed char     last_val, current ;
+       int                     k ;
+
+       last_val = pxi->last_16 >> 8 ;
+
+       for (k = 0 ; k < count ; k++)
+       {       current = lrint (src [k] * normfact) ;
+               dest [k] = current - last_val ;
+               last_val = current ;
+               } ;
+
+       pxi->last_16 = last_val << 8 ;
+} /* d2dsc_array */
+
+/*==============================================================================
+*/
+
+static void
+dles2s_array (XI_PRIVATE *pxi, short *src, int count, short *dest)
+{      short   last_val ;
+       int             k ;
+
+       last_val = pxi->last_16 ;
+
+       for (k = 0 ; k < count ; k++)
+       {       last_val += LES2H_SHORT (src [k]) ;
+               dest [k] = last_val ;
+               } ;
+
+       pxi->last_16 = last_val ;
+} /* dles2s_array */
+
+static void
+dles2i_array (XI_PRIVATE *pxi, short *src, int count, int *dest)
+{      short   last_val ;
+       int             k ;
+
+       last_val = pxi->last_16 ;
+
+       for (k = 0 ; k < count ; k++)
+       {       last_val += LES2H_SHORT (src [k]) ;
+               dest [k] = last_val << 16 ;
+               } ;
+
+       pxi->last_16 = last_val ;
+} /* dles2i_array */
+
+static void
+dles2f_array (XI_PRIVATE *pxi, short *src, int count, float *dest, float normfact)
+{      short   last_val ;
+       int             k ;
+
+       last_val = pxi->last_16 ;
+
+       for (k = 0 ; k < count ; k++)
+       {       last_val += LES2H_SHORT (src [k]) ;
+               dest [k] = last_val * normfact ;
+               } ;
+
+       pxi->last_16 = last_val ;
+} /* dles2f_array */
+
+static void
+dles2d_array (XI_PRIVATE *pxi, short *src, int count, double *dest, double normfact)
+{      short   last_val ;
+       int             k ;
+
+       last_val = pxi->last_16 ;
+
+       for (k = 0 ; k < count ; k++)
+       {       last_val += LES2H_SHORT (src [k]) ;
+               dest [k] = last_val * normfact ;
+               } ;
+
+       pxi->last_16 = last_val ;
+} /* dles2d_array */
+
+/*------------------------------------------------------------------------------
+*/
+
+static void
+s2dles_array (XI_PRIVATE *pxi, const short *src, short *dest, int count)
+{      short   diff, last_val ;
+       int             k ;
+
+       last_val = pxi->last_16 ;
+
+       for (k = 0 ; k < count ; k++)
+       {       diff = src [k] - last_val ;
+               dest [k] = LES2H_SHORT (diff) ;
+               last_val = src [k] ;
+               } ;
+
+       pxi->last_16 = last_val ;
+} /* s2dles_array */
+
+static void
+i2dles_array (XI_PRIVATE *pxi, const int *src, short *dest, int count)
+{      short   diff, last_val ;
+       int             k ;
+
+       last_val = pxi->last_16 ;
+
+       for (k = 0 ; k < count ; k++)
+       {       diff = (src [k] >> 16) - last_val ;
+               dest [k] = LES2H_SHORT (diff) ;
+               last_val = src [k] >> 16 ;
+               } ;
+
+       pxi->last_16 = last_val ;
+} /* i2dles_array */
+
+static void
+f2dles_array (XI_PRIVATE *pxi, const float *src, short *dest, int count, float normfact)
+{      short   diff, last_val, current ;
+       int             k ;
+
+       last_val = pxi->last_16 ;
+
+       for (k = 0 ; k < count ; k++)
+       {       current = lrintf (src [k] * normfact) ;
+               diff = current - last_val ;
+               dest [k] = LES2H_SHORT (diff) ;
+               last_val = current ;
+               } ;
+
+       pxi->last_16 = last_val ;
+} /* f2dles_array */
+
+static void
+d2dles_array (XI_PRIVATE *pxi, const double *src, short *dest, int count, double normfact)
+{      short   diff, last_val, current ;
+       int             k ;
+
+       last_val = pxi->last_16 ;
+
+       for (k = 0 ; k < count ; k++)
+       {       current = lrint (src [k] * normfact) ;
+               diff = current - last_val ;
+               dest [k] = LES2H_SHORT (diff) ;
+               last_val = current ;
+               } ;
+
+       pxi->last_16 = last_val ;
+} /* d2dles_array */
+
+/*
+** Do not edit or modify anything in this comment block.
+** The arch-tag line is a file identity tag for the GNU Arch 
+** revision control system.
+**
+** arch-tag: 1ab2dbe0-29af-4d80-9c6f-cb21b67521bc
+*/